我们先来看一下小梅君对于阻塞赋值与非阻塞赋值的讲解

我们仔细看一下下面4种情况,注意区分不同

一般情况下都建议非阻塞赋值,为什么呢?请看下面

看一下各自代码生成的电路图

发现不同了吗?block2和其他三种都不一样,少了一个D触发器 

我们可以看到,阻塞赋值的顺序不同,会影响电路的结果

行为差异(一句话总结)

  • 阻塞赋值(=按代码顺序立刻执行,像“接力赛”一样,前一句执行完才能执行下一句。

  • 非阻塞赋值(<=所有赋值并行发生,像“所有人同时起跑”,在时钟边沿统一更新结果。

常见错误案例

错误1:时序逻辑混用阻塞赋值
// 错误代码:试图交换a和b的值
always @(posedge clk) begin
    a = b;     // a立刻变成b的旧值
    b = a;     // b变成a的新值(等于旧b值)
end

结果ab永远相同,无法交换!

正确写法
// 正确写法:非阻塞赋值
always @(posedge clk) begin
    a <= b;    // 记录a的新值为旧b
    b <= a;    // 记录b的新值为旧a
end

结果ab成功交换!

使用场景规则

  1. 组合逻辑(always @(*)

    • 必须用阻塞赋值(=,确保顺序计算(如加减法、逻辑判断)。

    • 错误使用非阻塞会生成锁存器(Latch),导致电路异常!

  2. 时序逻辑(always @(posedge clk)

    • 必须用非阻塞赋值(<=,保证所有寄存器同步更新。

    • 错误使用阻塞会导致“数据覆盖”问题,仿真与硬件行为不一致!

总结(一句话口诀)

组合逻辑用 =,时序逻辑用 <=,非阻塞保同步,阻塞保顺序!

一般情况下如果你分不清又想要赋值的话,那么推荐你用非阻塞赋值!

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐