FPGA 时序约束:input_delay / output_delay / max_delay / min_delay
FPGA 时序约束input_delay / output_delay / max_delay / min_delay目录0. 基础概念1. set_input_delay2. set_output_delay3. set_max_delay / set_min_delay4. -datapath_only 什么时候加5. 决策速查表0. 基础概念三句话讲清本质input_delay/output_delay不是设 FPGA 内部的延迟是告诉工具外部世界的数据到达/出发时间工具拿时钟周期T - 外部延迟 - 寄存器开销反推出 FPGA 内部还能花多少时间max_delay/min_delay不看时钟直接管布线长度用于异步信号和 CDC约束影响布局约束影响布局吗机制create_clock✅ 强周期是硬上限input_delay/output_delay✅ 中~强通过 setup/hold 方程间接驱动set_max_delay/set_min_delay✅ 强直接限走线长度set_false_path⚠️ 放任砍掉后工具可能放飞1. set_input_delay1.1 物理模型外部器件 FPGA 内部 ┌────────────┐ ┌──────────────────┐ │ 寄存器 │ │ 寄存器 │ CLK ──────┼────────────┼────────────┼──────────────────┤ │ │ │ │ │ clk→Q ────┼── DATA ───┼── 组合逻辑 ──────┤ │ │ ↑ │ ↑ │ └────────────┘ ↑ └────────↑─────────┘ ↑ ↑ input_delay 内部路径 外部延迟 (工具要算的)set_input_delay 数据从外部寄存器的时钟沿到FPGA 数据 pin的时间。工具用这个值反推内部预算内部 setup 预算 T - input_delay_max - Tsu 内部 hold 预算 input_delay_min - Th1.2 物理系统与 PCB 延迟50MHz 晶振 │ ┌─────┴─────┐ │ 时钟缓冲器 │ └──┬─────┬───┘ │ │ PCB_clk1 │ │ PCB_clk2 3ns │ │ 2ns │ │ ┌────┴─┐ ┌─┴────────┐ │ FPGA │ │ ADC │ │ CLK │ │ CLK pin │ │ pin │ │ │ │ │ │ DOUT pin│ │ DATA │←┼──────────┘ │ pin │ PCB_data └──────┘ 1.5ns已知参数时钟周期: T 20ns (50MHz) ADC 参数: t_co_min 2ns, t_co_max 8ns (CLK↑→DOUT 有效) PCB 走线: PCB_clk1 3ns (晶振→FPGA) PCB_clk2 2ns (晶振→ADC) PCB_data 1.5ns (ADC→FPGA) FPGA: Tsu 0.4ns, Th 0.2ns1.3 计算公式input_delay_max PCB_clk2 t_co_max PCB_data - PCB_clk1 2 8 1.5 - 3 8.5ns input_delay_min PCB_clk2 t_co_min PCB_data - PCB_clk1 2 2 1.5 - 3 2.5ns为什么减 PCB_clk1input_delay的含义是FPGA 时钟 pin 收到沿之后数据还要多久才到。减 FPGA 侧的 PCB 延迟就是把测量基准从晶振挪到 FPGA 时钟 pin。1.4 时间轴推演SETUP 分析最慢路径t0 晶振输出时钟沿 t2 ADC 收到时钟沿 (PCB_clk22ns) ADC 开始输出数据, 最慢 t_co_max8ns t3 FPGA 收到时钟沿 (PCB_clk13ns) → 以此为 t0 (相对时间) t10 ADC DOUT 数据有效 (2810ns, 绝对) t11.5 FPGA 数据 pin 收到新数据 (101.511.5ns, 绝对) 相对时间: 11.5 - 3 8.5ns ← input_delay_max!时间轴 (以 FPGA CLK pin 为基准): 0 2 4 6 8 10 12 14 16 18 20ns ├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤ 基准: ┌──────────────────────────────┐ FPGA CLK pin(t0): ──┘ └── 下一个沿 ↑ ↑ 采沿(0) 采沿(20) 外部数据到 pin: ├────── input_delay_max8.5ns ───┤ ↓ │ t8.5ns ← 数据到了 │ FPGA 内部能花的: │◄──── 内部预算 11.1ns ────►│ 20 - 8.5 - 0.4(Tsu) 11.1nssetup 方程8.5 FPGA内部路径 20 - 0.4→ 内部路径 11.1ns。非常宽裕。1.5 时间轴推演HOLD 分析最快路径t0 晶振沿 t2 ADC 收到沿 → t_co_min2ns → 数据 t4 有效 t3 FPGA 收到沿 (相对 t0) t5.5 FPGA pin 收到数据 (41.55.5 绝对, 相对 5.5-32.5ns) hold 方程: 2.5 FPGA_internal_path_min 0.2(Th) → FPGA_internal_path_min -2.3ns → 实际内部最短 ~0.5ns -2.3ns → 自动满足 ✅1.6 极端例子负的 input_delay_minPCB_clk1(FPGA)15ns, PCB_clk2(ADC)2ns (ADC 紧贴晶振) PCB_data1.5ns, t_co_min2ns input_delay_min 221.5-15 -9.5ns ← 负数!含义FPGA 时钟 pin 还在等沿 (15ns)数据 5.5ns 就到了——数据比时钟早到 9.5ns。hold 要求: -9.5 FPGA_internal_path_min 0.2 → FPGA_internal_path_min 9.7ns 工具必须把内部路径拉到至少 9.7ns! → 插 buffer/LUT 拖慢 → 否则新数据会砸掉上一笔的 hold1.7 max/min 总结参数算什么管什么设错了的后果maxPCB_clk2t_co_maxPCB_data-PCB_clk1FPGA 内部 setup设太小→假违例设太大→实际违例漏报minPCB_clk2t_co_minPCB_data-PCB_clk1FPGA 内部 hold设太小→没问题(悲观)设太大→隐藏 hold 违例工程原则max 往大设min 往小设。两头悲观工具找真正的安全解。2. set_output_delay2.1 物理模型FPGA 内部 外部器件 ┌──────────────────┐ ┌────────────┐ │ 寄存器 │ │ 寄存器 │ CLK ───┼──────────────────┼───────────┼────────────┤ │ │ │ │ │ clk→Q ── DATA ──┼───────────┼── 组合 ────┤ │ │ ↑ │ ↑ │ └──────────────────┘ ↑ └─────↑──────┘ ↑ ↑ FPGA内部 output_delay 路径 外部延迟set_output_delay 数据从FPGA 输出 pin到下游器件寄存器 D 脚的时间含 PCB 下游 Tsu。2.2 等长 PCB无时钟歪斜50MHz 晶振 │ ┌─────┴─────┐ │ 时钟缓冲器 │ └──┬─────┬───┘ │ │ PCB_clk1 │ │ PCB_clk2 3ns │ │ 3ns ← 等长 │ │ ┌────┴─┐ ┌─┴────────┐ │ FPGA │ │ DAC │ │ │ │ │ │ DATA ├─┼──────────► │ pin │ PCB_data └──────┘ 2.5nsT20ns, FPGA Tco0.3~0.6ns, DAC Tsu1.5ns, Th0.8ns output_delay_max PCB_data Tsu 2.5 1.5 4.0ns output_delay_min PCB_data - Th 2.5 - 0.8 1.7ns2.3 时间轴推演SETUPt0 晶振沿 t3 FPGA 和 DAC 同时收到时钟 → 相对 t0 FPGA: t0 (相对) FPGA 时钟沿 t0.6 (最慢) Tco → 数据到 FF Q t0.6X 数据到 FPGA 输出 pin (X内部 routingOBUF) 外部: 数据 t0.6X2.5 到 DAC DIN pin DAC: t0 (相对) DAC 收到沿 t20 下一拍抓数据 Tsu1.5ns → 数据必须在 t18.5ns 前到 DAC pin setup 方程: 0.6 X 2.5 18.5 X 15.4ns ← 内部预算 ✅ 等价: X T - output_delay_max - Tco_max 20 - 4.0 - 0.6 15.4ns2.4 不等长 PCB——歪斜修正例 A: DAC 比 FPGA 远 例 B: DAC 比 FPGA 近 ───────────────────── ───────────────────── PCB_clk1 3ns PCB_clk1 5ns PCB_clk2 5ns PCB_clk2 2ns PCB_data 2.5ns PCB_data 2.5ns t_skew 5-3 2ns t_skew 2-5 -3ns (DAC 晚到 2ns) (DAC 早到 3ns)推导歪斜修正DAC 晚到 → 抓取沿推迟 → 数据赶路时间变长 → 可以慢一点 → 外部预算缩小 → FPGA 内部预算放大。output_delay_max PCB_data Tsu PCB_clk1 - PCB_clk2 例 A: 2.51.53-5 2.0ns → 内部预算 20-2.0-0.6 17.4ns ← 宽裕 例 B: 2.51.55-2 7.0ns → 内部预算 20-7.0-0.6 12.4ns ← 紧张物理直觉DAC 远例 ADAC 近例 B时钟歪斜DAC 晚 2nsDAC 早 3nsoutput_delay_max2.0ns小7.0ns大FPGA 内部预算17.4ns宽裕12.4ns紧张为什么DAC 晚抓不着急DAC 早抓得赶紧2.5 output_delay_minoutput_delay_min PCB_data - Th PCB_clk1 - PCB_clk2 例 A: 2.5-0.83-5 -0.3ns ← 负数! 内部不能太快 例 B: 2.5-0.85-2 4.7ns ← 正数, 外部延迟已经够大, hold 自动满足当 min 为负数数据可能比时钟早到达下游 pin → FPGA 内部最短路径必须大于 |min| → 工具插 buffer 拖慢。2.6 完整公式总结═══════════════════════════════════════════════════════════════ input_delay output_delay ═══════════════════════════════════════════════════════════════ 含义: 外部 pin 前的时间 外部 pin 后的时间 参考时钟: FPGA 时钟 pin FPGA 时钟 pin max: PCB_clk2 t_co_max PCB_data_max Tsu(下游) PCB_data - PCB_clk1 PCB_clk1 - PCB_clk2 min: PCB_clk2 t_co_min PCB_data_min - Th(下游) PCB_data - PCB_clk1 PCB_clk1 - PCB_clk2 歪斜项: (PCB_clk2 - PCB_clk1) (PCB_clk1 - PCB_clk2) 外部器件钟晚→外部变大 下游钟晚→外部变小 →内部预算缩小 →内部预算放大 max 管: FPGA 内部 setup FPGA 内部 setup min 管: FPGA 内部 hold FPGA 内部 hold ═══════════════════════════════════════════════════════════════歪斜项记忆谁钟晚到谁的 delay 就小因为可以慢。3. set_max_delay / set_min_delay3.1 和 input/output delay 的本质区别input/output delaymax/min delay参考时钟必须有不需要分析方式完整 setup/hold 方程纯数据路径延迟适用同步/源同步接口异步信号、CDC、伪路径存在的 min-min管 hold-min管路径不能太短3.2 使用场景场景 1异步输入防偏斜ADC 的 SCLK、DRDY、DOUT — 三根线FPGA 100MHz 过采样。 没参考时钟 → 不用 input_delay → 用 max_delay 控偏斜。三根线不加约束工具可能把 r_shift_reg[0] 放在 pin 旁r_shift_reg[23] 放芯片对角偏斜 最慢 - 最快 8.7 - 0.5 8.2ns (不加约束) 偏斜 3.8 - 1.2 2.6ns (加 maxmin 约束后)约束set_false_path -from [get_ports i_ads_sclk] set_false_path -from [get_ports i_ads_drdy] set_false_path -from [get_ports i_ads_dout] set_max_delay -from [get_ports i_ads_sclk] \ -to [get_cells -hier -filter {NAME ~ *r_sclk_r0*}] \ -datapath_only 5.000 set_max_delay -from [get_ports i_ads_drdy] \ -to [get_cells -hier -filter {NAME ~ *r_drdy_r0*}] \ -datapath_only 5.000 set_max_delay -from [get_ports i_ads_dout] \ -to [get_cells -hier -filter {NAME ~ *r_shift_reg*}] \ -datapath_only 5.000三根线同一上限 → 任意两根内部偏斜 ≤ 5ns → 板上物理先后关系被保留 → RTL 的组合逻辑w_sclk_pos r_drdy_r0正常工作。场景 2CDC 格雷码总线防偏斜clk_a 域写侧→ 4 位格雷码 → clk_b 域读侧 格雷码相邻值只变 1 bit。 但 4 根线偏斜 一个 clk_b 周期 → 同一拍内多 bit 翻转 → 不是合法格雷码 → 解码后指针错。 约束max_delay 控上限 min_delay 控下限 → 把 4 根线挤进窄窗。不加约束gray[0] 路由: 0.5ns 加 max(4ns)min(1ns) 后: gray[1] 路由: 1.2ns gray[0]: 1.2ns (插 buffer) gray[2] 路由: 3.8ns gray[1]: 1.5ns (插 buffer) gray[3] 路由: 8.7ns gray[2]: 3.2ns (换短路线) 偏斜: 8.2ns gray[3]: 3.8ns (移到 pin 旁) 偏斜: 2.6ns ← 压缩到 2.6ns所有 bit 在 1.2~3.8ns 之间到达clk_b 周期 10ns不可能采到多 bit 同时翻转。约束set_false_path -from [get_cells -hier -filter {NAME ~ *gray_a_reg*}] set_max_delay -from [get_cells -hier -filter {NAME ~ *gray_a_reg*}] \ -to [get_cells -hier -filter {NAME ~ *r_sync0*}] \ -datapath_only 4.000 set_min_delay -from [get_cells -hier -filter {NAME ~ *gray_a_reg*}] \ -to [get_cells -hier -filter {NAME ~ *r_sync0*}] \ 1.000 set_property ASYNC_REG TRUE ...3.3 max 和 min 分别干什么set_max_delayset_min_delay管什么路径不能太慢路径不能太快违规后果信号晚到 → 漏采 / 偏斜大信号早到 → 多 bit 偏斜大 / glitch 穿透工具解决换更短路线、移近 pin插 buffer/LUT、拉长走线单比特异步✅ 用防放飞❌ 不需要多比特异步✅ 用✅ 用偏斜窗 max - min。窗越窄多根线到达越齐。3.4 max/min 值怎么定单比特设一个合理上限如 5ns不设 min。目的是别让走线绕芯片一圈。多比特手册规定外部最小间隔 2.2ns (如 SCLK↑→DRDY↑) 要保留内部先后顺序: 内部偏斜 外部最小间隔 工程放宽: 半个 FPGA 时钟周期 (如 5ns100MHz 下)CDC 格雷码: 偏斜 半个捕获时钟周期 clk_b100MHz → 半周期5ns → max4ns, min1ns → 窗宽3ns 5ns4.-datapath_only什么时候加加不加的区别设定set_max_delay 5.000。工具内部计算不加 -datapath_only: 加 -datapath_only: ════════════════ ════════════════ data_path: 1.2ns data_path: 1.2ns clock_skew: 3.8ns clock_skew: 忽略 Tsu: 0.4ns Tsu: 忽略 ────────────── ────────────── 总计: 5.4ns 总计: 1.2ns 结果: VIOLATED ❌ 结果: PASS ✅-datapath_only砍掉了时钟偏斜和 Tsu只看纯数据路径长度。判断场景加-datapath_only原因异步输入 pin→寄存器✅ 加没有参考时钟算 Tsu 没意义CDC 跨时钟域✅ 加两时钟异步clock_skew 没物理意义伪路径后补 max_delay✅ 加false_path 已经砍了时钟关系同源时钟域覆盖默认约束❌ 不加需要完整 setup/holdclock_skew 真实存在判断标准源和目标的时钟有没有已知的物理相位关系。有 → 不加。没有 → 加。5. 决策速查表拿到一个 I/O 信号该用什么约束信号有合法的参考时钟进了 FPGA 吗 ├── 有 → input_delay / output_delay │ 参考时钟 手册算值 │ └── 没有 (异步) → 几根线? ├── 单根 → set_false_path 够了 │ pin→寄存器太远的话补 set_max_delay -datapath_only │ └── 多根且互有时序关系 → set_false_path set_max_delay -datapath_only (控上限) set_min_delay (控下限) ASYNC_REG (标同步器)完整速查场景约束源同步 (DCODATA)create_clockset_input_delay系统同步 (同源 CLK)create_clockset_input_delayFPGA 输出给 DAC/SDRAMcreate_clockset_output_delayADC 异步过采样 (单根)set_false_pathADC 异步过采样 (多根)set_false_pathset_max_delay -datapath_onlyset_min_delayASYNC_REGCDC 数据总线set_false_pathset_max_delay -datapath_onlyset_min_delayASYNC_REGCDC 单 bit 握手set_false_pathASYNC_REG异步复位分发 (多模块)set_false_pathset_max_delay -datapath_onlyset_min_delay静态配置信号set_false_path