返回

FPGA时钟复位管理的本质

深入探讨 FPGA 时钟复位管理的本质,分析复位释放导致的亚稳态风险,并提供工程化的异步复位同步释放方案,确保系统时序收敛与逻辑确定性。

FPGA 时钟复位管理:从问题本质到工程落地

一、问题的本质

FPGA 时钟复位管理要解决的核心问题只有一个:让系统在任何时刻进入复位,并在确定的时刻干净地退出复位

“干净"意味着:

  • 所有寄存器在同一个时钟沿统一开始工作
  • 没有寄存器因复位释放时机不同而产生竞争或亚稳态
  • 不同时钟域之间不会因复位释放的先后产生数据错乱

二、为什么复位会出问题?

2.1 复位释放的亚稳态

FPGA 中的触发器有建立时间 (Tsu) 和保持时间 (Th) 要求。复位信号本质上也是触发器的一个输入,释放时如果违反时序:

1
2
3
4
5
6
          ┌──────────────────────
rst ──────┘        ← 复位释放沿
     clk ─┴─┬─┬─┬─┬─┬─┬─┬─
            若释放沿落在 clk 上升沿附近,
            触发器可能进入亚稳态

亚稳态会导致:

  • 同一个复位信号在不同寄存器看来"释放时机不同”
  • 部分寄存器提前一拍开始工作,部分晚一拍
  • 状态机、计数器、协议握手等逻辑出现不可预测行为

2.2 多时钟域的复位同步问题

假设系统有 clk_Aclk_B 两个异步时钟域,共用一个复位源:

1
2
rst_in ─────┬───→ Domain A (clk_A)
            └───→ Domain B (clk_B)

如果 rst_in 直接分发:

  • clk_A 看来可能是某个时刻释放
  • clk_B 看来可能是另一个时刻释放
  • 两个域的复位释放差可达 1 个时钟周期甚至更多

后果:跨域握手信号在复位释放瞬间可能出现"一边还在复位,一边已经开始发数据"的窗口。


三、解决方案:异步置位、同步释放

3.1 核心思想

1
2
异步置位:复位信号一来,立即置位(不等时钟沿)
同步释放:复位信号释放后,必须经过本域时钟同步(2拍或多拍)再释放到逻辑

为什么这样设计?

动作要求原因
置位异步、立即复位本身是紧急停止,必须无条件生效
释放同步、延迟释放沿必须落在本域时钟有效沿,保证所有寄存器同时看到释放

3.2 基础电路:Reset Synchronizer

1
2
3
4
5
6
7
                     ┌─────┐   ┌─────┐
rst_in (async) ──────┤D   Q├───┤D   Q├──→ rst_out (sync to clk)
                     │     │   │     │
clk ─────────────────┴──┬──┘   └──┬──┘
                        │         │
                        └─────────┘
                         两级同步器

Verilog 实现要点:

1
2
3
4
5
6
7
8
9
// 高有效复位,异步置位、同步释放
always @(posedge i_clk or posedge i_rst_async) begin
    if (i_rst_async) begin
        r_rst_sync <= 2'b11;          // 异步置位
    end else begin
        r_rst_sync <= {r_rst_sync[0], 1'b0}; // 同步释放(移位)
    end
end
assign o_rst_sync = r_rst_sync[1];    // 输出稳定后的复位

关键点:

  • posedge i_rst_async:复位来时立即进入复位状态
  • else 分支只在时钟沿执行:复位释放经过 2 拍才输出
  • ASYNC_REG 属性:告诉工具这是同步器链,不要优化

3.3 多时钟域的复位拓扑

每个时钟域必须有独立的 Reset Synchronizer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
                          ┌─────────────────┐
                          │  Reset Bridge   │
                          │  @clk_A         │
              ┌───────────┤                 ├──→ rst_A
              │           └─────────────────┘
rst_source ───┼───────────┌─────────────────┐
              │           │  Reset Bridge   │
              │           │  @clk_B         │
              └───────────┤                 ├──→ rst_B
                          └─────────────────┘

规则

  1. 同一个复位源可以驱动多个域,但每个域必须有自己的同步器
  2. 各域复位释放时刻可能相差若干时钟周期,这是合理的、设计允许的
  3. 跨域通信必须有独立的 CDC 机制(握手/FIFO),不能依赖复位释放顺序

四、复位源的聚合与优先级

实际系统中,复位可能来自多个源:

复位源性质示例
外部按键/信号异步板上复位按钮
PLL/MMCM 锁定异步~mmcm_locked
看门狗同步超时触发
软件控制同步AXI 寄存器写入
依赖模块就绪同步~idelayctrl_rdy

聚合策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 复位源聚合(组合逻辑,全部高有效)
assign w_rst_combined = i_ext_rst 
                      | (~i_mmcm_locked)
                      | (~i_idelayctrl_rdy)
                      | i_soft_rst;

// 再送入各域的 Reset Synchronizer
reset_sync u_rst_sync_clk100 (
    .i_clk       (clk_100m),
    .i_rst_async (w_rst_combined),
    .o_rst_sync  (rst_clk100)
);

优先级:或操作天然是"任意一个有效即复位",无需额外仲裁。


五、时钟管理与复位的配合

5.1 时钟稳定是复位释放的前提

复位同步器依赖时钟沿工作,因此:

1
2
时钟未稳定 → 复位必须保持有效
时钟稳定后 → 复位才能开始释放流程

典型门槛:

  • MMCM/PLL 的 locked 信号
  • IDELAYCTRL 的 rdy 信号(如果用到 IDELAY)
1
2
3
4
5
                MMCM          Reset Sync
clk_in ────────┤├──→ clk_out ─────┤├──→ rst_out
                │                  │
         locked ┴──────────────────┘
                  locked=0 时保持复位

5.2 外部器件的复位时序

某些场景(如以太网 PHY、DDR 控制器)需要满足器件手册的复位时序:

1
2
3
PHY 复位典型时序:
├─ 复位保持 ≥ 10ms ──┼─ 释放后等待 ≥ 50ms ──┤
                                            └→ PHY 就绪

实现方式:

  • 用计数器状态机在系统时钟域实现延时
  • 延时完成后释放 phy_rst_done,再参与系统复位聚合

六、工程检查清单

检查项要求验证方法
每个时钟域有独立 Reset Synchronizer强制RTL 审查
同步器标注 ASYNC_REG强制约束/综合报告
复位释放前时钟已稳定强制仿真波形
跨域 CDC 不依赖复位顺序强制FIFO/握手机制验证
外部器件复位时序满足手册必须示波器/ILA 测量
复位释放可被 ILA 观测建议Debug 便利性

七、NetBoost 项目映射

将上述通用原则映射到本项目:

7.1 时钟拓扑

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
clk_ext (50MHz)
   MMCM ────┬──→ clk_50m   (未使用)
            ├──→ clk_100m  (系统主时钟 i_clk)
            ├──→ clk_125m  (GMII TX 时钟)
            ├──→ clk_125m_90 (RGMII TX DDR 发送相位)
            └──→ clk_200m  (IDELAYCTRL 参考时钟)

clk_ext 经 IBUFG → MMCM → 各路 BUFG 输出

7.2 复位拓扑

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
复位源聚合:
  ├─ ~mmcm_locked
  ├─ ~idelayctrl_rdy
  ├─ ~phy_rst_finish (PHY复位时序状态机)
  └─ 外部复位信号
   w_sys_rst_combined
        ├──→ Reset Sync @clk_100m   ──→ o_sys_reset
        ├──→ Reset Sync @clk_125m   ──→ o_gmii_tx_reset
        ├──→ Reset Sync @gmii0_rx_clk ──→ o_gmii0_rx_reset
        └──→ Reset Sync @gmii1_rx_clk ──→ o_gmii1_rx_reset

7.3 代码模块对应

概念模块说明
MMCM 配置clk_rst_mng.v生成多路时钟
Reset Synchronizerreset_gen.v每域一个实例
复位源聚合rst_domain_mgr.v组合所有复位条件
PHY 复位时序rst_domain_mgr.v 内 FSM10ms 保持 + 50ms 等待

八、总结

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
问题本质:复位释放时刻的不确定性导致系统行为不可预测

解决方案:
  ├─ 异步置位:紧急停止,立即生效
  └─ 同步释放:延迟到本域时钟沿,保证一致性

工程落地:
  ├─ 每域独立 Reset Synchronizer
  ├─ 时钟稳定作为复位释放的前提
  ├─ 复位源按需聚合
  └─ 外部器件时序单独处理

记住:复位管理的核心不是"怎么写代码",而是理解"为什么复位释放是个问题"以及"同步释放如何解决它"。

Licensed under CC BY-NC-SA 4.0
本文阅读量
🄯 2025 - 2026 DeerMiya的博客· 0Days
共书写了35.2k字·共 17篇文章
本站总访问量 · 访客数

DeerMiya的一些笔记
使用 Hugo 构建
主题 Stack ModIce Year 设计
🄯 Licensed Under CC BY-NC-SA 4.0