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

Verilog中阻塞与非阻塞赋值的深层区别与仿真陷阱:设计指南与验证实践

二牛学FPGA二牛学FPGA
技术分享
4小时前
0
0
5

Quick Start

  • 准备任意一款FPGA开发板(如Xilinx Artix-7)或仿真工具(Vivado Simulator / ModelSim)。
  • 创建两个Verilog模块:一个用阻塞赋值(=)实现移位寄存器,另一个用非阻塞赋值(<=)实现相同功能。
  • 编写测试平台,观察两种赋值方式在仿真波形上的差异。
  • 对比综合后的RTL网表,确认硬件实现是否一致。

前置条件

  • 熟悉Verilog基本语法,包括always块和敏感列表。
  • 已安装并配置好FPGA仿真工具(如Vivado Simulator 2020.1以上版本或ModelSim SE-64 10.6c)。
  • 具备基本数字电路知识,了解寄存器、组合逻辑和时序逻辑的区别。

目标与验收标准

  • 理解阻塞赋值与非阻塞赋值的核心语义差异:阻塞赋值立即更新,非阻塞赋值在块结束时统一更新。
  • 掌握两种赋值方式在组合逻辑与时序逻辑中的正确用法,避免常见仿真-综合不匹配问题。
  • 能够通过仿真波形识别因赋值方式错误导致的竞争冒险或功能错误。
  • 验收标准:在仿真中,阻塞赋值移位寄存器的输出会出现非预期的中间值,而非阻塞赋值版本则正确实现移位功能;综合后两者网表结构相同。

实施步骤

步骤1:编写阻塞赋值移位寄存器模块

module shift_reg_blocking (
    input clk,
    input rst_n,
    input din,
    output reg [3:0] dout
);
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        dout = 4'b0;
    else begin
        dout[0] = din;
        dout[1] = dout[0];  // 阻塞赋值:立即使用新值
        dout[2] = dout[1];
        dout[3] = dout[2];
    end
end
endmodule

此模块在时钟上升沿触发,但阻塞赋值导致赋值语句按顺序执行:dout[0]先被更新为din,随后dout[1]读取已更新的dout[0],依此类推。仿真中,一个时钟周期内所有位同时完成移位,但实际硬件中寄存器更新需要时间,因此仿真行为与硬件行为不一致。

步骤2:编写非阻塞赋值移位寄存器模块

module shift_reg_nonblocking (
    input clk,
    input rst_n,
    input din,
    output reg [3:0] dout
);
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        dout &lt;= 4'b0;
    else begin
        dout[0] &lt;= din;
        dout[1] &lt;= dout[0];  // 非阻塞赋值:使用旧值
        dout[2] &lt;= dout[1];
        dout[3] &lt;= dout[2];
    end
end
endmodule

非阻塞赋值在always块结束时统一更新,因此所有右值都使用进入always块时的旧值。仿真行为正确模拟了硬件寄存器在时钟边沿同时采样的特性。

步骤3:编写测试平台并运行仿真

module tb_shift_reg;
    reg clk, rst_n, din;
    wire [3:0] dout_block, dout_nonblock;

    shift_reg_blocking u_block (.clk(clk), .rst_n(rst_n), .din(din), .dout(dout_block));
    shift_reg_nonblocking u_nonblock (.clk(clk), .rst_n(rst_n), .din(din), .dout(dout_nonblock));

    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end

    initial begin
        rst_n = 0; din = 0;
        #20 rst_n = 1;
        #10 din = 1;
        #10 din = 0;
        #40 $finish;
    end
endmodule

运行仿真后,观察波形:阻塞赋值版本中,dout_block在时钟上升沿后立即变为全1(因为顺序赋值导致所有位同时更新),而非阻塞赋值版本中,dout_nonblock逐位移位,符合预期。

验证结果

  • 仿真结果:阻塞赋值模块在单个时钟周期内完成所有移位,产生“瞬移”现象;非阻塞赋值模块正确实现逐位移位。
  • 综合结果:两个模块综合后的网表相同,均为4个D触发器级联。因为综合工具忽略赋值方式,仅根据逻辑功能推断硬件。
  • 关键发现:仿真与综合的不匹配是阻塞赋值在时序逻辑中使用的典型陷阱。非阻塞赋值保证了仿真行为与硬件行为一致。

排障指南

  • 问题:仿真波形出现毛刺或意外跳变。
    原因:组合逻辑中使用了非阻塞赋值,导致赋值延迟。
    解决:组合逻辑always块中统一使用阻塞赋值。
  • 问题:仿真结果与硬件实测不一致。
    原因:时序逻辑中使用了阻塞赋值,仿真行为与硬件行为不同。
    解决:时序逻辑always块中统一使用非阻塞赋值。
  • 问题:综合后功能正确但仿真失败。
    原因:混合使用阻塞和非阻塞赋值导致仿真竞争。
    解决:遵循“组合逻辑用阻塞,时序逻辑用非阻塞”的黄金法则。

扩展:深入理解赋值机制

阻塞赋值与非阻塞赋值的本质差异源于Verilog的仿真事件调度机制。在仿真中,每个时间槽(time slot)分为多个区域:活跃区(active)、非活跃区(inactive)、NBA区(non-blocking assignment update)等。阻塞赋值在活跃区立即执行,而非阻塞赋值的右值计算在活跃区完成,但左值更新推迟到NBA区。这种调度机制使得非阻塞赋值天然适用于模拟寄存器行为,而阻塞赋值适用于组合逻辑的连续赋值。

风险边界:在同一个always块中混合使用阻塞和非阻塞赋值可能导致不可预测的仿真行为。例如,在时序逻辑中,如果部分信号用阻塞赋值、部分用非阻塞赋值,仿真结果可能依赖于语句顺序,而综合结果则完全由逻辑功能决定,造成仿真-综合不一致。此外,在多个always块中访问同一变量时,必须确保赋值方式一致,否则会产生竞争条件。

参考资源

  • IEEE Std 1364-2001, Verilog Hardware Description Language, Section 9.2: Blocking and non-blocking assignments.
  • Clifford E. Cummings, "Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!", SNUG 2000.
  • Xilinx UG901: Vivado Design Suite User Guide, Synthesis, Chapter 3: Coding Guidelines.

附录:常见错误模式与修正

  • 错误模式1:在时序逻辑中使用阻塞赋值实现计数器。
    修正:改用非阻塞赋值,或使用“dout <= dout + 1”形式。
  • 错误模式2:在组合逻辑中使用非阻塞赋值实现多路选择器。
    修正:改用阻塞赋值,或使用assign连续赋值语句。
  • 错误模式3:在同一个always块中同时使用阻塞和非阻塞赋值更新同一变量。
    修正:拆分为两个always块,或统一赋值方式。
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/37350.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
59917.50W3.93W3.67W
分享:
成电国芯FPGA赛事课即将上线
Vivado时序约束入门:基本周期与输入输出延迟配置指南
Vivado时序约束入门:基本周期与输入输出延迟配置指南上一篇
基于FPGA的FIR滤波器设计:系数生成与硬件实现下一篇
基于FPGA的FIR滤波器设计:系数生成与硬件实现
相关文章
总数:646
FPGA项目实战:基于OV5640摄像头的实时图像采集与显示系统

FPGA项目实战:基于OV5640摄像头的实时图像采集与显示系统

QuickStart准备硬件:确保你有一块带有HDMI/VGA输出接口…
技术分享
1天前
0
0
7
0
基于FPGA的实时视频缩放算法:双线性插值的Verilog实现与上手指南

基于FPGA的实时视频缩放算法:双线性插值的Verilog实现与上手指南

QuickStart下载并安装Vivado2020.1及以上版本,确…
技术分享
1天前
0
0
6
0
FPGA、嵌入式与单片机技术赛道:企业岗位与核心技能树指南

FPGA、嵌入式与单片机技术赛道:企业岗位与核心技能树指南

本文旨在为电子、通信、计算机等相关专业的在校生及初入职场者,提供一份关于…
技术分享
5天前
0
0
13
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容