常见面试笔试题verilog程序库.docx
《常见面试笔试题verilog程序库.docx》由会员分享,可在线阅读,更多相关《常见面试笔试题verilog程序库.docx(23页珍藏版)》请在冰豆网上搜索。
常见面试笔试题verilog程序库
加减法
moduleaddsub
(input[7:
0]dataa,
input[7:
0]datab,
inputadd_sub,//ifthisis1,add;elsesubtract
inputclk,
outputreg[8:
0]result);
always@(posedgeclk)
begin
if(add_sub)result<=dataa+datab;//or"assign{cout,sum}=dataa+datab;"
elseresult<=dataa-datab;
end
endmodule
四位的全加法器.
moduleadd4(cout,sum,a,b,cin)
input[3:
0]a,b;inputcin;
output[3:
0]sum;outputcout;
assign{cout,sum}=a+b+cin;
endmodule
补码不仅可以执行正值和负值转换,其实补码存在的意义,就是避免计算机去做减法的操作。
1101-3补
+10008
01015
假设-3+8,只要将-3转为补码形式,亦即0011=>1101,然后和8,亦即1000相加
就会得到5,亦即0101。
至于溢出的最高位可以无视掉。
乘法器
modulemult(outcome,a,b);
parameterSIZE=8;
input[SIZE:
1]a,b;
outputreg[2*SIZE:
1]outcome;
integeri;
always@(aorb)
beginoutcome<=0;
for(i=0,i<=SIZE;i=i+1)
if(b[i])outcome<=outcome+(a<<(i-1));
end
endmodule
另一种乘法器。
在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。
输出结果根据正负关系取得。
elseif(Start_Sig)
case(i)
0:
begin
isNeg<=Multiplicand[7]^Multiplier[7];
Mcand<=Multiplicand[7]?
(~Multiplicand+1'b1):
Multiplicand;
Mer<=Multiplier[7]?
(~Multiplier+1'b1):
Multiplier;
Temp<=16'd0;
i<=i+1'b1;
end
1:
//Multipling
if(Mer==0)i<=i+1'b1;
elsebeginTemp<=Temp+Mcand;Mer<=Mer-1'b1;end
2:
beginisDone<=1'b1;i<=i+1'b1;end
3:
beginisDone<=1'b0;i<=2'd0;end
endcase
assignDone_Sig=isDone;
assignProduct=isNeg?
(~Temp+1'b1):
Temp;
endmodule
booth乘法器
modulebooth_multiplier_module
(
inputCLK,
inputRSTn,
inputStart_Sig,
input[7:
0]A,
input[7:
0]B,
outputDone_Sig,
output[15:
0]Product,
output[7:
0]SQ_a,
output[7:
0]SQ_s,
output[16:
0]SQ_p
);
reg[3:
0]i;
reg[7:
0]a;//resultofA
reg[7:
0]s;//reverseresultofA
reg[16:
0]p;//p空间,16+1位
reg[3:
0]X;//指示n次循环
regisDone;
always@(posedgeCLKornegedgeRSTn)
if(!
RSTn)
begin
i<=4'd0;
a<=8'd0;
s<=8'd0;
p<=17'd0;
X<=4'd0;
isDone<=1'b0;
end
elseif(Start_Sig)
case(i)
0:
begina<=A;s<=(~A+1'b1);p<={8'd0,B,1'b0};i<=i+1'b1;end
1:
if(X==8)beginX<=4'd0;i<=i+4'd2;end
elseif(p[1:
0]==2'b01)beginp<={p[16:
9]+a,p[8:
0]};i<=i+1'b1;end
elseif(p[1:
0]==2'b10)beginp<={p[16:
9]+s,p[8:
0]};i<=i+1'b1;end
elsei<=i+1'b1;//00和11,无操作
2:
beginp<={p[16],p[16:
1]};X<=X+1'b1;i<=i-1'b1;end//右移,最高位补0or1.
3:
beginisDone<=1'b1;i<=i+1'b1;end
4:
beginisDone<=1'b0;i<=4'd0;end
endcase
assignDone_Sig=isDone;
assignProduct=p[16:
1];
endmodule
除法器
moduledivider_module
(
inputCLK,
inputRSTn,
inputStart_Sig,
input[7:
0]Dividend,
input[7:
0]Divisor,
outputDone_Sig,
output[7:
0]Quotient,
output[7:
0]Reminder,
);
reg[3:
0]i;
reg[7:
0]Dend;
reg[7:
0]Dsor;
reg[7:
0]Q;
reg[7:
0]R;
regisNeg;
regisDone;
always@(posedgeCLKornegedgeRSTn)
if(!
RSTn)
begin
i<=4'd0;
Dend<=8'd0;
Dsor<=8'd0;
Q<=8'd0;
isNeg<=1'b0;
isDone<=1'b0;
end
elseif(Start_Sig)
case(i)
0:
begin
Dend<=Dividend[7]?
~Dividend+1'b1:
Dividend;
Dsor<=Divisor[7]?
Divisor:
(~Divisor+1'b1);
isNeg<=Dividend[7]^Divisor[7];
i<=i+1'b1;
end
1:
if(Divisor>Dend)
beginQ<=isNeg?
(~Q+1'b1):
Q;i<=i+1'b1;end
elsebeginDend<=Dend+Dsor;Q<=Q+1'b1;end
2:
beginisDone<=1'b1;i<=i+1'b1;end
3:
beginisDone<=1'b0;i<=4'd0;end
endcase
assignDone_Sig=isDone;
assignQuotient=Q;
assignReminder=Dend;
endmodule
除法器2
modulediv(a,b,clk,result,yu)
input[3:
0]a,b;
outputreg[3:
0]result,yu;
inputclk;reg[1:
0]state;reg[3:
0]m,n;
parameterS0=2'b00,S1=2'b01,S2=2'b10;
always@(posedgeclk)
begincase(state)
S0:
beginif(a>b)beginn<=a-b;m<=4'b0001;state<=S1;end
elsebeginm<=4'b0000;n<=a;state<=S2;end
end
S1:
beginif(n>=b)beginm<=m+1;n<=n-b;state<=S1;end
elsebeginstate<=S2;end
end
S2:
beginresult<=m;yu<=n;state<=S0;end
defule:
state<=S0;
endcase
end
endmodule
13、一个可预置初值的7进制循环计数器
①verilog
modulecount(clk,reset,load,date,out);
inputload,clk,reset;
input[3:
0]date;
outputreg[3:
0]out;
parameterWIDTH=4'd7;
always@(clkorreset)
begin
if(reset)out<=4'd0;
elseif(load)out<=date;
elseif(out==WIDTH-1)out<=4'd0;
elseout<=out+1;
end
endmodule
Johnson计数器
约翰逊(Johnson)计数器又称扭环计数器,是一种用n位触发器来表示2n个状态的计数器。
它与环形计数器不同,后者用n位触发器仅可表示n个状态。
n位二进制计数器(n为触发器的个数)有2^n个状态。
若以四位二进制计数器为例,它可表示16个状态。
“0000-1000-1100-1110-1111-0111-0011-0001-0000-1000……”
moduleJohnson(inputclk,inputclr,outputreg[N-1:
0]q);
always@(posedgeclkornegedgeclr)
if(!
clr)q<={N{1’b0}}
elseif(!
q[0])q<={1’b1,q[N-1:
1]};
elseq<={1’b0,q[N-1]:
1}];
endmodule
任意分频,占空比不为50%
always(clk)
beginif(count==x-1)count<=0;
elsecount<=count+1;end
assignclkout=count[y]//y一般用count的最高位
偶数分频(8分频,占空比50%)(计数至n-1,翻转)
modulecount5(reset,clk,out)
inputclk,reset;outputout;
reg[1:
0]count;
always@(clk)
if(reset)begincount<=0;out<=0;end
elseif(count==3)begincount<=0;out<=!
out:
end
elsecount<=count+1;
endmodule
奇数分频电路(占空比50%)。
modulecount5(reset,clk,out)
inputclk,reset;outputout;
reg[2:
0]m,n;
regcount1;regcount2;
always@(posedgeclk)
begin
if(reset)beginm<=0;count1<=0;end
elsebeginif(m==4)m<=0;elsem<=m+1;//“4”为分频数NUM-1,NUM=5
if(m<2)count1<=1;elsecount1<=0;end
end
always@(negedgeclk)
begin
if(reset)beginn<=0;count2<=0;end
elsebeginif(n==4)n<=0;elsen<=n+1;
if(n<2)count2<=1;elsecount2<=0;end
end
assignout=count1|count2;
半整数分频
modulefdiv5_5(clkin,clr,clkout)
inputclkin,clr;outputregclkout;
regclk1;wireclk2;integercount;
xorxor1(clk2,clkin,clk1)
always@(posedgeclkoutornegedgeclr)
beginif(~clr)beginclk1<=1’b0;end
elseclk1<=~clk1;
end
always@(posedgeclk2ornegedgeclr)
beginif(~clr)
begincount<=0;clkout<=1’b0;end
elseif(count==5)
begincount<=0;clkout<=1’b1;end
elsebegincount<=count+1;clkout<=1’b0;end
end
endmodule
小数分频
N=M/P.N为分配比,M为分频器输入脉冲数,P为分频器输出脉冲数。
N=(8×9+9×1)/(9+1)=8.1先做9次8分频再做1次9分频。
modulefdiv8_1(clkin,rst,clkout)
inputclkin,rst;outputregclkout;
reg[3:
0]cnt1,cnt2;
always@(posedgeclkinorposedgerst)
beginif(rst)begincnt1<=0;cnt2<=0;clkout<=0;end
elseif(cnt1<9)//cnt1,0~8
begin
if(cnt2<7)begincnt2<=cnt2+1;clkout<=0;end
elsebegincnt2<=0;cnt1<=cnt1+1;clkout<=1;end
end
elsebegin//cnt1,9
if(cnt2<8)begincnt2<=cnt2+1;clkout<=0;end
elsebegincnt2<=0;cnt1<=0;clkout<=1;end
end
end
endmodule
串并转换
modulep2s(clk,clr,load,pi,so)
inputclk,clr,load;
input[3:
0]pi;
outputso;
reg[3:
0]r;
always@(posedgeclkornegedgeclr)
if(~clr)r<=4'h0;
elseif(load)r<=pi;
elser<={r,1'b0};//orr<<1;
assignso=r[3];
endmodule
modules2p(clk,clr,en,si,po)
inputclk,clr,en,si;
output[3:
0]po;
always@(posedgeclkornegedgeclr)
if(~clr)r<=8’ho;
elser<={r,si};
assignpo=(en)?
r:
4’h0;
endmodule
b)试用VHDL或VERILOG、ABLE描述8位D触发器逻辑。
moduledff(q,qn,d,clk,set,reset)
input[7:
0]d,set;
inputclk,reset;
outputreg[7:
0]q,qn;
always@(posedgeclk)
begin
if(reset)beginq<=8’h00;qn<=8’hFF;end
elseif(set)beginq<=8’hFF;qn<=8’h00;end
elsebeginq<=d;qn<=~d;end
end
endmodule
序列检测“101”
modulexulie101(clk,clr,x,z);
inputclk,clr,x;outputregz;
reg[1:
0]state,next_state;
parameters0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;
always@(posedgeclkorposedgeclr)
beginif(clr)state<=s0;
elsestate<=next_state;
end
always@(stateorx)
begin
case(state)
s0:
beginif(x)next_state<=s1;
elsenext_state<=s0;end
s1:
beginif(x)next_state<=s1;
elsenext_state<=s2;end
s2:
beginif(x)next_state<=s3;
elsenext_state<=s0;end
s3:
beginif(x)next_state<=s1;
elsenext_state<=s2;end
default:
next_state<=s0;
endcase
end
always@(state)
begincase(state)
s3:
z=1;
default:
z=0;
endcase
end
endmodule
按键消抖
1.采用一个频率较低的时钟,对输入进行采样,消除抖动。
moduleswitch(clk,keyin,keyout)
parameterCOUNTWIDTH=8;
inputclk,keyin;outputregkeyout;reg[COUNTWIDTH-1:
0]counter;
wireclk_use;//频率较低的时钟
assignclk_use=counter[COUNTWIDTH-1];
always@(posegdeclk)
counter<=counter+1’b1;
always@(posedgeclk_use)
keyout<=keyin;
endmodule
2.moduleswitch(clk,keyin,keyout)
parameterCOUNTWIDTH=8;
inputclk,keyin;outputregkeyout;reg[COUNTWIDTH-1:
0]counter;
initialcounter<=0,keyout<=0,keyin<=0;
always@(posegdeclk)
if(keyin=1)beginkey_m<=keyin,counter<=counter+1;end
elsecounter<=0;
if(keyin&&counter[m])keyout<=1;//m定义时延
endmodule
数码管显示
modulenumber_mod_module//分别取得数字的十位和个位
(CLK,RSTn,Number_Data,Ten_Data,One_Data);
inputCLK;
inputRSTn;
input[7:
0]Number_Data;
output[3:
0]Ten_Data;
output[3:
0]One_Data;
reg[31:
0]rTen;
reg[31:
0]rOne;
always@(posedgeCLKornegedgeRSTn)
if(!
RSTn)
begin
rTen<=32'd0;
rOne<=32'd0;
end
else
begin
rTen<=Number_Data/10;
rOne<=Number_Data%10;
end
assignTen_Data=rTen[3:
0];
assignOne_Data=rOne[3:
0];
endmodule
moduleled(CLK,Ten_Data,One_Data,led0,led1);//数码管显示
input[3:
0]Ten_Data,One_Data;
inputCLK;
output[7:
0]led0,led1;
reg[7:
0]led0,led1;
always@(posedgecp_50)
begin
casez(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;
endcase
casez(Ten_Data)
4'd0:
led1=