FPGA 时序约束实用指南:input_delay / output_delay / max_delay
FPGA 时序约束实用指南input_delay / output_delay / max_delay目录1. 核心认知2. set_input_delay3. set_output_delay4. set_max_delay5. set_false_path6. ASYNC_REG7. 决策树遇到一个信号该用什么约束8. 实战ADS1675 ADC 接口约束案例1. 核心认知1.1 约束不是在给 FPGA 设延迟set_input_delay和set_output_delay不是在设 FPGA 内部的延迟值而是在告诉工具外部世界的数据到达/出发时间。工具拿这些值反推出 FPGA 内部还能花多少时间。1.2 约束影响布局布线三类约束都会影响布局布线但机制不同约束对布局的影响机制create_clock✅ 强周期本身是硬上限set_input_delay/set_output_delay✅ 中~强通过 setup/hold 方程间接驱动距离set_max_delay✅ 强直接限制路径延迟上限set_false_path⚠️ 放任砍掉后工具可能放飞需 max_delay 补刀2. set_input_delay2.1 物理模型外部器件 FPGA 内部 ┌────────────┐ ┌──────────────────┐ │ 寄存器 │ │ 寄存器 │ CLK ──────┼────────────┼────────────┼──────────────────┤ │ │ │ │ │ clk→Q ────┼── DATA ───┼── 组合逻辑 ──────┤ │ ↑ │ ↑ │ ↑ │ └─────↑──────┘ ↑ └────────↑─────────┘ ↑ ↑ ↑ DF1 时钟沿 input_delay 内部路径 外部延迟 (工具要算的)set_input_delay 数据从外部寄存器的时钟沿到FPGA pin的时间。工具知道时钟周期 T 和 input_delay 后算出内部路径上限内部最大允许 T - input_delay_max - Tsu 管 setup 内部最小允许 input_delay_min - Th 管 hold2.2 max 和 min 分别管什么参数对应什么约束的是什么max外部最慢情况下的数据到达时间FPGA 内部setup数据不能到太晚min外部最快情况下的数据到达时间FPGA 内部hold数据不能到太早2.3 怎么算值input_delay_max 外部器件 t_co_max (手册) PCB 走线延迟_max input_delay_min 外部器件 t_co_min (手册) PCB 走线延迟_min2.4 详细例子ADS1274 接 FPGAADS1274 手册参数t_DO 5~12ns SCLK↑ → DOUT 有效即 ADS1274 的 clk→Q PCB 走线 1~2ns FPGA 时钟 25MHz / 40ns 周期计算input_delay_max 12 2 14ns input_delay_min 5 1 6ns时序分析0 10 20 30 40ns ├────────┼────────┼────────┼────────┤ CLK: ──┘ └── ← 采沿在 0ns 外部延迟: ────────┬──────────────┬───────────── 最快6ns │ 最慢14ns │ ↓ ↓ DATA到pin: t6 t14 内部setup预算 40 - 14 - 0.5(Tsu) 25.5ns ← 充裕 ✅ 内部hold检查: 数据最快6ns到比采沿(0ns)晚hold自然满足 ✅XDC 写法create_clock -period 40.000 -name sclk [get_ports i_sclk] set_input_delay -clock sclk -max 14.000 [get_ports i_dout] set_input_delay -clock sclk -min 6.000 [get_ports i_dout]2.5 max/min 设反了会怎样错误后果min 设太大告诉工具数据来得晚工具不防 hold → 实际数据到太快 → 芯片 hold 违例 → 可能死机max 设太小告诉工具数据来得早工具过度优化 → 假 setup 违例满天飞工程原则max 往大设悲观min 往小设悲观。3. set_output_delay3.1 物理模型FPGA 内部 外部器件 ┌──────────────────┐ ┌────────────┐ │ 寄存器 │ │ 寄存器 │ CLK ───┼──────────────────┼───────────┼────────────┤ │ │ │ │ │ clk→Q ── DATA ──┼───────────┼── 组合 ────┤ │ │ ↑ │ ↑ │ └──────────────────┘ ↑ └─────↑──────┘ ↑ ↑ FPGA内部 output_delay 路径 外部延迟set_output_delay 数据从FPGA pin到外部寄存器 D 脚的时间PCB 外部器件 Tsu。工具用它算内部还能花的时间内部最大允许 T - output_delay_max - Tco(内部)3.2 max 和 min 分别管什么参数值物理意义maxPCB_max Tsu(下游)数据最晚必须在下游采沿前多久到 pinminPCB_min - Th(下游)数据最早会到达可以是负数3.3 详细例子FPGA 输出给 DACFPGA→DAC同源 100MHz (T10ns) PCB 走线 0.5~2.0ns DAC Tsu 2.0ns, Th 0.8ns output_delay_max 2.0 2.0 4.0ns output_delay_min 0.5 - 0.8 -0.3ns ← 注意min 可以是负数!为什么 min 是负数最快路径下数据跑到太快比时钟沿还早到下游器件FPGA 最快 clk→Q routing 0.3 0.2 0.5ns → 到 pin PCB 0.5ns 数据到下游 D 脚 1.0ns 但下游还在抓上一笔数据Th 0.8ns → 需要 t0.8ns 后数据才允许变 → 数据 1.0ns 就到了只差 0.2ns ← 危险! → min -0.3ns工具知道了会插 buffer 拖慢 0.3nsXDC 写法create_clock -period 10.000 -name clk_100m [get_ports i_clk] set_output_delay -clock clk_100m -max 4.000 [get_ports o_data[*]] set_output_delay -clock clk_100m -min -0.300 [get_ports o_data[*]]4. set_max_delay4.1 和 input/output delay 的本质区别set_input_delay / set_output_delayset_max_delay参考时钟必须有物理关系的时钟不需要约束什么通过 setup/hold 方程间接约束直接限制路径走线延迟适用场景同步/源同步异步信号、CDC、伪路径有 min 吗有 (管 hold)有但不常用4.2 两种主要使用场景场景 A异步信号防布线放飞# ADC 的 SCLK/DRDY/DOUT 和 FPGA 100MHz 异步 # 不用 input_delay用 false_path max_delay: set_false_path -from [get_ports {i_ads_sclk i_ads_drdy i_ads_dout}] set_max_delay -from [get_ports i_ads_sclk] \ -to [get_cells -hier -filter {REF_NAME ~ *r_sclk_r0*}] \ -datapath_only 5.000-datapath_only表示只看走线缓冲延迟不算时钟偏斜和 Tsu。场景 BCDC 路径防布线放飞clk_a 域 → clk_b 域数据总线 32 位异步 FIFO 握手: set_false_path ← 砍时序检查 set_max_delay ← 但布线不能飞到几百 ns4.3 max_delay 值怎么定多比特信号防偏斜多根线有物理先后关系手册规定: SCLK↑ → DRDY↑ 2.2ns (最小间隔) 要保证内部不反转: 内部偏斜 2.2ns 工程放宽到 5ns: 内部偏斜 5ns 虽然反转了先后 但在 FPGA 100MHz(10ns) 的采样粒度下 这个反转被同步链消化了。 5ns 半个 FPGA 时钟周期工具轻松收敛。单比特异步信号值不敏感设一个合理的即可如 5~10ns目的是别让走线绕芯片一圈。4.4 max 和 min干什么异步场景用不用-max路径不能太慢✅ 用防布线放飞-min路径不能太快❌ 不用异步没有 hold 概念异步信号 min 没有意义——数据早到 5ns 还是 0.1ns没有时钟沿跟它比不存在 “hold 违例”。5. set_false_path5.1 作用告诉工具这条路径不需要做时序检查。5.2 使用场景异步输入没有参考时钟CDC 跨时钟域路径带握手/同步器保护纯静态信号配置寄存器上电后不变复位信号异步复位5.3 注意set_false_path砍掉后工具可能把路径放到芯片另一边不加约束。多比特异步信号或 CDC 数据总线必须加set_max_delay补刀。6. ASYNC_REG6.1 作用标记同步链上的寄存器告诉工具这是跨时钟域的第一/二级同步器把它们物理上放近降低 MTBF时序分析时特殊处理6.2 写法set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_sync_r0*}] set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_sync_r1*}]6.3 和其他约束的配合false_path: 别算时序 ← 管分析 max_delay: 但也别太慢 ← 管布线质量 ASYNC_REG: 这两级要贴紧 ← 管 MTBF三者各管一摊互补不互斥。7. 决策树遇到一个信号该用什么约束这个信号有合法的参考时钟进了 FPGA 吗 ├── 有 → 用 set_input_delay / set_output_delay │ 参考时钟 外部延迟值从手册算 │ └── 没有 (异步) → 信号有几根 ├── 单根 (如独立按钮) → set_false_path 就够了 │ └── 多根且互有时序关系 (如 ADC 的 SCLKDRDYDOUT) → set_false_path (砍时序检查) → set_max_delay 5ns (控三根线偏斜, 保留板级先后关系) → ASYNC_REG (标同步器, 降 MTBF)速查表场景用哪些约束源同步数据 (DCODATA)create_clockset_input_delay系统同步数据 (同源 CLK)create_clockset_input_delayFPGA 输出给 DAC/SDRAMcreate_clockset_output_delayADC 异步过采样 (多根线)set_false_pathset_max_delayASYNC_REG独立异步信号 (按钮)set_false_pathCDC 数据总线set_false_pathset_max_delayASYNC_REG静态配置信号set_false_path异步复位set_false_path8. 实战ADS1675 ADC 接口约束案例8.1 场景ADS1675 ADCCMOS 接口SCLK32MHzDRDY脉冲DOUT24bit 串行FPGA100MHz 过采样这三个信号SCLK 没有接 BUFG 当时钟用三个都是普通异步 I/ORTL 中有状态机依赖 SCLK/DRDY 的先后关系8.2 为什么不能用 input_delayADS1675 的 SCLK 在 FPGA 里当数据采、没当时钟用FPGA 100MHz 和 ADC 没有任何相位关系。没有合法参考时钟 →set_input_delay不适用。8.3 约束方案# 1. 时钟 create_clock -period 10.000 -name i_clk [get_ports i_clk] # 2. 三条异步输入: 砍时序检查 set_false_path -from [get_ports {i_ads_sclk i_ads_drdy i_ads_dout}] # 3. 三条线 pin→首级寄存器 布线 ≤ 5ns # 同一上限 → 任意两根内部偏斜 ≤ 上限 → 板级先后关系保留 set_max_delay -from [get_ports i_ads_sclk] \ -to [get_cells -hier -filter {REF_NAME ~ *r_sclk_r0*}] \ -datapath_only 5.000 set_max_delay -from [get_ports i_ads_drdy] \ -to [get_cells -hier -filter {REF_NAME ~ *r_drdy_r0*}] \ -datapath_only 5.000 set_max_delay -from [get_ports i_ads_dout] \ -to [get_cells -hier -filter {REF_NAME ~ *r_shift_reg*}] \ -datapath_only 5.000 # 4. 同步器标记 set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_sclk_r0*}] set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_sclk_r1*}] set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_drdy_r0*}] set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_drdy_r1*}] set_property ASYNC_REG TRUE [get_cells -hier -filter {NAME ~ *r_drdy_r2*}] # 5. 输出 (给下游 FIFO) set_output_delay -clock [get_clocks i_clk] -max 5.0 [get_ports {o_fifo_wr o_fifo_data[*]}] set_output_delay -clock [get_clocks i_clk] -min 1.0 [get_ports {o_fifo_wr o_fifo_data[*]}]8.4 约束策略总结false_path: 别拿不存在的时钟沿做 setup/hold 分析 max_delay 5ns: 三根线走线都控制在 5ns 内, 板上的先后顺序别搞反了 ASYNC_REG: 同步链两级寄存器靠紧放, 亚稳态概率最低 output_delay: 输出给下游 FIFO, 留半周期余量