3. 物理层基础:差分信号、通道、链路宽度、速率
好,咱们开始聊物理层的基础概念。说实话,你要是把PCIe链路初始化比作一场舞蹈,那物理层就是舞者的身体和舞台。身体不行,舞跳得再好也没用。这章的内容,说白了就是搞清楚这套通信系统的“物理底子”长什么样。
3.1 差分信号:为什么不用单端?
PCIe用的是差分信号,不是传统的单端信号。你别觉得这是小事,我当年刚接触SerDes的时候,差点被这个概念绕进去。
所谓差分信号,就是用一对线(D+和D-)来传一个信号。发送端在这对线上摆出幅度相等、极性相反的电压。接收端只看两根线的差值,不看它们各自对地的值。
核心优势:共模抑制
外部噪声(比如电源纹波、串扰)会同时耦合到D+和D-上。接收端一相减,噪声就被抵消了。这就是差分信号能在高频下跑几米甚至几十厘米的原因。
我举一个实在的例子:在PCIe Gen3(8 GT/s)的物理层,眼图张开的幅度可能只有几百毫伏。要是用单端信号,稍微一点地弹就能把眼图闭掉。差分信号在这里是刚需,不是锦上添花。
3.2 通道(PCIe Lane):一条差分对就够了?
PCIe里把一对差分发送线 + 一对差分接收线,叫作一条Lane。注意,一条Lane是4根线:发送差分对(Tx+ / Tx-)和接收差分对(Rx+ / Rx-)。
为什么发送和接收要分开?因为PCIe是全双工的。你可以同时发和收,不需要像I2C那样切换方向。这对于降低延迟太重要了。我记得有一次做FPGA调试,有人问能不能把Tx和Rx短接复用,省引脚。嗯,这想法很危险,你想想看,SerDes收发器的内部偏置完全不同,短接等于给自己埋雷。
个人经验:早期PCIe 1.0的物理层,每条Lane需要大约200mW的功耗。现在PCIe 5.0/6.0的同一条Lane功耗更高,但速率提升了10倍以上。你算算能效比,就知道技术进步有多夸张。
3.3 链路宽度(Link Width):到底捆几条Lane?
这个概念相对好理解。一条Lane叫x1,两条捆在一起叫x2,四条叫x4,依此类推,直到x16。PCIe规范允许的宽度是:x1、x2、x4、x8、x12、x16。注意,没有x3、x5、x10。
链路宽度是由硬件决定的,但可以在初始化时协商。比如一个x16的插槽,你插一块x8的卡,双方协商后就会以x8模式工作。不会出现不兼容的情况。我遇到过有人焊板子,x8的接口只拉了x4的走线,结果卡只能工作在x4,性能掉了一半。教训:Layout阶段就要把宽度的约束和PCB走线对齐,不要等板子回来再后悔。
| 宽度 | Lane数量 | 典型场景 |
|---|---|---|
| x1 | 1 | 网卡、扩展卡(低带宽) |
| x4 | 4 | NVMe SSD、内置RAID卡 |
| x8 | 8 | 高端GPU(部分)、万兆网卡 |
| x16 | 16 | GPU、高性能加速卡 |
宽度协商是链路训练的第一步。如果连接的两端在物理上能支持的最大宽度不一样,就取最小值。比如x16插槽插了x4卡,结果就是x4。核心参数叫最大Lane数(Max Link Width),由PCIe配置空间的Device Capability寄存器给出。
我曾经踩过的坑:有些平台会限制x16插槽只能跑x4,原因是BIOS里设置了gen x4 override。你安装了一张高性能GPU,系统却只能以x4启动,性能直接砍半。排查这种问题非常痛苦:先查槽位机械宽度,再查电气连接,最后发现是BIOS选项没改。所以遇到链路宽度异常,第一件事就是去BIOS里看PCIe的Subsystem设置。
3.4 速率(Transfer Rate):从Gen1到Gen5
PCIe每代速率几乎是翻倍增长的。注意我说的是数据传输速率,单位是GT/s(Giga Transfers per second),不是GB/s。每条Lane的原始带宽 = 速率 × 编码效率(8b/10b或128b/130b)。
表格列一下,你一看就明白:
| 代际 | 速率(GT/s) | 编码方式 | 有效带宽 / Lane(GB/s) |
|---|---|---|---|
| Gen1 | 2.5 GT/s | 8b/10b | 0.25 GB/s |
| Gen2 | 5.0 GT/s | 8b/10b | 0.50 GB/s |
| Gen3 | 8.0 GT/s | 128b/130b | 0.985 GB/s |
| Gen4 | 16.0 GT/s | 128b/130b | 1.969 GB/s |
| Gen5 | 32.0 GT/s | 128b/130b | 3.938 GB/s |
这里要注意一下编码方式的差异。Gen1和Gen2用8b/10b编码,每10 bits才传8 bits有效数据,20%的开销。到了Gen3,改用了更高效的128b/130b,开销只有约1.5%,所以带宽提升非常明显。嗯,这也是为什么Gen3之后,同样速率提升一倍,但有效带宽几乎翻倍还多一点。
3.5 调制方式:NRZ vs PAM4
到了PCIe 6.0,事情又变了。PCIe 6.0在物理层引入了PAM4调制,而不是传统的NRZ。NRZ每UI(单位间隔)传1 bit,PAM4每UI传2 bits,所以能在不提高时钟频率的前提下翻倍速率。
我提醒你注意一个关键点:PAM4对信号噪声更加敏感。因为电压摆幅被分成了4个电平,信号裕量比NRZ小得多。这也是为什么PCIe 6.0引入了前向纠错(FEC)和更复杂的均衡算法。如果你在做PCIe 6.0的硬件设计,建议重点看接收端的均衡器和时钟恢复电路的设计,那才是最要命的地方。
一个实用建议:在设计PCB时,对于Gen1和Gen2,走线长度匹配可以放松一些(±5 mil以内基本没事)。但Gen3以上,尤其是Gen4/5,同一对差分线内的正负走线长度差必须控制在2 mil以内。串扰和回流地孔间距也有更严格的要求。我习惯在Layout阶段就把PCIe Gen3+的差分对当成RF走线来对待:连续地平面、避免90度拐角、整条线不能跨越分割的电源/地平面。
接下来说说链路训练时,这些物理参数是怎么协同工作的。你会看到:发端先发一系列特定的电气序列(比如电气空闲、转向、训练序列TS1/TS2),接收端通过检测信号边沿和码型来锁定比特对齐和Lane对齐。这些都是物理层的锅,后面几章会逐步展开。
避坑指南:我曾遇到一个案例,某款FPGA的PCIe硬核在Gen3速率下偶发训练失败。排查了整整两周,最后发现是参考时钟的抖动超标(Jitter超出了30 ps RMS)。换了低相噪的振荡器,问题立刻解决。所以,参考时钟质量直接决定了PCIe物理层的稳定下限。你做方案时,至少用100 MHz、±100 ppm、抖动小于5 ps(RMS)的晶振。
好,我们把物理层的核心概念串了一下:差分信号、Lane、Link Width、速率、调制。这些参数在PCIe链路初始化时都是必须协商确定的。下一节开始,我会介绍具体的握手流程——从复位到L0状态的完整路径。