初始值:
a=1 b=6 c=9
always @(posedge clk) begin
a = b+1; // 阻塞赋值
b <= a; // 非阻塞赋值
c = a;
end
得到的结果是:
a=7 b=1 c=7
核心逻辑:阻塞赋值(=)立即更新左值,非阻塞赋值(<=)仅记录意图、过程块结束后统一更新,且非阻塞赋值的右值采样于「过程块起始时刻的旧值」。
- 初始状态 :时钟沿触发前,
a=1、b=6、c=9(均为reg类型); - 执行
a = b+1;(阻塞赋值) :立即用b的当前值(初始值 6)计算,6+1=7,a实时更新为 7 → 此时状态:a=7、b=6、c=9; - 执行
b <= a;(非阻塞赋值) :采样「过程块起始时a的旧值(1)」,记录赋值意图「b=1」,不立即更新b→ 此时状态不变:a=7、b=6、c=9; - 执行
c = a;(阻塞赋值) :立即用a的实时值(7)更新c→c=7,此时状态:a=7、b=6、c=7; - 过程块结束,非阻塞赋值生效 :记录的「
b=1」生效,b最终更新为 1。
非阻塞赋值的右值,永远采样于「整个 always 块刚开始执行时的变量旧值」,与该语句在块中的位置、块内其他语句是否修改了右值变量,都没有关系。
FR:徐海涛(hunkxu)