Verilog入门实战——第5讲:Testbench 仿真编写 + 波形查看与分析

文章目录

  • 一、前言
  • [二、Testbench 基本结构](#二、Testbench 基本结构)
  • 三、关键语法说明
  • [四、实战:全加器 Testbench 完整示例](#四、实战:全加器 Testbench 完整示例)
    • [1. 被测试模块(回顾)](#1. 被测试模块(回顾))
    • [2. 仿真模块 tb_full_adder.v](#2. 仿真模块 tb_full_adder.v)
  • 五、波形查看与简单分析
  • [六、通用 Testbench 模板](#六、通用 Testbench 模板)

一、前言

功能代码写完并不代表设计结束,必须通过**仿真(Simulation)**验证逻辑是否正确。Testbench就是专门给设计模块提供输入激励、采集输出结果的"测试程序",是数字电路学习与FPGA开发中必不可少的一环。

本篇只讲通用、可直接套用的Testbench写法,不涉及复杂语法,拿来就能用。

二、Testbench 基本结构

仿真模块与普通模块类似,但不需要定义输入输出端口,结构固定如下:

verilog 复制代码
// 测试模块名(一般 tb_xxx)
module tb_xxxx;

// 1. 激励信号定义(reg 型,给模块输入)
reg  clk;
reg  rst_n;
reg  in;

// 2. 输出信号定义(wire 型,接收模块输出)
wire out;

// 3. 例化被测试的设计模块(DUT)
xxxx u_xxxx(
    .clk    (clk),
    .rst_n  (rst_n),
    .in     (in),
    .out    (out)
);

// 4. 生成时钟激励(可选)
initial begin
    clk = 0;
    forever #10 clk = ~clk;
end

// 5. 生成复位、输入数据激励
initial begin
    // 初始化
    rst_n = 0;
    in    = 0;
    #20;
    rst_n = 1;

    // 输入变化
    #30 in = 1;
    #20 in = 0;

    // 结束仿真
    #100;
    $stop;
end

endmodule

三、关键语法说明

  1. reg 驱动输入,wire 接收输出

    • 给模块输入的信号:定义为 reg
    • 从模块输出的信号:定义为 wire
  2. initial 结构

    仿真开始时只执行一次,用于初始化、按时间给激励。

  3. #延时
    #20 表示延时20个仿真时间单位,仅用于仿真,不综合成电路。

  4. $stop / $finish

    • $stop:暂停仿真,方便看波形
    • $finish:结束仿真并退出
  5. forever

    循环执行,常用于生成时钟信号

四、实战:全加器 Testbench 完整示例

以第4讲的全加器为例,编写仿真激励。

1. 被测试模块(回顾)

verilog 复制代码
module full_adder(
    input  wire a,
    input  wire b,
    input  wire cin,
    output wire sum,
    output wire cout
);

wire sum1, cout1, cout2;

half_adder u_half1(.a(a),.b(b),.sum(sum1),.cout(cout1));
half_adder u_half2(.a(sum1),.b(cin),.sum(sum),.cout(cout2));

assign cout = cout1 | cout2;

endmodule

2. 仿真模块 tb_full_adder.v

verilog 复制代码
module tb_full_adder;

// 激励输入
reg a;
reg b;
reg cin;

// 输出采集
wire sum;
wire cout;

// 例化 DUT
full_adder u_full_adder(
    .a     (a),
    .b     (b),
    .cin   (cin),
    .sum   (sum),
    .cout  (cout)
);

// 测试激励
initial begin
    a    = 0;
    b    = 0;
    cin  = 0;
    #10;

    a   = 0; b=0; cin=1; #10;
    a   = 0; b=1; cin=0; #10;
    a   = 0; b=1; cin=1; #10;
    a   = 1; b=0; cin=0; #10;
    a   = 1; b=0; cin=1; #10;
    a   = 1; b=1; cin=0; #10;
    a   = 1; b=1; cin=1; #10;

    #100;
    $stop;
end

endmodule

五、波形查看与简单分析

  1. 在 Quartus 中启动仿真,或在 ModelSim 中加载工程
  2. 将信号 a/b/cin/sum/cout 添加到波形窗口
  3. 运行仿真,对照真值表检查:
    • 输入组合是否正确
    • 进位 cout 与和 sum 是否符合全加器逻辑
  4. 若输出与预期不一致,说明设计代码逻辑错误。

六、通用 Testbench 模板

verilog 复制代码
module tb_top;

// 输入激励
reg  in1;
reg  in2;

// 输出观测
wire out1;
wire out2;

// 例化
top u_top(
    .in1(in1),
    .in2(in2),
    .out1(out1),
    .out2(out2)
);

initial begin
    in1 = 0;
    in2 = 0;
    #10;

    // 自定义激励
    #100;
    $stop;
end

endmodule
相关推荐
神电测控3 小时前
新品发布:32通道50MS/s同步并行14位采集模块PG-FMC9249(支持任意FPGA/ZYNQ,兼容LabVIEW FPGA软件开发)
fpga开发·labview·ni·神电测控·王电令·ad9249·32通道
Drgfd4 小时前
半导体国产替代进入“深水区”:决战设备、材料、IP三大高地
网络·fpga开发
szxinmai主板定制专家7 小时前
驱控一体新范式:RK3576+FPGA+CODESYS工业实时AI控制架构全解
人工智能·嵌入式硬件·计算机视觉·fpga开发·架构·工业ai·驱控一体
国科安芯8 小时前
ASC0101S自动双向电平转换原理深剖
单片机·嵌入式硬件·fpga开发·云计算·信息与通信
落chen10 小时前
7 Series FPGAs Clocking Resources
fpga开发
落chen1 天前
基于FPGA的IIC协议通信-强化篇
fpga开发
梦开始的地方 �1 天前
实例化和句柄
fpga开发
lf2824814311 天前
11 FM调制与解调的仿真
fpga开发
千寻xun1 天前
三、实战篇-NVME SSD控制之FPGA实现(二)
fpga开发·nvme·nvme ssd
蓝悦无人机1 天前
Altium Designer 2024 PCB高级功能:不同Pitch的BGA设计要求
fpga开发·pcb·硬件设计·ad2024