FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

Verilog阻塞与非阻塞赋值:设计指南与常见陷阱解析

二牛学FPGA二牛学FPGA
技术分享
3小时前
0
0
2

Verilog硬件描述语言中,赋值语句是构建数字逻辑行为最核心的要素之一。其中,阻塞赋值=)与非阻塞赋值<=)的差异,是区分软件思维与硬件思维的关键,也是初学者乃至有经验工程师容易混淆和出错的重灾区。本文旨在提供一个清晰、可操作的上手指南,帮助你深入理解其底层机制,掌握正确的使用范式,并规避常见的设计陷阱。

快速概览

阻塞赋值(=)的行为类似于传统软件编程中的顺序赋值:语句立即执行,右侧表达式的值被计算后,立即更新到左侧变量,并阻塞同一always块内后续语句的执行,直到当前赋值完成。它常用于描述组合逻辑或测试平台中的激励生成。

非阻塞赋值<=)则体现了硬件并行性:在always块的一个时钟沿(或事件)触发时,所有右侧表达式的值被同时计算并暂存,直到该仿真时间步(time step)结束时,才统一更新到左侧寄存器。它专为描述时序逻辑(如触发器)而设计,是确保电路正确同步的关键。

前置条件与目标

前置知识

  • 了解Verilog基本语法与always块结构。
  • 理解组合逻辑与时序逻辑的基本概念。
  • 具备RTL仿真器的基本使用经验(如VCS, ModelSim, Vivado Simulator等)。

学习目标

  • 机制理解:清晰阐述阻塞与非阻塞赋值在仿真调度(Simulation Scheduling)中的不同行为。
  • 规则掌握:遵循“组合逻辑用阻塞,时序逻辑用非阻塞”的核心设计规则及其例外情况。
  • 陷阱识别:能够识别并修复因混用赋值方式导致的仿真与综合结果不一致、竞争冒险等问题。
  • 实施步骤:从理解到应用

    步骤一:剖析仿真调度机制

    理解差异的根源在于Verilog的仿真事件队列。一个时间步内,事件被分为多个区域:

      这就好比点餐与上菜:阻塞赋值是“点一道上一道”,而非阻塞赋值是“点完所有菜,再一起上桌”。

      步骤二:掌握核心设计规则

        步骤三:通过典型陷阱案例深化理解

        陷阱1:交换逻辑中的竞争冒险

        错误代码(在时序块中使用阻塞赋值交换变量):
        always @(posedge clk) begin
        a = b;
        b = a; // 意图交换a和b,但结果错误!
        end

        分析:由于阻塞赋值立即生效,第一句执行后a已变为b的旧值,第二句的b = a实际上变成了b = b,导致交换失败。

        正确代码(使用非阻塞赋值):
        always @(posedge clk) begin
        a <= b;
        b <= a; // 正确实现交换
        end

        分析:时钟沿到来时,右侧的ba(均为旧值)被同时计算并暂存,在时间步结束时同时更新,完美实现寄存器间数据交换。

        陷阱2:组合逻辑反馈产生的锁存器与仿真-综合失配

        问题代码:
        always @(*) begin
        if (sel) y = a;
        // 当sel为0时,y未被赋值,综合工具会推断出一个锁存器!
        end

        分析:在组合逻辑块中,如果存在条件分支未覆盖所有路径,变量将保持原值,这会被综合工具解释为需要记忆功能的锁存器。虽然语法正确,但锁存器在ASIC/FPGA中通常不受欢迎(易产生时序问题)。

        修正方法:确保组合逻辑always块的所有分支都对输出变量有明确的赋值。
        always @(*) begin
        if (sel) y = a;
        else y = b; // 或赋予一个默认值
        end

        验证结果与功能确认

          常见问题排障

            扩展知识与高级应用

            1. 关于“#0”延迟的警告:在测试平台中,有时会使用#0延迟来强制排序事件。这本质上是将事件插入到非阻塞赋值更新区之后的一个特殊区域。过度或不当使用#0会导致仿真依赖特定调度器,降低代码可移植性,应尽量避免。

            2. SystemVerilog的改进:SystemVerilog引入了always_combalways_ff等专用过程块,从语法层面强制了赋值规则(如在always_comb中不能使用非阻塞赋值),能有效避免此类错误,建议在新设计中使用。

            总结与最佳实践

              附录:参考与进一步阅读

              标签:
              本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
              如需转载,请注明出处:https://z.shaonianxue.cn/33820.html
              二牛学FPGA

              二牛学FPGA

              初级工程师
              这家伙真懒,几个字都不愿写!
              34816.54W3.89W3.67W
              分享:
              成电国芯FPGA赛事课即将上线
              Chiplet系统级验证中的FPGA原型验证实施指南
              Chiplet系统级验证中的FPGA原型验证实施指南上一篇
              Verilog阻塞赋值与非阻塞赋值:设计指南与常见陷阱解析下一篇
              Verilog阻塞赋值与非阻塞赋值:设计指南与常见陷阱解析
              相关文章
              总数:365
              SystemVerilog for FPGA:面向对象编程在验证中的高效应用

              SystemVerilog for FPGA:面向对象编程在验证中的高效应用

              在当今复杂的FPGA与ASIC设计项目中,验证工作占据了超过70%的开发…
              技术分享
              13天前
              0
              0
              35
              0
              一篇带你透彻了解FPGA!

              一篇带你透彻了解FPGA!

              一、FPGA是什么?FPGA,英文名:FieldProgra…
              技术分享
              1年前
              1
              0
              783
              3
              告别手工测试!用SystemVerilog玩转智能芯片验证

              告别手工测试!用SystemVerilog玩转智能芯片验证

              你知道吗?在复杂的FPGA和芯片设计里,验证工作往往要吃掉整个项目70%…
              技术分享
              21天前
              0
              0
              186
              0
              评论表单游客 您好,欢迎参与讨论。
              加载中…
              评论列表
              总数:0
              FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
              没有相关内容