Detect 状态:链路训练的起跑线 —— 子状态与转换条件详解

Detect 是 LTSSM 链路训练的第一站。说白了,就是你的 PCIe 设备在问:“对面有人吗?”

别小看这个“打招呼”的动作。我做过十几个 PCIe 项目,一半的链路训练失败都卡在 Detect 阶段,而且问题往往很隐蔽——不是电气特性不对,就是时序窗口没踩准。所以这一章我们把 Detect 的三个子状态掰开揉碎,结合转换条件,把每个细节讲透。

三个子状态,逐个击破

Detect 状态内部有三个子状态:Detect.Quiet、Detect.Active 和 Detect.DeBounce。它们形成一个闭环,像雷达扫描一样反复确认对端是否存在。下面我按顺序拆解。

1. Detect.Quiet — “先听,再说”

进入 Detect 后,设备首先停留在 Quiet 子状态。此时发送器处于电气空闲(Electrical Idle),不发送任何数据;接收器则全力检测对端是否存在。

怎么检测?通过监视接收器差分信号的共模电压变化。如果对端已经上电并开始发送训练序列,接收器会感应到信号跳变。

这里有个关键参数:电气空闲退出检测阈值。不同 IP 核的阈值设定可能略有差异,我遇到过一块 FPGA 原型板,因为接收器参考电压偏了 50 mV,导致始终检测不到对端,一直卡在 Quiet。后来用示波器量了差分峰峰值才发现问题。

转换条件就两条:

  • 检测到对端信号 → 跳转到 Detect.Active
  • 定时器超时(通常 12 ms) → 也跳转到 Detect.Active(用于主动发送训练序列,尝试建立链接)

你想想看,如果一直没人回应,设备不能永远等下去,超时后它会主动“喊一嗓子”。

2. Detect.Active — “打招呼并听回应”

进入 Active 后,发送器开始发送训练序列(TS1 或 TS2),接收器同时继续监听对端信号。这个阶段有点像两个人在黑暗中互相喊话:“我在这里,你在吗?”

训练序列的发送频率和内容由 PCIe Base Spec 定义,但具体实现中要注意占空比和信号完整性。我调试过一次 Gen3 链路,发现 Active 阶段发送的 TS1 序列幅值只有规范要求的一半,导致对端无法正确识别,反复回退到 Quiet。最后查出是发送端驱动强度配置错了。

Active 状态的转换条件:

  • 成功检测到对端的有效信号 → 进入 Detect.DeBounce
  • 未检测到对端,或信号质量不合格 → 回到 Detect.Quiet
  • 超时(通常也是 12 ms) → 回到 Detect.Quiet

嗯,这里要注意:从 Active 回到 Quiet 并不代表失败,只是重新开始一轮检测。LTSSM 设计有多次重试机制。

3. Detect.DeBounce — “确认不是噪声”

这个阶段是去抖动。对端信号可能因为反射、串扰或电源噪声产生毛刺,如果贸然进入下一状态,可能造成误判。DeBounce 的作用就是连续采样一段时间,确认信号是稳定的。

去抖动的时长没有硬性规定,通常在 2 ms 到 10 ms 之间,具体由芯片实现决定。我个人习惯把 DeBounce 窗口设得比规范最小值宽 20%,给信号完整性留点余量。

我曾经被去抖动时间坑过一次:某款国产交换芯片为了追求快速训练,把 DeBounce 窗口压缩到了 1 ms,结果在强电磁干扰环境下频繁误触发,链路反复掉线。后来我们把窗口调到 4 ms,问题迎刃而解。所以不要盲目追求“快”,稳定才是第一优先级。

转换条件:

  • 信号持续稳定超过去抖动窗口 → 退出 Detect,进入 Polling 状态
  • 信号中途丢失或出现毛刺 → 回到 Detect.Quiet,重新开始

关键要点

  • Detect 是 LTSSM 训练的入口,所有链路训练都从这里起步
  • 三个子状态形成一个“检测 → 发送 → 确认”的闭环
  • 去抖动窗口是抗干扰的第一道防线,不要设得太短
  • 超时回退是正常机制,不是错误
Detect 状态子状态机 Detect 状态子状态机 Detect.Quiet Detect.Active Detect.DeBounce Polling(下一状态) 超时回退 定时超时 / 信号检测 检测到对端 未检测到对端 去抖动成功 去抖动失败 重新训练 💡 说明: 超时回退是正常重试机制, 不是错误。连续多次回退才 需要排查硬件或电气问题。

转换条件全景表

为了方便你在调试时快速查询,我把所有转换路径整理成表格。建议收藏这张表,项目里肯定用得上。

当前子状态 目标子状态 转换条件 典型超时
Detect.Quiet Detect.Active 检测到对端信号,或定时器超时 12 ms
Detect.Active Detect.DeBounce 成功检测到对端有效信号 —
Detect.Active Detect.Quiet 未检测到对端,或信号质量不达标 12 ms
Detect.DeBounce Polling 信号持续稳定超过去抖动窗口 —
Detect.DeBounce Detect.Quiet 去抖动期间信号丢失或出现毛刺 —
任意子状态 Detect.Quiet 全局超时或链路复位触发 按实现定义

调试建议

我建议在仿真阶段就覆盖以下场景:

  • 对端从未上电(卡在 Quiet,应触发超时重试)
  • 对端信号幅值偏低(Active 阶段检测失败,回退)
  • 去抖动窗口内注入毛刺(验证 DeBounce 的容错能力)
  • 连续多次回退后的恢复机制

这些 case 我在项目里都踩过,提早验证能省下好几轮板级调试的时间。

避坑指南

我曾经在某个量产项目中遇到批量链路训练失败的问题。现象是 Detect 状态反复在 Active 和 Quiet 之间跳转,始终进不了 DeBounce。最后定位到是发送端共模电压偏了 80 mV,导致接收端信号检测逻辑误判。

排查方法很简单:用示波器量差分信号的眼图,重点关注共模电压和峰峰值。PCIe Gen3 规范要求差分峰峰值在 800 mV 到 1200 mV 之间,共模电压在 0 V 到 2 V 之间。只要有一项偏离,Detect 阶段就会出问题。

所以我的建议是:在板级调试时,先把 Detect 阶段的信号质量调到最优,再往下走。这个阶段的基础打不牢,后面的 Polling、L0 状态全是空中楼阁。