创建激励
本课属于 Coddy Verilog 学习旅程的“基础知识”单元。第 74 课,共 90 课。
刺激指你应用于设计的输入值,用于测试设计是否正常工作。通过更改输入并观察输出,你可以验证设计是否按预期运行。
可以把它想成测试一台机器:你按下不同的按钮(刺激),然后观察会发生什么(输出)。设计合适的刺激是编写测试平台的重要环节。
例如,看看下面测试平台中的激励:
module testbench;
reg a, b;
wire c;
and_gate dut (
.a(a),
.b(b),
.c(c)
);
initial begin
// 激励信号从这里开始
// 测试用例 1:两个输入均为 0
a = 0; b = 0; #10;
// 测试用例 2:a=0,b=1
a = 0; b = 1; #10;
// 测试用例 3:a=1,b=0
a = 1; b = 0; #10;
// 测试用例 4:两个输入均为 1
a = 1; b = 1; #10;
// 激励信号在这里结束
$finish;
end
endmodule每个激励施加后,我们会等待 10 个时间单位(#10),再施加下一个激励。这样可以给 DUT 留出生成输出的时间。
创建 STIMULUS 的方法
| 方法 | 适用场景 | 示例 |
|---|---|---|
| 顺序赋值 | 简单测试 | a = 0; b = 0; #10; |
| for 循环 | 测试所有组合 | for (i = 0; i < 4; i++) |
| repeat 循环 | 重复模式 | repeat (10) #5 clk = ~clk; |
| forever 循环 | 连续信号 | forever #5 clk = ~clk; |
方法 1:顺序赋值
创建 STIMULUS 的最简单方法。你可以逐个赋值,并添加延迟。
initial begin
a = 0; b = 0; #10;
a = 0; b = 1; #10;
a = 1; b = 0; #10;
a = 1; b = 1; #10;
$finish;
end方法 2:for 循环
当你想测试所有可能的输入组合时,这种方法很有用。
integer i;
initial begin
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
$finish;
end这会测试:00、01、10、11。
方法 3:重复循环
适用于多次重复相同的激励信号。
initial begin
a = 0; b = 1;
repeat (10) begin
#10 a = ~a;
end
$finish;
end方法 4:永久循环
适用于时钟等连续信号。
initial begin
clk = 0;
forever #5 clk = ~clk;
end重要规则
| 规则 | 说明 |
|---|---|
| 在 stimulus 赋值之间使用延迟 | #10 为 DUT 留出响应时间 |
对 stimulus 信号使用 reg | 因为它们会随时间变化 |
在末尾添加 $finish | 停止仿真 |
挑战
系统已提供一个 OR 门模块。你的任务是添加缺失的激励和 $display 语句,以打印结果。
操作步骤:
添加激励,测试全部四种输入组合(00、01、10、11):
- 每行设置
x和y的值 - 添加
#10作为延迟 - 添加
$display来打印结果
$display 应如下所示:
$display("%d %d | %d", x, y, z);亲手试试
module or_gate (
input x,
input y,
output z
);
assign z = x | y;
endmodule
module testbench;
reg x, y;
wire z;
or_gate dut (
.x(x),
.y(y),
.z(z)
);
initial begin
$display("x y | z");
$display("---------");
// TODO: 添加 0 0 对应的激励信号并显示结果
// TODO: 添加 0 1 对应的激励信号并显示结果
// TODO: 添加 1 0 对应的激励信号并显示结果
// TODO: 添加 1 1 对应的激励信号并显示结果
$finish;
end
endmodule这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Verilog 在线编译器