ARTICLE DETAIL

资讯详情

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

ZYNQ PS-MAC通过EMIO扩展RGMII网口:电平标准不匹配的排查与解决

ZYNQ PS-MAC通过EMIO扩展RGMII网口:电平标准不匹配的排查与解决 1. 问题现场网口死活不通数据全是乱码ZYNQ 平台上用 PS 端 MAC 控制器通过 PL 侧的 EMIO 把 RGMII 信号引到外部 PHY结果网口数据异常——要么链路起不来要么能协商但丢包严重要么收到的全是错帧。这个场景在 ZYNQ 开发里其实非常典型尤其是当你第一次尝试把 PS 的千兆网口通过 EMIO 绕到 PL 引脚上时。我遇到这个问题的时候第一反应是查约束、查时钟、查 PHY 配置折腾了大半天最后发现根因特别朴素RGMII 的 IO 电平标准给错了。PS 侧 MIO Bank 的电平和 PL 侧 Bank 的电平是两套独立的供电域EMIO 把信号从 PS 引到 PL 之后信号的实际电平由 PL Bank 的 VCCO 决定而不是 PS 侧。如果你在约束文件里给 RGMII 引脚指定的 IOSTANDARD 和实际 Bank 供电电压不匹配信号幅度就会出问题轻则时序裕量不够重则 PHY 根本识别不了。这篇文章适合正在用 ZYNQ 做网口扩展、或者准备用 EMIO 把 PS 外设引到 PL 的开发者。不管你是刚上手 ZYNQ 的新手还是做过几个项目但没深究过电平细节的老手这里面的排查思路和实操方法都能直接拿去用。我会把整个问题的来龙去脉、电平标准的底层逻辑、约束文件的正确写法、以及我踩过的坑全部摊开讲清楚。2. 先搞清楚 PS-MAC PL-EMIO 这条链路到底怎么走2.1 PS 端 MAC 和 EMIO 的关系ZYNQ 的 PS 端自带两个千兆以太网 MAC 控制器通常叫 GEM0 和 GEM1。这两个 MAC 的引脚可以走两条路一条是直接通过 MIO 引到芯片外部引脚另一条是通过 EMIO 绕到 PL 侧再从 PL 的 IO 引出去。走 MIO 的时候引脚的电平标准由 MIO Bank 的供电决定一般是 1.8V 或 3.3V这个在 Vivado 的 PS 配置里选好就行不太容易出错。但走 EMIO 就不一样了。EMIO 本质上是 PS 和 PL 之间的一条内部信号通道它把 PS 的 MAC 信号送到 PL 的逻辑资源里然后你需要把这些信号再分配到 PL 的 IO 引脚上。关键点来了信号一旦到了 PL 侧它的电平标准就由 PL Bank 的 VCCO 决定了跟 PS 侧 MIO 的供电没有直接关系。很多人在这里会想当然地以为“PS 配了 1.8V那 EMIO 出来的也是 1.8V”这个理解是错的。RGMII 接口本身需要的信号包括TXC、TXD[3:0]、TX_CTL、RXC、RXD[3:0]、RX_CTL另外还有 MDC、MDIO 用于管理。千兆模式下TXC 和 RXC 是 125MHz 的时钟数据在时钟的上下沿都采样所以实际数据率是 125M × 2 × 4bit 1000Mbps。这个时序对电平质量和走线延迟非常敏感电平给错了时序直接就崩了。2.2 EMIO 引出后电平由谁决定这里必须把逻辑理清楚。PS 侧的 MAC 控制器输出的是数字逻辑信号它在 PS 内部工作。当这些信号通过 EMIO 进入 PL 时PL 侧接收到的是一组逻辑电平这组逻辑电平的参考电压取决于 PL Bank 的 VCCO。也就是说你在 PL 侧约束文件里给这些引脚写的 IOSTANDARD必须和该 Bank 实际焊接的 VCCO 电压一致。举个例子如果你的 PL Bank 供电是 3.3V但你在 XDC 里给 RGMII 引脚写了IOSTANDARD LVCMOS18那 Vivado 在实现时就会按 1.8V 的标准去驱动这些引脚。实际输出电压会试图往 1.8V 的 VIH 靠但 Bank 供电是 3.3V这会导致输出电平异常——可能高电平不够高可能低电平不够低也可能上下冲严重。PHY 那边看到的信号质量一塌糊涂自然就出问题了。反过来说如果 Bank 供电是 1.8V你写了LVCMOS33那更危险因为 3.3V 的驱动标准在 1.8V 供电下根本达不到输出幅度会严重不足。所以这个匹配关系是硬性的不能拍脑袋。2.3 RGMII 电平标准的基本要求RGMII 规范里信号电平通常是 1.8V 或 2.5V 的 LVCMOS具体取决于 PHY 芯片的 VDDIO 供电。常见的千兆 PHY比如 Realtek RTL8211 系列、Marvell 88E1512 等它们的 RGMII 接口 VDDIO 可以配成 1.8V、2.5V 或 3.3V但大多数设计里为了兼顾功耗和时序会选 1.8V。这时候你的 PL Bank VCCO 也必须是 1.8VXDC 里写LVCMOS18三者一致才行。有些开发板为了兼容多种外设PL Bank 会分成好几个每个 Bank 的 VCCO 可以独立供电。你接线的时候一定要确认 RGMII 信号落在哪个 Bank那个 Bank 的 VCCO 实际接了多少伏。我见过有人把 RGMII 信号分配到 Bank 34结果 Bank 34 的 VCCO 接的是 3.3V但 PHY 那边是 1.8V 的 VDDIO两边电平不匹配信号直接过不去。3. 电平标准给错之后现象为什么这么诡异3.1 链路协商阶段的异常表现电平不对的时候最先出问题的往往是链路协商。PHY 和 MAC 之间通过 RGMII 传数据之前要先建立链路。如果 TXC 或者 RXC 的时钟信号电平不对PHY 可能根本检测不到有效的时钟链路就起不来。你会在ethtool里看到Link detected: no或者dmesg里反复打印eth0: Link is Down。还有一种情况是链路能起来但速率协商错误。比如千兆协商成千兆但因为电平裕量不够实际跑起来丢包率极高。你用ping测试可能前几个包能通后面就开始大量超时。这种间歇性故障最折磨人因为你会怀疑是驱动问题、是 PHY 配置问题、是时钟问题唯独容易忽略电平。3.2 数据帧错误的典型特征电平问题导致的数据错误有几个典型特征。第一错帧率高但并非全错因为电平不是完全不可用只是裕量不够某些比特位偶尔会翻转。第二错误往往集中在特定数据模式上比如连续多个 1 或者连续多个 0 的时候更容易出错因为电平的上升沿和下降沿质量差。第三温度变化或者电源波动时错误率会明显变化因为电平裕量本来就小外界干扰一放大就崩了。我在调试的时候用 ILA 抓过 RGMII 的 TXD 信号发现高电平只有 1.2V 左右而 PHY 的 VIH 最小值是 1.17V1.8V 供电时理论上勉强够但实际上因为过冲和振铃有效窗口很窄。这种“看起来能用但实际不稳”的状态就是电平给错的典型后果。3.3 为什么容易误判为时序问题RGMII 本身对时序要求很严尤其是千兆模式下TXC 和数据的 skew 要控制在很小范围内。所以一旦网口出问题大家第一反应往往是查时序约束、查 IDDR 配置、查 clock delay。我一开始也是这个思路在 XDC 里反复调set_input_delay和set_output_delay结果怎么调都不对。后来才意识到时序约束是建立在电平正确的前提下的。如果电平本身就不对信号的边沿位置和幅度都变了你再怎么调延迟参数都是在错误的基础上修修补补。所以排查顺序应该是先确认电平标准和供电匹配再查时序约束最后调 PHY 的 delay 参数。这个顺序搞反了就会浪费大量时间。4. 一步步排查从供电到约束的完整检查链4.1 确认 PL Bank 的实际供电电压第一步拿万用表量。不要看原理图上写的要看实际板子上那个 Bank 的 VCCO 引脚接了多少伏。有些开发板有跳线帽可以选择 Bank 电压出厂默认可能和原理图标注不一致。我遇到过一块板子原理图上写 Bank 34 是 1.8V但跳线帽实际接在 3.3V 档位上量出来就是 3.3V。量的时候要注意VCCO 引脚通常在 BGA 封装的下方不好直接量。你可以找该 Bank 的任意一个 IO 引脚配置成输出高电平然后量那个引脚对地的电压。如果输出高电平接近 VCCO说明供电正常如果明显偏低可能是 Bank 供电有问题。4.2 核对 XDC 中的 IOSTANDARD 设置第二步打开 Vivado 的 XDC 文件找到 RGMII 相关的引脚约束。每一行set_property IOSTANDARD都要和实际 Bank 供电对照。比如set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_txc}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_txd[0]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_txd[1]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_txd[2]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_txd[3]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_tx_ctl}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rxc}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rxd[0]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rxd[1]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rxd[2]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rxd[3]}] set_property IOSTANDARD LVCMOS18 [get_ports {eth_rgmii_rx_ctl}]如果 Bank 供电是 1.8V这些写LVCMOS18是对的。如果供电是 2.5V要改成LVCMOS25如果是 3.3V改成LVCMOS33。注意RGMII 一般不用LVTTL虽然LVTTL和LVCMOS33在 3.3V 下电气特性接近但规范上还是用LVCMOS系列更稳妥。4.3 检查 PHY 侧的 VDDIO 供电第三步确认 PHY 芯片的 RGMII 接口 VDDIO 是多少伏。这个信息在 PHY 的数据手册里通常有一个专门的引脚叫VDDIO或者DVDDIO。有些 PHY 支持多种电压通过引脚配置或者寄存器设置来选择。你要确保 PHY 的 VDDIO 和 PL Bank 的 VCCO 一致否则两边电平标准不同信号无法正确识别。比如 PHY 的 VDDIO 是 1.8VPL Bank 是 3.3V那 MAC 输出的 3.3V 信号加到 PHY 的 1.8V 输入引脚上可能超过 PHY 的绝对最大额定值长期运行会损坏 PHY。反过来PHY 输出 1.8V 信号给 PL 的 3.3V 输入PL 可能识别不到高电平因为 1.8V 达不到 3.3V LVCMOS 的 VIH 最小值通常是 0.7×VCCO 2.31V。4.4 用 ILA 实测信号质量第四步如果条件允许用 Vivado 的 ILA 抓一下 RGMII 信号。ILA 可以抓 PL 内部的信号也就是 EMIO 出来之后、到达 IO 引脚之前的信号。这个信号的电平是 PL 内部逻辑电平通常是 VCCO 域的逻辑值但你可以通过观察它的跳变和占空比来判断时序是否正常。不过 ILA 抓的是数字逻辑值看不到模拟的电平幅度。要看实际电平质量还是得用示波器。把探头接到 RGMII 的 TXC 或者 TXD 引脚上看高电平幅度、低电平幅度、上升沿时间、过冲和振铃。如果高电平明显低于 VCCO或者上升沿很缓那就是电平标准或者驱动能力的问题。5. 正确配置 RGMII 电平的完整实操5.1 Vivado 中 PS 端 GEM 的 EMIO 配置在 Vivado 的 Block Design 里双击 ZYNQ Processing System进入 PS 配置。找到Peripheral I/O Pins或者MIO Configuration在里面使能 GEM0 或 GEM1。关键一步是选择EMIO而不是MIO。选 EMIO 之后GEM 的 RGMII 信号会出现在 PS 的 EMIO 接口上你需要把这些信号引出到 PL 的顶层端口。具体操作是在 PS 配置界面里找到GEM0或者GEM1把GMII/MII to RGMII的选项勾上然后把MDIO也配上。然后在EMIO分类里你会看到GEM0的 RGMII 信号列表包括GEM0_RGMII_TXD、GEM0_RGMII_TXC等等。这些信号默认是内部信号你需要把它们 Make External变成顶层端口。5.2 顶层端口命名与 XDC 约束编写Make External 之后Vivado 会自动生成端口名比如GEM0_rgmii_txd[0]。你可以改成自己习惯的名字比如eth_rgmii_txd[0]。改完之后在 XDC 文件里给这些端口指定引脚位置和 IOSTANDARD。引脚位置根据你的原理图来比如 TXC 接在 PL 的某个引脚上就写set_property PACKAGE_PIN pin [get_ports eth_rgmii_txc]。IOSTANDARD 根据 Bank 供电来1.8V 就写LVCMOS18。这里有个细节RGMII 的时钟信号建议加上SLEW和DRIVE属性控制边沿速率和驱动电流。比如set_property IOSTANDARD LVCMOS18 [get_ports eth_rgmii_txc] set_property SLEW FAST [get_ports eth_rgmii_txc] set_property DRIVE 8 [get_ports eth_rgmii_txc]SLEW FAST让边沿更陡适合高速信号DRIVE 8表示驱动电流 8mA对于 RGMII 这种 125MHz 的信号8mA 通常够用如果走线较长可以加到 12mA。但驱动电流越大过冲和振铃也越严重所以要权衡。5.3 时钟约束与时序收敛RGMII 的时序约束是另一个关键点。千兆模式下TXC 是 125MHz数据在上下沿采样。你需要创建时钟约束create_clock -name rgmii_txc -period 8.000 [get_ports eth_rgmii_txc]8ns 周期对应 125MHz。然后设置输出延迟set_output_delay -clock rgmii_txc -max 1.0 [get_ports {eth_rgmii_txd[*] eth_rgmii_tx_ctl}] set_output_delay -clock rgmii_txc -min -1.0 [get_ports {eth_rgmii_txd[*] eth_rgmii_tx_ctl}]具体数值要根据 PHY 的建立保持时间要求和 PCB 走线延迟来算。一般 PHY 的数据手册会给出 RGMII 的时序参数比如建立时间 1.0ns、保持时间 0.5ns 之类的。你要把这些参数和 PCB 延迟一起考虑算出合适的 output delay。对于接收方向RXC 是 PHY 送过来的时钟你需要用create_clock创建然后设置set_input_delay。接收方向通常还需要在 PS 端或者 PL 端做 IDDR 采样把双沿数据转成单沿数据。ZYNQ 的 PS 端 GEM 控制器内部已经处理了 RGMII 的双沿采样所以你不需要在 PL 里额外写 IDDR只要把信号正确引到 PS 的 EMIO 接口就行。5.4 PHY 侧 delay 参数的配合调整RGMII 有一个经典问题TXC 和数据之间的 skew 需要控制。PHY 芯片通常内置了 delay 功能可以通过寄存器配置或者引脚 strapping 来调整。比如 Realtek RTL8211 可以通过寄存器 0x1C 来设置 TX delay 和 RX delay。如果 MAC 侧输出的 TXC 和数据是对齐的skew 为 0那 PHY 侧通常需要开启 RX delay把 RXC 延迟 2ns 左右让数据在时钟中间被采样。反过来如果 MAC 侧已经做了 delayPHY 侧就不需要再加。这个配合关系要在调试时确认否则即使电平对了时序也可能不满足。我一般会先用示波器看 TXC 和 TXD 的相位关系确认 MAC 侧输出的 skew 是多少然后决定 PHY 侧要不要开 delay。如果示波器不方便也可以通过读 PHY 的寄存器或者用 ILA 抓内部信号来间接判断。6. 常见问题速查与避坑经验6.1 电平标准匹配速查表PL Bank VCCOPHY VDDIOXDC IOSTANDARD是否匹配1.8V1.8VLVCMOS18匹配2.5V2.5VLVCMOS25匹配3.3V3.3VLVCMOS33匹配1.8V3.3VLVCMOS18不匹配PHY 可能识别不到高电平3.3V1.8VLVCMOS33不匹配可能损坏 PHY2.5V1.8VLVCMOS25不匹配电平过高1.8V2.5VLVCMOS18不匹配电平偏低这张表建议在调试前先对照一遍把不匹配的组合排除掉。6.2 常见问题与排查方法问题一链路起不来ethtool显示 Link Down。排查顺序先量 PL Bank VCCO 和 PHY VDDIO 是否一致再查 XDC 的 IOSTANDARD 是否和 VCCO 匹配然后查 TXC 是否有 125MHz 时钟输出用示波器或者频率计量最后查 PHY 的复位和配置引脚是否正常。问题二链路能起来但丢包严重。排查顺序先看电平幅度是否足够用示波器量高电平和低电平再查时序约束是否收敛看 Vivado 的 timing report然后查 PHY 的 delay 配置是否合适最后查 PCB 走线是否等长RGMII 的时钟和数据走线偏差要控制在很小范围内。问题三接收方向正常但发送方向异常。排查顺序先确认 TXC 和 TXD 的相位关系再查 PHY 的 TX delay 配置然后查 MAC 侧的 output delay 约束最后查 PHY 的发送使能信号是否正常。问题四温度升高后网口不稳定。排查顺序先量电平裕量看高电平和低电平是否接近阈值再查电源纹波VCCO 和 PHY VDDIO 的纹波要控制在几十毫伏以内然后查散热PHY 温度过高会导致内部延迟变化最后考虑降低驱动电流或者调整 slew rate。6.3 我踩过的坑第一个坑以为 PS 配了 1.8VEMIO 出来就是 1.8V。实际上 EMIO 只是内部信号通道到了 PL 侧电平由 PL Bank VCCO 决定。这个理解偏差让我在约束文件里写错了 IOSTANDARD折腾了很久。第二个坑只看原理图不看实物。原理图上写 Bank 34 是 1.8V但板子上跳线帽接在 3.3V实际量出来是 3.3V。后来养成习惯每次调试前先拿万用表量一遍关键供电。第三个坑时序约束调了半天结果电平是错的。时序约束是在电平正确的前提下才有意义电平不对的时候边沿位置和幅度都变了调延迟参数是白费功夫。所以排查顺序一定要先电平后时序。第四个坑忽略了 PHY 的 delay 配置。MAC 侧和 PHY 侧的 delay 要配合如果两边都开或者都不开可能导致采样点落在数据跳变沿上。我一般会先用示波器确认相位关系再决定 PHY 侧怎么配。6.4 实操心得调试 RGMII 的时候我习惯先做一个最简单的回环测试。把 TXD 和 RXD 短接TXC 和 RXC 短接然后让 MAC 发送数据看能不能收到。这个测试可以排除 PHY 的问题直接验证 MAC 和 PL 侧的电平、时序是否正确。如果回环能通说明 MAC 和 PL 侧没问题问题在 PHY 或者 PCB如果回环不通说明 MAC 或者 PL 侧还有问题。另外Vivado 的 timing report 一定要看。即使电平对了如果时序不收敛网口也会出问题。重点看set_output_delay和set_input_delay的 slack 是否为正如果为负说明时序不满足需要调整约束或者优化逻辑。还有一点RGMII 的 PCB 走线要尽量等长尤其是 TXC 和 TXD 之间、RXC 和 RXD 之间。偏差控制在 5mil 以内比较稳妥。如果走线偏差太大即使电平对了时序也会出问题。这个在画板子的时候就要注意后期调试很难补救。7. 最后再分享几个实用技巧如果你用的是 Xilinx 官方的 ZYNQ 开发板比如 ZC702 或者 ZC706它们的 PS 端 GEM 通常走 MIO 到板载 PHY不需要 EMIO。但如果你要扩展第二个网口或者板载 PHY 坏了想外接一个那就得走 EMIO。这时候电平匹配就是第一道坎。对于 PHY 的选择我建议选那些 VDDIO 支持 1.8V 的型号因为 1.8V 的电平在 PL Bank 上更容易实现功耗也低。3.3V 的 RGMII 虽然也能用但高速信号在 3.3V 下过冲和振铃更严重时序裕量更小。还有一个小技巧在 XDC 里给 RGMII 信号加上IBUF或者OBUF的约束确保 Vivado 正确推断 IO 缓冲。有时候 Vivado 会自动推断但显式指定更稳妥。比如set_property IOB TRUE [get_ports {eth_rgmii_txd[*]}]IOB TRUE会把寄存器放到 IO 单元里减少时钟到输出的延迟对时序收敛有帮助。但这个也要看具体情况不是所有设计都适合。最后如果你在调试过程中发现电平怎么都对不上不妨检查一下 EMIO 的约束是否正确。有时候 Vivado 会自动给 EMIO 信号分配引脚如果你没有手动约束它可能分配到错误的 Bank 上。所以一定要在 XDC 里显式指定每个 RGMII 信号的 PACKAGE_PIN 和 IOSTANDARD不要依赖自动分配。
返回列表