目录

  1. 引言
  2. Testbench 介绍
  3. Verilog Testbench 结构
  4. 完整 Testbench 示例
  5. 参考资料

引言

Verilog Testbench(测试激励)用于对设计模块进行仿真,验证功能是否符合预期。Testbench 是一段不综合的 Verilog 代码,仅用于仿真环境中运行,通常包含输入信号的激励、结果监测、波形生成等功能。


Testbench 介绍

Testbench 是 无端口的 Verilog 模块,用于驱动 DUT(Design Under Test,被测设计)。它的主要功能包括:

  • 生成 时序信号(如时钟、复位)
  • 施加 输入激励(模拟数据输入)
  • 监测 输出信号(检查 DUT 响应)
  • 记录 仿真结果(输出波形或终端打印)

Verilog Testbench 结构

典型的 Verilog Testbench 由以下部分组成:

3.1 端口定义

Testbench 需要定义 DUT 的输入和输出信号,并实例化 DUT。

module tb;  // Testbench 无端口

    // 定义 DUT 端口信号
    reg clk, reset;
    reg [7:0] data_in;
    wire [7:0] data_out;

    // 实例化 DUT
    my_module dut (
        .clk(clk),
        .reset(reset),
        .data_in(data_in),
        .data_out(data_out)
    );

endmodule


3.2 信号初始化

initial 代码块中初始化所有控制信号,确保仿真有确定的起始状态。

initial begin
    clk = 0;
    reset = 1;
    data_in = 0;
    #10 reset = 0;  // 10 个时间单位后释放复位
end


3.3 生成时序信号

通常使用 always 块生成 时钟信号,以驱动 DUT。

always #5 clk = ~clk;  // 5ns 反转一次,相当于 10ns 时钟周期


3.4 监视信号变化

使用 $monitor$display 打印仿真过程中变量的值,以便调试。

initial begin
    $monitor("Time=%0t | clk=%b | reset=%b | data_in=%h | data_out=%h",
             $time, clk, reset, data_in, data_out);
end


3.5 结束仿真

仿真不能无限执行,因此需要在合适的时间点结束。

initial begin
    #100;  // 运行 100 个时间单位
    $finish;  // 结束仿真
end


完整 Testbench 示例

以下是一个完整的 Testbench 代码,用于测试 my_module 模块。

module tb;  

    // 定义信号
    reg clk, reset;
    reg [7:0] data_in;
    wire [7:0] data_out;

    // 实例化 DUT
    my_module dut (
        .clk(clk),
        .reset(reset),
        .data_in(data_in),
        .data_out(data_out)
    );

    // 生成时钟信号
    always #5 clk = ~clk;

    // 初始化信号
    initial begin
        clk = 0;
        reset = 1;
        data_in = 8'h00;
        #10 reset = 0;  
        
        // 施加激励
        #20 data_in = 8'hA5;
        #30 data_in = 8'h3C;
        #40 data_in = 8'hFF;
        
        // 结束仿真
        #100;
        $finish;
    end

    // 监视信号变化
    initial begin
        $monitor("Time=%0t | clk=%b | reset=%b | data_in=%h | data_out=%h",
                 $time, clk, reset, data_in, data_out);
    end

endmodule


参考资料

  1. IEEE 1364-2005 Verilog Standard
  2. ASIC World – Verilog Testbench
  3. Verilog Testbench Tutorial – EDA Playground