4. Detect状态:接收器检测与阻抗检测机制
链路训练的第一步,就是Detect状态。
说白了,就是发送端要知道:对面有没有东西接着?
我刚开始接触PCIe时,觉得这步很简单——不就是测个阻抗吗?后来发现,这里的门道真不少。接收器检测做得不好,后续的Bit Lock、Symbol Lock全是白搭。
4.1 Detect状态在整个训练中的角色
Detect是链路训练状态机的第一个稳定状态。它的任务只有一个:确认对端接收器的存在。
你想想看,如果链路另一头根本没插设备,或者接触不良,这时候去做Bit Lock就是浪费电。所以PCIe的设计者们把接收器检测放在了最前面。
- 对端是否有接收器?(存在性检测)
- 接收器的阻抗特性是否正常?(阻抗检测)
只有这两个检测都通过了,链路才会进入Polling状态,开始尝试Bit Lock。
4.2 接收器检测的物理机理
接收器检测依赖于PCIe物理层的一个特性:交流耦合。
PCIe的差分对TX和RX之间,是通过电容做交流耦合的。发送端在发送数据前,会在TX线上施加一个电压。如果对端有接收器,接收器内部有直流偏置电阻(通常是50Ω到地),这个电阻会形成一个分压网络。发送端通过测量这个直流电压的变化,来判断接收器是否存在。
具体的操作流程是这样的:
- TX输出共模电压:发送端先在TX线上输出一个已知的共模电压(通常为0V或某个基准电压)。
- 测量电压变化:发送端的检测电路会测量TX线上的实际直流电压。如果接收器存在,因为阻抗匹配,电压会被拉低到一个特定值。
- 与阈值比较:检测电路将测量值与预设阈值比较。接收器存在时,电压会低于一个门槛;不存在时,电压接近开路电压(很高)。
记得有一次在调试一块测试板时,接收器检测总是失败。最后发现,是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。
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管脚上的直流电平变化,看看是否在预期的区间内。很多时候,问题出在第一步。