详细解释 — Verilog中非阻塞赋值为什么能解决时序逻辑里的“寄存器之间竞争 / 读写不一致” - 详解
文章目录
- 前言
- 一、非阻塞赋值的仿真语义(关键点)
- 二、依据具体例子演示(最直观)
- 示例 1 — 非阻塞赋值(期望的“并行”更新)
- 示例 2 — 阻塞赋值(会出现顺序依赖的问题)
- 三、为什么这跟真实硬件的 D 触发器匹配?
- 四、 delta cycle / 仿真细节(进阶)
- 五、 额外例子:多寄存器并行更新
- 六、 实战建议(工程经验)
- 七、 总结(一句话)
前言
我们把说明拆成几部分:语义(仿真规则)→ 例子与时序步骤 → 硬件映射 → 实战建议。过程尽量一步步推导,带具体数值与“波形”表格,便于理解。
一、非阻塞赋值的仿真语义(关键点)
在 always @(posedge clk) 中使用非阻塞赋值 <= 时,Verilog 的仿真采用两阶段行为:
计算阶段(sample):在时钟沿到达时,所有非阻塞赋值的右侧表达式(RHS)都用当前的旧值求值并暂存(即“读取旧值”)。
更新阶段(update):随后(在相同的仿真时间点的稍后delta cycle),把这些预先计算好的右侧结果写回到左侧信号(寄存器)。
关键:RHS 的读取发生在“同时”的瞬间,写回发生在“统一的后时刻”。因此多个寄存器之间不会互相看到已更新的新值 —— 它们都看到时钟到来前的旧值。
二、借助具体例子演示(最直观)
示例 1 — 非阻塞赋值(期望的“并行”更新)
reg a, b;
initial begin
a = 0;
b = 1;
end