Testbench基本入门

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产生确定数目的时钟脉冲

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

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

initial
   CLK = 0;
always
begin
   #3 CLK = ~CLK;
   #2 CLK = ~CLK;
end

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

initial
begin
   Rst = 1;
   #100;
   Rst = 0;
   #500;
   Rst = 1;
end

2)同步复位1

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

2)同步复位2

initial
begin
   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;
       endcase
end
endmodule

测试模块:

`timescale 1ns/100ps
module testbench;
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的序列。在时钟的每个上升沿检查数据。

module Count3_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 = Count + 1;
   else
       Count = 0;
   if(Count>=3)
       Detect3_1s = 1;
   else
       Detect3_1s = 0;
end
endmodule

测试模块:

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

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

Count3_1s      DUT(Data,Clock,Detect);  // 位置关联方式
initial
begin
   Clock = 0;
   forever
   #5 Clock = ~Clock;
end
initial
begin
   Data = 0;
   #5 Data = 1;
   #40 Data = 0;
   #10 Data = 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
  • 17
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值