4. I/O时序约束

FPGA与外部器件通信时,时序收敛的边界并不止于芯片内部。外部器件的数据有效窗口、PCB走线延迟、时钟偏斜,都会直接决定FPGA输入采样和输出驱动的时序余量。Quartus中的set_input_delay与set_output_delay,正是把外部世界的时间信息“翻译”给内部时序引擎的桥梁。理解这两个约束的工程计算方法,是源同步与系统同步接口能否真正收敛的前提。

一、约束的本质:把外部延迟折算到FPGA引脚

TimeQuest在分析I/O路径时,需要知道数据相对于参考时钟到达(或离开)FPGA引脚的时间。这个时间由外部器件和PCB共同决定,FPGA本身无法自动推断,因此必须由设计者通过SDC约束显式给出。set_input_delay描述的是:相对于某个参考时钟沿,数据到达FPGA输入引脚的最早与最晚时间;set_output_delay描述的是:相对于参考时钟沿,数据必须离开FPGA输出引脚的最早与最晚时间。

这里必须先明确参照约定:所有延迟值均以“数据到达/离开FPGA引脚”为观察点,正值表示在参考时钟沿之后,负值表示在参考时钟沿之前。全文及图示均采用这一约定,切换参照系时必须重新说明。

约束的基本形式为:

set_input_delay  -clock <ref_clk> -max <t_max> -min <t_min> [get_ports data_in]
set_output_delay -clock <ref_clk> -max <t_max> -min <t_min> [get_ports data_out]

其中-max用于建立时间(setup)分析,-min用于保持时间(hold)分析。这两个值不是随意填写的,而是由外部器件的输出有效窗口、时钟到数据的偏斜、PCB走线延迟共同计算得到。

二、系统同步接口的计算方法

系统同步接口的典型特征是:FPGA与外部器件共用同一个系统时钟,数据在时钟沿附近有效。以外部器件向FPGA发送数据为例,设外部器件的时钟到数据输出延迟为Tco,PCB数据走线延迟为Tpcb_data,PCB时钟走线延迟为Tpcb_clk,外部器件输出数据有效窗口为Tco_max与Tco_min。

则数据到达FPGA输入引脚的最晚时间为:

T_input_max = Tco_max + Tpcb_data - Tpcb_clk
T_input_min = Tco_min + Tpcb_data - Tpcb_clk

这两个值分别填入set_input_delay的-max和-min。注意,这里减去Tpcb_clk是因为参考时钟也经过PCB走线到达FPGA,数据与时钟之间的相对关系才是TimeQuest真正关心的量。

对于FPGA输出到外部器件的路径,设外部器件的建立时间要求为Tsu,保持时间要求为Th,则输出延迟约束为:

T_output_max = Tpcb_data + Tsu - Tpcb_clk
T_output_min = Tpcb_data - Th - Tpcb_clk

工程中常见的做法是:先从外部器件手册中提取Tco、Tsu、Th等参数,再结合PCB叠层与走线长度估算Tpcb。例如FR4板材上微带线延迟约为6.5 ps/mm,带状线约为7.2 ps/mm,若数据走线比时钟走线长20 mm,则Tpcb_data - Tpcb_clk约为130 ps。这些数值必须来自实际设计或合理假设,不能凭经验随意填写。

三、源同步接口的计算方法

源同步接口中,时钟与数据由同一个源器件发出,FPGA接收时通常使用随路时钟采样。此时参考时钟不再是系统时钟,而是随路时钟本身。设源器件输出数据相对随路时钟的偏斜为Tskew,数据有效窗口为Tvalid,则输入延迟约束为:

T_input_max = Tskew_max + Tpcb_data - Tpcb_clk
T_input_min = Tskew_min + Tpcb_data - Tpcb_clk

源同步接口的关键在于:数据与时钟的PCB走线必须等长或做补偿,否则Tpcb_data - Tpcb_clk会直接吃掉有效窗口。工程上通常要求两者走线长度差控制在±5 mil以内,对应约±0.8 ps的延迟差。

对于源同步输出,FPGA同时输出数据和时钟,外部器件用FPGA发出的时钟采样FPGA发出的数据。此时set_output_delay的参考时钟是FPGA输出的随路时钟,约束值主要取决于外部器件的建立/保持要求以及PCB走线匹配程度。

四、Virtual Clock处理纯输入输出路径

当FPGA的输入或输出路径没有对应的内部时钟域时,例如纯组合逻辑输入、或仅用于测试的输出引脚,TimeQuest无法用内部时钟作为参考。此时应使用create_clock创建一个虚拟时钟(Virtual Clock),它不对应任何实际引脚,只用于提供时序分析的参考沿。

create_clock -name virt_clk -period 10.000
set_input_delay  -clock virt_clk -max 3.0 -min 1.0 [get_ports data_in]
set_output_delay -clock virt_clk -max 2.5 -min 0.5 [get_ports data_out]

虚拟时钟的周期应设置为外部器件实际的工作周期,而不是FPGA内部时钟周期。这样TimeQuest才能正确计算建立和保持余量。对于纯输入路径,虚拟时钟只参与输入延迟分析;对于纯输出路径,虚拟时钟只参与输出延迟分析。若同一端口同时存在输入和输出约束,需分别指定。

I/O时序约束工程计算关系图 外部器件 Tco / Tsu / Th 输出有效窗口 随路时钟偏斜 Tskew PCB传输线 Tpcb_data Tpcb_clk 走线延迟差 ΔTpcb FPGA引脚 输入采样 / 输出驱动 TimeQuest分析点 setup / hold 余量 工程计算核心公式 输入:T_input_max = Tco_max + Tpcb_data − Tpcb_clk 输入:T_input_min = Tco_min + Tpcb_data − Tpcb_clk 输出:T_output_max = Tpcb_data + Tsu − Tpcb_clk 输出:T_output_min = Tpcb_data − Th − Tpcb_clk set_input_delay -max → 建立时间分析 -min → 保持时间分析 set_output_delay -max → 外部器件建立要求 -min → 外部器件保持要求 Virtual Clock 参考

五、工程计算中的关键检查点

完成约束编写后,不能只看“是否报错”,而要在TimeQuest中检查具体的时序报告。对于输入路径,重点看Input Delay报告中的Setup和Hold余量;对于输出路径,重点看Output Delay报告中的Setup和Hold余量。若余量为负,说明外部延迟估算过紧或内部逻辑延迟过大,需要调整约束值或优化内部路径。

一个常见的工程误区是:把set_input_delay的-max和-min设得过于宽松,导致时序报告“看起来通过”,但实际硬件无法工作。正确的做法是:约束值必须来自外部器件手册和PCB实际参数,并在报告中确认余量在合理范围内(通常建议保留10%~20%的裕量)。

实用检查清单:
  • 外部器件手册中的Tco/Tsu/Th是否已提取并确认单位(ns或ps)?
  • PCB走线延迟是否按实际叠层和长度计算,而非估算?
  • 源同步接口的数据与时钟走线是否等长或已做补偿?
  • 纯输入/输出路径是否已用Virtual Clock提供参考沿?
  • TimeQuest报告中Setup/Hold余量是否均为正且留有裕量?

最后需要强调:set_input_delay和set_output_delay不是孤立的约束,它们与create_clock、set_clock_groups、set_false_path共同构成完整的时序约束体系。只有把外部器件的真实时间信息准确折算到FPGA引脚,内部时序引擎才能做出正确的判断,源同步与系统同步接口的收敛才有可靠依据。