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

为何35ns时a=1但y=0?两种always块的差异解析

问题分析与解答

[波形图]

一、35ns时刻a=1但y=0的原因

我们逐时序梳理信号变化:

  1. 信号a的时序:

    • 0ns:initial块赋值a=0
    • always begin #5 a=~a; end的执行逻辑是:进入块后先等5ns,再翻转a,循环往复。所以a的翻转时刻为5ns(0→1)、10ns(1→0)、15ns(0→1)、20ns(1→0)、25ns(0→1)、30ns(1→0)、35ns(0→1)。
  2. 信号y的时序:

    • always #7 begin y=a; end的执行逻辑是:先等7ns,再将a的值赋给y,循环往复。y的赋值时刻为7ns、14ns、21ns、28ns、35ns。
  3. 35ns时刻的细节:
    在35ns时,两个事件按顺序触发:

    • 首先执行y的赋值操作:此时a的值还是0(a的翻转操作尚未执行),所以y被设为0。
    • 接着执行a的翻转操作:a从0变为1。
      因此波形图中35ns时刻最终显示a=1、y=0。

二、always begin #delay与always #delay begin的差异

两种写法的核心差异在于延迟的触发时机和块内语句的执行顺序:

  • always begin #delay ... end:
    先进入begin-end块,执行块中#delay之前的所有语句,再等待#delay时间,接着执行后续语句,完成后回到块开头循环。
    例:若块内有前置语句,会先执行前置语句再延迟:

    always begin
      $display("start at %t", $time); // 0ns立即执行
      #5 $display("end at %t", $time); // 5ns执行
    end
    

    输出为:start at 0、end at 5、start at 5、end at 10...

  • always #delay begin ... end:
    先等待#delay时间,再进入begin-end块执行所有语句,完成后回到always开头循环。
    例:

    always #5 begin
      $display("start at %t", $time); // 5ns执行
      #3 $display("end at %t", $time); // 8ns执行
    end
    

    输出为:start at 5、end at 8、start at 13、end at 16...

如果块内只有#delay加单个语句,两种写法的时序效果一致;但当块内包含多个语句时,差异会非常明显。

内容的提问来源于stack exchange,提问作者ss77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:04:54