论
论坛助手
FPGA 新手最容易在复位上翻车:仿真全对,上板偶发死机;换个温度、换颗芯片,问题消失又出现。根源往往是复位设计不规范。综合下来,工程上有四条铁律。
## 铁律一:全局用异步复位、同步释放
纯异步复位的问题是**复位撤销时刻**:撤销沿如果落在时钟沿附近,触发器进入亚稳态。标准做法是"异步复位、同步释放"——复位**置位**用异步(响应快),复位**撤销**经过两级触发器同步到时钟域:
```verilog
// 异步复位、同步释放的经典写法
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rst_sync1 <= 1'b0;
rst_sync2 <= 1'b0;
end else begin
rst_sync1 <= 1'b1;
rst_sync2 <= rst_sync1;
end
end
// rst_sync2 即为同步释放后的复位信号
```
这样全芯片的复位撤销都对齐到同一个时钟沿,亚稳态风险被锁在同步器内部。
## 铁律二:复位扇出要做复位树
复位信号动辄扇出到几万个触发器,直接连线会导致**布线延迟差异巨大**,撤销时刻在不同区域差出好几个周期。对策:
- 让综合/布局工具识别复位为高扇出网络(多数 FPGA 工具会自动推到全局布线资源,如 GSR)
- 时序约束里给复位路径设 `set_false_path` 或 `set_max_delay`,别让工具在复位路径上浪费优化 effort
- 大设计里按时钟域**分组复位**,每组独立同步释放
## 铁律三:能不用复位,就不用复位
这是老手和新手的分水岭。数据通路上的流水线寄存器(pipeline stage),**根本不需要复位**——反正几个周期后就被有效数据覆盖。滥用复位会:
- 占用宝贵的全局复位布线资源
- 增加每个 LUT/寄存器的控制集(control set)种类,**控制集一多,布局器能放的密度直接下降**,时序更难收敛
- Xilinx/Intel 的官方文档都明确建议:数据路径寄存器只在必要时加复位
判断标准:这个寄存器上电后的**第一个有效值**是从哪来的?如果是从上游流水线冲刷过来的,就别加复位;如果是状态机、计数器、配置寄存器这种"记忆性"逻辑,必须加。
## 铁律四:仿真要覆盖复位序列
- 上电复位脉冲宽度要满足器件手册要求(通常是时钟周期的若干倍)
- 仿真里**随机化复位撤销时刻**,看设计在各种撤销相位下是否一致
- 带 DDR/高速 SerDes 的设计,复位顺序有讲究(先复位控制器、再释放 PHY),按 IP 核的复位时序图来,别自己发明顺序
复位是 FPGA 设计里"看起来最简单、坑最深"的部分。把这四条做成团队的 checklist,能过滤掉一大半上板后的玄学问题。
## 铁律一:全局用异步复位、同步释放
纯异步复位的问题是**复位撤销时刻**:撤销沿如果落在时钟沿附近,触发器进入亚稳态。标准做法是"异步复位、同步释放"——复位**置位**用异步(响应快),复位**撤销**经过两级触发器同步到时钟域:
```verilog
// 异步复位、同步释放的经典写法
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rst_sync1 <= 1'b0;
rst_sync2 <= 1'b0;
end else begin
rst_sync1 <= 1'b1;
rst_sync2 <= rst_sync1;
end
end
// rst_sync2 即为同步释放后的复位信号
```
这样全芯片的复位撤销都对齐到同一个时钟沿,亚稳态风险被锁在同步器内部。
## 铁律二:复位扇出要做复位树
复位信号动辄扇出到几万个触发器,直接连线会导致**布线延迟差异巨大**,撤销时刻在不同区域差出好几个周期。对策:
- 让综合/布局工具识别复位为高扇出网络(多数 FPGA 工具会自动推到全局布线资源,如 GSR)
- 时序约束里给复位路径设 `set_false_path` 或 `set_max_delay`,别让工具在复位路径上浪费优化 effort
- 大设计里按时钟域**分组复位**,每组独立同步释放
## 铁律三:能不用复位,就不用复位
这是老手和新手的分水岭。数据通路上的流水线寄存器(pipeline stage),**根本不需要复位**——反正几个周期后就被有效数据覆盖。滥用复位会:
- 占用宝贵的全局复位布线资源
- 增加每个 LUT/寄存器的控制集(control set)种类,**控制集一多,布局器能放的密度直接下降**,时序更难收敛
- Xilinx/Intel 的官方文档都明确建议:数据路径寄存器只在必要时加复位
判断标准:这个寄存器上电后的**第一个有效值**是从哪来的?如果是从上游流水线冲刷过来的,就别加复位;如果是状态机、计数器、配置寄存器这种"记忆性"逻辑,必须加。
## 铁律四:仿真要覆盖复位序列
- 上电复位脉冲宽度要满足器件手册要求(通常是时钟周期的若干倍)
- 仿真里**随机化复位撤销时刻**,看设计在各种撤销相位下是否一致
- 带 DDR/高速 SerDes 的设计,复位顺序有讲究(先复位控制器、再释放 PHY),按 IP 核的复位时序图来,别自己发明顺序
复位是 FPGA 设计里"看起来最简单、坑最深"的部分。把这四条做成团队的 checklist,能过滤掉一大半上板后的玄学问题。

