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是核心,时序约束是保障。把这三点吃透了,千兆以太网的物理层就算拿下了。

RGMII接口时序知识体系 信号定义 6组信号,12根线 DDR双沿采样 125MHz→250M采样/s 时钟数据对齐 边沿对齐 vs 中心对齐 时序约束 输入/输出/伪路径 RXC/RXD/RX_CTL/TXC/TXD/TX_CTL 上升沿低4位,下降沿高4位 PHY内部移相 vs FPGA移相 set_input_delay / set_output_delay 实战避坑指南 PCB等长 | ODDR/IDDR原语 | 复位顺序 | 示波器验证 核心逻辑:信号定义 → DDR实现 → 时钟对齐 → 时序约束 → 实战验证

专注资料整理