Introduction to writing a test bench in HDL
What is a Test Bench
- Test Bench is a program that verifies the functional correctness of the hardware design.
- The test bench program checks whether the hardware model does what it is supposed to do and is not doing what it is not supposed to do.
0.用HDL代码生成DUT的输入激励码
输入激励码产生方式:
- 用单独的always语句或assign赋值语句产生时钟信号;
- 用简单的initial语句块产生置/复位信号的激励;
- 在initial语句块中用循环语句块产生按一定规律变化的信号的激励码;
- 用Task过程产生特殊信号的输入激励;
- 用三态buffer产生或监控Bidirectional信号的激励;
- 必要时预估DUT的输出变化情形并加以比较
Testbench基本入门
verilog语言中wire型变量和reg 型变量的区别
存器型数据保持最后一次的赋值,而线型数据需要持续的驱动
1.基本的testbench结构
module test_bench;
// 通常testbench没有输入与输出端口
信号或变量定义声明
使用initial或always语句来产生激励波形
例化设计模块
监控和比较输出响应
endmodule
2.产生时钟信号
2.1 initial 方式产生占空比50%的时钟
initial
begin
CLK=0;
#delay;
forever
#(period/2) CLK = ~CLK;
end
一定要给时钟赋初始值,因为信号的缺省值为z,如果不赋初值,则反相后还是z,时钟就一直处于高阻z状态。
2.2 always 方式
initial
CLK=0;
always
#(period/2) CLK=~CLK;
2.3 使用repeat产生确定数目的时钟脉冲
该例使用repeat产生3个时钟脉冲
initial
begin
CLK =0;
repeat(6)
#(period/2) CLK = ~CLK;
end
2.4 产生占空比非50﹪的时钟
initial
CLK=0;
always
begin
#3 CLK=~CLK;
#2 CLK=~CLK;
end
3. 产生复位信号
3.1 异步复位
initial
begin
Rst =1;
#100;
Rst =0;
#500;
Rst =1;
end
3.2 同步复位(法1)
initial
begin
Rst=1;
@(negedge CLK); //等待时钟下降沿
Rst=0;
#30;
@(negedge CLK); //等待时钟下降沿
Rst =1;
end
3.3 同步复位(法2)
initial
begin
Rst =1;
@(negedge CLK); //等待时钟下降沿
repeat(3) @(negedge CLK); //经过3个时钟下降沿
Rst =1
end
4. testbench 实例
4.1 2-4解码器
verilog 语言 编写解码器
module dec2x4(A,B,Enable,Z);
input A,B,Enable;
output[3:0] Z;
reg [3:0] Z_o;
assign Z = Z_o;
always@(A or B or Enable)
begin
if(Enable == 1'b0)
Z_o = 4'b1111;
else
case({A,B})
2'b00: Z_o = 4'b1110;
2'b01: Z_o = 4'b1101;
2'b10: Z_o = 4'b1011;
2'b11: Z_o = 4'b0111;
default: Z_o =4'b1111;
endcase
end
endmodule
测试模块
`timescale 1ns/100ps
module testbench;
//信号变量声明
//wire赋值用assign,reg在always内使用。
reg a,b,en;
wire [3:0] z;
//例化被测试模块
dec2x4 DUT(.A(a), .B(b), .Enable(en), .Z(z));
//产生输入激励
initial
begin
en=0;
a=0;
b=0;
#10 en=1;
#10 b=1;
#10 a=1;
#10 b=0;
#10 a=0;
#10 $stop;
end
//显示输出结果
always@(en or a or b or z)
begin
display("At time %t, input is %b%b%b, output is %b", $time,a,b,en,z)
end
endmodule
4.2 时序检测器
下面是一个时序检测器的验证实例,被检测模型用于检测数据线上连续三个1的序列。在时钟的每个上升沿检查数据。
Verilog 模块代码
module Cont3_1s(Data,Clock,Detect3_1s);
input Data,Clock;
output Detect3_1s;
integer Count;
reg Detect3_1s;
initial
begin
Count = 0;
Detect3_1s =0;
end
always@(posedge Clock)
begin
if(Data==1)
Count+=1;
else
Count =0;
if(Count>=3)
Detect3_1s=1;
end
endmodule
测试模块代码
//仿真的单位时间为1ns,精度为1ps
`timescale 1ns/100ps
module testbench;
//变量声明
reg Data,CLOCK;
wire Detect;
integer Out_file;
//待测试模块的应用实例
Count3_1s DUT(Data,Clock,Detect); //位置关联方式 implicit
//产生输入激励
initial
begin
Clock =0;
forever
#5 Clock = ~Clock;
end
initial
begin
Data=0;
#5 Data=1;
#40 Data=0;
#10 ata=1;
#40 Data=0;
#20 $stop; //仿真结束
end
//创建一个记录文件
initial
Out_file =$fopen("results.txt");
//在文件中保存监控信息
always@(posedge Clock)
begin
if(Detect == 1'b1)
$fwrite(Out_file,"At time %t, Detect out is 1\n",$time);
end
endmodule