4. Detect状态:接收器检测与阻抗检测机制

链路训练的第一步,就是Detect状态。

说白了,就是发送端要知道:对面有没有东西接着?

我刚开始接触PCIe时,觉得这步很简单——不就是测个阻抗吗?后来发现,这里的门道真不少。接收器检测做得不好,后续的Bit Lock、Symbol Lock全是白搭。

4.1 Detect状态在整个训练中的角色

Detect是链路训练状态机的第一个稳定状态。它的任务只有一个:确认对端接收器的存在。

你想想看,如果链路另一头根本没插设备,或者接触不良,这时候去做Bit Lock就是浪费电。所以PCIe的设计者们把接收器检测放在了最前面。

Detect状态需要回答两个问题:
  • 对端是否有接收器?(存在性检测)
  • 接收器的阻抗特性是否正常?(阻抗检测)

只有这两个检测都通过了,链路才会进入Polling状态,开始尝试Bit Lock。

4.2 接收器检测的物理机理

接收器检测依赖于PCIe物理层的一个特性:交流耦合。

PCIe的差分对TX和RX之间,是通过电容做交流耦合的。发送端在发送数据前,会在TX线上施加一个电压。如果对端有接收器,接收器内部有直流偏置电阻(通常是50Ω到地),这个电阻会形成一个分压网络。发送端通过测量这个直流电压的变化,来判断接收器是否存在。

具体的操作流程是这样的:

  1. TX输出共模电压:发送端先在TX线上输出一个已知的共模电压(通常为0V或某个基准电压)。
  2. 测量电压变化:发送端的检测电路会测量TX线上的实际直流电压。如果接收器存在,因为阻抗匹配,电压会被拉低到一个特定值。
  3. 与阈值比较:检测电路将测量值与预设阈值比较。接收器存在时,电压会低于一个门槛;不存在时,电压接近开路电压(很高)。
我踩过的坑:
记得有一次在调试一块测试板时,接收器检测总是失败。最后发现,是TX路径上的交流耦合电容不良,导致了共模电压建立异常。从那以后,我在硬件设计审查时特别关注交流耦合电容的容值和ESR参数。

4.3 接收器检测的两种方式

PCIe规范定义了两种接收器检测方式:NRz检测和RC检测。

检测方式 原理 优点 缺点
NRz检测
(Non-Return to Zero)
发送端输出一个固定的直流电压,测量直流电流或电压变化。 实现简单,检测速度快。 受温度和工艺影响大,精度相对较低。
RC检测
(Resistance Capacitance)
发送端施加一个阶跃电压,测量电压建立的时间常数(RC常数)。 精度高,抗干扰能力强。 实现复杂,检测时间稍长。

在实际芯片中,我见过的大部分PCIe控制器同时支持这两种方式。Gen1和Gen2时代,NRz检测用得比较多。到了Gen3之后,因为信号速率高了,对检测精度的要求也高了,RC检测就成了主流。

注意事项:
接收器检测必须在物理层电气空闲(Electrical Idle)状态下进行。如果在数据发送过程中做检测,结果完全不可信。这也是为什么Detect状态要在Polling之前——它们都是电气空闲状态下的操作。

4.4 阻抗检测的细节

接收器检测本身只回答“有/没有”的问题。但有时接收器虽然存在,它的输入阻抗可能已经偏离了规范要求(PCIe要求RX端对地直流阻抗在40-60Ω之间)。这就引入了阻抗检测。

阻抗检测的流程:

  • 第一步:粗测——先大致判断接收器是否存在。如果存在,继续;如果不存在,链路停留在Detect状态,或者进入Reset。
  • 第二步:精测——发送端通过改变输出电流或电压,测量接收器的I-V特性,计算出等效直流阻抗。
  • 第三步:判定——如果阻抗在40-60Ω范围内,视为合格;如果超出范围,链路判定为“接收器异常”,不会进入Polling。

我个人习惯,在分析链路训练失败问题时,首先会抓取Detect状态下的阻抗测量结果。很多接触不良的问题,在这个阶段就能发现端倪。

4.5 Detect状态的状态机与定时器

Detect状态内部也有自己的状态机:

  • Detect.Quiet:链路保持电气空闲。发送端等待对端可能的信号。
  • Detect.Active:发送端发起接收器检测。定时器开始计时。
  • Detect.Wait:等待检测结果。定时器超时则回到Quiet。

PCIe规范规定,Detect状态的整个流程必须在12ms内完成。如果12ms内没能成功检测到接收器,链路会尝试重新训练或进入错误处理。

关键定时参数:
整个Detect状态(包括接收器检测+阻抗检测)总时间上限为12ms。
其中接收器检测本身通常只需要几μs到几ms,剩下的时间主要是留给阻抗检测和状态切换的开销。

4.6 Detect状态的全流程

我把整个Detect状态的逻辑梳理成了一张图。你可以看到,从链路上电或复位开始,Detect状态如何一步步完成检测,并决定是进入Polling还是继续留在Detect。

Detect状态接收器检测与阻抗检测流程图 Detect状态检测流程 链路进入Detect 判定检测方向 配置TX驱动 NRz检测 固定电压/电流测量 RC检测 阶跃电压/时间常数测量 接收器存在? (比较测量值与阈值) 接收器不存在 等待超时或重新检测 否 执行阻抗检测 测量RX直流阻抗是否正常 是 阻抗在范围? (40-60Ω正常) 进入Polling状态 开始Bit Lock 是 接收器异常 返回/报告错误 否 注意 检测必须在电气空闲下进行 总定时上限12ms

4.7 避坑指南

最后,我分享几个项目中遇到的Detect状态问题。

第一个坑:共模电压建立时间不足。

我曾经在一块Gen3的测试板上遇到链路训练经常失败,症状是Detect状态反复失败,然后进入Recovery。最后发现,是板上的交流耦合电容旁边的一个去耦电容焊错了位置,导致共模电压建立时间比预期长了很多。PCIe的接收器检测电路默认在几十纳秒内就能完成检测,但因为共模电压没稳定,导致测量结果不准确。

第二个坑:阻抗检测对温度的敏感性。

接收器的输入阻抗虽然被规范约束在40-60Ω,但实际芯片的阻抗会随温度漂移。在常温下是50Ω的设备,在-40°C或85°C时可能就漂到了35Ω或65Ω。如果你的Detect状态阈值卡得太紧,有可能只在某些温度下才能训练成功。我习惯在做系统级测试时,至少跑一组高低温循环,专门用来验证Detect状态在全温度范围下的稳定性。

第三个坑:高速信号下的接收器检测干扰。

在Gen4和Gen5的高速率设计中,信号边沿速率很高。如果PCB布局不干净,TX和RX之间有串扰,就可能干扰接收器检测的直流测量结果。虽然接收器检测本身是一个低频操作,但高速串扰的直流分量会叠加到测量电压上,导致误判。我在一个项目中就是因为这个原因,不得不加长了Detect状态内的稳定等待时间。

我的调试建议:
如果你在调试链路训练问题,不要急着看后面的Bit Lock或Symbol Lock。先确认Detect状态是否正常。用逻辑分析仪抓一下TX管脚上的直流电平变化,看看是否在预期的区间内。很多时候,问题出在第一步。