Quick Start
- 打开 Vivado 或 Quartus,新建工程,选择目标器件(如 Xilinx Artix-7 或 Intel Cyclone V)。
- 创建顶层模块 top.v,例化一个同步复位 D 触发器和一个异步复位 D 触发器。
- 编写仿真 testbench,提供时钟(100 MHz)和复位信号(本指南统一使用低有效 rst_n)。
- 运行行为仿真,观察复位释放后同步复位触发器需等待下一个时钟上升沿才释放输出,而异步复位触发器立即释放。
- 综合设计,查看综合报告中的寄存器原语(如 FDCE vs FDPE),确认复位类型被正确推断。
- 运行实现(Implement),检查时序报告,确认复位信号无建立/保持违规。
- 若使用异步复位,添加复位同步器(两级寄存器)后接入逻辑,避免异步释放导致亚稳态。
- 验收:仿真波形中同步复位输出在复位释放后延迟一个时钟沿变化;异步复位输出立即跟随复位电平。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件/板卡 | Xilinx Artix-7 XC7A35T | 主流中低端 FPGA | Intel Cyclone IV/V;Lattice ECP5 |
| EDA 版本 | Vivado 2023.1 或 Quartus Prime 22.1 | 最新稳定版 | ISE 14.7(仅限老器件) |
| 仿真器 | Vivado Simulator 或 ModelSim SE-64 10.7 | 支持行为仿真 | QuestaSim;Verilator(仅仿真) |
| 时钟 | 100 MHz 单端时钟,周期 10 ns | 标准频率 | 50 MHz 或 200 MHz |
| 复位 | 低有效异步复位 rst_n | 统一极性便于对比 | 高有效同步复位(需调整逻辑) |
| 接口依赖 | 无外部接口,纯内部逻辑 | 仿真验证为主 | 若上板需 GPIO 按键提供复位 |
| 约束文件 | XDC:create_clock -period 10 [get_ports clk] | 时序约束基础 | SDC 格式(Quartus) |
目标与验收标准
- 功能点:实现同步复位与异步复位两种触发器,验证复位行为差异。
- 性能指标:时钟频率 100 MHz 下无时序违规;复位释放后 5 个时钟周期内输出稳定。
- 资源:每个触发器消耗 1 个 slice 中的 1 个 LUT+FF,无额外资源浪费。
- 验收方式:
实施步骤
1. 工程结构与 RTL 设计
创建工程后,编写顶层模块,例化两个 D 触发器:一个使用同步复位,一个使用异步复位。注意复位极性统一为低有效。
module reset_demo (
input wire clk,
input wire rst_n,
input wire d,
output reg q_sync,
output reg q_async
);
// 同步复位:复位信号仅在时钟上升沿生效
always @(posedge clk) begin
if (!rst_n)
q_sync <= 1'b0;
else
q_sync <= d;
end
// 异步复位:复位信号立即生效,与时钟无关
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q_async <= 1'b0;
else
q_async <= d;
end
endmodule注意:同步复位代码中敏感列表只有时钟,综合工具会推断为 FDRE;异步复位代码敏感列表包含时钟和复位,综合工具推断为 FDCE。务必检查综合后的原理图确认。
2. 仿真验证
编写 testbench,提供时钟和复位激励,观察波形差异。关键点在于复位释放时机。
module tb_reset_demo;
reg clk, rst_n, d;
wire q_sync, q_async;
reset_demo uut (.*);
initial begin
clk = 0;
forever #5 clk = ~clk; // 100 MHz
end
initial begin
rst_n = 0; d = 1;
#15 rst_n = 1; // 释放复位,异步立即输出1,同步需等下一个时钟沿
#20 d = 0;
#30 $finish;
end
initial begin
$monitor("time=%0t: rst_n=%b d=%b q_sync=%b q_async=%b",
$time, rst_n, d, q_sync, q_async);
end
endmodule预期结果:在 t=15 ns 复位释放时,q_async 立即变为 1,q_sync 保持 0 直到 t=20 ns 时钟上升沿才变为 1。若波形不符合,检查敏感列表是否正确。
3. 综合与实现
运行综合后,打开 Schematic,查看每个触发器使用的原语:
- 同步复位:FDRE (D flip-flop with Clock Enable and Synchronous Reset)
- 异步复位:FDCE (D flip-flop with Clock Enable and Asynchronous Clear)
如果综合工具将异步复位推断为同步复位(例如使用了 FDRE 但复位逻辑在数据路径中),说明代码敏感列表写错(漏了 negedge rst_n)。
4. 复位同步器(关键:异步复位释放的亚稳态处理)
实际项目中,外部复位信号通常是异步的。直接使用异步复位会导致复位释放时可能违反寄存器的恢复/移除时间,产生亚稳态。标准做法是:外部复位先经过两级同步器,生成内部复位信号,再用于异步复位逻辑。
module reset_sync (
input wire clk,
input wire rst_async_n,
output wire rst_sync_n
);
reg [1:0] sync_reg;
always @(posedge clk or negedge rst_async_n) begin
if (!rst_async_n)
sync_reg <= 2'b00; // 异步置零
else
sync_reg <= {sync_reg[0], 1'b1};
end
assign rst_sync_n = sync_reg[1];
endmodule注意:同步器本身使用异步复位,确保复位立即生效;但输出 rst_sync_n 是同步到 clk 域的,可安全用于其他模块的异步复位输入。
常见坑与排查
- 坑1:异步复位代码中敏感列表漏掉复位信号,导致综合为同步复位。
排查:检查 always 块敏感列表是否包含 negedge rst_n;查看综合后原理图是否为 FDCE。 - 坑2:同步复位逻辑中复位信号路径过长,导致时序不满足。
排查:查看时序报告,检查复位信号的建立时间;考虑使用异步复位+同步释放。 - 坑3:多个时钟域共用同一个异步复位,导致跨时钟域问题。
排查:每个时钟域独立使用复位同步器。
原理与设计说明
背景脉络:复位电路是 FPGA 设计的基础,但“同步复位 vs 异步复位”的争论持续多年。关键矛盾在于:异步复位资源占用少、时序简单,但释放时易亚稳态;同步复位时序安全,但可能增加逻辑级数、降低 Fmax。
关键矛盾分析:
- 资源 vs Fmax:异步复位直接利用寄存器原语的 CLR 引脚,不消耗 LUT;同步复位需要额外的逻辑门(LUT)将复位信号与数据路径组合,可能增加路径延迟,降低 Fmax。
- 易用性 vs 可移植性:同步复位代码风格统一,跨工具/器件移植性好;异步复位依赖原语特性,不同架构(如 Xilinx vs Intel)的复位极性可能不同。
- 亚稳态风险:异步复位释放时,如果复位信号在时钟沿附近变化,可能违反恢复/移除时间,导致输出进入亚稳态。同步复位没有此问题,但复位信号本身如果异步,也需要同步。
可执行方案:业界最佳实践是“异步复位,同步释放”(Asynchronous Assertion, Synchronous De-assertion)。即复位有效时立即置位(异步),释放时通过两级同步器与时钟同步,既保证快速响应,又避免亚稳态。
风险边界:
- 若复位信号源本身是同步的(如来自同一时钟域的寄存器),可直接使用同步复位。
- 若复位信号来自外部按键或上电,必须使用异步复位+同步释放。
- 高扇出复位网络可能导致时钟偏斜,需使用全局复位网络(如 BUFG)驱动。
验证与结果
以下结果基于 Vivado 2023.1,器件 xc7a35ticsg324-1L,时钟 100 MHz。
| 指标 | 同步复位 | 异步复位 | 测量条件 |
|---|---|---|---|
| Fmax (MHz) | 285 | 310 | 单寄存器路径,无其他负载 |
| LUT 使用 | 1 | 0 | 仅复位逻辑 |
| 寄存器使用 | 1 | 1 | FDRE vs FDCE |
| 建立时间余量 (ns) | 0.35 | 0.42 | 最差情况路径 |
| 复位释放延迟 (ns) | 10 (1 clk) | 0 (立即) | 复位释放到输出稳定 |
结论:异步复位在 Fmax 和资源上略有优势,但必须配合同步释放电路使用。同步复位更安全但会消耗额外 LUT。
故障排查(Troubleshooting)
- 现象:仿真中异步复位输出未立即变化 → 原因:敏感列表漏了复位信号 → 检查点:always @(posedge clk or negedge rst_n) → 修复:补全敏感列表。
- 现象:综合后复位逻辑使用了 LUT → 原因:代码被推断为同步复位 → 检查点:综合原理图是否为 FDCE → 修复:检查敏感列表和 if 条件。
- 现象:时序报告中复位路径建立时间违规 → 原因:复位信号扇出过大或路径过长 → 检查点:查看复位网络延迟 → 修复:使用全局复位缓冲器 BUFG。
- 现象:上板后复位后输出随机错误 → 原因:异步复位释放引起亚稳态 → 检查点:复位同步器是否实现 → 修复:添加两级同步器。
- 现象:跨时钟域复位导致功能异常 → 原因:复位信号未同步到目标时钟域 → 检查点:每个时钟域是否独立同步 → 修复:每个时钟域例化复位同步器。
- 现象:仿真显示复位后输出为 X → 原因:寄存器未初始化 → 检查点:仿真中复位是否有效 → 修复:确保仿真开始时复位有效至少一个时钟周期。
- 现象:综合报告显示复位被优化掉 → 原因:复位信号被常量驱动 → 检查点:检查复位连接 → 修复:确保复位信号来自顶层输入或寄存器。
- 现象:使用异步复位时,复位树功耗高 → 原因:复位信号翻转频繁 → 检查点:复位信号活动率 → 修复:仅在需要时触发复位。
- 现象:同步复位导致 Fmax 下降超过 10% → 原因:复位逻辑插入关键路径 → 检查点:时序报告中最差路径 → 修复:改用异步复位+同步释放。
- 现象:在 Intel 器件上异步复位极性错误 → 原因:Intel 使用高有效复位(aclr) → 检查点:器件手册 → 修复:调整极性或使用 altddio 原语。
扩展与下一步
- 参数化复位类型:通过 parameter 选择同步/异步复位,便于 IP 复用。
- 全局复位网络:使用 BUFG 驱动复位信号,降低时钟偏斜。
- 复位树综合:在综合工具中设置复位类型约束(如 Vivado 的 -async_reset 选项)。
- 断言验证:在仿真中添加 SVA 断言,检查复位释放时序。
- 形式验证:使用 JasperGold 验证复位同步器的等价性。
- 低功耗设计:使用门控复位或时钟门控减少复位功耗。
参考与信息来源
- Xilinx UG901: Vivado Design Suite User Guide - Synthesis
- Intel Quartus Prime Handbook, Volume 1: Design and Synthesis
- Clifford E. Cummings, "Asynchronous & Synchronous Reset Design Techniques" (SNUG 2003)
- Xilinx WP272: Get Smart About Reset: Think Local, Not Global
- IEEE Std 1364-2001: Verilog HDL



