PCIe协议基础(一):体系结构、分层模型与拓扑
各位同学,今天我们来聊聊PCIe协议的基础。说实话,PCIe这玩意儿,我刚入行时也觉得挺玄乎的。那么多层,那么多信号,看着就头大。但后来我发现,只要把它的骨架搭起来,剩下的细节其实都是水到渠成的事。
我个人习惯把PCIe理解成一个“高速公路系统”。物理层是路面和车道,数据链路层是交通规则,事务层则是你车上拉的那批货。嗯,这么一想,是不是清晰多了?
1. PCIe体系结构:从并行到串行的革命
老一点的工程师可能还记得PCI总线。那是个并行总线,32位或64位数据线一起跑。但并行总线有个硬伤——频率一高,信号之间串扰严重,时序根本对不齐。我记得当年调试PCI时,为了等长布线,板子画得跟迷宫似的。
PCIe彻底抛弃了并行方案。它改用串行差分信号,一对差分线就是一个Lane。说白了,就是一根线发数据,一根线收数据,各走各的道。这样做的好处是频率可以拉得极高——从最初的2.5GT/s(Gen1)一路干到现在的32GT/s(Gen5)甚至更高。
你想想看,串行传输虽然单线速率高,但一条Lane的带宽毕竟有限。怎么办?多搞几条Lane并联呗。这就是x1、x4、x8、x16的由来。x16就是16条Lane同时干活,带宽直接乘以16。
核心要点:PCIe是点对点串行总线,每个设备独享带宽。不像老PCI那样共享一条总线,谁抢到谁用。
2. 分层模型:三层架构各司其职
PCIe协议栈分为三层:事务层(Transaction Layer)、数据链路层(Data Link Layer)、物理层(Physical Layer)。每一层只干自己的活,上层只管发命令,下层只管传比特。这种分层设计,说白了就是为了解耦——改物理层不影响事务层,改事务层也不影响物理层。
下面这张图是我自己画的,把三层模型和它们之间的交互关系展示得很清楚:
3. 事务层:你的数据快递员
事务层是离软件最近的一层。CPU发一个读内存的命令,事务层就把它打包成一个TLP(Transaction Layer Packet)。TLP里包含了地址、长度、请求类型等信息。
事务层主要处理四种请求类型:
- 存储器事务:最常用,读写系统内存。我项目中90%以上的流量都是这个。
- IO事务:兼容老设备用的,现在基本绝迹。
- 配置事务:枚举设备、分配资源时用。系统启动时全靠它。
- 消息事务:中断、错误报告等带外信息。
避坑指南:我曾经在做一个NVMe SSD控制器时,发现写TLP的Fmt和Type字段总是配错。后来仔细看了协议才发现——存储器读和存储器写的Fmt编码是不一样的。读请求不带数据,写请求才带数据。这个细节卡了我整整两天。
4. 数据链路层:保证不丢包
数据链路层干的事,说白了就是给TLP加个“快递单号”和“防伪标签”。它给每个TLP加上序列号(Sequence Number)和CRC校验码。接收方收到后,如果CRC校验通过,就回一个ACK包;如果校验失败,就回一个NAK包,要求重传。
这个机制叫ACK/NAK协议。为什么需要它?因为物理层虽然速度快,但偶尔也会出错。尤其是高频信号穿过连接器时,眼图可能闭合,误码率就上来了。数据链路层就是最后一道防线。
我记得有一次调试,发现链路偶尔丢包,但CRC又没报错。查了半天,原来是数据链路层的重传缓冲区溢出了。嗯,这个坑提醒我们——重传机制虽然好,但缓冲区大小一定要算够。
5. 物理层:比特搬运工
物理层分两个子层:逻辑子层和电气子层。
逻辑子层负责编码——Gen1/Gen2用8b/10b编码,Gen3及以上用128b/130b编码。8b/10b编码会把8位数据变成10位,多出来的2位用于直流平衡和时钟恢复。128b/130b更高效,开销只有1.5%。
电气子层负责差分信号的发送和接收。每条Lane有两对差分线——一对发(TX),一对收(RX)。信号摆幅很小,只有几百毫伏,所以功耗低、速度快。
物理层还有一个重要功能——链路训练。设备上电后,物理层会自动协商速率和宽度。比如一个x16的插槽,如果插了个x8的卡,物理层会自动降为x8模式。这个过程完全不需要软件干预。
注意:链路训练时,物理层会发送训练序列(TS1/TS2)。如果你用逻辑分析仪抓PCIe信号,看到一堆重复的0xAA、0x55,那就是在训练。别慌,等它训练完就好了。
6. 拓扑结构:树形连接
PCIe的拓扑结构是树形的。根节点叫Root Complex(RC),通常集成在CPU内部。叶子节点是各种Endpoint(EP),比如显卡、SSD、网卡。中间可以有Switch,用来扩展端口。
Switch内部其实是一个逻辑上的“路由器”。它把上游端口(Upstream Port)来的数据,根据地址转发到对应的下游端口(Downstream Port)。每个端口对应一条独立的PCIe链路。
为什么不用总线型?你想想看,如果所有设备都挂在一根线上,一个设备发数据,其他设备都得等着。PCIe的点对点拓扑,每个设备都有自己的专用通道,互不干扰。这才是高性能的保证。
我见过一个服务器主板,上面挂了十几个NVMe SSD,全部通过Switch连接到CPU。每个SSD独享x4带宽,同时跑满都没问题。这要是换成老PCI,早就卡死了。
7. 小结
这一章我们讲了PCIe的骨架——三层模型和树形拓扑。事务层管打包,数据链路层管可靠,物理层管传输。三层各司其职,配合默契。拓扑上,RC是根,EP是叶,Switch是中间节点,形成一棵倒挂的树。
下一章我们会深入事务层,看看TLP到底长什么样,各种请求类型怎么编码。嗯,到时候我会拿一个真实的抓包数据来拆解,保证让你看个明白。
公众号:蓝海资料掘金营,微信deep3321