第三章 时序路径分类:输入路径、内部路径、输出路径的分析方法

做时序约束,第一件事不是急着写命令,而是先把路径看懂。

路径分三类:输入路径、内部路径、输出路径。这个分类是STA的基础,也是PLL配置时判断时钟相位要不要调整的依据。我见过不少工程师,上来就set_input_delay,结果内部时序反而崩了——就是因为没搞清楚路径归属。

3.1 为什么要把路径分成三类?

说白了,FPGA的时序路径跨越不同的物理区域和时钟域。从芯片引脚进来,经过内部逻辑,再从引脚出去。每一段的延迟来源不一样,约束方法也不一样。

我个人习惯把路径想象成一条流水线:

  • 输入路径:从外部器件(或PCB走线)到达FPGA输入引脚,再到第一个寄存器。
  • 内部路径:FPGA内部寄存器到寄存器。
  • 输出路径:FPGA内部最后一个寄存器到输出引脚,再到外部器件。

你想想看,如果这三类路径混在一起分析,收敛条件根本说不清楚。工具报告violation,你都不知道该调PLL还是改PCB。

核心观点:每一类路径的时序余量由不同的变量决定。输入路径依赖外部器件的输出延迟;内部路径完全由FPGA本身决定;输出路径依赖外部负载。

3.2 输入路径分析方法

输入路径的起点是外部时钟到达外部器件输出端的时刻,终点是FPGA内部第一个寄存器的D端。

约束时我们需要告诉工具两个数:

  • 最大输入延迟(Input Delay Max):外部数据从时钟沿开始,到FPGA引脚稳定所需的最长时间。
  • 最小输入延迟(Input Delay Min):同样条件下最短的稳定时间(用于hold分析)。

我在项目中遇到过一块AD采集板,PCB走线长度不一致,导致数据总线skew达到0.5ns。第一次仿真全红,后来按最差路径取了输入延迟,把PLL的相位调整了90°,才把建立时间余量拉回来。

小技巧:很多新手会忽略PCB走线延迟。其实0.5ns的PCB延迟在100MHz系统里已经占了半个周期,必须算进输入延迟里。

计算公式(概念性):

Input Delay Max = Tco_ext + Tpcb_max + Tmargin
Input Delay Min = Tco_ext + Tpcb_min - Tmargin

其中Tco_ext是外部器件时钟到数据输出延迟,Tpcb是PCB走线延迟。

3.3 内部路径分析方法

内部路径是最容易理解的——从FPGA内部的一个寄存器到另一个寄存器。STA工具会自动计算组合逻辑延迟、布线延迟、时钟skew和jitter。

这里要注意两点:

  1. 跨时钟域路径。如果两个寄存器用不同的时钟,必须明确是同步跨时钟域还是异步。同步域可以用set_clock_groups约束,异步域必须用同步器处理,否则STA会报false path。
  2. 时钟抖动与时钟不确定性。PLL产生的时钟有jitter,我在默认约束里会留出0.05ns~0.1ns的uncertainty,特别是高频场景。有一次我只留了0.02ns,结果裕量看起来很好,实际上板子偶尔误触发。

警告:不要指望内部路径约束能“自动通过”。寄存器间的组合逻辑深度太大,或者扇出太大,都会导致时序违例。这时候需要调整PLL输出频率,或者重新安排寄存器的位置。

3.4 输出路径分析方法

输出路径是“最后一公里”。FPGA内部最后一个寄存器的输出经过IO缓冲,到达FPGA引脚,然后被外部器件采样。

约束时我们要设置输出延迟:

  • Output Delay Max:外部器件对数据的建立时间要求。即FPGA最后一个时钟沿之后,数据必须在某个时间内到达外部器件。
  • Output Delay Min:外部器件对数据的保持时间要求。

我曾经碰到一个案例:片外DDR3颗粒要求数据在时钟沿前0.2ns稳定,我们设置的输出延迟偏大,结果每次写入都有偶发错误。后来把输出延迟精确到0.15ns,PLL相位调整后,就再也没出现过。

输出延迟计算示例:

Output Delay Max = Tsetup_ext + Tpcb_max + Tmargin
Output Delay Min = Thold_ext - Tpcb_min - Tmargin

3.5 三类路径的关系与PLL配置

PLL的作用不只是倍频分频,还能通过相位调整来补偿路径延迟。输入路径如果需要更多建立时间,可以把PLL输出时钟相位前移。输出路径如果需要更快的数据输出,可以把时钟相位后移。

但是,调整PLL相位会影响所有路径——你在解决输入路径问题的同时,可能把内部路径搞乱。所以我的做法是:

  1. 先不看PLL,直接用默认相位跑STA,看每条路径的余量。
  2. 找出最差路径的那一类(输入/内部/输出)。
  3. 针对性地调整PLL相位,幅度不宜超过半个周期。
  4. 重新跑STA,检查其他路径的余量是否变差。

我的习惯:调整PLL相位不以整度为步长,而是按时钟周期的1/16或1/32来微调。比如200MHz系统,周期5ns,一次调整0.3125ns,比较安全。

下面这张图总结了三种路径的构成和约束要点:

时序路径分类与约束要点 输入路径 起点:外部器件输出 终点:FPGA内部第一级FF 约束:set_input_delay 关键因素:Tco_ext + PCB延迟 内部路径 起点/终点:FPGA内部FF 约束:时钟周期 + 组合逻辑 自动分析:setup/hold 关键因素:逻辑深度、扇出 输出路径 起点:FPGA内部最后一级FF 终点:外部器件输入 约束:set_output_delay 关键因素:Tsetup_ext + PCB PLL相位调整影响所有路径 应先跑STA找出最差路径类别,再对症下药 调整幅度建议:周期/16 ~ 周期/8 三类路径共同约束链 输入路径 → 内部路径 → 输出路径,环环相扣

3.6 实际分析流程(三步法)

我总结了一个三步走的套路,适用于大部分FPGA设计:

  1. 拆路径:打开时序报告,按源时钟分组。先找所有register-to-register路径,剩下的就是I/O路径。这一步用最简单的report_timing就能做。
  2. 分组看余量:我习惯建一个表格,把三类路径的最差余量、中位数余量记录下来。如果某类路径的余量普遍小于0.1ns,就需要重点关注。
  3. 定位瓶颈:输入路径瓶颈往往在PLL相位或PCB延迟;内部路径瓶颈在逻辑级数或布线拥塞;输出路径瓶颈在外部器件时序要求。
路径类型 主要约束命令 典型瓶颈 PLL调整方向
输入路径 set_input_delay PCB走线、外部器件Tco 时钟前移(负相位)
内部路径 create_clock 逻辑深度、扇出 一般不调或调频率
输出路径 set_output_delay 外部setup/hold 时钟后移(正相位)

避坑提醒:我曾经在新项目里只做了内部路径的STA,觉得外部接口很简单,就没写输入输出延迟。结果板子上电,外部器件读回来全是乱码。后来老老实实加约束,才稳定。所以,三类路径的约束一个都不能少。

3.7 实战中的常见误区

  • 误区一:以为输入延迟和输出延迟可以随便写。其实它们直接影响PLL相位和IOB布局,写错了整个时序分析都会歪。
  • 误区二:内部路径只要时钟周期正确就行。实际还有clock skew、jitter、OCV(片上工艺偏差)。我建议保守起见,在周期约束里多留5%~10%的余量。
  • 误区三:调整PLL相位时,只关心最差的那条路径,忽略其他路径是否被破坏。我吃过一次亏,把内部路径余量从+0.3ns调成了-0.1ns,只好花两天重新优化逻辑。

嗯,这一章的内容其实很重要。搞懂了路径分类,你才能知道工具在报告什么,也知道该从哪里下手。不管是新手还是老手,每次做STA前脑子里过一遍这三类路径,能省下不少调试时间。