3. GMII 时序参数详解:建立时间、保持时间、时钟到输出延迟
做 GMII 接口,说白了就三个时序参数你必须吃透:建立时间(Tsu)、保持时间(Th)、时钟到输出延迟(Tco)。这三个东西不理解透,你写的约束全是瞎蒙。我刚开始学 GMII 时,就在这上面栽过跟头——总觉得只要频率跑够就行,结果板子一调,数据老丢包。
这节课,我把这三个参数掰开了讲。哪些是器件给的?哪些是你必须满足的?怎么用它们写约束?咱们一个一个来。
3.1 建立时间(Tsu)——数据必须先到
建立时间的定义很简单:在时钟有效沿到来之前,数据必须稳定下来的最短时间。你想想看,如果数据在时钟沿快到的时候还在跳变,那采样结果就是错的。GMII 作为源同步接口,数据线和时钟线是分开送的,这个 Tsu 通常由接收端(PHY 或 MAC)内部寄存器决定。
我查过主流 GMII 器件的手册,Tsu 一般要求在 2ns~3ns 之间。举个例子:某款 PHY 芯片的 Tsu 是 2.5ns,意味着在时钟上升沿前 2.5ns,数据就得稳住了。如果 PCB 走线有偏差或者信号过冲,你实际能用的建立时间余量就会缩水。
那怎么在约束里体现 Tsu?常见的写法是这样(以 SDC 为例):
# 假设时钟周期为 8ns (125MHz)
# 输入延迟:数据从 PHY 发出到 FPGA 输入管脚的路径延迟
set_input_delay -clock [get_clocks gmii_rx_clk] -max 3.5 [get_ports gmii_rxd*]
set_input_delay -clock [get_clocks gmii_rx_clk] -min 1.0 [get_ports gmii_rxd*]
-max 对应建立时间分析,这里 3.5ns 是参考数据手册算出来的最坏情况。你可以理解为,数据在时钟沿前 3.5ns 就到管脚了,但内部还得留 2.5ns 给建立时间,所以实际约束必须比器件要求更紧。
3.2 保持时间(Th)——数据不能早走
保持时间刚好反过来:在时钟有效沿之后,数据必须保持稳定的最短时间。数据不能立马撤走,得等着寄存器把数据锁存完。
GMII 接口的保持时间要求通常比建立时间短,很多 PHY 只要求 1ns~1.5ns。但别小看这 1ns——如果时钟偏移太大,或者数据因反射导致回勾,保持时间一样会被违反。
保持时间约束在 SDC 里用 -min 来控制,也就是看数据路径上的最小延迟。一般来说,输入延迟的 -min 值要比 -max 小很多,因为保持时间分析走的是最小路径:
# 保持时间主要靠 -min 来卡
set_input_delay -clock [get_clocks gmii_rx_clk] -min 1.0 [get_ports gmii_rxd*]
注意:建立时间和保持时间是矛盾的。你加长走线让数据早到,建立时间余量变大,但保持时间余量会变小;缩短走线让数据晚到,保持时间余量变大,建立时间又紧张了。调时序就像走钢丝。
3.3 时钟到输出延迟(Tco)——源端数据的发送窗口
Tco 是从时钟有效沿到数据出现在输出管脚上的延迟。这个参数是发送端的重要特性。在 GMII 接口里,MAC 端发送数据时,Tco 决定了数据在时钟沿后多久才会稳定。PHY 端会用同样的时钟沿来采样,所以 Tco 和时钟偏斜共同决定了接收端看到的窗口。
举个例子:某 FPGA 的 GMII 输出 Tco 典型值是 4ns,最大 6ns。这意味着时钟上升沿之后,数据最多 6ns 后才能完全稳定。PHY 如果要正确采样,得保证数据在建立时间窗口内是干净的。
约束写法:发送路径用 set_output_delay 来描述。
# 输出延迟:FPGA 送到 PHY 的路径
set_output_delay -clock [get_clocks gmii_tx_clk] -max 5.5 [get_ports gmii_txd*]
set_output_delay -clock [get_clocks gmii_tx_clk] -min 1.5 [get_ports gmii_txd*]
-max 对应建立时间检查——你需要确保数据在时钟沿之前足够早到 PHY 的输入。-min 对应保持时间检查——数据不能撤得太快。
3.4 三个参数的关联——一张图全看懂
为了让你直观理解这三个参数怎么配合,我画了一张时序关系图。别小看这张图,当年我花了整整一个晚上才理顺的。
3.5 三个参数实战对照表
我整理了常见 GMII 器件的典型时序数值,方便你查表约束的时候直接参考:
| 参数 | 典型值 | 最坏条件 | 约束方向 | 对应 SDC 关键词 |
|---|---|---|---|---|
| Tsu(接收端) | 2.5 ns | 2.0 ns | 数据必须早于时钟 | -max |
| Th(接收端) | 1.2 ns | 1.0 ns | 数据不能太快撤走 | -min |
| Tco(发送端) | 4.0 ns | 6.0 ns | 数据输出延迟 | set_output_delay |
3.6 一个常见误解——Tco 不是传播延迟
很多人容易把 Tco 和 PCB 走线延迟混为一谈。其实 Tco 是器件的内部延迟,不是外部走线的延迟。Tco 包括寄存器 CK-to-Q 延迟、内部缓冲、输出驱动等。外部走线的延迟是另外加的,叫 PCB 飞行时间。在整体时序计算中,你要把 Tco + 走线延迟 + 接收端 Tsu/Th 全部加起来算。
举个例子:MAC 的 Tco 是 4ns,PCB 走线 0.8ns,PHY 的 Tsu 是 2.5ns,那么留给时钟偏斜的余量就是 8ns - 4ns - 0.8ns - 2.5ns = 0.7ns。就这么点!所以 PCB 走线必须等长,否则连 0.7ns 都会被吃掉。
嗯,这三个参数讲完了。做 GMII 时序约束,你只要抓住 Tsu、Th、Tco 这三个铁三角,配合 SDC 里的 set_input_delay 和 set_output_delay,基本就能覆盖 90% 的场景。剩下的 10% 靠调试,靠看波形,靠仔细抠余量。下节课咱们就聊这些约束怎么写。