SystemVerilog中expect语句是否会阻塞至a在100ns时从0变1?
你的SystemVerilog Expect语句行为分析
首先贴出你的测试代码方便时序与逻辑分析:
module tb; logic a; logic clk=0; default clocking @(posedge clk); endclocking always #5ns clk = ~clk; initial begin $dumpfile("dump.vcd"); $dumpvars; $display("START"); a = 0; #100ns; a = 1; #100ns; $finish; end initial begin #10ns; expect(@(posedge clk) 1 ##1 $changed(a) |-> 1) $display("SUCCESS"); else $display("FAIL"); end endmodule
直接给结论:这个expect语句确实会阻塞,直到a完成从0到1的变化后,对应的下一个时钟上升沿到来时才会解除阻塞。下面详细拆解背后的逻辑:
时钟时序梳理
clk初始为0,每5ns翻转一次,所以时钟上升沿出现在5ns、15ns、25ns...95ns、105ns、115ns这些时间点,时钟周期为10ns。expect语句的检查逻辑
第二个initial块在仿真时间10ns时启动expect语句。它的属性表达式@(posedge clk) 1 ##1 $changed(a) |-> 1可以拆成两步:- 第一步:在任意时钟上升沿,
1永远成立,相当于启动一个检查序列; - 第二步:等待下一个时钟上升沿,检查
$changed(a)是否为真——这个系统函数会对比当前采样的a值与上一个时钟上升沿的采样值,若不同则返回真。
- 第一步:在任意时钟上升沿,
a的变化与匹配过程
a在0时刻被设为0,直到100ns时才变为1。在100ns之前的所有时钟上升沿(比如15ns、25ns...95ns),$changed(a)都为假,因为a始终保持0。
当仿真到95ns的时钟上升沿时,第一步的1成立,随后等待下一个时钟上升沿(105ns)。此时a已经在100ns完成了从0到1的变化,105ns采样a时,与95ns的采样值(0)对比发生了变化,$changed(a)返回真,整个属性表达式满足,expect随即输出SUCCESS并解除阻塞。
简单来说,expect不会在100ns(a变化的瞬间)立刻结束阻塞,而是要等到变化发生后的第一个时钟上升沿完成检查后才会放行,但本质上它确实会一直等待a的变化发生,直到属性被满足为止。
内容的提问来源于stack exchange,提问作者Viktorinox
相关产品推荐
相关产品推荐

