RGMII 时钟相位概念:时钟与数据对齐方式、双沿采样原理
搞 RGMII 调试,绕不开一个核心问题 —— 时钟和数据到底怎么对齐的?
很多人一上来就看眼图、调 delay,但根本概念没理清,调半天都是瞎蒙。
先说说 双沿采样。RGMII 这个名字里的「G」就是 gigabit,千兆。千兆以太网在 125 MHz 时钟下要传 1 Gbps 数据,传统 SDR(单沿采样)需要 8 位数据线同时翻转,PCB 布线压力超大。所以 RGMII 用了 DDR(双数据率)—— 时钟的上升沿和下降沿各采一次数据。说白了,一根数据线在单沿模式下只能传 1 bit/周期,DDR 就能传 2 bit。
| 参数 | SDR(单沿) | DDR(双沿) |
|---|---|---|
| 数据速率(125 MHz) | 125 Mbps | 250 Mbps |
| 所需数据线数量 | 8 根 | 4 根 |
| 有效数据窗口 | 半个周期(4 ns) | 四分之一周期(2 ns) |
| 时钟抖动容限 | 较宽 | 较紧 |
你想想看,每根线在 4 ns 里要传两个 bit,数据稳定窗口只剩下 2 ns 左右。这对时钟和数据的相对相位要求就非常苛刻了。
两种对齐方式:边沿对齐 vs 中心对齐
按 RGMII 规范(IEEE 802.3-2008 条款 35),发送端有两种对齐方式:
- 边沿对齐(Edge-aligned / Non-return-to-zero):时钟跳变沿正好位于数据翻转处。上升沿采 D0,下降沿采 D1。
- 中心对齐(Center-aligned / Internal delay):时钟跳变沿对准数据的正中间(稳定区域)。
这是最容易被忽略的地方,也是我踩过最大的坑。
规范本身没强制要求 PHY 和 MAC 必须用哪种模式,但业界主流做法是:
- 发送端(TX)通常使用 边沿对齐(数据随时钟同时输出)
- 接收端(RX)必须通过 PCB 走线或内部延迟把数据移到时钟中心位置
但在实际芯片里,很多 FPGA 或 ASIC 的 RGMII 接口会在内部自带 2 ns 左右的延迟,让数据相对时钟偏移 90°。这其实就是把边沿对齐转成了中心对齐。
双沿采样的时序约束
我们先画一下理想情况下的时序。注意:下面的 SVG 图展示了时钟和数据的关系以及两种对齐方式。
从图里能清楚看到:边沿对齐时,时钟的上升沿正好在数据从 0 变 1 的位置,理论上采样点就是跳变后的瞬间。但实际中走线延迟、门延迟都会让这个对齐变模糊。中心对齐则是在源端把数据延迟了约 90°(2 ns),这样时钟边沿就落到了数据稳定区的正中央,采样可靠性大大提高。
核心概念:RGMII 的双沿采样不是靠时钟占空比保证的,而是靠数据相对于时钟的相移。这个相移要么靠 PCB 走线长度差(外部延迟),要么靠芯片内部的延迟链(内部延迟)。
实际调试时的相位关系判断
我记得有一次调一块 FPGA 和 Marvell PHY 的对接,无论如何 link 都起不来。用示波器抓了 RX 时钟和数据,发现时钟上升沿落在数据的跳变区域,根本不是采样窗口内。那问题就清楚了:MAC 端没有做延迟,而 PHY 期望的是中心对齐。
解决办法:在 FPGA 的约束里加一个 set_output_delay,让 RGMII TX 输出去对齐到时钟中心。或者直接改 PHY 的寄存器,让它用边沿对齐模式收发。我后来习惯把 FPGA 端的 RGMII 接口都设计成可配置的:
// 示例:在 VHDL 中通过参数选择模式
entity rgmii_tx is
generic (
DELAY_MODE : integer := 1 -- 0: 边沿对齐 1: 中心对齐
);
port (
clk125 : in std_logic;
data : in std_logic_vector(3 downto 0);
txc : out std_logic;
txd : out std_logic_vector(3 downto 0)
);
end entity;
architecture behavioral of rgmii_tx is
signal data_delayed : std_logic_vector(3 downto 0);
signal clk_delayed : std_logic;
begin
-- 内部延迟生成(简化版)
gen_center : if DELAY_MODE = 1 generate
delay_data : process(clk125) begin
if rising_edge(clk125) then
data_delayed <= data;
end if;
end process;
txd <= data_delayed;
end generate;
-- 边沿对齐直接输出
gen_edge : if DELAY_MODE = 0 generate
txd <= data;
end generate;
end architecture;
对了,如果你在 PHY 端也遇到类似问题,可以去翻一下数据手册里关于 RGMII_DELAY_CTRL(或者 TXC_DELAY、RXD_DELAY)的寄存器描述。很多 PHY 都有内部粗调/细调单元,可以在 0~2 ns 范围内步进调节。
为什么双沿采样对相位如此敏感
说白了,单沿采样时数据窗口有 4 ns,你走线多 500 ps 基本没事。但双沿采样把周期二等分,每个 bit 的理论有效窗口只有 2 ns。再加上时钟抖动(jitter)、占空比失真、电源噪声,实际可用的窗口可能只剩 1 ns 左右。
我把常见的问题列了一张表,你可以对照排查:
| 现象 | 可能原因 | 检查方向 |
|---|---|---|
| 链路不通,偶尔通一下 | 采样点完全落在跳变区 | 示波器测时钟与数据相对相位 |
| 链路能通,但 ping 丢包 10%~50% | 采样点接近跳变边缘,margin 不足 | 增加/减少 0.5~1 ns 的延迟步进试验 |
| 高温下丢包率上升 | 温度导致内部延迟链漂移 | 改用片外走线延迟,或加温度补偿 |
| 只有某些 PHY 或 FPGA 批次有问题 | 芯片工艺角差异,延迟抖动量不同 | 预留寄存器可调,不要写死 |
我自己最头疼的是第三种 —— 量产时高温箱 85 °C 下丢包,常温正常。查了一圈发现是 FPGA 内部的 ODELAY 受温度影响严重,后来换成 PCB 走线绕线(增加约 1.5 ns 延迟)并靠近 PHY,问题才解决。所以说,硬件调试不只靠示波器,还要理解芯片内部的延时单元是怎么实现的,它们受 PVT 影响多大。
小结一下
RGMII 时钟相位的核心就两点:
- 双沿采样 让数据窗口缩小到 2 ns,决定了你必须仔细控制相位。
- 对齐方式(边沿 vs 中心)决定了你的调试起点 —— 先确认两侧的模式匹配,再去调具体延迟值。
搞懂这两点,你再去调那个 rgmii_txc_delay 寄存器,心里就有底了。