1、PCIe基础概念:PCIe总线的起源与发展、PCIe与PCI的区别、PCIe的拓扑结构
大家好,我是你们的芯片验证讲师。今天咱们聊聊PCIe最基础的东西。
说实话,很多工程师干了三五年,对PCIe的认知还停留在“它很快”这个层面。但你要做链路训练、做故障定位,不懂这些底层的来龙去脉,后面会非常痛苦。我自己刚入行那会儿,就被一个链路训练失败的问题折磨了两周,最后发现是对拓扑结构理解有偏差。嗯,咱们今天就把这些地基打牢。
1.1 PCIe总线的起源与发展
PCIe的全称是Peripheral Component Interconnect Express,翻译过来就是“外围组件互连快速通道”。它诞生于2003年,由Intel、AMD、IBM等大佬联合推出。
为什么要搞PCIe?因为老大哥PCI(Peripheral Component Interconnect)实在跑不动了。PCI是并行总线,32位或64位宽,最高频率也就133MHz,理论带宽不过1GB/s。你想想看,2000年以后的显卡、网卡、存储卡,哪个不是嗷嗷待哺?PCI那点带宽根本不够分。
PCIe从1.0一路发展到5.0、6.0,甚至7.0已经在路上了。我简单列个表,大家感受一下这个速度的飞跃:
| 版本 | 单通道速率 | 编码方式 | 发布年份 |
|---|---|---|---|
| PCIe 1.0 | 2.5 GT/s | 8b/10b | 2003 |
| PCIe 2.0 | 5.0 GT/s | 8b/10b | 2007 |
| PCIe 3.0 | 8.0 GT/s | 128b/130b | 2010 |
| PCIe 4.0 | 16.0 GT/s | 128b/130b | 2017 |
| PCIe 5.0 | 32.0 GT/s | 128b/130b | 2019 |
| PCIe 6.0 | 64.0 GT/s | PAM4 + FLIT | 2022 |
注意看编码方式的变化。从1.0到2.0用的8b/10b编码,说白了就是每传8位有效数据,实际要发10位,20%的带宽浪费掉了。到了3.0改用128b/130b,效率直接拉到99%以上。我个人觉得,这是PCIe历史上最漂亮的一次升级。
核心要点:PCIe的每一次版本升级,核心目标都是“更快、更省、更可靠”。链路训练状态机也是随着版本迭代不断优化的,但基础框架从1.0到现在基本没变。
1.2 PCIe与PCI的区别
很多新手会问:PCIe和PCI,名字就差一个字母,到底差在哪?
我直接说结论:这是两种完全不同的总线架构。
PCI是并行总线,所有设备共享一套地址、数据、控制线。你想想看,一个共享的通道,大家排队用,效率能高吗?而且并行总线有个天然缺陷——信号同步。频率一高,线之间的串扰、时钟偏斜全来了。PCI到133MHz基本就到头了,再往上走,信号质量根本没法看。
PCIe就不一样了。它是串行差分总线,采用点对点连接。每个设备都有自己的专用通道,不用跟别人抢。而且串行信号天生抗干扰能力强,频率可以轻松拉到GHz级别。
我列个对比表,大家一目了然:
| 对比项 | PCI | PCIe |
|---|---|---|
| 总线类型 | 并行共享总线 | 串行点对点 |
| 信号方式 | 单端信号 | 差分信号 |
| 带宽 | 最高1GB/s | 单通道可达2GB/s(5.0) |
| 可扩展性 | 差,受限于负载 | 好,通过Switch扩展 |
| 热插拔 | 不支持 | 原生支持 |
| 配置方式 | 硬件跳线/BIOS | 软件枚举+配置空间 |
避坑指南:我曾经在项目中遇到一个同事,把PCIe的REFCLK当成普通时钟来处理,结果链路死活训练不过。记住,PCIe的差分时钟对抖动和相位噪声要求极高,不是随便一个晶振就能用的。
1.3 PCIe的拓扑结构
PCIe的拓扑结构,说白了就是一个树形结构。三个核心角色:Root Complex(根复合体)、Switch(交换器)、Endpoint(端点设备)。
我画了一张图,帮大家理解这个结构:
我来逐一解释这三个角色:
1.3.1 Root Complex (RC)
RC是整个PCIe层次结构的根节点。它连接CPU、内存和PCIe总线。说白了,RC就是CPU和外部设备之间的“翻译官”和“交通警察”。
在验证工作中,RC的链路训练是最关键的。我见过很多板卡,RC侧的REFCLK质量不好,导致下游设备怎么都训练不上。嗯,这里要注意,RC通常集成在CPU或芯片组里,我们做验证时,要重点关注RC发出的Configuration Space访问请求。
1.3.2 Switch
Switch相当于一个PCIe的“集线器”。它可以把一个上行端口扩展成多个下行端口。注意,Switch内部其实是由多个虚拟PCI-to-PCI桥组成的。
我个人习惯把Switch想象成一个火车站。上行端口是进站口,下行端口是各个站台。数据包就像火车,从进站口进来,根据目的地(BDF地址)被分配到对应的站台出去。
重要提醒:Switch不是简单的信号中继器。它内部有完整的TLP(事务层包)路由逻辑和流量控制机制。在链路训练时,Switch的每个端口都要独立完成训练,一个端口失败不影响其他端口。但如果是上行端口训练失败,整个Switch下面的所有设备都会掉线。
1.3.3 Endpoint
Endpoint就是最终的功能设备。显卡、网卡、NVMe硬盘、FPGA加速卡,这些都是Endpoint。它们不负责转发数据,只负责消费或产生数据。
Endpoint的链路训练相对简单,因为它只需要跟上游的RC或Switch端口建立连接。但简单不代表容易。我曾经遇到一个Endpoint,它的LTSSM(链路训练状态机)在Polling状态反复跳转,最后发现是发送端的电气参数没配好。这种问题,示波器一抓就能看到眼图是闭的。
1.4 拓扑结构中的关键概念
除了上面三个角色,还有几个概念你必须搞清楚:
- BDF地址:Bus(总线号)、Device(设备号)、Function(功能号)。每个PCIe设备在枚举时都会被分配一个唯一的BDF地址。比如00:1f.2,表示总线0、设备31、功能2。
- 配置空间:每个PCIe设备都有256字节的标准配置空间(Type 0或Type 1)。链路训练完成后,软件通过配置空间读取设备的能力和状态。
- VC(Virtual Channel):虚拟通道。PCIe支持多个VC,用于区分不同优先级的数据流。链路训练时,VC0是必须建立的,其他VC可选。
个人经验:在做链路训练故障定位时,我建议你先用逻辑分析仪抓一下Configuration Space的访问时序。如果RC能成功读取到设备的Vendor ID和Device ID,说明链路训练已经完成了物理层和数据链路层的握手。剩下的问题大概率在事务层或软件配置上。
好了,这一章的内容就到这里。PCIe的基础概念是后面所有章节的基石。你把这些搞懂了,后面讲链路训练状态机、讲故障定位方法,你才能听得明白、用得顺手。
公众号:蓝海资料掘金营,微信deep3321