news 2026/9/28 19:50:08

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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.8V,XDC 里写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.17V(1.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.8V,PL 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 侧已经做了 delay,PHY 侧就不需要再加。这个配合关系要在调试时确认,否则即使电平对了,时序也可能不满足。

我一般会先用示波器看 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不匹配,可能损坏 PHY
2.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.8V,EMIO 出来就是 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,不要依赖自动分配。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 19:49:40

卷积神经网络实现红外图像非均匀性校正:从原理到Python实战

简介&#xff1a;面向毕设项目、课程设计、大作业与工程实训场景&#xff0c;交付一套基于卷积神经网络的红外图像非均匀性校正完整方案。针对红外焦平面阵列输出中常见的条纹与固定图案噪声&#xff0c;方案采用两个残差块级联的残差学习结构&#xff08;RNUC&#xff09;&…

作者头像 李华
网站建设 2026/9/28 19:49:38

基于CNN的红外图像非均匀性校正:条纹消除实战指南

简介&#xff1a;基于Python与卷积神经网络的红外图像非均匀性校正毕业设计&#xff0c;聚焦红外图像中的非均匀性噪声问题&#xff0c;提出一种命名为RNUC的残差学习校正网络&#xff0c;通过级联两个残差块并配合合并式特征提取单元&#xff0c;实现端到端的校正处理。资源面…

作者头像 李华
网站建设 2026/9/28 19:49:06

OpenClaw Windows Node 实战:用 TaoToken 统一 Key 打通 AI Agent 配置链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 19:47:45

ONVIF与GB28181多语言协议栈发版:onvif-go v2迁移与设备侧收官

1. 五个协议库同天发版的背后逻辑1.1 为什么协议库扎堆发版不是巧合做视频监控和安防设备接入的同行应该都有感觉&#xff0c;ONVIF 和 GB28181 这两个协议栈的维护工作&#xff0c;平时是细水长流&#xff0c;但一到版本节点就容易扎堆。这次五个库同天发版&#xff0c;表面上…

作者头像 李华