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

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

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

Verilog硬件描述语言中,赋值语句是构建数字逻辑行为模型的核心。其中,阻塞赋值=)与非阻塞赋值<=)的差异,是初学者乃至有经验的设计者都必须深刻理解的关键概念。选择不当不仅会导致仿真与综合结果不一致,更会引入难以调试的竞争冒险和功能错误。本指南旨在通过清晰的步骤与机制分析,帮助你建立正确的赋值模型思维,并规避常见的设计陷阱。

快速概览

阻塞赋值类似于软件中的顺序执行,语句按书写顺序依次计算并立即更新左值;而非阻塞赋值则将所有右值表达式在当前时刻同时采样,并在当前仿真时间步结束时统一更新左值。简单来说,阻塞赋值是“立即生效”,而非阻塞赋值是“稍后同时生效”。

前置条件与目标

在开始实践前,请确保你已具备以下基础:

  • 了解Verilog模块(module)和过程块(alwaysinitial)的基本结构。
  • 熟悉寄存器(reg)与线网(wire)数据类型。
  • 拥有可运行的仿真环境(如ModelSim、VCS或Icarus Verilog)。

本指南的目标与验收标准:完成学习后,你将能够:

  • 准确解释两种赋值在仿真时间模型中的执行机制。
  • 在组合逻辑和时序逻辑设计中正确选用赋值类型。
  • 识别并修复因赋值使用不当导致的典型电路功能错误。
  • 编写仿真与综合结果一致的稳健RTL代码。

核心机制与实施步骤

步骤一:理解仿真事件队列

Verilog仿真器维护一个事件队列,这是理解赋值差异的基石。队列主要分为:

  • 活跃事件:当前仿真时间需要执行的操作,如计算阻塞赋值的右值并立即更新。
  • 非阻塞赋值更新事件:被安排在当前时间步结束时,统一更新所有非阻塞赋值的左值。

你可以将仿真过程想象成一场会议:阻塞赋值是“想到就说,立刻修改白板”,而非阻塞赋值是“各自把想法写在纸条上,等主持人说‘现在统一贴到白板上’时再同时张贴”。

步骤二:组合逻辑设计——使用阻塞赋值

在描述组合逻辑的always @(*)块中,应使用阻塞赋值(=)。其行为模拟了信号通过组合逻辑门的瞬时传播(忽略延迟)。

// 示例:一个简单的与或逻辑链
always @(*) begin
    temp = a &amp; b;       // 阻塞赋值,temp立即更新
    y = temp | c;       // 使用更新后的temp值计算y
end

原因与风险边界:这里使用阻塞赋值确保了语句的顺序依赖性,正确建模了信号从a、b到y的级联路径。若误用非阻塞赋值,由于temp和y的更新被推迟且同时发生,y将使用temp的旧值,导致逻辑错误。风险在于,如果组合逻辑块中存在反馈(例如a = a + 1),使用阻塞赋值会产生仿真死锁,这已不属于纯组合逻辑范畴。

步骤三:时序逻辑设计——使用非阻塞赋值

在描述时序逻辑(如触发器)的always @(posedge clk)块中,必须使用非阻塞赋值(<=)。这精确建模了所有寄存器在同一时钟沿后同时更新的硬件行为。

// 示例:带同步复位的移位寄存器
always @(posedge clk) begin
    if (rst) begin
        q1 &lt;= 1&#039;b0;
        q2 &lt;= 1&#039;b0;
    end else begin
        q1 &lt;= d;     // 时钟沿时刻采样d,结束后更新q1
        q2 &lt;= q1;    // 采样的是q1的旧值(上一周期的值)
    end
end

原因与机制分析:在时钟上升沿,仿真器同时采样所有右值(d和q1的旧值),然后在时间步结束时同时更新q1和q2。这保证了q2得到的是q1在上一时钟周期的值,从而实现正确的移位功能。若误用阻塞赋值(q1 = d; q2 = q1;),则q1会立即更新,导致q2在同一时钟沿就获得了新的q1值,这相当于一个触发器,而非两个级联的触发器,综合结果将与预期严重不符。

步骤四:验证设计——编写测试用例

通过仿真对比正确与错误赋值方式的结果,是巩固理解的最佳途径。

// 测试片段:激励生成
initial begin
    clk = 0; rst = 1; d = 1;
    #10 rst = 0;
    // 观察多个时钟周期...
end

always #5 clk = ~clk; // 生成时钟

在仿真波形中,重点观察在rst释放后的第一个时钟上升沿:
1. 正确情况(非阻塞):q1变为1(d的值),q2变为0(复位值)。
2. 错误情况(阻塞):q1变为1,q2也立即变为1(拿到了新的q1值)。

常见陷阱与排障指南

  • 陷阱1:在同一个always块中混合使用
    现象:仿真行为难以预测,综合可能报错或产生锁存器。
    解决:严格遵循单一准则——组合逻辑块全用阻塞,时序逻辑块全用非阻塞。绝不要混合。
  • 陷阱2:使用非阻塞赋值描述组合逻辑
    现象:仿真结果看似正常,但综合后电路面积可能增大,且功能在特定路径延迟下可能出错(仿真与综合失配)。
    解决:检查所有always @(*)块,确保其中没有<=
  • 陷阱3:在时序逻辑中使用阻塞赋值实现“临时计算”
    现象:意图是先计算一个中间值,再用其更新寄存器,但破坏了并行性。
    解决:将中间计算提取到独立的组合逻辑always块中,或使用连续的阻塞赋值在always @(posedge clk)开始处先计算好,再用非阻塞赋值将最终结果赋给寄存器。但后者需格外小心,推荐前者。

扩展与最佳实践

1. 统一编码风格:团队应强制执行“时序逻辑非阻塞,组合逻辑阻塞”的规则,并在代码审查中重点检查。
2. 仿真与综合一致性:牢记,非阻塞赋值是确保仿真模型与综合后网表行为一致的关键。综合工具会将非阻塞赋值解读为并行寄存器更新。
3. 处理复杂顺序:对于依赖于多个前序状态的复杂时序更新,可考虑使用“计算-更新”两段式模型,或使用generate块和数组来保持代码的清晰与正确性。

总结与参考

掌握阻塞与非阻塞赋值的本质,是写出可靠、可综合Verilog代码的里程碑。其核心在于深刻理解Verilog的仿真调度机制,并以此映射到真实的硬件并行行为。始终问自己:我描述的是一组同时变化的寄存器(用<=),还是一条信号传播的组合路径(用=)?

进一步参考
• IEEE Standard for Verilog Hardware Description Language (IEEE Std 1364). 重点关注“Scheduling semantics”章节。
• Cummings, Clifford E. 的经典论文《Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!》对陷阱有深入论述。

附录:快速自查清单

  • 我的always @(posedge clk)块中是否只使用了<=
  • 我的always @(*)块中是否只使用了=
  • 我是否避免了在同一个always块内混合两种赋值?
  • 我的测试波形是否显示了寄存器在时钟沿后同时更新?
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/33821.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
34816.54W3.89W3.67W
分享:
成电国芯FPGA赛事课即将上线
Verilog阻塞与非阻塞赋值:设计指南与常见陷阱解析
Verilog阻塞与非阻塞赋值:设计指南与常见陷阱解析上一篇
Verilog阻塞与非阻塞赋值:设计指南与常见陷阱解析下一篇
Verilog阻塞与非阻塞赋值:设计指南与常见陷阱解析
相关文章
总数:365
零基础玩转FPGA,FPGA中级进阶教程即将推出

零基础玩转FPGA,FPGA中级进阶教程即将推出

在认真培养方案上,背靠电子科大校友会和校友企业,以“产业”为导向来落地人…
技术分享
3年前
3
0
911
0
FPGA AI推理加速器设计指南:支持动态稀疏性与混合精度计算的硬件架构实现

FPGA AI推理加速器设计指南:支持动态稀疏性与混合精度计算的硬件架构实现

本文档旨在为FPGA硬件工程师提供一套完整的、可落地的硬件架构方案,用于…
技术分享
7天前
0
0
17
0
异步FIFO设计实施指南:深度计算与格雷码应用实践

异步FIFO设计实施指南:深度计算与格雷码应用实践

异步FIFO是处理FPGA跨时钟域数据通信的核心组件,其深度设计与指针同…
技术分享
5天前
0
0
19
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容