第1章 PCIe协议概述
说起PCIe,做验证的兄弟应该都不陌生。这个接口几乎统治了现代计算机里几乎所有高速互联——从CPU到显卡,从SSD到网卡,到处都有它的影子。我最早接触PCIe是在十多年前做一块服务器主板的时候,那时候PCIe 2.0刚普及,大家还在纠结到底要不要上3.0。现在回头一看,PCIe 6.0都已经在路上了,想想挺感慨的。
这一章咱们先聊清楚三件事:PCIe怎么一路发展到今天的?它的协议栈到底分了哪几层?什么场景必须上PCIe而不是其他总线?你把这些搞明白了,后面看波形、抓包排查的时候才不会两眼一抹黑。
1.1 PCIe的发展历史
PCIe的前身是PCI(Peripheral Component Interconnect),一种并行总线。我记得早年修一台老服务器,插个千兆网卡还得调中断共享,一个设备掉线整条总线都得崩。说白了,并行总线的布线长度、频率、信号完整性问题已经到了天花板。
2003年PCI-SIG发布了PCIe 1.0,彻底转向点对点串行差分传输。我上手第一块PCIe 1.0 X1的网卡,跑2.5GT/s,心想这速度够用了。结果两年后显卡需求一上来,PCIe 2.0(5GT/s)就来了。接着是PCIe 3.0(8GT/s)、4.0(16GT/s)、5.0(32GT/s),再到2022年发布的6.0(64GT/s,PAM4编码)。
很多人问我为什么迭代这么快?你想想看,AI训练集群里GPU之间的互联,没有足够的带宽根本喂不饱计算单元。我去年参与的一个项目,用PCIe 5.0连了四个GPU,协商链路宽度X16,峰值带宽接近64GB/s——放在十年前根本不敢想。
| 版本 | 发布年份 | 单通道速率 | 编码方式 | 单通道有效带宽 |
|---|---|---|---|---|
| PCIe 1.0 | 2003 | 2.5 GT/s | 8b/10b | 250 MB/s |
| PCIe 2.0 | 2007 | 5.0 GT/s | 8b/10b | 500 MB/s |
| PCIe 3.0 | 2010 | 8.0 GT/s | 128b/130b | ≈985 MB/s |
| PCIe 4.0 | 2017 | 16.0 GT/s | 128b/130b | ≈2.0 GB/s |
| PCIe 5.0 | 2019 | 32.0 GT/s | 128b/130b | ≈4.0 GB/s |
| PCIe 6.0 | 2022 | 64.0 GT/s | PAM4 + FLIT | ≈7.6 GB/s |
小提示:编码方式的变化很关键。8b/10b有20%开销,128b/130b只有1.5%左右。到了PCIe 6.0改用PAM4和FLIT打包,误差更小但物理层调试难度直接翻倍。我第一次调PAM4信号时,眼图睁开不到30%,折腾了两周才搞定。
1.2 架构分层
PCIe协议用了一种分层架构,跟网络里的OSI模型有点像。一共四层:设备核心层(软件层)、事务层、数据链路层、物理层。咱们做验证抓包,其实主要跟后面三层打交道。
- 设备核心层(软件层)——就是驱动和OS做的事,我们做验证通常通过配置空间和BAR访问来模拟它。说白了,这一层发的是读/写请求,不管怎么打包传到底层。
- 事务层(TL层)——这一层生成TLP(事务层包)。分成四个基本类型:MRd(存储器读)、MWr(存储器写)、配置读写、消息。我习惯叫它“快递打包处”,把软件要的操作装进包裹贴上标签。
- 数据链路层(DLL层)——负责可靠传输。加序列号(Seq Number)、CRC校验(LCRC),还有ACK/NAK重传机制。我曾经在分析一次链路超时问题时,发现DLL层连续收到NAK导致重传风暴,差点把带宽吃光。
- 物理层(PHY层)——处理电气信号、编码、时钟恢复、链路训练状态机(LTSSM)。抓包时看到链路不断的“训练-训练-空闲”,多半是物理层没Lock住。
作为验证工程师,我的经验是:8成的Bug都出在事务层与数据链路层的交互边界上。比如TLP长度字段填错、TD字段位搞反、DLLP与TLP顺序乱掉……这些你单看协议文本很难发现,抓一次真实的PCIe trace一下子就暴露了。
1.3 应用场景
PCIe不是万能总线,但它的应用场景非常集中。我个人归纳一下,大概分三类:
- 高性能计算与AI加速——GPU / FPGA / DPU之间的互联。我见过一个8卡GPU工作站,所有卡通过PCIe Switch连接,开启Resizable BAR后性能提升15%。这个场景对带宽和延迟极其敏感,PCIe 4.0起步,5.0/6.0是趋势。
- 存储扩展——NVMe SSD几乎全部走PCIe。以前SATA SSD不到600MB/s,现在PCIe 4.0 x4的NVMe能跑到7GB/s。我刚做验证的时候,帮客户定位过一块NVMe盘在热插拔后链路协商降速的问题,查了半天发现是物理层ESD保护电路导致阻抗不匹配。
- 嵌入式与消费电子——WiFi模块、有线网卡、图像采集卡。这类设备通常只用x1或x2链路,但对功耗和成本敏感。我记得有一个摄像头项目,为了省PIN脚,硬是把PCIe x2降成x1用,还得在驱动里做带宽收敛。
踩坑提醒:曾经有个客户,把PCIe 5.0的板卡插到PCIe 3.0的slot里,结果链路速率一直协商在2.5GT/s——因为PCB走线过长导致信号衰减,LTSSM退回到了Gen1。嗯,这里要注意:链路能力协商受物理层质量影响很大,不是软件设一下就能跑满的。
从验证角度,我个人最怕的是业务层和协议层之间的语义扭曲。比如驱动认为写了一个4字节,但事务层生成了一个长度字段为0的TLP——这种事抓一次包就原形毕露。所以做PCIe验证,一定要敢上协议分析仪抓实物波形,光看仿真波形有时候发现不了电气层和链路层的协同问题。