ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RGMII时钟延迟配置与调试指南:从设备树到PHY寄存器的完整实践

RGMII时钟延迟配置与调试指南:从设备树到PHY寄存器的完整实践 RGMII接口调试十个坑有八个都出在时钟延迟上。前阵子帮同事查一块新板子现象非常典型网络能够协商上百兆、千兆ping网关却只有 30% 左右成功率抓包全是 RX CRC Error。一开始怀疑 PCB 走线Layout 反馈 RGMII 信号组已经做了等长控制串阻也加了又怀疑 PHY 供电纹波量了一圈也正常。查了两天才发现MAC 侧和 PHY 侧的 TX delay 同时被打开了时钟相对数据多延迟了接近 4ns正好落在采样窗口边缘。这种问题在 RGMII 接口上几乎每天都能遇到根源就是 RGMII 这个接口本身的设计机制——它把时钟和数据如何对齐这个矛盾从硬件设计转嫁给了时钟延迟配置。这篇文章就把 RGMII 时钟延迟的来龙去脉、MAC/PHY 两侧的配置方法、以及实际排查流程完整拆开讲一遍适合正在调 RGMII 的嵌入式工程师、做 FPGAPHY 方案的朋友以及所有被时通时不通折磨过的人。1. RGMII 的时钟陷阱到底在哪儿从接口本质看问题根源1.1 RGMII 为什么要把时钟和数据同步关系搞得这么复杂RGMIIReduced Gigabit Media Independent Interface是对 GMII 接口的缩减。GMII 用 8 根数据线加上收发时钟、控制信号一共 24 根RGMII 砍到 12 根数据线从 8 根变 4 根发送和接收方向各只需要 TXD[3:0] 和 RXD[3:0]外加 TX_CLK、RX_CLK、TX_CTL、RX_CTL。它的诀窍是用了 DDR 双沿采样TXD[3:0] 在 TX_CLK 的上升沿送低 4 位数据下降沿送高 4 位等于把 4 根线当 8 根用。千兆模式下 TX_CLK 频率是 125MHz由于双沿采样等效数据吞吐就是 1Gbps。问题就出在这个双沿采样上。数据是沿着时钟边沿发送的edge-aligned也就是说发送端在时钟上升沿或下降沿的瞬间把数据放到总线上。如果接收端也在这个边沿去采样采到的很可能就是正处于跳变过程中的电平结果完全不可预测。标准 RGMII 在定义时就意识到了这个问题所以引入了时钟延迟或数据延迟的机制允许发送端把时钟相对于数据延迟约 2ns或者让接收端把输入数据延迟约 2ns让采样沿落在数据电平稳定的区域中央也就是把边沿对齐变成中心对齐。很多人第一次接触这个概念会觉得绕既然要中心对齐为什么发射端不直接做成中心对齐因为 RGMII 要从兼容 GMII 的时序出发而且 2ns 延迟通过芯片内部 delay 链比通过复杂的时钟管理实现起来便宜得多。理解了这一点就理解后续所有配置冲突的根源了延迟只能补在一端或者 MAC 端、或者 PHY 端目的是让最终到达接收端采样触发器的时钟沿和数据窗口相对位置正确而不是两端都补。1.2 延迟到底是谁造成的三笔账要让 RGMII 正常工作需要把三笔延迟账加在一起看。第一笔是芯片内部 delay。MAC 和 PHY 芯片内部通常都集成了可选的延迟单元典型值在 1.5ns 到 2ns 之间。这些延迟单元通过寄存器位或设备树属性来控制开关这也是绝大多数工程师口中的RGMII delay 配置。第二笔是 PCB 走线延迟。电信号在 FR4 板材中的传播速度大约是每英寸 6 英寸/纳秒反过来说每英寸走线大约带来 160ps 到 200ps 的延迟。RGMII 信号组要求数据线之间等长、数据线与时钟线之间也要控制长度差。等长控制不是消除延迟而是让同一组信号到达接收端时相对位置保持一致。如果时钟线比数据线短 5 英寸时钟就会比数据早到约 1ns这 1ns 偏移会叠加在内部 delay 上。第三笔是数据有效窗口。千兆 RGMII 的时钟周期是 8nsDDR 模式下每个半周期只有 4ns。考虑接收端的建立时间和保持时间通常各需要 0.8ns 到 1.2ns数据实际有效稳定的窗口大约只有 2ns 左右。要让时钟采样沿稳稳地落在窗口中央理想情况下时钟沿要相对数据窗口延迟约 2ns。这也是为什么所有 RGMII delay 配置都围绕 2ns 这个数字转。把三笔账加在一起真正需要关心的是到达接收端时时钟沿与数据窗口中心的偏差。如果 MAC 和 PHY 都往时钟路径上加 2ns时钟就比数据多走了约 4ns采样沿跑到了数据窗口外面轻则偶发 CRC 错误重则完全不通。如果两端都不加采样沿贴着数据跳变沿板子可能今天能通、明天不能通换个批次芯片又不能通。1.3 哪些现象属于时钟延迟问题RGMII 时钟延迟配置出问题表现通常不是百分百断网而是带有一系列特征完全不通PHY 的 link 都建立不起来或者 link 起来但 MAC 侧没有任何收包ping 时通时不通或者 ping 小包正常、ping 大包超过 MTU 分片丢包严重MAC 统计寄存器里 RX CRC Error、FCS Error、Alignment Error 数量持续上涨百兆正常、千兆异常或者 10/100M 都正常一到 1000M 就出问题常温调试没问题高低温箱里跑几小时开始丢包如果你的板子出现了上面任何一种情况时钟延迟配置就是首要怀疑对象。但要注意RGMII 时钟问题不是唯一会导致这些现象的原因MDIO 配置异常、PHY 复位时序、电源纹波过大、参考时钟异常、引脚复用错误都会表现出类似症状。所以在动手调 delay 之前先把这些基础项确认掉否则容易白忙一场。2. 时钟延迟配置的两条路线硬件层修与软件层补2.1 硬件层的物理修法PCB 设计与端接先讲硬件层因为很多工程师一上来就改设备树忽略了 PCB 层面的问题。RGMII 是源同步接口设计上要求 TX 方向和 RX 方向的信号组分别做等长控制。具体控制多少不同厂家的参考设计不太一样比较常见的规则是组内数据线之间控制在 ±50mil 以内时钟线与数据线的长度差控制在 ±100mil 左右。这里有个经验时钟线的走线延迟不要刻意做得比数据线长很多来做相位补偿。有些 Layout 工程师习惯把时钟线做成蛇形线、拉长 1.5 英寸约 250ps来补偿这在 RGMII 上并不推荐。因为芯片内部 delay 的精度和可控性远高于 PCB 走线PCB 上的蛇形补偿很难精确控制还会引入额外的串扰和回流问题。正确的做法是等长控制做好把精确的 2ns 延迟交给芯片内部的 delay 单元。串阻也是 RGMII 硬件设计里容易忽略的点。RGMII 通常是 3.3V/2.5V/1.8V 的 CMOS 电平或 HSTL 类电平驱动器的输出阻抗一般不高为了减小反射源端串阻通常取 22Ω 到 33Ω。但要注意有些 PHY 芯片内部已经做了阻抗匹配外部再加串阻反而会让信号幅值降低、边沿变缓。拿到新 PHY 时先看数据手册里的 RGMII 接口输出阻抗描述和参考设计再决定加不加、加多大。2.2 MAC 侧的软件修法设备树 phy-mode 详解在 Linux 系统里RGMII 时钟延迟配置首选是通过设备树phy-mode属性来声明。Linux 网络子系统和 PHYLIB 框架定义了几种和 RGMII delay 相关的模式phy-mode含义rgmii不启用任何内部延迟认为时钟和数据通过外部 PCB 走线自然对齐rgmii-id同时启用 TX 和 RX 内部延迟rgmii-txid只启用 TX 方向内部延迟rgmii-rxid只启用 RX 方向内部延迟这个属性的语义是面向MAC 与 PHY 之间的整体延迟分配的但具体行为由两端共同决定。一部分 SoC 的 MAC 驱动会读取这个模式去配置 MAC 内部的时钟延迟寄存器另一部分 SoC 的 MAC 没有内部延迟能力驱动会把模式传递给 PHY 驱动由 PHY 驱动去配置 PHY 芯片的 delay 寄存器还有些情况是 MAC 和 PHY 都具备延迟能力设备树只是告诉两端你们谁也别加或者某一端加。我在实际项目中见过最容易踩的坑就是设备树写的是rgmii-id但内核版本较老MAC 驱动对rgmii-id支持不完整只配置了 TX 方向的延迟PHY 驱动看到rgmii-id后又把 PHY 的 TX/RX delay 也开了。这样 TX 方向被双重延迟RX 方向只靠 PHY 单端延迟最终表现就是ping 通但 iperf 打流大量丢包。所以收到一个开发板的设备树不要直接抄先确认 MAC 驱动源码对四种phy-mode的处理分支再确认 PHY 驱动对PHY_INTERFACE_MODE_RGMII_ID的处理逻辑。除了phy-mode部分 SoC 还支持更精细的延迟量控制。比如 Xilinx Zynq UltraScale 的 GEM 驱动支持tx-internal-delay-ps和rx-internal-delay-ps可以直接指定延迟皮秒数Rockchip 的 gmac 驱动则用tx_delay/rx_delay十六进制编码配合 GRF 寄存器实现细微调节。如果你的板子出现所有组合都试了仍然不稳定很可能就是固定 2ns 延迟不够精确需要用到这类细调接口。2.3 PHY 侧的软件修法寄存器与 PHY 驱动如果说 MAC 侧配置还算是设备树写对就差不多PHY 侧的 delay 配置才是真正五花八门的地方。不同厂商、不同型号的 PHY 芯片delay 控制位的位置、默认值、甚至复位后的行为都不一样。更麻烦的是同一颗 PHY 芯片的不同封装版本或硅版本delay 行为也可能有差异。拿几颗常见的 PHY 举例。Marvell 88E1512 主要通过 MMD 扩展寄存器和标准寄存器配合控制 RGMII delayRealtek RTL8211F 的 RGMII TX/RX delay 控制在寄存器 0x1C 的特定 bitTI DP83867 则有自己的延迟控制寄存器支持以更细的步进调节延迟量并且可以通过 strap 引脚在复位时锁定初始配置。这三颗 PHY 的 delay 寄存器位完全不同没有任何通用写法只能在各自的数据手册里找 RGMII 相关章节。如果你在内核里用的 PHY 驱动比较新通常 PHY 驱动会在config_init阶段根据phydev-interface也就是设备树里的phy-mode自动完成 delay 寄存器配置。比如老牌的 marvell PHY 驱动、realtek 驱动都有类似逻辑。这种情况下设备树phy-mode写对了PHY 侧就不用手动操作。但嵌入式项目里经常遇到一种情况PHY 不在内核 PHY 驱动的默认支持列表里或者厂商只给了裸机寄存器操作代码。这时候就需要在板级代码里手动配置 PHY。我的建议是优先用 Linux 的 mdio-tools 在用户态验证寄存器值确认哪个 bit 能解决问题再写进驱动。直接用 devmem 或者 ioctl 硬怼 PHY 寄存器容易一次写错、来回烧录调试效率很低。2.4 推荐组合与选型时的坑前预警那么在 MAC 和 PHY 之间delay 到底应该放在哪一边我的经验是首版验证时优先PHY 侧开 delay、MAC 侧关 delay。原因有两点一是大部分 PHY 芯片的 RGMII delay 默认值就是为 2ns 设计的和协议推荐值最接近二是很多 SoC MAC 的内部 delay 实际延迟量受 PVT工艺、电压、温度影响较大稳定性往往不如 PHY 内部的 delay 单元。如果把所有可能组合列出来的话大概是这样方案MAC TX delayPHY TX delay效果方案 A关开推荐PHY 的 delay 精度通常更好方案 B开关也可行但需确认 MAC 内部 delay 实际值方案 C开开双重延迟时钟相对数据偏移约 4ns大概率异常方案 D关关完全依赖 PCB 走线只对极短走线可行不推荐另外选 PHY 的时候建议看看它的 delay 默认值和可配置范围。有些低成本 PHY 只支持开/关固定的 2ns 延迟不具备细调能力在 PCB layout 不太理想的情况下会很被动。预算允许的情况下优先选支持延迟细调的 PHY比如 DP83867 这类调试余量会大很多。3. 配置实战从规格书到设备树的全流程3.1 第一步把 PHY 规格书里的 RGMII 章节读透拿到一颗新 PHY配置 delay 之前先花半小时读数据手册重点找这几个关键词RGMII、TX delay、RX delay、Internal delay、Clock skew、RGMII timing。一般数据手册会有一个 RGMII 接口章节里面有两类信息最关键。第一类是功能描述说明这颗 PHY 的 RGMII delay 由哪些 bit 控制、上电默认值是多少、是 strap 引脚决定还是寄存器决定。第二类是时序参数表里面有setup time、hold time、clock to data skew这类数值。这两个信息决定了你在设备树里写rgmii-id还是rgmii-txid决定了要不要在板级代码里额外写 PHY 寄存器。注意一个容易踩的细节同一颗 PHY 芯片可能既有RGMII with internal delay的版本也有RGMII without internal delay的版本后缀不一样配置方式就完全不一样。比如有些 PHY 型号带后缀-Z或不带后缀其内部 delay 能力就不同。不要只看主型号要连后缀一起对清楚。3.2 第二步配置 MAC 端设备树 驱动确认以 Zynq UltraScale 的 GEM Marvell 88E1512 为例。设备树里这样写gem0 { status okay; phy-mode rgmii-id; phy-handle ethernet_phy0; mdio { #address-cells 1; #size-cells 0; ethernet_phy0: ethernet-phy7 { reg 7; device_type ethernet-phy; }; }; };这里phy-mode rgmii-id会让 GEM 驱动去配置 MAC 内部的 TX/RX delay。不过新版本内核和 Xilinx SDK 的驱动行为不完全一样有的驱动里rgmii-id只作为告诉 PHY 驱动去配 delay的信号MAC 侧不动有的驱动里则需要额外写tx-internal-delay-ps和rx-internal-delay-ps来明确延迟量。我在调试 ZynqMP 时遇到过一次设备树只写了rgmii-id但驱动判断需要tx-internal-delay-ps属性才真正写寄存器结果就是 MAC 侧 delay 一直没有生效。所以在改完设备树之后一定要去对应驱动源码里搜rgmii-id和PHY_INTERFACE_MODE_RGMII_ID确认这个平台具体是怎么处理的。PHY 地址7则是根据 PHY 的 strap 引脚确定的。PHY 上电时 AD0/AD1/AD2 这些引脚的电平组合决定 MDIO 地址很多 PHY 默认地址是 0 或 7但也可能是 1、4、8 等。地址不对的话MDIO 通信完全不通设备树改再多 delay 也没用。3.3 第三步配置 PHY 端寄存器操作与驱动验证如果 PHY 驱动没有自动处理 delay或者你想跳过驱动、先确认 PHY 侧的 delay 行为可以用 mdio-tools 直接在用户态操作。假设 PHY 地址是 7寄存器 0x1C 里包含 RGMII delay 控制位可以这样读# 读取 PHY 地址 7、寄存器 0x1C mdio eth0 phy 7 0x1c以 Realtek RTL8211F 为例0x1C 是 RGMII control 寄存器其中 TX delay 和 RX delay 各由不同的 bit 控制。把对应位置 1 后再回读确认写入成功# 假设原值是 0x40现在读出来看 bit 是否变化 mdio eth0 phy 7 0x1c 0x50在开发阶段用这种方式验证 PHY 的 delay 开关对网络稳定性的影响比反复编译内核快得多。确认具体 bit 和值有效后再落地到驱动代码里避免每次都手动敲命令。如果你用的 PHY 驱动已经是新版内核自带且支持这个 PHY那么驱动会根据phy-mode自动配置。这时候反而要注意别双重配置驱动自动配了一遍你自己的板级代码又写了一遍如果两次写反板子会在莫名其妙的时机变得不稳定。3.4 第四步验证配置是否真正生效配置完成后至少做三层验证第一层是寄存器回读。MAC 侧的 delay 寄存器、PHY 侧的 delay 寄存器都要回读确认不能只看配置代码执行了没有。很多芯片的寄存器写入是有条件的比如只有在复位释放后一段时间内可写或者需要先解锁保护位。回读是最直接的证据。第二层是功能验证。先 ping 大包ping -s 1472超过 1472 就需要分片能验证大包路径再到 iperf3 打流看 UDP 丢包率有没有归零。iperf3 的 UDP 打流在 RGMII 这样的源同步接口上比 ping 敏感得多丢包率在千兆线速下能到 0才能说明时钟余量够。第三层是示波器测量。用 500MHz 以上带宽的示波器测 MAC 的 TX_CLK 和 TXD[0] 之间的相位关系。如果 delay 生效时钟沿相对数据跳变沿应该有约 2ns 的偏移如果测出来几乎为 0ns说明延迟没有加上。测量 RX 方向时要在 PHY 的 RX_CLK 和 RXD[0] 上量而不是在 MAC 发射端量。探头地线要短否则地环路会引入额外噪声把本来就小的 2ns 相位差掩盖掉。4. 线上问题排查全链路从心跳不通到稳定复现4.1 第一刀先排除掉伪 RGMII 时序问题遇到 RGMII 通信故障第一件事不是查 delay而是把基础项排除掉。我见过太多人在 delay 配置上折腾几天最后发现 PHY 的复位脚被 CPU 的 GPIO 拉低了或者 MDC/MDIO 引脚根本没有做 pinmux 复用。基础项就这几项MDIO 能不能正常读写 PHY。如果能读出 PHY ID 寄存器说明管理通道已经通了PHY 的 link 状态。ethtool 或 mii-tool 看 speed/duplex 是否正常PHY 复位时序。有些 PHY 需要复位脚保持低电平至少 10ms释放后再等 100ms 才能访问 MDIO参考时钟是否稳定。RGMII 的 TX_CLK 从哪来是 MAC 输出还是 PHY 提供频率和幅值对不对引脚复用是否配置了。很多 SoC 的 RGMII 引脚默认是 GPIObootloader 没初始化的话数据根本出不来这些项目确认完再往时钟延迟方向排查。跳过这一步的代价往往是浪费一整天在错误的维度上反复组合配置。4.2 第二步用 MAC 统计寄存器和环回测试缩小范围如果基础项正常接下来要弄清楚问题出在 TX 方向还是 RX 方向这决定了你去调rgmii-txid还是rgmii-rxid。linux 下可以用 ethtool 的统计接口或者直接读 MAC 的寄存器。重点看这几类错误RX CRC Error接收方向数据采样出错优先怀疑 RX delayTX 方向如果对端一直回包不正常、或者对端看到大量 FCS 错误那是 TX delay 的问题如果 TX/RX 方向同时有错误先看时钟整体质量再考虑是不是两端重复配置环回测试是定位方向的好工具。多数 PHY 支持内部环回模式PHY 内部把 TX 数据直接环回给 RX在 PHY 侧环回能验证 MAC-PHY 这个链路。MAC 侧如果需要也可以用 internal loopback 模式验证 MAC 自身的 RGMII TX/RX 通路。具体做法是设置 PHY 的 loopback 寄存器位然后用 ping 检测。环回通了说明数据面链路没问题环回不通再用示波器量时钟和数据相位看到底是采样窗口跑偏还是电平问题。4.3 第三步寄存器遍历法快速定位 delay 组合当你怀疑 delay 配置有问题但又不确定具体是哪一端没生效时推荐用寄存器遍历法把设备树phy-mode在rgmii、rgmii-id、rgmii-txid、rgmii-rxid之间切换每种模式跑一次打流测试对比结果。这个是排查 delay 问题最高效的方法。通常你会发现某一种模式下完全不通另一种模式下丢包率降到 0两种模式都通但一种模式下 CRC 错误持续增长我曾经处理过一个 FPGA 平台的问题设备树写的是rgmii-id但 FPGA 厂商的 MAC 驱动根本没有实现对这个模式的处理实际寄存器里 delay 位一直是 0。切换模式后发现所有模式表现一模一样才意识到 MAC 驱动是个空壳真正起作用的只有 PHY 侧的寄存器。后来直接在板级代码里给 PHY 写死 delay 配置问题才解决。另一个经典案例就是开头提到的MAC 和 PHY 同时开 TX delay。现象是能 link、偶尔通、CRC 错误多示波器测量发现时钟比数据超前约 4ns明显是 22 的叠加。把 MAC 侧 delay 关掉只保留 PHY 侧 delay问题立刻消失。这种双重配置发生的原因往往是设备树写了rgmii-txid而 PHY 驱动默认就在config_init里打开了自身 delay两边都不知道对方做了什么。4.4 边界情况千兆、百兆与高低温漂移RGMII 时钟延迟的敏感度和速率强相关。千兆模式下时钟周期是 8ns数据窗口只有 2ns 左右对 delay 极其敏感百兆模式下时钟周期变成 40ns数据窗口宽裕得多2ns 的偏差根本不算什么。所以百兆正常、千兆不通是 RGMII delay 配置异常的典型指标。反过来也有一种情况千兆勉强能通百兆反而持续报错。这时候问题往往不在 delay而在 MAC 或 PHY 对百兆模式下 RGMII 时钟的处理。有些 SoC 在切到百兆时需要改变 TX_CLK 的频率来源或分频系数配置没跟上就会导致百兆模式时钟异常。查这种问题不要死磕 delay先把时钟树和 PHY 的 100M speed 配置捋一遍。高低温变化会让 delay 问题从隐性变成显性。芯片内部的 delay 单元受温度影响明显PCB 走线延迟也会随温度轻微变化。常温下采样窗口余量可能还有 500ps到 85°C 就只剩 100ps 甚至归零这时就出现高低温测试中的随机丢包。所以验证 RGMII 稳定性一定要安排高低温循环测试只做常温验证等于没有验证。5. 不同硬件组合的特别提醒FPGA、SoC 与 PHY 的搭配细节5.1 SoC MAC 外置 PHY配置接口千差万别同样是 SoC 的 MAC 接外置 PHY不同厂商的 delay 配置接口完全不一样。Zynq 系列用phy-mode加tx-internal-delay-ps/rx-internal-delay-psNXP i.MX 系主要靠设备树phy-mode配合 FEC 驱动内部处理Rockchip 的 gmac 设备树里常见tx_delay 0x26这种编码值需要查 TRM 确认编码和实际延迟量的对应关系全志的 EMAC 驱动则用allwinner,tx-delay-ps这类厂商私有属性。从调试角度我特别想提醒 Rockchip 平台的读者tx_delay和rx_delay的值不是随便填的它对应 GRF 寄存器里的一段区域编码和延迟时间有确定但非线性的关系。有人从某篇博客抄了0x26和0x1b到自己的板子上结果问题依旧因为不同 PHY 需要的最佳延迟值根本不一样。拿到平台后先找到 TRM 中 delay 编码表再结合示波器测量来选值不要盲抄。不同 SoC 的设备树属性名各不相同内核版本升级后还可能出现兼容性变化最好以源码中的device tree binding文档为准。5.2 FPGA PHY时序约束才是主战场FPGA 做 MAC 接外置 PHY 时delay 配置的责任不完全在寄存器更多在 FPGA 工程的时序约束上。RGMII 是源同步 DDR 接口在 FPGA 里使用 IDELAY 或 ODELAY 原语来补偿数据与时钟的关系。比如 Xilinx 7 系列里常用的做法是RX 方向把 RXD 和 RX_CTL 经过 IDELAY延迟值通常设到约 2ns让数据相对 RX_CLK 中心对齐TX 方向用 OSERDES 的 DDR 输出再配合 ODELAY 调整输出数据与 TX_CLK 的相位关系。时序约束上需要给 RGMII 的输入和输出分别做约束。重点是可用的 Vivado 或 Quartus 参考设计。Vivado 里 Xilinx 官方提供 Zynq-7000 和 7 系列的 RGMII 参考设计包含完整的约束文件Intel 有个 AN-477 应用笔记专门讲源同步接口的时序分析里面就有 RGMII 的set_input_delay/set_output_delay示例。这些资料比自己在网上搜碎片化教程靠谱得多。FPGA 调试还有一个特殊优势delay 值可以做成可调的寄存器接口在上位机里在线调整。我在 FPGA 方案里习惯把 RX delay 做成 32 级可调调试时通过串口或者 JTAG 实时改延迟值观察哪种组合下错误计数归零确定后再固定下来。这个手段在 SoC 方案里很难实现属于 FPGA 红利。5.3 电压型、电流型 PHY 与接口电平匹配热搜里有个词是电压型和电流型 PHY这个维度和时钟 delay 是两个独立的问题但处理不当也会表现为类似的现象。简单说PHY 的 RGMII 输出驱动器实现方式分两类一类是电压型推挽输出输出高低电平由内部电源轨决定外接串阻和端接相对简单另一类是电流型输出内部用电流源驱动对输出端接网络有明确要求通常需要在引脚外部加偏置或端接电阻才能获得标准的摆幅和共模电平。如果硬件设计师把电流型 PHY 当电压型 PHY 处理省了端接电阻RGMII 信号幅度可能只有正常值的 60%接收端判决器在大部分时间内处于亚稳态区间表现出来就是随机 CRC 错误、误码、偶发丢包和时钟 delay 问题非常像。排查手段也很简单用示波器量 RGMII 引脚波形看高电平是不是足够高、信号边沿是否在噪声中抖动。如果波形质量很差先修硬件再调 delay因为 delay 配得再好也救不了烂信号。另一个常见坑是 MAC 和 PHY 的电平域不匹配。有的 SoC RGMII 引脚是 1.8VPHY 却是 3.3V中间没有做电平转换或者只是简单串阻分压。这种情况在长时间运行后特别容易出间歇性故障。选型阶段就要把 MAC 引脚的电平能力和 PHY RGMII 引脚的电平要求对齐不要指望软件能绕过。5.4 引脚复用、strap 引脚和参考时钟的隐性坑最后提醒几个容易被忽略的隐性配置项。第一是 pinmux。不少 SoC 的 RGMII 信号引脚和 GPIO、CAN、UART 等功能复用。bootloader 里只初始化了核心板需要的外设没有给 MAC 做 pinmux 配置或者 pinmux 配置了但电压域没有切换RGMII 信号就是出不来。这种问题光看设备树 phy-mode 是找不出原因的要看芯片 reference manual 的 IOMUX 章节。第二是 PHY 的 strap 引脚。很多 PHY 在上电复位时会锁存 bootstrap 引脚这些引脚决定了 PHY 的默认寄存器值包括 delay 是否开启、PHY 地址、接口模式等。软件后续可以通过 MDIO 覆盖这些默认值但如果 PHY 的 strap 电平设计有问题——比如本该拉高的引脚被错误地拉低——软件无论如何配置 delay行为都可能和预期相反。遇到寄存器回读明明设置了但现象没改善的情况去查 strap 引脚的电平。硬件设计时还要注意 strap 引脚不能和 PHY 的其它外设共用一个强上拉/下拉否则上电顺序稍微一变PHY 配置就锁存成不同状态。第三是参考时钟来源。RGMII 的 TX_CLK 通常由 MAC 提供但有些平台允许配置成由 PHY 反馈或外部时钟输入。设备树里像 Rockchip 的clock_in_out input或output就控制这一点。配置不对时PHY 的 link 可能正常但数据通路上完全没有时钟表现为 MAC 发出去的数据对端永远收不到。这种问题很隐蔽因为 link 状态是好的排查时会绕很大一圈。6. 沉淀下来的避坑清单与调试建议6.1 常见问题速查表把 RGMII 时钟延迟和周边相关的问题整理成一张表方便在现场快速对照现象最常见原因优先处理动作完全不通、MDIO 也不通PHY 复位、电源、strap 地址不对确认 strap、复位时序、MDC/MDIO 上拉link 正常但 ping 不通RGMII delay 配置错误或不匹配切换 phy-mode 四种模式对比ping 小包通、打流丢包采样窗口余量不足用示波器量相位微调 delay 值大量 RX CRC ErrorRX delay 缺失或双重延迟回读两端 delay 寄存器确认单端配置百兆正常、千兆不通千兆时钟窗口敏感delay 偏移重点检查 TX/RX delay 和信号质量高温失效、常温正常delay 值余量不足温度漂移增加 delay 或换支持细调的 PHYCRC 间歇性出现、波形很差电平失配、端接错误、电源纹波先修硬件信号质量再调 delay6.2 项目前期就该做的验证项RGMII delay 问题大部分可以在项目早期就避免不需要等到板子回来再排查。原理图阶段就要确认三件事第一PHY 的 RGMII delay 控制方式是 strap、寄存器还是两者都支持strap 引脚在原理图上是如何接的。第二MAC 侧是否支持内部 delay设备树规划用哪个phy-mode。第三RGMII 信号组电平域是否匹配端接方式是否符合 PHY 数据手册要求。Layout 完成后对照 PHY 厂商的参考设计检查一遍 RGMII 走线等长是否收敛、参考平面是否完整、有没有跨越分割槽。信号完整性上RGMII 的时钟线不要走内层换层太多过孔会引入额外延迟和不连续阻抗。Bring-up 阶段按顺序来先调通 MDIO 读 PHY ID再看 link 状态然后在最简单配置比如只有 MAC 和 PHY 短距离直连下验证 RGMII 通信最后再接变压器和 RJ45。网络上有一个环节不通过别为了方便直接跳过否则后面所有测试结果都不可信。6.3 现场调试的三条实用经验最后分享三条我自己的习惯都是在实际项目里被验证过的。第一条调试 RGMII 时维护一张 delay 配置记录表至少记录四列MAC 侧配置、PHY 侧配置、PCB 走线长度差、实测结果。每次组合都记录在案不要靠脑子记。我吃过亏同一块板子上午测 A 组合丢包下午测 B 组合正常晚上又发现电源噪声影响复现不记录就会浪费大量时间重复验证。第二条修改设备树phy-mode后不要只跑一次 ping 就算验证完成要跑至少五分钟的 iperf UDP 双向打流。RGMII 的采样余量不足时错误是概率性的短时间测试可能完全正常。我习惯用iperf3 -u -b 900M -t 300这类接近线速的长时打流来压测能在短时间内把采样窗口边缘的问题逼出来。第三条示波器测量时注意测量点位置。TX 方向在 MAC 引脚附近量RX 方向在 PHY 引脚附近量并且用差分探头或短地弹簧探头别用长接地夹。2ns 的相位差在普通探头下很容易被噪声淹没量出来的结果会误导调试方向。有条件的话把示波器的采样率开到 5GS/s 以上测量时钟上升沿和数据跳变沿的时间差多测几组取平均再判断 delay 的方向和大小。RGMII 时钟延迟配置说难也难说简单也简单。难在它牵扯 MAC 驱动、PHY 寄存器、设备树、PCB 走线、参考时钟多个维度任何一个环节不一致表象都是同一个简单在只要理解了延迟只能单端补、目标是采样窗口中心对齐这个核心原则再按本文的步骤逐项验证大部分问题都能在一个小时内定位。下次再遇到时通时不通的板子先别急着怀疑人品拿起示波器量一下时钟和数据的相位差多半答案就在那里。
返回列表