常见面试笔试题-verilog程序库(共14页).docx
精选优质文档-倾情为你奉上加减法module addsub ( input 7:0 dataa, input 7:0 datab, input add_sub, / if this is 1, add; else subtract input clk, output reg 8:0 result ); always (posedge clk) begin if (add_sub) result <= dataa + datab; /or "assign cout,sum=dataa+datab;" else result <= dataa - datab; end endmodule 四位的 全加法器.module add4(cout,sum,a,b,cin)input3:0a,b; input cin;output 3:0 sum; output cout;assign cout,sum=a+b+cin;endmodule补码不仅可以执行正值和负值转换,其实补码存在的意义,就是避免计算机去做减法的操作。1101 -3 补+ 1000 8 01015 假设 -3 + 8,只要将 -3 转为补码形式,亦即 0011 => 1101,然后和 8,亦即 1000 相加就会得到 5,亦即 0101。至于溢出的最高位可以无视掉。乘法器module mult(outcome,a,b);parameter SIZE=8;inputSIZE:1 a,b;output reg2*SIZE:1 outcome;integer i;always (a or b) begin outcome<=0; for(i=0,i<=SIZE;i=i+1) if(bi) outcome<=outcome+(a<<(i-1); endendmodule另一种乘法器。在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。输出结果根据正负关系取得。else if( Start_Sig ) case( i ) 0: begin isNeg <= Multiplicand7 Multiplier7; Mcand <= Multiplicand7 ? ( Multiplicand + 1'b1 ) : Multiplicand; Mer <= Multiplier7 ? ( Multiplier + 1'b1 ) : Multiplier; Temp <= 16'd0; i <= i + 1'b1; end 1: / Multipling if( Mer = 0 ) i <= i + 1'b1; else begin Temp <= Temp + Mcand; Mer <= Mer - 1'b1; end 2: begin isDone <= 1'b1; i <= i + 1'b1; end 3: begin isDone <= 1'b0; i <= 2'd0; end endcase assign Done_Sig = isDone; assign Product = isNeg ? ( Temp + 1'b1 ) : Temp; endmodule booth乘法器 module booth_multiplier_module( input CLK, input RSTn, input Start_Sig, input 7:0A, input 7:0B, output Done_Sig, output 15:0Product, output 7:0SQ_a, output 7:0SQ_s, output 16:0SQ_p); reg 3:0i; reg 7:0a; / result of A reg 7:0s; / reverse result of A reg 16:0p; / p空间,16+1位 reg 3:0X;/指示n次循环 reg isDone;always ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; a <= 8'd0; s <= 8'd0; p <= 17'd0; X <= 4'd0; isDone <= 1'b0;end else if( Start_Sig ) case( i )0: begin a <= A; s <= ( A + 1'b1 ); p <= 8'd0 , B , 1'b0 ; i <= i + 1'b1; end1: if( X = 8 ) begin X <= 4'd0; i <= i + 4'd2; endelse if( p1:0 = 2'b01 ) begin p <= p16:9 + a , p8:0 ; i <= i + 1'b1; endelse if( p1:0 = 2'b10 ) begin p <= p16:9 + s , p8:0 ; i <= i + 1'b1; endelse i <= i + 1'b1;/00和11,无操作2:begin p <= p16 , p16:1 ; X <= X + 1'b1; i <= i - 1'b1; end /右移,最高位补0 or 1.3:begin isDone <= 1'b1; i <= i + 1'b1; end4:begin isDone <= 1'b0; i <= 4'd0; endendcase assign Done_Sig = isDone; assign Product = p16:1;endmodule 除法器module divider_module( input CLK, input RSTn, input Start_Sig, input 7:0Dividend, input 7:0Divisor, output Done_Sig, output 7:0Quotient, output 7:0Reminder, ); reg 3:0i; reg 7:0Dend; reg 7:0Dsor;reg 7:0Q;reg 7:0R; reg isNeg; reg isDone; always ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; Dend <= 8'd0; Dsor <= 8'd0; Q <= 8'd0; isNeg <= 1'b0; isDone <= 1'b0; end else if( Start_Sig ) case( i ) 0: begin Dend <= Dividend7 ? Dividend + 1'b1 : Dividend; Dsor <= Divisor7 ? Divisor : ( Divisor + 1'b1 ); isNeg <= Dividend7 Divisor7; i <= i + 1'b1; end 1: if( Divisor > Dend ) begin Q <= isNeg ? ( Q + 1'b1 ) : Q; i <= i + 1'b1; endelse begin Dend <= Dend + Dsor; Q <= Q + 1'b1; end2: begin isDone <= 1'b1; i <= i + 1'b1; end3: begin isDone <= 1'b0; i <= 4'd0; end endcase assign Done_Sig = isDone; assign Quotient = Q;assign Reminder = Dend;endmodule 除法器2module div(a,b,clk,result,yu) input3:0a,b; output reg3:0 result,yu; input clk; reg1:0 state;reg3:0 m,n; parameter S0=2'b00,S1=2'b01,S2=2'b10; always(posedge clk) begin case(state) S0: begin if(a>b) begin n<=a-b;m<=4'b0001; state<=S1; end else begin m<=4'b0000;n<=a; state<=S2; end end S1: begin if(n>=b) begin m<=m+1;n<=n-b;state<=S1;end else begin state<=S2;end end S2: begin result<=m;yu<=n;state<=S0;end defule:state<=S0; endcase endendmodule13、一个可预置初值的7进制循环计数器verilogmodule count(clk,reset,load,date,out);input load,clk,reset;input3:0 date;output reg3:0 out;parameter WIDTH=4'd7;always(clk or reset)beginif(reset) out<=4'd0;else if(load)out<=date;else if(out=WIDTH-1) out<=4'd0;else out<=out+1;endendmoduleJohnson计数器约翰逊(Johnson)计数器又称扭环计数器,是一种用n位触发器来表示2n个状态的计数器。它与环形计数器不同,后者用n位触发器仅可表示n个状态。n位二进制计数器(n为触发器的个数)有2n个状态。若以四位二进制计数器为例,它可表示16个状态。“0000-1000-1100-1110-1111-0111-0011-0001-0000-1000”module Johnson(input clk,input clr,output regN-1:0 q);always(posedge clk or negedge clr)if(!clr)q<=N1b0else if(!q0)q<=1b1,qN-1:1;elseq<=1b0,qN-1:1;endmodule任意分频,占空比不为50%always(clk)beginif(count=x-1) count<=0;elsecount<=count+1;endassign clkout=county/y一般用count的最高位偶数分频(8分频,占空比50%)(计数至n-1,翻转)module count5(reset,clk,out)input clk,reset;output out;reg1:0 count;always(clk)if(reset) begin count<=0; out<=0; endelse if(count=3)begin count<=0;out<=!out: endelse count<=count+1;endmodule奇数分频电路(占空比50%)。module count5(reset,clk,out)input clk,reset;output out;reg2:0 m,n;reg count1;reg count2;always(posedge clk)beginif(reset) beginm<=0;count1<=0;endelsebegin if(m=4) m<=0; else m<=m+1; /“4”为分频数NUM-1,NUM=5if(m<2) count1<=1; else count1<=0;endendalways(negedge clk)beginif(reset) beginn<=0;count2<=0;endelsebegin if(n=4) n<=0; else n<=n+1;if(n<2) count2<=1; else count2<=0;endendassign out=count1|count2;半整数分频module fdiv5_5(clkin,clr,clkout)input clkin,clr;output reg clkout;reg clk1; wire clk2; integer count;xor xor1(clk2,clkin,clk1)always(posedge clkout or negedge clr)beginif(clr) begin clk1<=1b0; endelse clk1<=clk1;endalways( posedge clk2 or negedge clr)beginif(clr)begin count<=0; clkout<=1b0; endelse if(count=5)begin count<=0; clkout<=1b1; endelse begin count<=count+1; clkout<=1b0; endend endmodule 小数分频N=M/P. N为分配比,M为分频器输入脉冲数,P为分频器输出脉冲数。N=(8×9+9×1)/(9+1)=8.1 先做9次8分频再做1次9分频。module fdiv8_1(clkin,rst,clkout) input clkin,rst; output reg clkout; reg3:0 cnt1,cnt2; always(posedge clkin or posedge rst) begin if(rst) begin cnt1<=0;cnt2<=0;clkout<=0; end else if(cnt1<9) /cnt1, 08 begin if(cnt2<7) begin cnt2<=cnt2+1;clkout<=0; end else begin cnt2<=0;cnt1<=cnt1+1;clkout<=1; end end else begin /cnt1, 9 if(cnt2<8) begin cnt2<=cnt2+1;clkout<=0; end else begin cnt2<=0;cnt1<=0;clkout<=1;end end endendmodule串并转换module p2s(clk,clr,load,pi,so)input clk,clr,load;input 3:0 pi;output so;reg3:0 r;always(posedge clk or negedge clr)if(clr)r<=4'h0;else if(load)r<=pi;elser<=r, 1'b0; / or r<<1;assign so=r3;endmodulemodule s2p(clk,clr,en,si,po)input clk,clr,en,si;output3:0 po;always(posedge clk or negedge clr)if(clr)r<=8ho;else r<=r,si;assign po=(en) ? r : 4h0;endmoduleb) 试用VHDL或VERILOG、ABLE描述8位D触发器逻辑。module dff(q,qn,d,clk,set,reset)input7:0 d,set;input clk,reset;output reg7:0 q,qn;always (posedge clk) beginif(reset) beginq<=8h00; qn<=8hFF;endelse if(set) beginq<=8hFF; qn<=8h00;endelse begin q<=d; qn<=d; endendendmodule序列检测“101”module xulie101(clk,clr,x,z);input clk,clr,x;output reg z;reg1:0 state,next_state;parameter s0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;always (posedge clk or posedge clr)begin if(clr) state<=s0;else state<=next_state;endalways (state or x)begincase(state)s0:begin if(x)next_state<=s1; elsenext_state<=s0;ends1:begin if(x)next_state<=s1; elsenext_state<=s2;ends2:begin if(x)next_state<=s3; elsenext_state<=s0;ends3:begin if(x)next_state<=s1; elsenext_state<=s2;enddefault: next_state<=s0;endcaseendalways (state)begincase(state)s3:z=1;default:z=0;endcaseendendmodule按键消抖1. 采用一个频率较低的时钟,对输入进行采样,消除抖动。module switch(clk,keyin,keyout)parameter COUNTWIDTH=8;input clk,keyin;output reg keyout; regCOUNTWIDTH-1:0 counter;wire clk_use;/频率较低的时钟assign clk_use=counterCOUNTWIDTH-1;always(posegde clk)counter<=counter+1b1;always(posedge clk_use)keyout<=keyin;endmodule2. module switch(clk,keyin,keyout)parameter COUNTWIDTH=8;input clk,keyin;output reg keyout; regCOUNTWIDTH-1:0 counter;initial counter<=0,keyout<=0,keyin<=0;always(posegde clk)if(keyin=1) begin key_m<=keyin, counter<=counter+1;endelse counter<=0;if(keyin&&counterm) keyout<=1;/m定义时延endmodule数码管显示module number_mod_module /分别取得数字的十位和个位(CLK, RSTn, Number_Data, Ten_Data, One_Data); input CLK; input RSTn; input 7:0Number_Data; output 3:0Ten_Data; output 3:0One_Data; reg 31:0rTen; reg 31:0rOne; always ( posedge CLK or negedge RSTn ) if( !RSTn ) begin rTen <= 32'd0; rOne <= 32'd0;endelse begin rTen <= Number_Data / 10; rOne <= Number_Data % 10; end assign Ten_Data = rTen3:0; assign One_Data = rOne3:0;endmodulemodule led(CLK, Ten_Data, One_Data,led0, led1); /数码管显示input 3:0 Ten_Data, One_Data;input CLK;output 7:0 led0, led1;reg7:0 led0, led1;always ( posedge cp_50)begincasez (One_Data)4'd0 : led0 = 8'b1100_0000;4'd1 : led0 = 8'b1111_1001;4'd2 : led0 = 8'b1010_0100;4'd3 : led0 = 8'b1011_0000;4'd4 : led0 = 8'b1001_1001;4'd5 : led0 = 8'b1001_0010;4'd6 : led0 = 8'b1000_0010;4'd7 : led0 = 8'b1111_1000;4'd8 : led0 = 8'b1000_0000;4'd9 : led0 = 8'b1001_0000;default: led0 = 8'b1111_1111;endcasecasez (Ten_Data)4'd0 : led1 = 8'b1100_0000;4'd1 : led1 = 8'b1111_1001;4'd2 : led1 = 8'b1010_0100;4'd3 : led1 = 8'b1011_0000;4'd4 : led1 = 8'b1001_1001;4'd5 : led1 = 8'b1001_0010;4'd6 : led1 = 8'b1000_0010;4'd7 : led1 = 8'b1111_1000;4'd8 : led1 = 8'b1000_0000;4'd9 : led1 = 8'b1001_0000;default: led0 = 8'b1111_1111;endcaseendendmodule5. fifo控制器.FIFO存储器 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 在系统设计中,以增加数据传输率、处理大量数据流、匹配具有不同传输率的系统为目的而广泛使用FIFO存储器,从而提高了系统性能.FIFO参数:FIFO的宽度,the width,指FIFO一次读写操作的数据位;FIFO深度,THE DEEPTH,指FIFO可以存储多少个N位的数据;满标志,FIFO已满或将要满时送出的一个信号,以阻止FIFO的血操作继续向FIFO中写数据而造成溢出(overflow);空标志,阻止FIFIO的读操作;module fifo_module( input CLK, input RSTn, input Write_Req, input 7:0FIFO_Write_Data, input Read_Req, output 7:0FIFO_Read_Data, output Full_Sig, output Empty_Sig, /*/ output 7:0SQ_rS1, output 7:0SQ_rS2, output 7:0SQ_rS3, output 7:0SQ_rS4, output 2:0SQ_Count /*/); /*/ parameter DEEP = 3'd4; /*/ reg 7:0rShift DEEP:0; reg 2:0Count; reg 7:0Data; always ( posedge CLK or negedge RSTn ) if( !RSTn ) begin rShift0 <= 8'd0; rShift1 <= 8'd0; rShift2 <= 8'd0; rShift3 <= 8'd0; rShift4 <= 8'd0; Count <= 3'd0; Data <= 8'd0; end else if( Read_Req && Write_Req && Count < DEEP && Count > 0 ) begin rShift1 <= FIFO_Write_Data; rShift2 <= rShift1; rShift3 <= rShift2; rShift4 <= rShift3; Data <= rShift Count ; end else if( Write_Req && Count < DEEP ) begin rShift1 <= FIFO_Write_Data; rShift2 <= rShift1; rShift3 <= rShift2; rShift4 <= rShift3; Count <= Count + 1'b1; end else if( Read_Req && Count > 0 ) begin Data <= rShiftCount; Count <= Count - 1'b1; end /*/ assign FIFO_Read_Data = Data; assign Full_Sig = ( Count = DEEP ) ? 1'b1 : 1'b0; assign Empty_Sig = ( Count = 0 ) ? 1'b1 : 1'b0; /*/ assign SQ_rS1 = rShift1; assign SQ_rS2 = rShift2; assign SQ_rS3 = rShift3; assign SQ_rS4 = rShift4; assign SQ_Count = Count; /*/Endmodulefifi 2 (指针控制)module FIFO(date,q,clr,clk,we,re,ff,ef);parameter WIDTH=8,DEEPTH=8,ADDR=3;input clk,clr;input we,re;inputWIDTH-1:0 date;output ff,ef;output regWIDTH-1:0 q;regWIDTH-1:0 mem_dateDEEPTH-1:0;regADDR-1:0 waddr,raddr;reg ff,ef;always(posedge clk or negedge clr)/写地址begin if(!clr) waddr=0;else if(we=1&&ff=0) waddr=waddr+1;else if(we=1&&ff=0&&waddr=7) waddr=0;endalways(posedge clk)begin if(we&&!ff) mem_datewaddr=date;endalways(posedge clk or negedge clr)/读地址begin if(!clr) raddr=0;else if(re=1&&ef