Verilog中阻塞与非阻塞赋值拆分后的执行逻辑疑问
你的思路错在哪?
首先明确:Clifford Cummings提到两种版本结果一致,不管是综合后的电路功能还是合法同步设计下的仿真行为,这个结论都成立。你的问题出在对Verilog事件调度规则和同步设计规范的误解上。
1. 你假设的“b在时钟上升沿变化”是同步设计中的非法场景
在规范的同步数字设计里,输入信号a、b必须是与时钟clk同步的——它们的跳变只会发生在时钟沿之后的稳定时段,绝不会恰好和时钟上升沿同时出现。这种情况下,负责计算a^b的组合逻辑always块会有足够时间算出y的新值,等下一个时钟上升沿到来时,时序always块采样的y就是正确的结果,和原代码直接采样a^b的行为完全一致。
2. 就算看极端仿真场景,你的事件顺序分析也有误
假设真出现a/b和时钟沿同时跳变的极端情况,Verilog的事件队列调度规则也会保证两种代码行为一致:
- 时钟边沿触发的时序always块会优先进入Active事件队列执行,此时读取的y是上一时间步的旧值;而原代码中,
a^b读取的也是a/b的旧值——因为a/b的跳变事件会被调度到Reactive事件队列,要等Active队列的事件全部执行完才会处理,此时a/b的新值还没被读取到。 - 时序always块执行完毕后,组合逻辑always块才会运行,把y更新为新的
a^b值,但这个新值要等到下一个时钟沿才会被采样,和原代码的行为完全匹配。
3. 从综合角度看,两种代码完全等价
综合工具会把两种代码翻译成一模一样的硬件电路:一个带异步复位的D触发器,输入端接异或门(原代码是把异或逻辑直接写在触发器输入端口,拆分后的代码是显式定义异或门)。硬件电路的行为是固定的,不存在“执行顺序”的概念,所以功能必然完全一致。
内容的提问来源于stack exchange,提问作者C.Kim
相关产品推荐
相关产品推荐

