Testbench基本入门

来源:互联网 发布:linux 下安装jdk 编辑:程序博客网 时间:2024/05/22 16:46

1 编写testbench目的

编写testbench的主要目的是为了对使用硬件描述语言(HDL)设计的电路进行仿真验证,测试设计电路的功能、部分性能是否与预期的目标相符。
编写testbench进行测试的过程如下:
1) 产生模拟激励(波形);
2) 将产生的激励加入到被测试模块并观察其输出响应;
3) 将输出响应与期望进行比较,从而判断设计的正确性。
2 基本的testbench结构
module test_bench;
// 通常testbench没有输入与输出端口
信号或变量定义声明
使用initial或always语句来产生激励波形
例化设计模块
监控和比较输出响应
endmodule
简单的testbench的结构通常需要建立一个顶层文件,顶层文件没有输入和输出端口。在顶层文件里,把被测模块和激励产生模块实例化进来,并且把被测模块的端口与激励模块的端口进行对应连接,使得激励可以输入到被测模块。端口连接的方式有名称和位置关联两种方式,我们常常使用“名称关联”方式。

3 产生激励的一些描写方式
3.1 产生时钟的几种方式
1)使用initial方式产生占空比50﹪的时钟

    initial    begin       CLK = 0;       #delay;       forever       #(period/2) CLK = ~CLK;    end

注意:一定要给时钟赋初始值,因为信号的缺省值为z,如果不赋初值,则反相后还是z,时钟就一直处于高阻z状态。
产生的时钟信号如下图所示:
这里写图片描述
2)使用always方式

    initial                CLK = 0;    always  #(period/2) CLK = ~CLK;

3)使用repeat产生确定数目的时钟脉冲

initialbegin   CLK = 0;   repeat(6) #(period/2) CLK = ~CLK;end

4)产生占空比非50﹪的时钟

initial   CLK = 0;alwaysbegin   #3 CLK = ~CLK;   #2 CLK = ~CLK;end

3.2 产生复位信号的几种形式
1)异步复位

initialbegin   Rst = 1;   #100;   Rst = 0;   #500;   Rst = 1;end

2)同步复位1

initialbegin   Rst = 1;   @(negedge CLK);  // 等待时钟下降沿   Rst = 0;   #30;   @(negedge CLK);  // 等待时钟下降沿   Rst = 1;end

2)同步复位2

initialbegin   Rst = 1;   @(negedge CLK);  // 等待时钟下降沿   repeat (3) @(negedge CLK);   // 经过3个时钟下降沿   Rst = 1;end

4 testbench实例

4.1 2-4解码器实例

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;       endcaseendendmodule

测试模块:

`timescale 1ns/100psmodule testbench;reg a, b, en;wire [3:0] z;

//例化被测试模块

dec2x4 DUT(.A(a),.B(b),.Enable(en),.Z(z));

//产生输入激励

initialbegin   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的序列。在时钟的每个上升沿检查数据。

module Count3_1s(Data, Clock, Detect3_1s);   input Data, Clock;   output Detect3_1s;   integer Count;   reg Detect3_1s;initialbegin   Count = 0;   Detect3_1s = 0;endalways@(posedge Clock)begin   if(Data == 1)       Count = Count + 1;   else       Count = 0;   if(Count>=3)       Detect3_1s = 1;   else       Detect3_1s = 0;endendmodule

测试模块:

`timescale 1ns/100psmodule testbench;reg Data, Clock;wire Detect;integer Out_file;

// 待测试模块的应用实例

Count3_1s      DUT(Data,Clock,Detect);  // 位置关联方式initialbegin   Clock = 0;   forever   #5 Clock = ~Clock;endinitialbegin   Data = 0;   #5 Data = 1;   #40 Data = 0;   #10 Data = 1;   #40 Data = 0;   #20 $stop;  // 仿真结束end

// 创建一个记录文件:

initialOut_file = $fopen("results.txt");

// 在文件中保存监控信息

always@(posedge Clock)begin   if(Detect == 1'b1)       $fwrite(Out_file,"At time %t, Detect out is 1\n", $time);endendmodule
原创粉丝点击