亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Verilog

Verilog阻塞与非阻塞赋值:关键区别详解

阻塞赋值

阻塞赋值使用=符号,在过程块中按顺序依次执行。但不会阻止并行块中语句的执行。

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

两个initial块在仿真开始时并行执行。每个块内语句顺序执行,两块均在0ns完成。变量先赋值,随后执行显示语句,然后执行其他赋值。首个$display时和尚未赋值,显示为8'hxx。

非阻塞赋值

非阻塞赋值使用<=符号,允许调度赋值而不阻塞后续语句执行。同一时间步的所有非阻塞赋值右侧值先被捕获,时间步结束时统一赋给左侧变量。

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

所有$display均打印'h'x,因为非阻塞赋值在时间步结束前不更新变量。这是建模时序逻辑、避免竞争冒险的关键机制。

核心区别总结

  • 阻塞赋值:即时更新,适合组合逻辑建模
  • 非阻塞赋值:延迟更新,适合时序逻辑建模,避免竞态条件
  • 同一时间步内,非阻塞赋值的RHS先捕获,时间步结束统一更新LHS

Verilog

  1. Verilog基础:设计你的第一个与门
  2. Verilog 入门:数字电路设计完整教程
  3. 掌握 Verilog 拼接操作:实用指南
  4. 深入理解 Verilog 赋值语句:类型、语法与最佳实践
  5. 掌握Verilog函数:高效RTL设计的复用利器
  6. 理解Verilog任务:函数vs任务、语法与用法全解析
  7. Verilog 时钟发生器设计与实现指南
  8. 掌握 Verilog 数学函数:高效硬件设计的利器
  9. 掌握 Verilog $timeformat:精度控制与显示格式化
  10. 理解与打印 Verilog 任意作用域下的 Timescale
  11. 掌握 Verilog 文件 I/O:打开、读取、写入和关闭
  12. Verilog 入门指南:Hello World 示例