3. 时钟同步机制:50MHz参考时钟,数据窗口与时钟沿对齐关系

你要是问我,RMII 里最容易出问题的地方是哪里?我会说,十有八九都出在时钟和数据窗口的配合上。50MHz 的参考时钟,周期 20ns,看起来简单,但数据窗口怎么跟时钟沿对齐,这里面的门道,我是在几次板子调不通之后才真正搞明白的。

3.1 50MHz 参考时钟——RMII 的心跳

RMII 为什么选 50MHz?因为它是 2 位并行总线。2 位 × 50MHz = 100Mbps,正好跑满百兆以太网。这个时钟是所有数据收发的基准,没有它,一切免谈。

时钟的来源通常有三种:

  • MAC 提供时钟:MAC 芯片自己产生 50MHz,送给 PHY。这时候时序由 MAC 主导,PHY 跟着走。
  • PHY 提供时钟:PHY 内部有锁相环,从外部晶振倍频出 50MHz,反向送给 MAC。这是最常见的做法。
  • 外部晶振直接提供:一颗 50MHz 有源晶振,同时给 MAC 和 PHY 供电。两边各自看时钟沿,谁都不依赖谁。

我个人习惯用 PHY 提供时钟的方式,因为 PHY 内部的时钟整形通常比 MAC 做得好,抖动更小。但要注意,不管时钟从哪来,占空比必须控制在 45%~55% 之间,否则数据窗口的有效宽度会被压缩。

我曾经在一个项目里用过便宜的晶振,输出占空比只有 42%,结果 100M 就是不通,降到 10M 就正常。换了颗高精度晶振,问题立刻消失。时钟的质量,真的不能省。

3.2 数据窗口与时钟沿的对齐模型

说白了,数据窗口就是数据在时钟沿附近保持稳定的那段时间。RMII 是 SDR(单数据速率),只在 REF_CLK 的上升沿 采样数据。所以数据窗口必须覆盖这个上升沿,而且前后都要留出余量。

下面这张图,是我自己总结的对齐模型。花 5 分钟看懂它,后面调试能省不少时间。

数据窗口与时钟沿对齐关系(50MHz REF_CLK) REF_CLK (50MHz, 周期 20ns) 上升沿 上升沿 上升沿 TXD[1:0] / RXD[1:0] 数据窗口(稳定区域) tSU(建立时间) tHD(保持时间) 采样沿 数据窗口必须覆盖时钟上升沿,并在沿的前后分别满足 tSU 和 tHD 的要求。 典型 tSU:2~5ns,典型 tHD:1~3ns(具体值以 PHY 数据手册为准)

从图上能看得很清楚:数据在上升沿之前已经稳定(建立时间),在上升沿之后继续保持稳定(保持时间)。这两个参数,就是数据窗口的边界。

3.3 建立时间与保持时间——不可逾越的边界

你想想看,如果数据在时钟沿到来的时候还没稳定,或者刚稳定又马上变了,接收端采样到的就是错误值。这就是建立时间和保持时间存在的意义。

参数 含义 典型值(RMII) 如果违反会怎样
tSU(建立时间) 时钟上升沿之前,数据必须保持稳定的最短时间 2~5 ns 采样值不确定,可能为 0 也可能为 1
tHD(保持时间) 时钟上升沿之后,数据必须保持稳定的最长时间 1~3 ns 数据被"读脏",CRC 错误频发

不同 PHY 芯片的时序参数差异很大。我记得有次用了一颗国产 PHY,数据手册上写 tSU 要 4ns,tHD 要 2ns。结果板子 layout 没控制好,实际跑下来 tSU 只剩 2.5ns,100M 就是不稳定,降速到 10M 反而正常。后来加了一级 clock buffer 才救回来。

关键原则:数据窗口的稳定区域必须完全覆盖时钟上升沿,且在沿前后的持续时间 ≥ tSU + tHD。20ns 的时钟周期里,数据窗口至少要有 30%~50% 的宽度留给建立和保持时间。

3.4 时钟偏移——隐藏的时序杀手

什么叫时钟偏移?就是同一个 50MHz 信号,到达 MAC 和到达 PHY 的时间不一样。这个时间差会直接压缩数据窗口的有效宽度。

时钟偏移的来源主要有两个:

  1. 走线长度差:REF_CLK 到 MAC 和 PHY 的 PCB 走线长度不一致。每 1 英寸走线大约产生 150~170ps 的延迟。
  2. 负载差异:MAC 和 PHY 的输入电容不同,导致时钟沿的上升时间不一样,等效偏移。

怎么应对?我一般会做三件事:

  • REF_CLK 走线做到 等长,误差控制在 ±5 mil 以内。
  • 时钟线上 不加多余的测试点或过孔,减少反射和容性负载。
  • 如果 PHY 和 MAC 距离较远(超过 2 英寸),在时钟源端加 串联电阻(22Ω~33Ω) 来抑制过冲。
注意:时钟偏移不是"只有一点点,忽略不计"的问题。在 50MHz 下,1ns 的偏移就能吃掉 5% 的数据窗口宽度。如果你的板子通信不稳定,先拿示波器量一下时钟沿到达两边的时刻差。

3.5 实战调试:如何检查时钟与数据窗口的对齐

理论讲完了,来点实际的。怎么确认你的板子上时钟和数据窗口是对齐的?我自己的调试流程是这样的:

  1. 先看时钟波形:用示波器测 REF_CLK,确认频率是 50MHz ±50ppm,占空比 45%~55%,上升/下降时间 ≤ 2ns。如果时钟本身就不干净,后面的都不用看了。
  2. 再测数据信号:把 TXD 或 RXD 接到示波器上,触发源选 REF_CLK 的上升沿。看数据跳变沿离时钟沿有多远。
  3. 估算建立/保持时间:从时钟上升沿往回数,数据最后稳定的那个时刻就是 tSU 的起点;往前进,数据开始变化的时刻就是 tHD 的终点。这两个时间必须大于 PHY 手册的要求。
  4. 跑压力测试:用 iperf 或类似工具打满 100M 流量,跑 30 分钟,抓 CRC 错误计数。如果计数器一直为 0,说明时序裕量充足。

我曾经用这个流程帮一个团队排查问题。他们的板子在高温箱里 65°C 就开始丢包。一量才发现,温度升高后 PHY 的输入电容变了,保持时间从 2ns 缩到了 0.8ns,刚好低于阈值。后来在 REF_CLK 上串联了一个 27Ω 电阻,把沿变缓了一点,反而让保持时间恢复到了 1.5ns。嗯,有时候"慢"一点反而更稳。

一个小技巧:在示波器上打开"余晖"模式(persistence),看数据跳变沿的抖动范围。如果抖动超过了 2ns,说明时钟或者数据路径上有噪声干扰,需要检查电源和地平面。

好了,关于时钟同步机制,核心就这些。数据窗口对齐时钟沿这件事,看似基础,但直接影响整条链路能不能跑稳。下一层我们要面对的是数据采样窗口的具体计算方法——到时候会用实际案例带你一步步算清楚。