You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的变化后,对应的下一个时钟上升沿到来时才会解除阻塞。下面详细拆解背后的逻辑:

  1. 时钟时序梳理
    clk初始为0,每5ns翻转一次,所以时钟上升沿出现在5ns、15ns、25ns...95ns、105ns、115ns这些时间点,时钟周期为10ns。

  2. expect语句的检查逻辑
    第二个initial块在仿真时间10ns时启动expect语句。它的属性表达式@(posedge clk) 1 ##1 $changed(a) |-> 1可以拆成两步:

    • 第一步:在任意时钟上升沿,1永远成立,相当于启动一个检查序列;
    • 第二步:等待下一个时钟上升沿,检查$changed(a)是否为真——这个系统函数会对比当前采样的a值与上一个时钟上升沿的采样值,若不同则返回真。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:19:48