为何35ns时a=1但y=0?两种always块的差异解析
问题分析与解答
[波形图]
一、35ns时刻a=1但y=0的原因
我们逐时序梳理信号变化:
信号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)。
- 0ns:initial块赋值
信号y的时序:
always #7 begin y=a; end的执行逻辑是:先等7ns,再将a的值赋给y,循环往复。y的赋值时刻为7ns、14ns、21ns、28ns、35ns。
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
相关产品推荐
相关产品推荐

