MDIO 物理层实现:SMI 接口信号与时序分析

MDIO 的物理层,说白了就是 SMI(串行管理接口)怎么在两根线上跑起来。我刚开始调试 MII 时,总觉得时序图看起来很简单,但一上示波器就发现毛刺满天飞。嗯,这一节我们把信号定义和时序参数拆开揉碎讲清楚。

SMI 接口信号

SMI 只有两根线:

  • MDC(管理数据时钟)—— 由主设备驱动,频率不超过 2.5 MHz(标准模式下)。
  • MDIO(管理数据输入输出)—— 双向数据线,需要上拉电阻。

你想想看,两根线就能读写所有 PHY 寄存器,挺神奇的。但代价就是速度慢,而且时序要求很严格。

关键点: MDIO 属于三态总线。读操作时 PHY 驱动数据,写操作时主设备驱动。空闲时 MDIO 保持高阻,靠外部上拉维持高电平。

时序参数对照表

我习惯在调试前先把规格书的时序参数列出来。下面是 IEEE 802.3 标准中 SMI 的主要时序要求(参考 100BASE-TX PHY):

参数 符号 最小值 最大值 单位
MDC 时钟周期 Tcyc 400 — ns
MDC 高电平宽度 Thigh 160 — ns
MDC 低电平宽度 Tlow 160 — ns
MDIO 数据建立时间(写/读) Tsetup 10 — ns
MDIO 数据保持时间(写/读) Thold 10 — ns
MDIO 输出延迟(从 PHY) Tdly 0 100 ns

避坑指南:我曾经在 FPGA 上直接用 25 MHz 时钟分频做 MDC,结果分频后的占空比只有 20%。MDC 低电平时间过短,PHY 根本无法采样。后来老老实实加了个计数器,保证高、低电平都 ≥160 ns。

读写时序分析

SMI 的帧结构大家都熟:32 位前导码 + 起始位 + 操作码 + PHY 地址 + 寄存器地址 + 转向位 + 数据。但时序上有个小陷阱——转向位(TA)时钟周期。

读操作时,在 TA 的前半拍主设备释放总线,后半拍 PHY 开始驱动 MDIO。如果主设备释放不够快(比如三态门延迟),会和 PHY 的输出产生冲突。我用示波器抓到过总线竞争产生的毛刺,数据全错。

// 一个简化的 MDIO 读时序 Verilog 片段(仅供参考)
reg [4:0] phy_addr, reg_addr;
reg [15:0] read_data;
reg [31:0] clk_cnt;

always @(posedge mdc_2_5M) begin
  case (state)
    IDLE: begin
      if (start) begin
        mdio_out_en <= 1;  // 主机驱动前导码和帧头
        state <= PREAMBLE;
      end
    end
    PREAMBLE: begin
      // 32 个 1 后跳转
      if (cnt == 31) state <= START;
    end
    // ...
    TURN_AROUND: begin
      if (cnt == 0) mdio_out_en <= 0;  // 释放总线
      if (cnt == 1) begin
        mdio_out_en <= 0;  // 读数据,由 PHY 驱动
        read_data[15:0] <= {read_data[14:0], mdio_in};
      end
    end
  endcase
end

个人经验:我建议在 TA 的前半周期插入一个 dummy 周期,让总线浮空更干净。很多商用 PHY 的 TA 窗口是 ±10 ns,留点余量总没错。

时序验证与常见问题

  • MDC 时钟抖动过大: 如果 MDC 由软件产生(比如 GPIO 模拟),抖动可能超过 100 ns,导致 PHY 采样错误。解决办法:改用硬件定时器或 SPI 外设。
  • MDIO 上拉电阻失效: 读操作时 MDIO 浮空,如果外部上拉太小(比如 1kΩ),总线电平可能被芯片内部下拉拉到低电平,读回全 0。
  • 背靠背读写间隔: 有些 PHY 要求连续两次 SMI 操作之间至少间隔 1 个 MDC 周期,否则内部状态机未复位。

为什么要关注这些?因为 MDIO 是调试的第一步。如果连寄存器都读不到,后面链路分析无从谈起。

MDIO 读操作帧时序结构(SMI 物理层) MDC 时钟(2.5 MHz) 前导码 32 个 '1' ST 01 OP 10(读) PHY 地址 5-bit 寄存器地址 5-bit TA Z→0 数据(16-bit) ⚠ 读操作注意 TA 周期后半拍 PHY 驱动 MDIO,主机需释放总线 ⏱ 时序关键点 建立时间 ≥10 ns 保持时间 ≥10 ns

上图展示了读操作时的帧结构顺序。你看到 TA 之后数据段才由 PHY 驱动,所以之前主机必须把 MDIO 拉成高阻。调试时我习惯用逻辑分析仪抓整个帧,重点看 TA 处的电平变化是否干净。

小技巧:如果读回的寄存器值偶尔全 F,大概率是 MDIO 上拉没接好,或者主设备在 TA 后仍然保持输出。用示波器看 MDIO 波形,若 TA 后有不该出现的下降沿,就是冲突信号。

掌握 SMI 时序,你就有了调试 MDIO 的「眼睛」。后面章节我们会结合 D-PHY 链路,看看时序问题怎么通过 MDIO 读回的错误值反向定位。