Verilog测试台如何让代码2在代码1执行后自动运行?
Verilog测试台:自动等待循环执行完毕后检查错误值
问题描述
现有两段Verilog测试台代码:
循环生成激励并统计错误数的代码:
//code 1 integer i; for(i = 0; i < 100; i = i + 1) begin a = %random(seed1); b = %random(seed2); #10 result = a + b; if(sum !== result) err = err + 1; end
目前需要手动指定1100ns延迟,等待循环执行完毕后再检查错误值:
//code 2 initial begin #1100 if(err !== 0) ..... end
需求:无需手动设置固定延迟,让代码2在代码1的循环执行完毕后自动运行检查逻辑。
解决方案
方法1:使用事件(event)同步
这是跨initial块同步的常用方式,通过自定义事件触发检查逻辑。
- 在模块级定义同步事件:
event done; // 声明用于同步的事件
- 修改代码1,在循环结束后触发事件:
//code 1 修改后 integer i; err = 0; // 建议初始化错误计数器 for(i = 0; i < 100; i = i + 1) begin a = $random(seed1); // 注意:Verilog标准随机函数是$random,不是%random b = $random(seed2); #10 result = a + b; if(sum !== result) err = err + 1; end -> done; // 循环执行完毕后触发done事件
- 修改代码2,等待事件触发后执行检查:
//code 2 修改后 initial begin @done; // 等待done事件被触发 if(err !== 0) $display("测试失败,共%0d个错误", err); else $display("测试通过!"); // 其他后续处理逻辑 end
方法2:将检查逻辑合并到同一个initial块
如果不需要拆分两个initial块,直接把检查逻辑放在循环之后,利用Verilog顺序执行的特性,天然保证检查在循环结束后运行:
initial begin integer i; err = 0; // 原循环逻辑 for(i = 0; i < 100; i = i + 1) begin a = $random(seed1); b = $random(seed2); #10 result = a + b; if(sum !== result) err = err + 1; end // 循环结束后直接执行检查 if(err !== 0) $display("测试失败,共%0d个错误", err); else $display("测试通过!"); end
方法3:使用标志位配合wait语句
通过寄存器标志位标记循环状态,检查逻辑等待标志位置位。
- 在模块级定义标志位:
reg finish_flag = 1'b0; // 初始化标志位为0
- 修改代码1,循环结束后置位标志:
//code 1 修改后 integer i; err = 0; for(i = 0; i < 100; i = i + 1) begin a = $random(seed1); b = $random(seed2); #10 result = a + b; if(sum !== result) err = err + 1; end finish_flag = 1'b1; // 循环结束后置位标志
- 修改代码2,等待标志位为1后执行检查:
//code 2 修改后 initial begin wait(finish_flag); // 等待标志位变为1 if(err !== 0) $display("测试失败,共%0d个错误", err); else $display("测试通过!"); end
注意:原代码中的
%random是语法错误,Verilog标准的随机数生成函数为$random,需要修正。
内容的提问来源于stack exchange,提问作者Jimmy wu
相关产品推荐
相关产品推荐

