返回

Xilinx 7-series 复位设计与 FF 原语深度指南

深入解析 Xilinx 7-series FPGA 的触发器架构、复位设计最佳实践及异步置位同步释放(Reset Bridge)实现。

Xilinx 7-series 复位设计与 FF 原语深度指南

本文深入解析 Xilinx 7-series FPGA 的触发器(FF)架构、复位设计的最佳实践,以及如何正确实现"异步置位、同步释放"的复位同步器。


1. 7-series Slice 中的 FF 架构

1.1 Slice 基本结构

Xilinx 7-series(Artix-7、Kintex-7、Virtex-7)的 CLB(Configurable Logic Block)包含两个 Slice,每个 Slice 包含:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
┌─────────────────────────────────────────────────────────────┐
│                         SLICE                               │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │  LUT_A  │  │  LUT_B  │  │  LUT_C  │  │  LUT_D  │        │  4 × 6-LUT
│  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘        │
│       │            │            │            │              │
│  ┌────▼────┐  ┌────▼────┐  ┌────▼────┐  ┌────▼────┐        │
│  │  FF_A   │  │  FF_B   │  │  FF_C   │  │  FF_D   │        │  4 × FF(上层)
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │  FF_A2  │  │  FF_B2  │  │  FF_C2  │  │  FF_D2  │        │  4 × FF(下层)
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
│                                                             │
│  + Carry Chain (CARRY4) + Wide MUX + 其他控制逻辑          │
└─────────────────────────────────────────────────────────────┘

关键点:每个 Slice 有 8 个 FF,物理结构相同,功能通过配置决定。

1.2 FF 的控制信号

每个 FF 有以下控制端口:

端口名称说明
CClock时钟输入
DData数据输入
QOutput数据输出
CEClock Enable时钟使能(高有效)
SRSet/Reset置位/复位控制

重要限制:同一 Slice 内的 8 个 FF 共享以下控制信号:

共享信号限制
CLK必须同时钟
CE必须同使能
SR必须同复位信号
SR 极性必须同为同步或异步
SR 功能必须同为置位或复位

这意味着:不能在同一 Slice 内混用 FDRE 和 FDPE

1.3 FF 的四种配置模式

通过配置 SR 端的功能,同一物理 FF 可以实现四种不同行为:

原语名称全称SR 功能复位类型复位后状态
FDREFF + sync Reset + CE同步复位同步Q = 0
FDSEFF + sync Set + CE同步置位同步Q = 1
FDCEFF + async Clear + CE异步清零异步Q = 0
FDPEFF + async Preset + CE异步置位异步Q = 1

2. RTL 写法与综合结果对照

2.1 综合器如何推断 FF 类型

综合器根据 always 块的敏感列表和代码结构推断 FF 类型:

同步复位 → FDRE / FDSE

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 复位到 0 → FDRE
always @(posedge clk) begin
    if (rst)
        q <= 1'b0;
    else
        q <= d;
end

// 复位到 1 → FDSE
always @(posedge clk) begin
    if (rst)
        q <= 1'b1;
    else
        q <= d;
end

异步复位 → FDCE / FDPE

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 异步复位到 0 → FDCE
always @(posedge clk or posedge rst) begin  // 注意:敏感列表包含 rst
    if (rst)
        q <= 1'b0;
    else
        q <= d;
end

// 异步复位到 1 → FDPE
always @(posedge clk or posedge rst) begin
    if (rst)
        q <= 1'b1;
    else
        q <= d;
end

无复位 → FDRE(SR 悬空)

1
2
3
always @(posedge clk) begin
    q <= d;
end

2.2 综合对照表

RTL 写法敏感列表复位条件推断原语
同步复位到 0posedge clkif (rst) q <= 0FDRE
同步复位到 1posedge clkif (rst) q <= 1FDSE
异步复位到 0posedge clk or posedge rstif (rst) q <= 0FDCE
异步复位到 1posedge clk or posedge rstif (rst) q <= 1FDPE
无复位posedge clkFDRE

3. 同步复位 vs 异步复位:如何选择

3.1 Xilinx 官方推荐

Xilinx WP272《Get Smart About Reset》明确推荐:同步复位优先。

3.2 对比分析

对比项同步复位异步复位
时序收敛✅ 复位信号被时序约束覆盖⚠️ 需要额外的 recovery/removal 约束
资源利用✅ 复位逻辑可合并进 LUT❌ 必须使用 SR 专用信号
仿真一致性✅ 敏感列表简单,不易出错⚠️ 敏感列表易漏写 or posedge rst
亚稳态风险✅ 无⚠️ 复位释放时可能亚稳态
时钟未起振时❌ 无法复位✅ 可以复位

3.3 最佳实践结论

场景推荐做法
普通逻辑(FSM、计数器)同步复位
数据通路(流水线寄存器)不加复位
复位同步器内部(第一级 FF)异步置位(FDPE)

3.4 推荐代码风格

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 控制逻辑:同步复位
always @(posedge i_clk) begin
    if (i_rst_p)
        r_state <= S_IDLE;
    else
        r_state <= r_next_state;
end

// 数据通路:不加复位
always @(posedge i_clk) begin
    r_data_d1 <= w_data_in;
    r_data_d2 <= r_data_d1;
end

4. 复位同步器:异步置位、同步释放

4.1 为什么需要复位同步器

当复位信号来自外部(按钮、另一个时钟域),它相对于本时钟域是异步的。如果直接使用:

1
2
3
4
5
        ┌───────┐
rst_in ─┤ FF    ├─ q    ← 复位释放时刻随机,可能在时钟边沿附近
        └───┬───┘
           clk

问题:复位释放时刻不确定,可能违反 FF 的 recovery/removal 时间,导致亚稳态。

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
                    异步置位(立即生效)
rst_in ───────────────────┼───────────────────────┐
                          ▼                       ▼
                    ┌──────────┐            ┌──────────┐
              0 ───►│  FDPE    │──► sync0 ──►│  FDPE    │──► sync1 ──► rst_out
                    │  (PRE)   │            │  (PRE)   │
                    └────┬─────┘            └────┬─────┘
                         │                       │
                        clk                     clk
                                          同步释放(等时钟沿)

工作原理

阶段行为
复位置位rst_in=1 → PRE 端立即置位 → sync0=1sync1=1rst_out=1(不等时钟)
复位释放rst_in=0 → PRE 释放 → D 端开始传递 0 → 经过 2-3 个时钟周期 → rst_out=0

4.3 为什么用 FDPE 而不是 FDCE

需求FDPE (Preset)FDCE (Clear)
异步置位到 1(高有效复位)✅ 直接支持❌ 只能清零
配合 rst_in 高有效✅ PRE 高有效需要取反

4.4 Xilinx 原语实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 3 级复位同步器:异步置位、同步释放
(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDPE #(.INIT(1)) u_sync_r0 (.C(clk), .CE(1'b1), .PRE(rst_in), .D(1'b0   ), .Q(sync_r0));

(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDPE #(.INIT(1)) u_sync_r1 (.C(clk), .CE(1'b1), .PRE(rst_in), .D(sync_r0), .Q(sync_r1));

(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDPE #(.INIT(1)) u_sync_r2 (.C(clk), .CE(1'b1), .PRE(rst_in), .D(sync_r1), .Q(sync_r2));

assign rst_out = sync_r2;

关键属性

属性作用
ASYNC_REG="TRUE"告诉 Vivado 这是异步信号同步链,强制放在同一 Slice
SHREG_EXTRACT="NO"禁止综合成 SRL16,保持物理 FF 结构
.INIT(1)上电时 Q=1,保证上电复位

5. CDC 同步器:与复位同步器的区别

5.1 为什么 CDC 用 FDRE

CDC(跨时钟域)同步的是普通数据信号,不是复位:

需求对比复位同步器CDC 同步器
需要立即生效✅ 必须❌ 不需要
可以等时钟沿
需要异步控制端✅ PRE
应该被复位吗N/A❌ 不应该

5.2 CDC 同步器实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// CDC 同步器:纯数据通路,无复位
(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDRE #(.INIT(0)) u_sync_r0 (.C(clk), .CE(1'b1), .R(1'b0), .D(din    ), .Q(sync_r0));

(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDRE #(.INIT(0)) u_sync_r1 (.C(clk), .CE(1'b1), .R(1'b0), .D(sync_r0), .Q(sync_r1));

(*ASYNC_REG="TRUE", SHREG_EXTRACT="NO"*)
FDRE #(.INIT(0)) u_sync_r2 (.C(clk), .CE(1'b1), .R(1'b0), .D(sync_r1), .Q(sync_r2));

assign dout = sync_r2;

注意.R(1'b0) 表示不使用复位。如果 CDC 同步器带复位,复位信号本身又是跨时钟域的,会产生新的 CDC 问题。


6. 同步链级数:2 级、3 级还是 5 级?

6.1 亚稳态恢复概率

亚稳态恢复概率是指数衰减的:

1
P(亚稳态未恢复) ≈ e^(-t / τ)
  • 7-series FF 的 τ 约为 30~100ps
  • 一个时钟周期(@200MHz = 5ns)远大于 5τ
  • 第 2 级之后,亚稳态概率已可忽略

6.2 工业标准

级数适用场景常见于
2 级常规应用Xilinx XPM_CDC 默认
3 级高可靠性(航空、医疗)UG576 FIFO Generator
4+ 级极端保守通常过度设计

6.3 推荐

复位同步器和 CDC 同步器使用 3 级——既满足可靠性要求,又不过度消耗资源。


7. 常见错误与规避

7.1 错误:RTL 写复位同步器

1
2
3
4
// ❌ 错误:综合结果不可控
always @(posedge clk or posedge rst_in)
    if (rst_in) sync_r <= 1;
    else        sync_r <= sync_r_prev;

问题

  • 综合器可能用等效但不同的结构
  • ASYNC_REG 属性可能未正确应用
  • 综合器可能"优化"掉中间级

正确做法:显式使用 FDPE 原语。

7.2 错误:CDC 同步器带复位

1
2
// ❌ 错误:CDC 同步器不应有复位
FDRE u_sync (.R(rst), .D(din), .Q(dout));

问题:复位信号本身可能是跨时钟域的,引入新的 CDC 问题。

正确做法.R(1'b0)

7.3 错误:异步复位信号直接使用

1
2
3
4
// ❌ 错误:直接使用外部异步复位
always @(posedge clk or posedge btn_rst)
    if (btn_rst) r_data <= 0;
    else         r_data <= w_data;

问题btn_rst 释放时刻随机,可能导致亚稳态。

正确做法:先经过复位同步器。


8. 总结:复位设计检查清单

检查项要求
外部/异步复位源✅ 必须经过复位同步器
复位同步器✅ 使用 FDPE + ASYNC_REG
普通逻辑✅ 使用同步复位(或不复位)
数据通路✅ 不加复位
CDC 同步器✅ 使用 FDRE,.R(1'b0)
同步链级数✅ 3 级
Slice 内 FF 类型✅ 同一 Slice 内 FF 类型相同

参考文献

  1. Xilinx WP272: Get Smart About Reset: Think Local, Not Global
  2. Xilinx UG953: Vivado Design Suite 7 Series FPGA and Zynq-7000 SoC Libraries Guide
  3. Xilinx XAPP495: Designing Robust CDC Structures
  4. Xilinx UG474: 7 Series FPGAs Configurable Logic Block User Guide
🄯 2025 - 2026 DeerMiya的博客· 0Days
共书写了35.2k字·共 17篇文章
本站总访问量 · 访客数

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