第一章 PCIe 基础回顾:从总线到分层模型,再到代际演进
咱们开篇先把地基夯实。PCIe 这套东西,你如果光啃 spec 会觉得很抽象,但结合我实际调试中的体会来讲,会好理解很多。
1.1 总线架构:从共享到点对点
早期的 PCI 总线是共享并行架构。什么意思呢?就是所有设备挂在同一条总线上,谁要说话先申请,总线仲裁器点头了你再发。设备一多,带宽就抢来抢去,延迟也上去了。
PCIe 彻底推翻了这种玩法。它换成了点对点串行差分总线。每个设备跟 Root Complex 之间,或者设备跟 Switch 之间,都有自己的专用通道。说白了,就是每条 Lane 都是一条独立的快车道,不再需要排队等仲裁了。我个人习惯把这种架构叫“专线制”,互不干扰。
1.2 分层模型:事务层、数据链路层、物理层
PCIe 协议栈分三层:事务层(TL, Transaction Layer)、数据链路层(DLL, Data Link Layer)、物理层(PHY, Physical Layer)。说人话就是:
- 事务层:负责把软件发出的读写请求打包成 TLP(Transaction Layer Packet)。你想想看,CPU 想读显卡里的一段数据,这个指令就是从这里变成数据包的。
- 数据链路层:给 TLP 加上序列号和 CRC 校验,保证数据不丢不坏。它还管流控——告诉发端“我缓冲区还能收几个包,你先等会儿”。
- 物理层:干脏活的。把数据编码、加扰、串化,然后差分信号发出去。接收端再解串、去扰、解码。Gen1/2 用 8b/10b 编码,Gen3 开始换成 128b/130b,效率高了很多。
我记得刚接触 PCIe 时,总觉得分层模型很抽象。后来在实际定位链路训练失败故障时才发现,每一层都有它独特的问题域:物理层出问题表现为链路无法“Up”,数据链路层出问题表现为 CRC 错误暴增,事务层出问题则可能是 Completion Timeout。你定位问题时,先判断是哪个层出了事,至少能省一半时间。
1.3 链路拓扑:RC、Switch、Endpoint 与树形结构
PCIe 的拓扑是 树形结构。Root Complex(RC)在树根,往下接 Switch,Switch 再接多个 Endpoint(EP)。RC 一般集成在 CPU 里,Switch 就是个大号的分线器。EP 就是显卡、NVMe SSD、网卡这些实际干活的设备。
为什么用树形而不是网状?因为 PCIe 的设计初衷是软件透明枚举。系统启动时,BIOS 从 RC 开始,一层层遍历,给每个设备分配 Bus Number、Device Number、Function Number,以及配置空间里的 MMIO 地址空间。拓扑越简单,枚举越不容易出岔子。
我在项目中遇到过一种奇葩现象:同一块板子,换一个型号的 NVMe SSD 就训练不上,换回原来品牌就正常。查到最后,是 Switch 的 Lane 极性翻转配置不兼容。那种问题,光看软件 log 根本看不出来,必须用示波器抓物理层信号才能找到。
- RC (Root Complex) — 树根
- Switch (交换器) — 分支节点
- EP (Endpoint) — 叶片节点
- 每对 EP 到 RC 的路径是点对点虚拟通道
- 支持 Non-Transparent Bridge (NTB) 实现多主机互联
1.4 Gen1/2/3/4/5/6 演进概述
PCIe 代际演进,核心就是两条线:单 Lane 速率和编码效率。我整理了一张表,把关键参数列出来,方便你做方案选型时快速查阅。
| 代际 | 单 Lane 速率 (GT/s) | 编码方案 | x16 总带宽 (GB/s) | 信号摆幅 (mV) | 均衡化 |
|---|---|---|---|---|---|
| Gen1 | 2.5 | 8b/10b | 4 | 800~1200 | 无 |
| Gen2 | 5.0 | 8b/10b | 8 | 800~1200 | 无 (可选项) |
| Gen3 | 8.0 | 128b/130b | 16 | 800~1200 | CTLE + DFE 必需 |
| Gen4 | 16.0 | 128b/130b | 32 | 800~1200 | CTLE + DFE 必需 |
| Gen5 | 32.0 | 128b/130b | 64 | 800~1000 | CTLE + DFE + TX FIR |
| Gen6 | 64.0 | PAM-4 + 242b/257b | 128 | 约 400~800 | 多抽头均衡化 |
几点体会:
- Gen1 → Gen2:速率翻倍,但编码还是 8b/10b,有 20% 的编码开销。链路训练流程基本一致,兼容性很好。
- Gen3:是个分水岭。128b/130b 编码让有效带宽大增,但代价是必须引入 CTLE 和 DFE 来对抗信道损耗。我有个朋友做服务器主板,Gen3 信号眼图总是张不开,最后发现是 PCB 过孔残桩没处理好,换了背钻工艺才解决。
- Gen4:速率再翻倍,对 PCB 材料的要求更高了。低损耗的 Megtron 6 或更高级的材料是常态。做 Gen4 时,我个人习惯一定要做全通道仿真,尤其是包含连接器的链路。
- Gen5:32 GT/s,NRZ 调制的巅峰。TX FIR 滤波器在这里成了标配,用于预加重和去加重。信道插损预算一般要求在 28 dB 以内(Nyquist 频率)。你想想看,28 dB 的衰减意味着接收到的信号幅度只有发射端的 1/25 左右,差一点都不行。
- Gen6:改用 PAM-4 调制,每个符号携带 2 bit 信息,加上 242b/257b 编码。速率达到了 64 GT/s,但信号电压裕量大幅缩小,均衡化复杂度也成倍增加。我目前在做 Gen6 的预研项目,光是 CTLE 的离散极点配置就调了三个版本。