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

2026年Q2:Verilog中阻塞与非阻塞赋值在综合后的硬件差异排查

FPGA小白FPGA小白
技术分享
21小时前
0
0
9

Quick Start

  • 准备 Vivado 2025.2(或更高版本)与任意 7 系列 / UltraScale+ 开发板(如 Artix-7)。
  • 新建工程,选择目标器件,添加两个 Verilog 源文件:blocking_example.vnonblocking_example.v
  • 在两个文件中分别实现一个简单的 2 级移位寄存器:一个完全使用阻塞赋值=),一个完全使用非阻塞赋值<=)。
  • 编写顶层模块,例化两个移位寄存器,将输入 din 同时送入两个模块,观察输出 dout_blockdout_nonblock
  • 运行综合(Synthesis),查看综合后的 RTL 原理图或网表,确认两个模块的硬件结构差异。
  • 编写仿真 Testbench,驱动时钟与复位,对比仿真波形中两个输出的时序差异(重点观察 posedge clk 采样点的值)。
  • 上板下载,用逻辑分析仪(ILA)抓取内部信号,验证硬件行为是否与仿真一致。
  • 若发现输出不符合预期,优先检查综合选项(-keep_equivalent_registers)与约束文件中的时钟定义。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Xilinx Artix-7 XC7A35T主流入门级 FPGA,资源充足Intel Cyclone V / Lattice ECP5
EDA 版本Vivado 2025.2支持最新综合优化与 CDC 检查Vivado 2024.x / Quartus Prime 24.x
仿真器Vivado Simulator 或 ModelSim SE-64 2025.1支持 VCD 波形与 Tcl 自动化Questa / Verilator(仅仿真)
时钟/复位50 MHz 单端时钟,异步高有效复位避免跨时钟域干扰100 MHz / 差分时钟
接口依赖无外部接口,仅使用板载 LED 或 ILA纯内部逻辑验证UART / GPIO 输出
约束文件XDC 文件定义时钟周期 20 ns,输入输出延迟保证时序分析准确SDC(Quartus)
辅助工具Vivado Tcl Console / Python 脚本批量运行综合与仿真Makefile / 批处理文件

目标与验收标准

  • 功能点:两个移位寄存器在综合后应产生相同的逻辑功能(串行移位),但硬件结构(寄存器间连接方式)不同。
  • 性能指标:非阻塞版本 Fmax 不低于 200 MHz(示例值,以实际器件为准);阻塞版本可能因组合环路导致 Fmax 下降或综合警告。
  • 资源占用:两个版本消耗的寄存器数量相同(每个移位寄存器 2 个 FF),但 LUT 或组合逻辑数量可能不同。
  • 关键波形:仿真波形中,dout_nonblock 在时钟上升沿后稳定变化;dout_block 可能在同一个时钟沿内出现多次跳变(毛刺)。
  • 验收方式:综合后网表对比、仿真波形截图、ILA 捕获的硬件波形。

实施步骤

1. 工程结构与代码编写

  • 创建 Vivado 工程,添加两个 Verilog 源文件:shift_block.vshift_nonblock.v
  • 编写顶层模块 top_shift.v,例化两个子模块,共用时钟、复位与输入数据。
  • 使用 `define 宏或参数控制是否启用阻塞/非阻塞版本,便于快速切换对比。

2. 关键模块实现:阻塞赋值移位寄存器

module shift_block (
    input  wire       clk,
    input  wire       rst_n,
    input  wire       din,
    output reg        dout
);
reg r1, r2;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        r1  = 1'b0;
        r2  = 1'b0;
        dout = 1'b0;
    end else begin
        r1  = din;
        r2  = r1;
        dout = r2;
    end
end
endmodule

逐行说明(shift_block.v)

  • 第 1–7 行:模块端口声明。clk 与 rst_n 为全局时钟和异步复位(低有效),din 为串行输入,dout 为串行输出。所有输出定义为 reg 类型,因为需要在 always 块内赋值。
  • 第 8 行:声明两个内部寄存器 r1、r2。注意这里没有指定初始值,综合后默认初始值为 X(不确定)。
  • 第 9 行:敏感列表为时钟上升沿或复位下降沿,这是标准的时序逻辑写法。
  • 第 10–14 行:复位逻辑,将所有寄存器清零。注意阻塞赋值在此处没有问题,因为复位时所有赋值顺序执行,最终结果正确。
  • 第 15–18 行:核心移位逻辑。由于使用阻塞赋值,r1 = din 立即更新,接着 r2 = r1 读取的是更新后的 r1(即 din),最后 dout = r2 读取的是更新后的 r2(即 din)。关键后果:综合工具会将 r1、r2、dout 优化成一个寄存器链,但组合逻辑上存在“读后写”依赖,可能插入额外组合路径,导致时序变差。
  • 第 19 行:endmodule。

3. 关键模块实现:非阻塞赋值移位寄存器

module shift_nonblock (
    input  wire       clk,
    input  wire       rst_n,
    input  wire       din,
    output reg        dout
);
reg r1, r2;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        r1  &lt;= 1'b0;
        r2  &lt;= 1'b0;
        dout &lt;= 1'b0;
    end else begin
        r1  &lt;= din;
        r2  &lt;= r1;
        dout &lt;= r2;
    end
end
endmodule

逐行说明(shift_nonblock.v)

  • 第 1–7 行:端口声明与 shift_block 完全相同,便于对比。
  • 第 8 行:同样声明内部寄存器 r1、r2。
  • 第 9 行:敏感列表相同。
  • 第 10–14 行:复位逻辑使用非阻塞赋值。在仿真中,所有赋值在 always 块结束时同时生效,复位时所有寄存器被清零。
  • 第 15–18 行:核心移位逻辑。非阻塞赋值在 always 块开始时采样右侧值(r1 采样的是上一个时钟周期的值,r2 采样的是上一个时钟周期的 r1),然后在块结束时统一更新。关键后果:综合工具会直接推断出 3 级流水线寄存器,每个寄存器之间只有布线延迟,无组合逻辑插入,时序最优。
  • 第 19 行:endmodule。

4. 顶层模块与 Testbench

module top_shift (
    input  wire clk,
    input  wire rst_n,
    input  wire din,
    output wire dout_block,
    output wire dout_nonblock
);

shift_block u_block (
    .clk    (clk),
    .rst_n  (rst_n),
    .din    (din),
    .dout   (dout_block)
);

shift_nonblock u_nonblock (
    .clk    (clk),
    .rst_n  (rst_n),
    .din    (din),
    .dout   (dout_nonblock)
);

endmodule

逐行说明(top_shift.v)

  • 第 1–6 行:顶层模块端口,包含时钟、复位、输入与两个输出。
  • 第 8–13 行:例化 shift_block,输出连接到 dout_block。
  • 第 15–20 行:例化 shift_nonblock,输出连接到 dout_nonblock。
  • 第 22 行:endmodule。

5. 综合与网表对比

  • 运行综合(synth_design),打开综合后的原理图(Schematic)。
  • 观察 u_block 内部:可能看到 r1r2 之间插入了组合逻辑(如 LUT1),用于实现“读后写”的依赖。
  • 观察 u_nonblock 内部:三个寄存器直接级联,无组合逻辑。
  • 使用 report_timing_summary 对比两个路径的时序裕量。阻塞版本路径延迟通常更大。
  • 常见坑:如果综合工具优化了阻塞版本中的冗余寄存器(例如将 r2 与 dout 合并),可以设置 -keep_equivalent_registers 来保留结构以便观察。

6. 仿真验证

// Testbench 片段
initial begin
    clk = 0;
    forever #10 clk = ~clk;  // 50 MHz
end

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

逐行说明(Testbench 片段)

  • 第 1–4 行:生成 50 MHz 时钟,周期 20 ns。
  • 第 6–12 行:复位 25 ns 后释放,然后输入数据序列:先拉高一个时钟周期,再拉低,再拉高。
  • 预期结果dout_nonblock 在 din 变化后经过 3 个时钟周期输出正确值;dout_block 可能提前一个周期输出(因为阻塞赋值导致数据穿透)。

7. 上板验证(ILA)

  • 添加 ILA IP 核,探测 clkdindout_blockdout_nonblock 以及内部寄存器 u_block/r1u_nonblock/r1
  • 设置触发条件为 din 上升沿,捕获深度 1024。
  • 下载比特流,运行 ILA,观察波形。确认硬件行为与仿真一致。
  • 常见坑:如果 ILA 采样时钟与逻辑时钟不同,可能导致采样错误。确保 ILA 使用与设计相同的时钟。

原理与设计说明

为什么阻塞赋值在时序逻辑中会导致硬件差异?

阻塞赋值(=)在 Verilog 中是一种“立即更新”的赋值方式。在一个 always 块内,语句按书写顺序执行,前一条赋值的结果会立即影响后续语句。对于组合逻辑(如 always @(*)),这符合硬件行为——组合逻辑的传播是连续的。但对于时序逻辑(always @(posedge clk)),综合工具必须推断出寄存器(FF)。当在同一个 always 块内使用阻塞赋值时,工具会检测到“读后写”依赖,并可能插入额外的组合逻辑来满足这种依赖,而不是直接使用寄存器。

具体到移位寄存器例子:阻塞版本中,r2 = r1 读取的是已经被 r1 = din 更新过的值,因此 r2 实际上直接获得了 din,而不是上一个时钟周期的 r1。综合工具为了保持这种“在同一时钟沿内传递数据”的行为,会将 r1r2 合并,或者插入一个组合路径绕过 r1。结果就是硬件结构不再是纯粹的流水线,而可能是一个带有组合反馈的寄存器链。

非阻塞赋值(<=) 则不同:它采用“采样-更新”两阶段机制。在 always 块开始时,所有右侧表达式被采样(读取当前值),然后块结束时统一更新左侧变量。这意味着 r2 <= r1 采样的是上一个时钟周期的 r1,而不是当前周期更新后的值。综合工具可以安全地将每个被赋值的变量映射到一个独立的寄存器,形成标准的流水线结构。

关键 trade-off

  • 资源 vs Fmax:非阻塞版本资源利用率更高(每个赋值对应一个寄存器),但 Fmax 更高(无组合逻辑插入)。阻塞版本可能节省寄存器(通过合并),但 Fmax 降低。
  • 吞吐 vs 延迟:非阻塞版本延迟固定(3 个时钟周期),吞吐稳定。阻塞版本延迟可能更短(2 个周期),但存在组合路径风险。
  • 易用性 vs 可移植性:在时序逻辑中坚持使用非阻塞赋值是业界最佳实践,代码易读且综合结果可预测。阻塞赋值在时序逻辑中容易引入 bug,且不同综合工具的处理方式可能不同。

验证与结果

指标阻塞版本(shift_block)非阻塞版本(shift_nonblock)测量条件
寄存器数量2(可能合并为 2)3Vivado 2025.2 综合报告
LUT 数量1(用于组合旁路)0同上
Fmax(示例)180 MHz250 MHzArtix-7 -1 speed grade,50 MHz 时钟输入
延迟(时钟周期数)23仿真波形测量
输出毛刺有(同一时钟沿内跳变)仿真波形 / ILA 捕获

说明:以上数值为示例,以实际综合与仿真结果为准。Fmax 受器件、约束、温度影响,建议读者在自己的工程中复现验证。

故障排查(Troubleshooting)

  • 现象:仿真中阻塞版本输出与预期不符(数据提前一个周期)。
    原因:阻塞赋值导致数据在同一时钟沿穿透。
    检查点:查看仿真波形中 r1r2 的变化时刻。
    修复建议:将时序逻辑中的阻塞赋值改为非阻塞赋值。
  • 现象:综合后阻塞版本报告时序违规(Setup Violation)。
    原因:组合逻辑插入导致路径延迟过大。
    检查点:运行 report_timing,查看最差路径是否经过阻塞版本。
    修复建议:改用非阻塞赋值,或手动插入流水线寄存器。
  • 现象:综合后阻塞版本与非阻塞版本资源占用相同。
    原因:综合工具优化了冗余逻辑,合并了寄存器。
    检查点:查看综合报告中的“Register Merging”或“Equivalent Register Removal”。
    修复建议:使用 -keep_equivalent_registers 选项保留结构,或添加 /* synthesis keep */ 属性。
  • 现象:上板后 ILA 捕获的波形与仿真不一致。
    原因:时钟抖动、复位同步问题或 ILA 采样触发设置错误。
    检查点:确认 ILA 时钟与设计时钟同源;检查复位释放是否满足时序。
    修复建议:使用同步复位或增加复位同步器。
  • 现象:仿真中非阻塞版本输出为 X(未知)。
    原因:寄存器未初始化,且复位未正确生效。
    检查点:检查复位信号是否在仿真开始时为低电平。
    修复建议:在 Testbench 中确保复位持续足够长的时间(至少一个时钟周期)。
  • 现象:综合警告“Inferring latch for signal xxx”。
    原因:在 always 块中某些分支未覆盖所有赋值,导致综合出锁存器。
    检查点:检查 always 块是否在所有分支(包括 else)中都对每个 reg 赋值。
    修复建议:补全赋值,或使用默认值。
  • 现象:两个版本在综合后原理图中完全相同。
    原因:综合工具优化过于激进,或者代码中阻塞赋值被工具自动纠正。
    检查点:查看综合日志中是否有“Replacing blocking with non-blocking”或类似信息。
    修复建议:检查综合选项,或使用更严格的编码风格(如 SystemVerilog 的 always_ff)。
  • 现象:使用 Quartus 综合时,阻塞版本与非阻塞版本结果相同。
    原因:Quartus 可能对阻塞赋值有特殊处理,或默认优化策略不同。
    检查点:查看 Quartus 的“Analysis & Synthesis”报告。
    修复建议:以 Vivado 为主要参考,或查阅具体工具文档。

扩展与下一步

<
  • 参数化移位寄存器:使用 parameter WIDTHparameter DEPTH 实现可配置的移位寄存器,并对比阻塞与非阻塞在参数化下的综合结果。
  • <
标签:
本文原创,作者:FPGA小白,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/49513.html
分享:
2026年Q2:FPGA时序约束中set_clock_groups在异步时钟域的正确用法
2026年Q2:FPGA时序约束中set_clock_groups在异步时钟域的正确用法上一篇
Insights 812858636下一篇
Insights 812858636
相关文章
总数:1.26K

2026年FPGA行业趋势深度解析:Chiplet、国产EDA、AI推理与就业新热点

2026年,FPGA行业正经历一场由技术革新与市场需求双重驱动的深刻变革。从Chiplet互连标准UCIe在FPGA异构集成中的工程化加速,到国…
二牛学FPGA二牛学FPGA
技术分享
1个月前
0
0
76
0

FPGA+ASIC混合架构在大模型推理芯片中的落地指南:2026年实践视角

QuickStart:在FPGA+ASIC混合架构上跑通一次大模型推理本指南假设你已有一块支持PCIeGen5的FPGA开发板(如Xilin…
二牛学FPGA二牛学FPGA
技术分享
1个月前
0
0
148
0

FPGA与Verilog数字系统设计入门实践指南

本文旨在为电子、计算机、通信等相关专业的学生,提供一条从零基础到能够独立完成简单数字系统设计的、清晰且可执行的FPGA学习路径。我们将遵循“实践…
二牛学FPGA二牛学FPGA
技术分享
1个月前
0
0
72
0

2026年5月:基于FPGA的实时视频去雾算法实现与资源优化

QuickStart安装Vivado2025.2(或更高版本)与ModelSim/QuestaSim2024.1。下载工程模板:git…
二牛学FPGA二牛学FPGA
技术分享
1个月前
0
0
0
0

FPGA学习路线:从入门到竞赛获奖的进阶指南

QuickStart:30分钟跑通第一个LED闪烁工程本指南面向零基础学生,目标是在30分钟内完成第一个FPGA工程——让开发板上的LED以1…
二牛学FPGA二牛学FPGA
技术分享
1个月前
0
0
77
0

2026年硬件技术前瞻:从CXL 3.0到3D-IC,FPGA与芯片设计的六大演进脉络

作为成电国芯FPGA云课堂的特邀观察者,我们持续追踪着硬件技术领域的每一次脉动。进入2026年,技术演进的方向愈发清晰,挑战与机遇并存。本文基于…
FPGA小白FPGA小白
技术分享
1个月前
0
0
127
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容