3. I/O时序约束与接口收敛

Agilex 的 I/O 时序收敛与内部寄存器到寄存器路径有本质区别:数据在芯片外部走线,时钟可能由 FPGA 发出也可能由外部器件发出,约束必须描述“外部世界”的延迟,而不是芯片内部的逻辑级数。理解这一点,是写好 set_input_delay / set_output_delay 的前提。

一、Agilex I/O 单元结构与可约束资源

Agilex 每个 I/O bank 由 IOBUF、输入寄存器、输出寄存器、输出使能寄存器以及可选的 DDIO 双沿寄存器、延迟链(delay chain)和 OCT 校准电路组成。关键点在于:

  • 输入路径:引脚 → 输入缓冲 → 可选输入延迟链 → 输入寄存器(或 DDIO 的上升/下降沿寄存器)。
  • 输出路径:输出寄存器(或 DDIO)→ 输出缓冲 → 引脚,可插入输出延迟链做微调。
  • 时钟资源:源同步接口通常使用 PLL 生成的随路时钟,通过专用时钟输出引脚(如 CLKOUT)发出,或由外部器件提供时钟经时钟输入引脚进入。

约束时,工具需要知道“数据相对时钟在引脚处的到达关系”,这正是 input/output delay 的语义。Agilex 的 I/O 约束最终会映射到这些寄存器与延迟链上,因此约束值必须与 PCB 走线、外部器件 tCO/tSU/tH 等参数一致,否则会出现“约束通过但板级失败”的情况。

二、输入/输出延迟约束的物理含义

先统一参照约定:以下所有延迟均以时钟沿为参考点,正值表示数据在时钟沿之后到达(对输入)或需要在时钟沿之后保持稳定(对输出)。

set_input_delay 描述外部器件把数据送到 FPGA 引脚的时间。以源同步输入为例,若外部器件在时钟沿后 tCO 输出数据,PCB 走线延迟为 tPCB,则:

set_input_delay -clock [get_clocks ext_clk] \
    -max [expr tCO_max + tPCB_max] [get_ports data_in*]
set_input_delay -clock [get_clocks ext_clk] \
    -min [expr tCO_min + tPCB_min] [get_ports data_in*]

set_output_delay 描述 FPGA 输出数据后,外部器件需要多久才能可靠采样。若外部器件要求数据在时钟沿前 tSU 稳定、沿后 tH 保持,则:

set_output_delay -clock [get_clocks sys_clk] \
    -max [expr tSU - tPCB_min] [get_ports data_out*]
set_output_delay -clock [get_clocks sys_clk] \
    -min [expr -tH - tPCB_max] [get_ports data_out*]

注意 -min 的符号:保持时间约束对应负值,这是最容易写错的地方。若外部器件在时钟沿后仍要求数据保持 tH,则输出数据不能过早变化,因此 min 约束为负。

三、源同步接口的时序建模

源同步接口的核心是“时钟与数据同源”。以 Agilex 作为发送端、外部 ADC 作为接收端为例,FPGA 用 PLL 产生 200 MHz 时钟,经 CLKOUT 引脚输出,数据经普通 I/O 输出。此时需要建模:

  • FPGA 内部从输出寄存器到引脚的 tCO(由工具根据 I/O 标准、驱动强度、 slew rate 估算)。
  • PCB 上时钟走线与数据走线的长度差,换算为延迟差 Δt。
  • 外部 ADC 的建立/保持窗口。

若时钟走线比数据走线长 5 mm,按 FR4 约 6.5 ps/mm 估算,Δt ≈ 32.5 ps。这个差值会直接改变数据相对时钟的相位,必须在 output delay 中体现。实际工程中常用“时钟走线略长于数据走线”来补偿 FPGA 输出延迟,使采样窗口居中。

四、DDR 接口的时序建模要点

DDR 接口在时钟上下沿都传输数据,因此约束要分别针对上升沿和下降沿。Agilex 的 DDIO 寄存器天然支持双沿,但约束仍需用 -rise / -fall 区分:

set_output_delay -clock [get_clocks ddr_clk] -rise \
    -max [expr tSU - tPCB] [get_ports dq*]
set_output_delay -clock [get_clocks ddr_clk] -fall \
    -max [expr tSU - tPCB] [get_ports dq*]
set_output_delay -clock [get_clocks ddr_clk] -rise \
    -min [expr -tH - tPCB] [get_ports dq*]
set_output_delay -clock [get_clocks ddr_clk] -fall \
    -min [expr -tH - tPCB] [get_ports dq*]

DDR 还涉及 DQS 与 DQ 的相位关系。写方向时,DQS 由 FPGA 发出,需保证 DQS 边沿位于 DQ 数据眼中心;读方向时,DQS 由外部器件发出,FPGA 用 DQS 采样 DQ,此时 input delay 要基于 DQS 而非系统时钟。Agilex 的 I/O PLL 和动态相位对齐(DPA)可用于读方向微调,但约束仍要如实描述外部时序。

Agilex 源同步输出接口时序建模 Agilex FPGA 输出寄存器 / DDIO 输出缓冲 + 延迟链 PLL / 时钟输出 I/O 引脚 PCB 走线 tPCB_data tPCB_clk Δt = tPCB_clk − tPCB_data (走线长度差 × 6.5 ps/mm) 外部接收器件 数据采样寄存器 tSU / tH 窗口 时钟输入引脚 set_output_delay -max = tSU − tPCB_min set_output_delay -min = −tH − tPCB_max

五、实战:从约束到收敛的检查流程

写完约束后,不能只看“无违例”。建议按以下顺序检查:

  1. 确认时钟定义正确:源同步接口的时钟必须用 create_clock 或 create_generated_clock 正确定义,否则 delay 约束无参考点。
  2. 检查约束覆盖:用 report_timing -from [get_ports ...] 确认输入路径被约束,report_timing -to [get_ports ...] 确认输出路径被约束。
  3. 看 slack 分布:若某组 DQ 的 slack 明显偏负,优先检查该组走线是否等长、是否与 DQS 匹配。
  4. 用 DPA 或延迟链微调:Agilex 支持在 I/O 单元内插入延迟,可在约束不变的前提下改善采样窗口,但调整后需重新跑时序。
  5. 板级验证:最终用示波器或误码率测试确认眼图张开度,约束只是手段,板级稳定才是目标。
一个常见误区:把 input delay 写成“数据到达时间”的绝对值。实际上它是相对时钟沿的偏移,且必须同时给 max 和 min,否则工具只按单边约束优化,容易在另一侧失败。
DDR 接口中,若 DQS 与 DQ 的 PCB 走线长度差超过约 2 mm,仅靠约束很难收敛,应优先改板或使用 Agilex 的 DPA 动态对齐功能。

总结来说,Agilex 的 I/O 时序约束是“把板级物理事实翻译成工具能理解的数字”。I/O 单元结构决定了可调资源,input/output delay 决定了约束边界,源同步与 DDR 建模决定了约束的复杂度。只有约束值与实际 PCB、外部器件参数一致,时序收敛才有意义。