RGMII接口概述:信号定义与时序标准
大家在做千兆以太网的时候,十有八九会碰到RGMII这个接口。它全称是Reduced Gigabit Media Independent Interface,说白了就是简化版的GMII。为什么要有它?因为GMII信号太多了——时钟、数据、控制加一起快30根线,在DDR时代根本扛不住。RGMII只用了12根线就把事情干了,代价就是时序窗口变窄,调试起来特别考验耐心。
我接手第一个GMAC项目时,照着参考设计连完线,板上跑千兆死活不通。后来拿示波器一量,发现RGMII的时钟和数据之间差了快1ns。嗯,从那天起,我就知道这个接口不是随便连连就能用的。
1.1 信号定义
RGMII总共12根信号,分成两组:数据组和控制组。我习惯先记一个口诀:发端三对收端三对,时钟数据都走DDR。具体如下表:
| 信号名 | 方向 | 宽度 | 说明 |
|---|---|---|---|
| ETH_RXC | 接收时钟 | 1 | 125MHz,DDR采样 |
| ETH_RX_CTL | 接收控制 | 1 | 高电平有效,指示数据有效 |
| ETH_RXD[3:0] | 接收数据 | 4 | 时钟上升沿送低4位,下降沿送高4位 |
| ETH_TXC | 发送时钟 | 1 | 125MHz,DDR采样 |
| ETH_TX_CTL | 发送控制 | 1 | 高电平有效,指示数据有效 |
| ETH_TXD[3:0] | 发送数据 | 4 | 时钟上升沿送低4位,下降沿送高4位 |
看到这里你可能要问:4位数据线怎么传输8位并行数据?因为用了DDR——每个时钟沿传半个字节,一个时钟周期就能拼出完整一字节。控制信号也一样,上升沿送TX_EN,下降沿送TX_ER或错码标志。这种做法让PCB走线数量直接砍半,但代价就是时序约束要做两个沿。
关键认知:RGMII本质上是源同步DDR接口。发送端随路送出时钟,接收端用这个时钟去采样数据和控制。时钟偏移的问题,恰恰就出在这个「随路时钟」上——如果PCB走线不等长,或者芯片内部输出延迟不一致,时钟沿和数据眼中心就错位了。
1.2 时序标准归纳
RGMII的时序标准由IEEE 802.3定义,但实际工程中常用的有两个版本:RGMII v1.3和RGMII v2.0。我做过的项目里,大多数PHY芯片和FPGA IP都支持v2.0,但老旧器件可能只支持v1.3。两者的核心区别就在时钟沿和数据的关系上。
1.2.1 v1.3(时钟对齐)
v1.3要求:时钟沿与数据跳变沿对齐。也就是说,TX_CLK的上升沿正好在TXD切换的时刻。这样做的好处是时序分析简单——你只需要保证建立时间和保持时间就够了。坏处呢?实际PCB上走线稍微有点寄生电容,数据沿就会往后滑,时钟沿却因为负载轻跑得快,两者一错开,接收端采样的就是毛刺。
避坑经验:我曾经在一个使用v1.3的百兆PHY方案上折腾了一周,最后发现是因为FPGA输出的TXD和TX_CLK经过不同的IO bank,内部路径延迟差了0.3ns。解决方法是把两组信号放到同一个bank,并加了一组输出延迟约束。
1.2.2 v2.0(时钟偏移90°)
v2.0把时钟与数据的相位关系做了个巧妙的调整:时钟沿要相对于数据沿偏移90°(也就是T/4)。125MHz对应的周期是8ns,90°就是2ns。这样一来,数据跳变沿和时钟沿错开,采样点刚好落在数据眼中心。这是目前绝大多数高速RGMII设计采用的方式。
不过要注意一个细节:v2.0的偏移到底发生在发送端还是接收端?标准其实允许两种做法——发送端调延迟,或者接收端在内部做时钟相移。我在实际项目中更推荐在发送端做,因为FPGA这边有现成的ODDR/OSERDES原语可以精确控制输出时钟相位,调试也更直观。
- v1.3:时钟与数据边沿对齐。容易实现,但时序裕量小,对PCB走线长度差敏感。
- v2.0:时钟偏移90°(2ns)。采样窗口大,但需要额外的时钟相位调整逻辑。
说实话,现在的PHY芯片几乎都支持自动协商v2.0。如果发现千兆链路不通,第一件事别急着改代码,先去读PHY的寄存器,看看它工作在哪个模式。我遇到过好几次——FPGA配置成v2.0,但PHY默认是v1.3,两边各玩各的,数据全是错的。
1.3 核心参数速查表
下面这张表是我自己做项目时经常翻的,贴出来给大家参考。每个参数都是在室温+典型电压下测得,设计时要留起码20%的余量。
| 参数 | 符号 | 最小 | 典型 | 最大 | 单位 |
|---|---|---|---|---|---|
| 时钟频率 | f_clk | — | 125 | — | MHz |
| 时钟周期 | T_per | — | 8 | — | ns |
| 输出数据有效偏斜(v1.3) | T_skew | -0.5 | 0 | +0.5 | ns |
| 输出数据有效偏斜(v2.0) | T_skew_v2 | 1.5 | 2.0 | 2.5 | ns |
| 接收端建立时间 | T_setup | 1 | — | — | ns |
| 接收端保持时间 | T_hold | 1 | — | — | ns |
⚠️ 特别提醒:上表中T_skew_v2的“典型2.0ns”是数据与时钟沿之间的期望偏移量。实际工程中这个值会受到IO驱动强度、PCB走线长度、温度电压变化的影响。我曾在一个-40°C的低温实验中发现偏移量漂了0.8ns,差点把时序裕量吃光。所以做约束时,建议把目标偏移设为2.0ns±0.3ns,给后级留点呼吸空间。
1.4 RGMII时序本质:一张图讲清楚
为什么RGMII的时钟偏移这么难调?我画了张图来帮你把底层逻辑理清楚。它不是一个简单的数据采样模型,而是一个源同步DDR+两个版本偏移选择的复合问题。
这张图里,发送端内部PLL产生125MHz时钟,同时通过DDR方式送出4位数据和控制信号。时钟和数据两条路径经过PCB走线到达接收端。偏移量ΔT就是我们需要校准的核心——你想想看,如果走线长度差导致ΔT偏离了标准的2ns,接收端采样点就会从眼中心往边缘移动,误码率随之飙升。
实用技巧:调试时先拿示波器测时钟沿和数据跳变沿之间的时间差。如果是v2.0,你应该看到大约2ns的间隔。如果只有0.5ns,赶紧检查PCB等长设计或FPGA内部的ODDR相位配置。我习惯在FPGA里留一个可调的延时链,用寄存器写值来微调,比换PCB方便得多。
1.5 动手前的检查清单
为了帮你少走弯路,我把启动RGMII调试前必须确认的事情列成了一个清单。每项做到位了,后面的调偏移步骤才能顺利推进。
- 确认PHY/MAC支持的版本:读寄存器0x00的bit6,v2.0一般置1。如果两端不一致,协商会失败。
- 测量时钟频率:125MHz±50ppm才算合格。我曾因为晶振选错频率,导致速率协商到100M才通——千兆下全是错包。
- 检查PCB走线长度差:同组信号线(4根数据+1根时钟+1根控制)长度差控制在5mm以内。每差1cm大约引入80ps的延迟。
- 查看IO Bank电压:RGMII一般是3.3V或2.5V。电压偏低会导致输出驱动变弱,上升沿变缓,时序偏移增大。
- 确认端接电阻:高速信号要求在接收端靠近芯片放置50Ω下拉(或上拉到VDD),防止反射造成数据沿抖动。