第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.020032.5 GT/s8b/10b250 MB/s
PCIe 2.020075.0 GT/s8b/10b500 MB/s
PCIe 3.020108.0 GT/s128b/130b≈985 MB/s
PCIe 4.0201716.0 GT/s128b/130b≈2.0 GB/s
PCIe 5.0201932.0 GT/s128b/130b≈4.0 GB/s
PCIe 6.0202264.0 GT/sPAM4 + 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一下子就暴露了。

PCIe协议分层架构 物理层 (PHY) 电气信号 · LTSSM · 编码 · 时钟恢复 数据链路层 (DLL) 序列号 · LCRC · ACK/NAK · 重传 事务层 (TL) TLP打包 · 事务类型 · 流量分类 · 序号 设备核心层 / 软件层 配置空间 · BAR · 驱动 · 中断 验证关注点 TLP格式错误 / DLL重传风暴 / LTSSM卡死 常见抓包工具解析 违反Ordering / 跨层字段不一致

1.3 应用场景

PCIe不是万能总线,但它的应用场景非常集中。我个人归纳一下,大概分三类:

  1. 高性能计算与AI加速——GPU / FPGA / DPU之间的互联。我见过一个8卡GPU工作站,所有卡通过PCIe Switch连接,开启Resizable BAR后性能提升15%。这个场景对带宽和延迟极其敏感,PCIe 4.0起步,5.0/6.0是趋势。
  2. 存储扩展——NVMe SSD几乎全部走PCIe。以前SATA SSD不到600MB/s,现在PCIe 4.0 x4的NVMe能跑到7GB/s。我刚做验证的时候,帮客户定位过一块NVMe盘在热插拔后链路协商降速的问题,查了半天发现是物理层ESD保护电路导致阻抗不匹配。
  3. 嵌入式与消费电子——WiFi模块、有线网卡、图像采集卡。这类设备通常只用x1或x2链路,但对功耗和成本敏感。我记得有一个摄像头项目,为了省PIN脚,硬是把PCIe x2降成x1用,还得在驱动里做带宽收敛。

踩坑提醒:曾经有个客户,把PCIe 5.0的板卡插到PCIe 3.0的slot里,结果链路速率一直协商在2.5GT/s——因为PCB走线过长导致信号衰减,LTSSM退回到了Gen1。嗯,这里要注意:链路能力协商受物理层质量影响很大,不是软件设一下就能跑满的。

从验证角度,我个人最怕的是业务层和协议层之间的语义扭曲。比如驱动认为写了一个4字节,但事务层生成了一个长度字段为0的TLP——这种事抓一次包就原形毕露。所以做PCIe验证,一定要敢上协议分析仪抓实物波形,光看仿真波形有时候发现不了电气层和链路层的协同问题。