第2章:上电复位时序——电源稳定与复位释放条件
搞PCIe链路训练,第一步不是看LTSSM状态机,而是先把供电和复位搞定。要是电源没站稳就急着跑复位,或者复位释放得不对,后边的链路训练全白搭。我刚开始接触PCIe时,就吃过这个亏——板子焊好了,死活Link不起来,查了三天,最后发现是电源斜坡斜率太慢,复位释放的时候核心电压才1.7V(标称1.8V)。
所以这一章咱们把上电复位时序彻底说清楚。你想想看,PCBA上电之后,各个电压轨按什么顺序起来?Perst信号什么时候才能拉高?这些时序窗口到底谁约束谁?搞明白这些,后面的L0训练才有根基。
2.1 电源稳定的三个关键点
PCIe设备上电,不是简单的“电压到了就行”。我习惯把电源稳定性拆成三个维度来检查:
- 电压达到标称值的时间——从0到90%标称电压的上升时间,通常叫斜坡时间。PCIe规范没有卡死具体数值,但实际项目中乱设会有问题。比如某个FPGA PCIe硬核要求电源斜坡在10ms~50ms之间,太慢会导致内部POR(上电复位)误判。
- 电压过冲/下冲——稳定后不能超过±3%的容差。Core电压1.0V,最低不能掉到0.97V以下,最高1.03V。
- 时序关系——多个电压轨之间可能有先上后下的要求。比如有些Endpoint需要VAUX先稳定,再上VMAIN。
实战经验:我记得有一次调试M.2插槽的SSD,每次冷启动都能识别,热重启PCIe设备就掉。后来抓了Perst和电源波形,发现热重启时Perst释放太快,而VMAIN因为电容残压没有完全掉到零,导致内部POR逻辑状态混乱。最后加了一颗放电电阻解决。所以别以为“掉电”只是一个瞬间——残压有时候比你想的顽强。
2.2 复位释放的硬性条件
Perst#(PCI Express 复位信号)释放前,必须同时满足以下三个条件。少了任何一个,链路训练都可能异常。
| 条件 | 说明 | 典型参数 |
|---|---|---|
| 所有电源稳定 | VMAIN、VAUX 在标称值±3%内 | 参考具体芯片手册 |
| REFCLK稳定 | 100MHz差分时钟,频率容差±300ppm | 抖动通常要求< 86ps p-p |
| Perst低电平保持时间 TPVPGL | Perst# 必须保持低电平至少100μs(规范值),但很多芯片要求100ms | 100μs~100ms,取决于平台 |
为什么Perst要等那么久?其实是为了让内部PLL锁相、偏置电路建立、模拟前端稳定。你不是把数字逻辑复位就行,高速SerDes需要时间来做眼图对齐和校准。我见过一个案例,某款PCIE Switch因为系统Power Manager在50μs后就释放了Perst,结果Switch的SerDes内部状态没有建立好,总是Training Error。后来把延时改成10ms就稳定了。
2.3 你需要注意的时序细节
到这里你可能觉得“哦,照做就好”,其实坑还不少。我顺带提几个容易翻车的地方:
- 上升沿斜率——Perst从低到高的上升时间建议控制在1ms以内。太慢会导致设备在阈值区间反复跳变,带来毛刺。
- Perst与电源的先后顺序——规范只要求Perst在电源稳定后才能释放,但很多控制器希望Perst在电源到位之后再过几十ms才拉高,避免竞争。
- 多设备挂同一条Perst总线——如果有多个PCIe设备共享同一个Perst信号,要注意每个设备的de-assert时间窗口可能不同。有些设备延迟小,有些延迟大,容易造成上游RC侧误认为设备已就绪。
我的习惯:在Perst释放前加一级反相器加RC延时,或者在FPGA/CPLD中做一个可编程的延时计数器。这样调试的时候可以动态调整TPVPGL长度,不用改PCB。我曾经用这种方法快速定位了一个由于Perst时序导致链路不稳定的大坑。
2.4 参考波形与参数速查
拿典型的Root Complex平台举例子,从上电到L0整个复位序列大致如下:
时间轴(不按比例):
V_MAIN ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
| 斜坡期 ~10ms | 稳定期
V_AUX ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
| 通常比V_MAIN早或同时 |
REFCLK ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
| 电源稳定后很快稳定 |
Perst# ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
| 保持低电平 >=100ms | 拉高 → 设备初始化 → 链路训练
注意上图只是一个理想场景。实际项目中你可以把Perst的保持时间设得保守一些,比如200ms。多出的这几百毫秒不影响用户体验,但能给电源和时钟更多的裕量。
2.5 避坑指南——我踩过的那些雷
警告:千万不要忽视Perst信号的毛刺。我曾经在项目测试中发现,服务器主板上的Perst因为走线过长、过孔太多,被电源噪声耦合出了一个100ns的正脉冲。这个毛刺正好落在设备内部数字滤波器的检测窗口之外——设备根本感知不到它。但搞笑的是下游PCIe交换机却因为这段毛刺触发了误复位,导致后级所有Endpoint同时断链。最后定位原因耗时两周。那以后我所有涉及Perst的设计都在靠近设备引脚处加一个RC低通滤波,时间常数约1μs,把窄毛刺滤掉。
再补充一个很多人忽略的点:热插拔场景下的复位时序。如果你做的是支持Hot-Plug的槽位,当设备插入时,电源上升和Perst的关系要重新考量。规范规定Perst必须在电源稳定后的100μs内拉低,再保持至少100ms。但如果你插进去的瞬间电源有抖振,控制器的检测逻辑可能会误判。过去我处理过一个案例:插卡时机械接触有抖动,电源在几十微秒内掉了三次,导致Perst控制失效。最后的解决方案是增加一个去抖电路,Perst释放之前先检测到电源连续稳定10ms才拉高。
好,电源稳定和复位释放的时序要求,大概就这些。这一块虽然看起来只是简单的“等电源再释放复位”,但实际项目中因为时序裕量不足、毛刺干扰、多电源轨序等问题踩进去的坑太多了。希望你带着这些经验去设计,能少走弯路。记住一个原则:宁可多等100ms,也不要抢那10μs。链路训练这件事,开局稳定才能跑得稳。