在给激励的过程中,fork join 似乎时一个万能的公式,他能将多个进程同时启动并执行完进程后退出当前fork join语句。假设你的1、2、3进程中均出现需要执行循环体,那么该如何写此段激励。
目的:现需要实现一种激励在不同的条件下,给出不同的脉冲宽度该激励还需循环执行。
错误做法:使用 fork join 启动a、b、c三个循环体,并使用wait作为判断条件。
代码结构:

原因:在fork join启动进程,使用wait作为判断条件进入循环体后,循环体执行后无法退出,即便后面出发B、C条件后,b、c进程也不会执行。
思考一下,如果你要执行不同条件下的多个循环体
正确做法1:将循环体放在判断条件外执行。
代码结构:

正确做法2:将使用多个always块来实现这个功能,每个区间对应一个独立的always块。这样既能避免fork...join的阻塞问题,又能保持并行执行特性。考虑设计三个always块:第一个处理fltcnt1≤10的情况,第二个处理10<fltcnt1<1FF的情况,第三个处理1FF≤fltcnt1≤555的情况,在每个always块中,会使用wait来监控fltcnt1的值。当条件满足时,执行相应的延时和信号驱动操作。
代码结构:

代码优点:
-
并行化与独立性
- 每个区间逻辑封装在独立的
always块中,并行执行且互不阻塞。 - 使用
wait(condition)替代if,确保逻辑仅在条件满足时触发,避免空转。
- 每个区间逻辑封装在独立的
-
动态退出机制
- 每个
always块在完成一次信号驱动后自动结束,不会陷入死循环。 - 当
fltcnt1的值变化时,其他always块可立即响应新条件,无需等待当前操作完成。
- 每个
-
代码可维护性
- 命名块(
blk_low/blk_mid/blk_high)明确标识功能,便于调试和禁用(如disable blk_low)。 - 保留原始逻辑的随机延迟范围和显示信息(
$display)。
- 命名块(
-
避免零延迟死循环
always块内的#(delay)语句自动释放仿真调度权,确保其他进程(如监控fltcnt1的代码)可及时执行。
小结:此方案通过 独立的并行 always 块 + 条件触发 机制,彻底解决了 fork...join 的阻塞问题,同时保持功能完整性和代码简洁性。适用于需要动态响应信号变化的测试场景。
2058

被折叠的 条评论
为什么被折叠?



