4. RGMII接口时序:信号定义、DDR双沿采样、时钟与数据对齐、时序约束要点
好,咱们今天聊聊RGMII接口。这个接口在千兆以太网里太常见了,几乎每个FPGA工程师都会碰到。我记得刚入行那会儿,第一次调RGMII,板子死活不通,折腾了两天才发现是时序对齐的问题。嗯,今天就把这些坑和经验一起分享给你。
4.1 RGMII信号定义
RGMII,全称是Reduced Gigabit Media Independent Interface。说白了,就是简化版的千兆媒体独立接口。它比原来的GMII引脚少了一半,从24根减到12根。为什么要减?因为引脚贵啊,尤其是BGA封装的FPGA,一个引脚就是一分钱。
RGMII的信号其实很简单,我列个表给你看:
| 信号名 | 方向 | 说明 |
|---|---|---|
| RXC | PHY→MAC | 接收时钟,125MHz |
| RXD[3:0] | PHY→MAC | 接收数据,DDR方式 |
| RX_CTL | PHY→MAC | 接收控制,DDR方式 |
| TXC | MAC→PHY | 发送时钟,125MHz |
| TXD[3:0] | MAC→PHY | 发送数据,DDR方式 |
| TX_CTL | MAC→PHY | 发送控制,DDR方式 |
你看,总共就6组信号,12根线。数据总线从GMII的8位缩到了4位,但时钟频率还是125MHz。怎么做到千兆的呢?答案就是——DDR双沿采样。
4.2 DDR双沿采样
DDR,Double Data Rate,双倍数据速率。什么意思?就是时钟的上升沿和下降沿都传输数据。125MHz的时钟,一个周期2ns,上升沿采一次,下降沿采一次,等效数据速率就是250M采样/秒。4位数据总线,4×250M = 1Gbps。千兆就是这么来的。
我刚开始理解这个的时候,总觉得别扭。为什么非要搞个双沿?其实你想想看,如果不用DDR,那就得把时钟提到250MHz。250MHz的时钟在PCB上跑,信号完整性可就难搞了。DDR方式用125MHz,时序裕量更大,设计更稳健。
具体到每个信号,RXD[3:0]在时钟上升沿传输低4位数据,下降沿传输高4位数据。RX_CTL也一样,上升沿表示数据有效(DV),下降沿表示错误指示(ER)。发送方向同理。
关键点:RGMII的DDR方式,本质上是把8位数据拆成两个4位,分别在时钟的两个沿传输。接收端需要把这两个4位拼回8位。
4.3 时钟与数据对齐
这里有个大坑,我必须重点说。RGMII标准规定了两种对齐方式:
- 方式一:时钟与数据边沿对齐(源同步方式)
- 方式二:时钟与数据中心对齐(90度相移)
早期的PHY芯片大多用方式一,时钟边沿和数据跳变沿对齐。但这种方式对接收端很不友好,因为时钟沿正好在数据变化的时候,建立时间和保持时间都很紧张。
后来大家发现,把时钟移相90度,让时钟沿落在数据的中心位置,时序裕量就大多了。现在的PHY芯片,内部一般都做了这个移相。但FPGA这边呢?你得根据PHY的实际情况来调整。
我曾经在一个项目里,用的PHY芯片是RTL8211,它默认输出时钟和数据是边沿对齐的。我按照数据手册的推荐,在FPGA内部用PLL把接收时钟移相90度,然后再去采数据。结果呢?死活采不对。后来用示波器一看,发现PHY内部已经做了移相,我再移一次就变成180度了,正好采在数据跳变沿上。嗯,这个教训挺深刻的。
我的建议:拿到一块新板子,先用示波器看RXC和RXD的相位关系。别完全相信数据手册,实际PCB走线长度、PHY内部配置都可能影响相位。用眼睛看过才放心。
4.4 时序约束要点
RGMII的时序约束,说白了就是告诉工具:这个时钟和这个数据之间是什么关系。我一般会做以下几类约束:
4.4.1 输入延迟约束
对于接收路径,PHY发送时钟和数据到FPGA,我们需要约束输入延迟。典型的约束写法:
# 创建接收时钟
create_clock -name rgmii_rxc -period 8.0 [get_ports RXC]
# 约束输入延迟
set_input_delay -clock rgmii_rxc -max 2.0 [get_ports {RXD[*] RX_CTL}]
set_input_delay -clock rgmii_rxc -min 0.5 [get_ports {RXD[*] RX_CTL}]
这里的max和min值怎么定?要看PHY的datasheet里Tskew参数。一般RGMII的Tskew在0.5ns到2.0ns之间。我习惯留点裕量,取1.5ns和0.8ns。
4.4.2 输出延迟约束
发送路径相反,是FPGA输出数据给PHY。约束写法:
# 创建发送时钟
create_clock -name rgmii_txc -period 8.0 [get_ports TXC]
# 约束输出延迟
set_output_delay -clock rgmii_txc -max 1.5 [get_ports {TXD[*] TX_CTL}]
set_output_delay -clock rgmii_txc -min 0.5 [get_ports {TXD[*] TX_CTL}]
4.4.3 伪路径约束
有时候,跨时钟域的信号不需要做时序分析。比如,RXC和TXC是两个独立的时钟域,它们之间的路径可以设为伪路径:
set_false_path -from [get_clocks rgmii_rxc] -to [get_clocks rgmii_txc]
set_false_path -from [get_clocks rgmii_txc] -to [get_clocks rgmii_rxc]
注意:伪路径要慎用。只有确定不需要时序分析的路径才能设。我曾经见过有人把RXC到内部逻辑的路径也设成伪路径,结果功能仿真没问题,上板就跑飞了。因为内部逻辑确实需要RXC的时序约束。
4.5 实战中的避坑指南
最后,分享几个我踩过的坑:
- PCB走线等长:RGMII的4位数据和时钟,走线长度差不要超过50mil。我有个项目,因为布局紧张,时钟线比数据线长了200mil,结果时序直接崩了。
- ODDR原语:在FPGA内部实现DDR输出,一定要用ODDR原语,别自己用逻辑拼。Xilinx的OSERDESE2、Altera的ALTDDIO_OUT都是现成的。
- IDDR原语:接收端用IDDR,注意选择正确的采样沿模式。SAME_EDGE_PIPELINED模式可以省掉一个寄存器,但要注意时序。
- 复位顺序:PHY芯片的复位和FPGA的初始化顺序要配合好。我习惯先复位PHY,等它稳定后再配置FPGA内部的RGMII逻辑。
嗯,RGMII接口的内容就这些。说白了,信号定义是基础,DDR是核心,时序约束是保障。把这三点吃透了,千兆以太网的物理层就算拿下了。