文章目录
- 一、前言
- [二、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
三、关键语法说明
-
reg驱动输入,wire接收输出- 给模块输入的信号:定义为
reg - 从模块输出的信号:定义为
wire
- 给模块输入的信号:定义为
-
initial结构仿真开始时只执行一次,用于初始化、按时间给激励。
-
#延时
#20表示延时20个仿真时间单位,仅用于仿真,不综合成电路。 -
$stop/$finish$stop:暂停仿真,方便看波形$finish:结束仿真并退出
-
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
五、波形查看与简单分析
- 在 Quartus 中启动仿真,或在 ModelSim 中加载工程
- 将信号
a/b/cin/sum/cout添加到波形窗口 - 运行仿真,对照真值表检查:
- 输入组合是否正确
- 进位
cout与和sum是否符合全加器逻辑
- 若输出与预期不一致,说明设计代码逻辑错误。
六、通用 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