文章目录一、前言二、Testbench 基本结构三、关键语法说明四、实战全加器 Testbench 完整示例1. 被测试模块回顾2. 仿真模块 tb_full_adder.v五、波形查看与简单分析六、通用 Testbench 模板一、前言功能代码写完并不代表设计结束必须通过**仿真Simulation**验证逻辑是否正确。Testbench就是专门给设计模块提供输入激励、采集输出结果的“测试程序”是数字电路学习与FPGA开发中必不可少的一环。本篇只讲通用、可直接套用的Testbench写法不涉及复杂语法拿来就能用。二、Testbench 基本结构仿真模块与普通模块类似但不需要定义输入输出端口结构固定如下// 测试模块名一般 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三、关键语法说明reg驱动输入wire接收输出给模块输入的信号定义为reg从模块输出的信号定义为wireinitial结构仿真开始时只执行一次用于初始化、按时间给激励。#延时#20表示延时20个仿真时间单位仅用于仿真不综合成电路。$stop/$finish$stop暂停仿真方便看波形$finish结束仿真并退出forever循环执行常用于生成时钟信号。四、实战全加器 Testbench 完整示例以第4讲的全加器为例编写仿真激励。1. 被测试模块回顾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; endmodule2. 仿真模块 tb_full_adder.vmodule 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; b0; cin1; #10; a 0; b1; cin0; #10; a 0; b1; cin1; #10; a 1; b0; cin0; #10; a 1; b0; cin1; #10; a 1; b1; cin0; #10; a 1; b1; cin1; #10; #100; $stop; end endmodule五、波形查看与简单分析在 Quartus 中启动仿真或在 ModelSim 中加载工程将信号a/b/cin/sum/cout添加到波形窗口运行仿真对照真值表检查输入组合是否正确进位cout与和sum是否符合全加器逻辑若输出与预期不一致说明设计代码逻辑错误。六、通用 Testbench 模板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