system verilog 语句 耗时规则
在 SystemVerilog 中,确实有一类语句是**不消耗仿真时间(zero simulation time)**的,我们一般叫它们:
✅ 零延迟语句(Zero-Time Statements)
🔹1. 什么是“不费时间”的语句?
这些语句在仿真时是立即完成、在当前仿真时间点内执行完的,仿真时间不会前进一丝一毫。即使你写了100行,它们也可能在同一个时间点内完成执行
立即完成, 即开始时间等于结束时间, 即 你 将 打印时间放在 零延迟语句前后 你打印 时刻是相同的.
但是这里和 执行顺序 没关系.
我们专注在你要的点上:SystemVerilog 中哪些语句 “耗仿真时间”,哪些“不耗仿真时间”。
✅ 一、耗仿真时间的语句(仿真时间会前进)
这些语句的执行会导致仿真时间跳变或暂停,通常意味着 仿真时间不再停留在当前时间点。
语句类型 | 举例 |
---|---|
延迟语句 | #10; , #(delay_var); |
事件等待 | @(posedge clk); , @signal; , @(a or b or c); |
条件等待 | wait(a == 1); , wait_ready(); |
时间控制循环(包含耗时语句) | forever @(posedge clk); , repeat(10) #1; |
fork 中的耗时线程 | fork #5; join , fork wait(cond); join_any |
@* 等隐式事件控制 | 用于 always_comb , always_ff 等 |
❌ 二、不耗仿真时间的语句(不会引起时间变化)
这些语句在仿真的当前时间点完成,不会导致仿真时间推进。
语句类型 | 举例 |
---|---|
阻塞赋值 | a = b; |
非阻塞赋值 | a <= b; (赋值延后,但不耗时) |
begin…end 顺序块 | begin a = 1; b = 2; end |
if-else / case 等条件判断 | if(a) b = 1; else b = 0; |
函数调用(无等待语句) | a = my_func(); |
disable / break / continue | 控制流语句本身不耗时 |
assert (表达式类型) | assert(a == b); |
initial / always 声明本身 | 只是启动行为,不耗时 |
类方法调用(不含耗时) | obj.do_stuff(); |
static 、automatic 变量声明 | static int x; |
new() 构造函数调用 | obj = new(); |
🚩 三、模糊点说明(小心区分)
示例 | 是否耗时 | 说明 |
---|---|---|
a <= b; | ❌ | 非阻塞赋值本身不耗时,值更新在 NBA 阶段 |
@(posedge clk) | ✅ | 会等待下一个事件触发,耗时间 |
wait(a == 1) | ✅ | 如果条件不满足,会停在这等 |
my_task(); | 取决于task体 | 如果 task 内有 # , @ 等,就是耗时 |
fork a=1; b=2; join | ❌ | 子线程执行无耗时,整个结构也不耗时 |
fork #1; #2; join | ✅ | 子线程耗时,整个结构耗时 |