第7章代码.docx
《第7章代码.docx》由会员分享,可在线阅读,更多相关《第7章代码.docx(12页珍藏版)》请在冰豆网上搜索。
第7章代码
第7章基于Verilog的时序电路设计及验证
7.1.3带清零D锁存器一
modulelatch_1_c(Clk,D,Q,Rst);
inputClk,D,Rst;
outputQ;
regQ;
always@(DorClkorRst)
if(!
Rst)Q<=0;//语句1
elseif(Clk)Q<=D;
endmodule
程序说明:
(1)程序采用具有时序语句特色的进程语句,其中数据信号D、时钟信号Clk和清0(复位)信号Rst都被列于敏感信号表中,实现了Clk的电平触发特性和Rst的异步特性。
(2)异步清0实现的效果,就是当Rst一旦变成0,就马上对输出进行清0,而不需要理会时钟、输入数据等的状态。
也就是Rst是优先级最高的控制信号,在代码(语句1)中,可通过“if…elseif…”语句来实现优先级控制。
测试平台设计
`timescale1ns/1ns
moduletestbench_latch;
regclk,D,rst;
wireQ;
initial
begin
clk=0;
#50clk=1;
#70clk=0;
#80clk=1;
end
initial
begin
D=0;
repeat(20)
#20D=$random;
end
initial
begin
rst=0;
#60rst=1;
#80rst=0;
#40rst=1;
end
latch_1_ctestbench_latch(clk,D,Q,rst);
endmodule
7.2.2D触发器二(异步清零边沿触发)
moduled_ff_2(D,Clk,Q,Rst,En);
inputD,Clk,Rst,En;
outputQ;
regQ;
always@(posedgeClkornegedgeRst)
begin
if(!
Rst)Q<=0;
elseif(En)Q<=D;
end
endmodule
测试平台设计
`timescale1ns/1ns
moduletestbench;
regD,Rst,Clk,En;
wireQ;
initial
Clk=0;
parameterclock_period=20;
always#(clock_period/2)Clk=~Clk;
initial
begin
D=0;
repeat(20)
#20D=$random;
end
initial
begin
Rst=0;
repeat(20)
#20Rst=$random;
end
initial
begin
En=0;
repeat(20)
#20En=$random;
end
d_ff_2testbench_dff(D,Clk,Q,Rst,En);
initial
#400$finish;
endmodule
7.2.7JK触发器
modulejk_ff(J,K,Clk,Q,Qn);
inputJ,K,Clk;
outputQ,Qn;
regQ;
assignQn=~Q;
always@(posedgeClk)
case({J,K})
2'b00:
Q<=Q;
2'b01:
Q<=1'b0;
2'b10:
Q<=1'b1;
2'b11:
Q<=~Q;
default:
Q<=1'bx;
endcase
endmodule
测试平台设计
`timescale1ns/1ns
moduletestbench;
regj,k,Clk;
wireQ,Qn;
initial
Clk=0;
parameterclock_period=20;
always#(clock_period/2)Clk=~Clk;
initial
begin
j=0;
repeat(20)
#20j=$random;
end
initial
begin
k=0;
repeat(20)
#20k=$random;
end
initial
#300$finish;
jk_fftestbench_jk(j,k,Clk,Q,Qn);
endmodule
7.3.2基本寄存器二(异步清零异步置1)
以下的设计具有异步清零端(Aclr)和异步置1端(Aset),异步清零的优先级比异步置1高。
modulereg4_2(Data,Aclr,Aset,Clock,Q);
input[3:
0]Data;
inputAclr;
inputAset;
inputClock;
output[3:
0]Q;
reg[3:
0]Q;
always@(posedgeClockornegedgeAclrorposedgeAset)
if(!
Aclr)
Q<=4'b0000;
elseif(Aset)
Q<=4'b1111;
elseQ<=Data;
endmodule
测试平台设计
`timescale1ns/1ns
moduletestbench;
reg[3:
0]Data;
regAclr,Aset,Clock;
wire[3:
0]Q;
initial
Clock=0;
parameterclock_period=20;
always#(clock_period/2)Clock=~Clock;
initial
begin
Data=0;
repeat(20)
#20Data=$random;
end
initial
begin
Aclr=0;
repeat(20)
#20Aclr=$random;
end
initial
begin
Aset=0;
#200Aset=1;
end
reg4_2test_reg(Data,Aclr,Aset,Clock,Q);
initial
#300$finish;
endmodule
7.3.4移位寄存器二(并入串出单向左移)
moduleshift_reg_piso(Data,Enable,Shiften,Shiftin,Aclr,Clock,Shiftout);
input[1:
0]Data;
inputAclr;
inputEnable;
inputShiften;
inputShiftin;
inputClock;
outputShiftout;
reg[1:
0]Qaux;
always@(posedgeAclrorposedgeClock)
begin
if(Aclr)
Qaux=0;
elseif(Enable)
Qaux=Data;
elseif(Shiften)
Qaux={Qaux[0],Shiftin};//语句1
end
assignShiftout=Qaux[1];//语句2
endmodule
程序说明:
(1)程序实现2位移位寄存器,串行输出左向移位。
(2)程序逻辑与设计一的一致,只是在最后输出的时候,设计一是并行输出整个结果,而设计二是输出最高位,达到串行输出的结果。
(3)如果要改为右移,语句1应改为“Qaux={Shiftin,Qaux[1};”,并且语句2改为输出最低位Qaux[0]。
测试平台设计
(1)
`timescale1ns/1ns
moduletestbench;
reg[1:
0]Data;
regAclr,Enable,Shiften,Shiftin,Clock;
wireShiftout;
parameterclock_period=20;
always#(clock_period/2)Clock=~Clock;
initial
begin
Data=0;
repeat(20)
#20Data=$random;
end
initial
begin
Clock=0;//时钟信号的初始化,可放在任一个initial过程中
Aclr=0;
#40Aclr=1;
#100Aclr=0;
end
initial
begin
Enable=0;
#100Enable=1;
#100Enable=0;
end
initial
begin
Shiften=0;
repeat(20)
#20Shiften=$random;
end
initial
begin
Shiftin=0;
repeat(10)
#40Shiftin=$random;
end
shift_reg_pisotestbench_piso(Data,Enable,Shiften,Shiftin,Aclr,Clock,Shiftout);
initial
#400$finish;
endmodule
为了查看效果更完整,要把Qaux也输出显示到Wave窗口中,需要在“sim”窗口中选择“testbench_piso”实例,然后在“objects”窗口中找到Qaux变量,把该变量设置在Wave窗口中显示。
如果不把Qaux加入到波形中,光从Shiftout是很难看出其移位过程的。
测试平台设计
(2)
在测试平台设计
(1)中,对于每一个控制信号,要么指定变化的时间,要么周期性用随机数生成,这样可以产生不同的测试信号组合。
但这样的设计很容易产生一些无意义的状态组合和有些情况未能列出。
在测试平台设计
(2)中,Aclr和Clock的信号单独产生;另外3个控制和输入信号(Enable,Shiften,Shiftin)则通过循环方法,生成所有可能出现的组合情况;Data输入则随机产生。
`timescale1ns/1ns
moduletestbench2;
reg[1:
0]Data;
regAclr,Enable,Shiften,Shiftin,Clock;
wireShiftout;
reg[2:
0]CtrlVec;
integerI;
parameterperiod=20;
always
#(period/2)Clock=~Clock;
initial
begin
Clock=0;
Aclr=0;
#160Aclr=1;
end
initial
begin
Data=0;
repeat(12)
#20Data=$random;
end
initial
begin
for(I=0;I<=11;I=I+1)
begin
CtrlVec=I;
{Enable,Shiften,Shiftin}=CtrlVec;
#20;
end
end
shift_reg_pisotestbench_piso2(Data,Enable,Shiften,Shiftin,Aclr,Clock,Shiftout);
initial
#240$finish;
endmodule
程序说明:
(1)I的循环只需要8次即可列举出Enable,Shiften,Shiftin三个控制信号的8种状态组合,但为了测试Aclr为0时的结果,增加了4次循环(I等于8~11时)。
(2)Enable,Shiften,Shiftin的组合情况从000~111变化后,又重新从000开始,因为当I为8(即'b1000)时,Enable,Shiften,Shiftin分别获得了低位的0,而最高位的1没有被任何变量获得,这是一个常用技巧。
7.4.2计数器二(带置数)
modulecnt4_2(clock,q,aclr,sload,data);
inputclock;
output[3:
0]q;
inputaclr;
inputsload;
input[3:
0]data;
reg[3:
0]qaux;
always@(posedgeclockorposedgeaclr)
begin
if(aclr)
qaux<=4'b0000;
elseif(sload)
qaux<=data;
elseqaux<=qaux+1;
end
assignq=qaux;
endmodule
测试平台设计
`timescale1ns/1ns
moduletestbench;
regclock,sload,aclr;
reg[3:
0]data;
wire[3:
0]q;
initial
clock=0;
parameterDELY=20;
always#(DELY/2)clock=~clock;
initial
begin
sload=0;
repeat(15)
#DELYsload=$random;
end
initial
begin
aclr=0;
#DELYaclr=1;
#60aclr=0;
end
initial
begin
data=0;
repeat(15)
#DELYdata=$random;
end
cnt4_2test_cnt_42(clock,q,aclr,sload,data);
initial
#300$finish;
endmodule