简介:面向FPGA、嵌入式硬件工程师与以太网接口设计者的YT8521S硬件电路设计参考图,聚焦RGMII转SGMII这一常见接口转换场景,帮助读者在LS2K1000平台与XC7VX690T FPGA之间快速搭建稳定的PHY电路。资源包仅含1个PDF文件,约193KB,以原理图形式集中呈现CPU、PHY与FPGA三方的连接关系、功能与电压配置细节。图中涵盖复位信号由CPLD控制或RC电路控制的两种方案、3.3V上拉建议,以及smi_sds_phy配置SDS模式、mode_sel设为3'b101(SGMAC_TO_RGPHY)等关键软件配置要点,并附电源滤波与布局走线示意。该电路已通过实际生产测试,可作为设计核对与故障排查的参照,减少调试弯路。目前已有1573人学习下载,适合需要快速验证RGMII转SGMII链路的硬件开发者参考。
1. 拿到 YT8521S 参考图先别急着画板:RGMII 转 SGMII 到底卡在哪
一块板子上同时挂着 LS2K1000、XC7VX690T 和 YT8521S,最容易翻车的不是电源,而是 PHY 这颗小芯片的接口模式配错。YT8521S 是裕太微电子的一颗千兆 PHY,核心价值在于能把 MAC 侧的 RGMII 信号转成 SGMII 送出去,让只支持 RGMII 的 CPU 或 FPGA 也能接光模块、接背板。这份硬件电路设计参考图把 LS2K1000 部分原理图、YT8521S 功能与电压配置、XC7VX690T 部分原理图放在一起,还带了复位控制和 LED 配置细节,属于能直接照着落板子的资料。适合正在做国产化网络接口、需要 RGMII 与 SGMII 互转的硬件工程师和驱动工程师,新手能顺着图走线,熟手能对着配置位核对边界。
2. 拆开参考图看门道:三颗芯片怎么协同
2.1 LS2K1000 侧 RGMII 的引脚与时钟关系
参考图里 LS2K1000 的 GMAC 走的是标准 RGMII:TXD[3:0]、RXD[3:0]、TX_CTL、RX_CTL 各四根数据线加控制线,时钟分 TXC 和 RXC 两路。RGMII 在千兆模式下是双沿采样,125MHz 时钟上下沿各传一次,所以布线上对等长和参考平面的要求比 SGMII 高得多。图里把 RGMII1_TXC、RGMII1_RXC 单独拉出来,并在 PHY 侧标注了延时调整,这一点很关键——LS2K1000 的 GMAC 输出时钟和 PHY 期望的采样窗口不一定对齐,常见做法是靠 PHY 内部的延时单元补,而不是在 PCB 上绕等长线硬凑。
从图上看,RGMII 这组信号全部挂在 DVDD_RGMII_G1 这个电源域下,而该域被配置成 3.3V。这里有个容易忽略的点:LS2K1000 的 GMAC 电压是 3.3V,YT8521S 的 RGMII 侧 IO 电压必须跟着匹配,否则电平不兼容会直接导致链路起不来。参考图通过 CFG_LDO[1:0]=2b00 把 DVDD_RGMII 定在 3.3V,这个配置位和电源域是一一对应的,改一个就得回头核对另一个。
2.2 YT8521S 的功能配置位与电压域
YT8521S 的灵活性全在几个配置引脚上,参考图把它们标得很清楚。CFG_LDO[1:0] 决定内部 LDO 输出和 RGMII IO 电压,2b00 对应 DVDD_RGMII=3.3V;LED1/CFG_LDO0、LED2/CFG_LDO1 这些引脚在上电瞬间是配置脚,上电后才切成 LED 驱动。图里特别注明 LED2 上电时为高电平、LED1 为低电平有效,这意味着外部上下拉电阻的接法会直接改变配置结果,不能随手照抄别的板子。
电源部分分了三路:VCC_3V3 供主电源,VCC_1V8 供内核,DVDD_RGMII_G1 供 RGMII IO。图里用 BLM18SD220SN1D 磁珠把 AVDD33_G1、DVDD_RGMII_G1 和主 3.3V 隔开,每个电源脚旁边配 100nF 加 4.7uF 的组合。这种磁珠加电容的隔离不是形式主义,PHY 的模拟侧对电源纹波敏感,尤其 SGMII 的 SerDes 部分,电源不干净会表现为链路偶发丢包,而不是彻底不通,排查起来很折磨人。
2.3 XC7VX690T 侧 SGMII 与参考时钟
FPGA 侧走的是 SGMII,图里对应 SGMII_TXP/TXN、SGMII_RXP/RXN 差分对,以及一路 REFCLK_PHY_G1_25M。这路 25MHz 参考时钟标注为 3.3V、25ppm、CMOS 输出,直接进 PHY 的 REFCLK 引脚。SGMII 是 1.25Gbps 的串行接口,对参考时钟的抖动有要求,25ppm 是底线,如果板上还有别的时钟源能共用,优先共用而不是再放一颗晶振,少一个器件少一处抖动来源。
FPGA 的 GTX 收发器接 SGMII 时,需要在约束里把对应的 bank 电压和参考时钟频率配对。图里 SGMII 差分对没有串交流耦合电容,这一点要结合 PHY 侧是否内部带耦合来判断——YT8521S 的 SGMII 侧通常需要外部 AC 耦合,参考图若未画,说明该设计依赖 PHY 内部或对端处理,照抄前务必确认,否则直流偏置会把眼图压塌。
3. 照着参考图落板:从电源到复位的实操顺序
3.1 电源域与去耦的落地检查
拿到图先别铺线,先把三路电源的归属列清楚。下面这张表是我按参考图整理的电源核对清单,画板前逐项打勾:
| 电源域 | 电压 | 供给对象 | 隔离器件 | 去耦配置 |
|---|---|---|---|---|
| VCC_3V3 | 3.3V | PHY 主电源、LED | 磁珠 BLM18SD220SN1D | 100nF + 4.7uF |
| VCC_1V8 | 1.8V | PHY 内核 | 独立 LDO | 100nF |
| DVDD_RGMII_G1 | 3.3V | RGMII IO | 磁珠隔离 | 100nF |
| AVDD33_G1 | 3.3V | 模拟侧 | 磁珠隔离 | 100nF + 4.7uF |
去耦电容的摆放比选型更重要。100nF 要贴着电源脚放,4.7uF 可以稍远但仍在同一电源岛内。图里每个电源脚都配了 100nF/10%/25V,25V 耐压对 3.3V 域是余量充足的选择,换成 10V 也能用,但批量时别为了省几分钱把耐压压到 6.3V,浪涌和纹波叠加下容易出问题。
3.2 复位电路:CPLD 控制与 RC 电路二选一
参考图给了两种复位方案:板卡 CPLD 控制,或者自己搭 RC 电路。摘要里明确说复位信号上拉建议选 3.3V。用 CPLD 控制的好处是复位时序可编程,能保证 PHY 在电源稳定后才释放复位;RC 方案简单但时序靠电容值算,下面是一个常见的 RC 复位参数估算:
# RC 复位延时估算:t = R * C * ln(Vcc / (Vcc - Vth)) # 取 R=10k, C=100nF, Vcc=3.3V, 复位阈值 Vth=1.5V python3 -c " import math R=10e3; C=100e-9; Vcc=3.3; Vth=1.5 t=R*C*math.log(Vcc/(Vcc-Vth)) print(f'复位释放延时约 {t*1000:.2f} ms') "这段算的是复位引脚从低电平爬升到阈值的时间,结果大约 0.6ms 量级。实际设计里这个值要大于电源爬升时间,否则电源还没稳复位就放了,PHY 内部状态机会锁死。我一般会把 RC 延时留到 10ms 以上,宁可慢一点也别抢跑。图里 G1_RESET_N 还标了“>10ms”的字样,和这个思路一致。用 CPLD 控制时,复位释放前先读一遍电源 good 信号,比纯 RC 稳。
3.3 RGMII 与 SGMII 走线的边界条件
RGMII 这组线在参考图里是单端走线,四根数据加一根控制,时钟单独。布线上要求 TXC/RXC 与对应数据组内等长,误差控制在 ±100mil 以内,组间不用等长。SGMII 差分对则要求 100Ω 差分阻抗,对内等长 ±5mil,且尽量少换层,换层时旁边补地过孔。图里 SGMII 差分对走的是短直连,没有多余过孔,照这个思路走就行。
有个细节值得说:RGMII 的 TXC 是从 MAC 发往 PHY 的,RXC 是从 PHY 发往 MAC 的,两路方向相反,布线时不要为了“好看”把它们并排贴太近,串扰会让采样窗口变窄。常见做法是两组时钟之间留出至少 3W 的间距,或者用地线隔开。
4. 软件配置才是隐形战场:SDS 模式与 mode_sel 怎么设
4.1 smi_sds_phy 配成 SDS 模式的含义
摘要里那句“smi_sds_phy 应配置 SDS 模式”是整份资料里最值钱的一句。SDS 指的是 SerDes 相关配置,YT8521S 内部有 SGMII 的 SerDes 模块,如果这个配置位没设对,PHY 的 SGMII 侧根本不会正常起链路,表现是 FPGA 侧收不到光、CPU 侧 RGMII 却看着正常,很容易误判成硬件焊接问题。配置通常通过 MDIO 写寄存器完成,下面是一段示意性的配置流程:
# 通过 MDIO 配置 YT8521S 进入 SDS 模式(寄存器地址为示意,以手册为准) def config_yt8521s_sds(mdio_bus, phy_addr): # 步骤1:切换到扩展寄存器页 mdio_bus.write(phy_addr, 0x1E, 0x0007) # 步骤2:使能 SDS/SerDes 相关功能位 mdio_bus.write(phy_addr, 0x10, 0x0001) # 步骤3:确认 mode_sel 进入 SGMAC_TO_RGPHY val = mdio_bus.read(phy_addr, 0x11) assert (val & 0x7) == 0b101, "mode_sel 未进入 3'b101" # 步骤4:软复位让配置生效 mdio_bus.write(phy_addr, 0x00, 0x8000)这段代码的重点不在寄存器地址(不同批次手册可能不同),而在流程:先切页、再改功能位、再读回校验、最后软复位。少了读回校验这一步,配置写没写进去全靠猜,调试时就是黑匣子。参数上 phy_addr 由硬件 strapping 决定,参考图里 PHYAD 相关引脚有上下拉,落板前先确认地址,别和总线上其他器件撞了。
4.2 mode_sel 配 3'b101 的验证方法
mode_sel 是三位配置,3'b101 对应 SGMAC_TO_RGPHY 模式,意思是 SGMII 侧作为 MAC 对接 RGMII 侧 PHY。这个模式选错,数据方向就反了,链路能起来但不通包。验证方法分两步:先读寄存器确认 mode_sel 读回值是 101,再用回环或打流确认双向通。我一般会先让 FPGA 侧发固定长度的包,在 CPU 侧抓,通了再反过来,两个方向都通才算数。摘要说功能测试验证没问题,但那是别人的板子,自己的板子必须重走一遍这个流程。
4.3 复位时序与配置加载的先后
复位释放和 MDIO 配置之间有严格的先后:复位没释放前写 MDIO 是无效的,复位释放后要等 PHY 内部初始化完成(通常几毫秒到几十毫秒)再写配置。参考图里复位由 CPLD 控,软件上就要保证 CPLD 释放复位后延时足够再发起 MDIO 访问。常见翻车是驱动一上电就猛写寄存器,结果前几笔写丢了,后面配置全乱。稳妥做法是复位释放后先读一个固定寄存器(比如 PHY ID),读到了再往下走,读不到就重试。
5. 避坑排查:这几处翻车我见过太多次
5.1 链路起不来但 RGMII 侧看着正常
现象:CPU 侧 RGMII 有收发,FPGA 侧 SGMII 无光无包。原因多半是 smi_sds_phy 没配成 SDS 模式,SerDes 没使能。解决:按 4.1 的流程切页写功能位,读回确认后再软复位,别只写不读。
5.2 配置位读回值和预期不符
现象:mode_sel 读回不是 101,或者 CFG_LDO 读回和硬件配置对不上。原因通常是 strapping 引脚在上电瞬间被 LED 负载或外部上下拉拉偏了,参考图里 LED1/LED2 复用配置脚,外部电阻接错就会改配置。解决:对照图核对每个复用脚的上下拉,上电瞬间用示波器抓电平,别信“应该没问题”。
5.3 电源纹波导致偶发丢包
现象:链路能起,打流跑一段时间偶发丢包,重启又好。原因多是 SGMII SerDes 的模拟电源不干净,磁珠选型或去耦不足。解决:量 AVDD33_G1 的纹波,超过几十毫伏就查磁珠和电容,必要时在磁珠后加一级 LC。这类问题最玄学,因为不是必现,血泪经验是早期就把电源纹波纳入测试项。
5.4 复位释放过早导致 PHY 锁死
现象:上电后 PHY 完全无响应,MDIO 读不到 ID。原因是 RC 复位延时短于电源爬升时间,PHY 在欠压状态下进了异常态。解决:加大 RC 时间常数或改用 CPLD 控制,复位释放前确认电源 good。后悔药没有,只能改板或飞线,所以画板时就把延时留足。
5.5 SGMII 差分对未做 AC 耦合
现象:眼图张不开,误码率高。原因是差分对直流偏置不匹配,参考图未画耦合电容时容易漏掉。解决:确认 PHY 和对端是否需要外部 AC 耦合电容,需要就在靠近发送端加 100nF,别省这两颗。
6. 把参考图用成自己的检查表:一个可复用的核对脚本
参考图最大的价值不是让你照抄,而是变成一张可执行的核对表。我习惯把关键配置项写成脚本,每次新板 bring-up 先跑一遍,把“人肉核对”变成“机器核对”。下面这段是读取 PHY 关键寄存器并和预期比对的骨架:
# YT8521S bring-up 自检:读关键配置并与预期比对 EXPECTED = { "phy_id_hi": 0x0000, # 以实际手册为准 "mode_sel": 0b101, # SGMAC_TO_RGPHY "sds_en": 0x1, # SDS 模式使能 } def bringup_check(mdio_bus, phy_addr): report = [] # 1. 读 PHY ID,确认 MDIO 通路正常 id_hi = mdio_bus.read(phy_addr, 0x02) report.append(("phy_id_hi", id_hi, EXPECTED["phy_id_hi"])) # 2. 切页读 mode_sel mdio_bus.write(phy_addr, 0x1E, 0x0007) mode = mdio_bus.read(phy_addr, 0x11) & 0x7 report.append(("mode_sel", mode, EXPECTED["mode_sel"])) # 3. 读 SDS 使能位 sds = (mdio_bus.read(phy_addr, 0x10) >> 0) & 0x1 report.append(("sds_en", sds, EXPECTED["sds_en"])) # 4. 汇总,任一项不符即报错 for name, got, want in report: flag = "OK" if got == want else "FAIL" print(f"[{flag}] {name}: got=0x{got:x}, want=0x{want:x}") return all(g == w for _, g, w in report)这段脚本的用法是:每次上电、每次改配置、每次换板都跑一遍,输出里出现 FAIL 就先解决 FAIL,别急着打流。参数上 EXPECTED 里的值要按自己板子的实际配置填,不能照抄;phy_id_hi 只是占位,真实值以手册为准。把这段和 4.1 的配置流程串起来,就形成“配置—校验—打流”的闭环。
还有一个习惯值得分享:参考图里的每一处标注(比如“>10ms”“3.3V 上拉”“DNP”)我都当成待确认项,而不是既定事实。DNP 的器件要确认是真的不贴还是预留,上拉电压要确认和电源域一致,延时标注要确认测试条件。从那以后我每次拿到参考图,都先把它翻译成一张带勾选框的核对表,硬件画完勾一遍,软件配完再勾一遍,两次都对上才敢说这块板子稳了。希望帮到你。
本文还有配套的精品资源,点击获取