Testbench 入门

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

猜你喜欢

转载自blog.csdn.net/GreatSimulation/article/details/108818701
今日推荐