4. SGMII链路建立过程:Auto-Negotiation,Link Training,时钟同步

SGMII的链路建立,说白了就是两端设备先打个招呼,再互相对齐,最后才能跑起来。 我见过不少工程师,一上来就盯着时钟恢复或者眼图看,结果折腾半天发现是前面的握手就没成功。 这其实挺冤枉的,因为SGMII的建立是有固定流程的,一步一步来,才能把问题范围缩小。

我个人习惯把SGMII的链路建立分为三个主要阶段:Auto-Negotiation(自动协商)、Link Training(链路训练)和时钟同步。 这三个阶段是串行执行的,前一个阶段没过,后面的想都别想。 下面我结合项目里遇到的坑,一个一个讲清楚。

4.1 Auto-Negotiation(自动协商)

Auto-Negotiation,也就是我们常说的“自协商”。 干什么用的呢?就是让两端的SGMII设备互相告诉对方:我能跑多快、什么工作模式,然后商量出一个两边都能支持的连接参数。

在SGMII场景下,自协商的流程很简单。 它不像传统以太网那样需要协商速度和双工模式,SGMII链路两端强制设定为1000Mbps全双工。 那SGMII自协商在协商什么?

  • 确认对端是SGMII设备:两端都需要宣告自己支持SGMII。
  • 传递链路速度信息:虽然SGMII本身是1000Mbps,但背后的MAC和PHY可能有多种速度(如10/100/1000Mbps)。SGMII自协商会告诉对端,当前应工作于哪个速度。
  • 确认流控能力:协商是否启用PAUSE帧流控。

自协商的报文叫作Base Page和Next Page。 SGMII把它简化了,一般就只交换两页信息。

避坑指南: 我曾经遇到一个项目,两端的SGMII设备死活连不上。用示波器抓差分对信号,发现自协商脉冲一直在发,但就是无法进入下一阶段。 查了三天,最后发现其中一端的SGMII自协商功能根本没有使能。 那时候我才意识到,有些FPGA的SGMII IP核默认自协商是关闭的,得手动配置寄存器开启。
阶段 关键行为 典型问题
能力交换 发送Base Page 对端无应答
确认 收到ACK 误码导致握手失败
完成 Link UP,进入Training 寄存器未配置

4.2 Link Training(链路训练)

自协商完成之后,两端的链路建立了最基本连接,接下来就是Link Training。 这个名字听起来有点玄乎,你想想看,其实就是SGMII链路上的“信号对齐”。

SGMII虽然是一种串行接口,但它不像PCIe那样有复杂的链路训练状态机。 它的Link Training核心目的就两个:

  1. 发送端调整预加重/去加重:补偿传输介质的损耗,让眼图更好看。
  2. 接收端调整均衡器:优化采样位置,减少误码。

我记得有一次调试一块高速背板上的SGMII链路,直连测试都能跑通,但一上背板就报错。 后来反复看眼图,发现信号经过背板后,上升沿变缓,眼图几乎闭合。 打开SGMII IP核的Link Training功能后,发送端自动调整了预加重系数,眼图一下就打开了。

Link Training是双向的过程。 每一端的发送器都会发出特定的训练序列,对端的接收器根据收到的信号质量,反馈一个“再大点”或“再小点”的调整值。 这个过程会持续到误差小到可接受为止,或者超出迭代次数上限然后超时失败。

要点提示: SGMII的Link Training一般由PHY或MAC中的数字逻辑自动完成。 你作为调试者,重点关注的是:
1. Training是否完成(检查寄存器状态的Link_Training_OK位)。
2. Training失败时,看看是发送端系数不收敛,还是接收端均衡器锁不住。

4.3 时钟同步

好了,有了自协商打底,有了训练对齐,最后一步就是时钟同步。 这一步,说白了就是让接收端从SGMII数据流里,把准确的时钟信息恢复出来。

SGMII是源同步吗?并不是。 它没有独立的参考时钟线跟着数据一起传。接收端只能拿到串行数据,里面混合了数据和时钟。 CDR电路的任务,就是从这串流里“抠”出时钟来。

时钟同步要做的事情包括:

  • CDR锁定:根据数据边沿,调整本地PLL(锁相环),让采样时钟与数据流同频同相。
  • 字节对齐:SGMII数据是10位编码(8B/10B),接收端需要找到码组的边界。
  • 时钟域同步:将恢复出的时钟用于数据读取,然后把数据从恢复时钟域转换到系统时钟域。

你可能会问:“链路训练之后,信号质量很好了,CDR还锁不住吗?” 嗯,这里要注意。CDR是连续工作的,当SGMII链路长时间没有数据跳变时,PLL可能会漂移。 我见过最坑的一种情况是链路空载时一切正常,一跑大流量突发数据,CDR瞬间失锁,然后就是一片误码。

我的经验: 调试SGMII时钟同步阶段,最实用的工具就是看CDR的状态寄存器。 我一般先看PLL的锁定指示位,再看字节对齐的时钟恢复状态。 如果CDR锁住了,但数据还是错误,那八成是Byte Alignment没对齐,或者跨时钟域处理有问题。

下面这张图,是我画的SGMII链路建立全流程。 你可以看到三个阶段的先后次序,以及各自对应的核心节点。

SGMII链路建立流程 Auto-Negotiation 交换能力宣告(Base/Next Page) ACK确认,完成握手 关键:使能自协商寄存器 AN_Good(链路建立) Link Training 发送端调整预加重/去加重 接收端均衡器调整 双向迭代,系数收敛 Training_OK 时钟同步 CDR PLL锁定,恢复时钟 8B/10B字节对齐 时钟域同步,数据可用 三个阶段串行执行 成功则链路完全建立

这三个阶段走下来,SGMII链路才算真正建立。 如果哪个阶段卡住了,别灰心,结合我上面说的那些关注点,一步步查。 我个人习惯是先看Register的Link Status,再追CDR的Lock状态。 基本上,只要Traing过了,时钟同步问题就少了。

补充提醒: 链路建立后,时钟恢复并非一成不变。 环境温度变化、电压波动,都可能导致CDR需要重新调整。 有些设计为了稳定,每过一段时间会发起一次快速重训练。 调试时如果发现链路中断后又自己恢复,可以先查一下是不是触发了链路重训练机制。