4、PCIe Switch核心参数:端口数量与类型(上游/下游)、通道宽度(x1/x2/x4/x8/x16)、数据包路由机制(ID路由、地址路由、隐式路由)
各位工程师朋友,咱们接着聊。上一章我们把PCIe Switch的拓扑结构讲清楚了,这一章我打算深入它的“内脏”——也就是那些你在选型时不得不看的核心参数。
说实话,很多刚接触PCIe的工程师,拿到Switch的Datasheet就懵了。端口数量、通道宽度、路由机制……这些词看着都认识,但真到选型时,往往不知道该优先看哪个。我当年也踩过这个坑,所以今天咱们就把它彻底掰开揉碎。
4.1 端口数量与类型:上游与下游的“身份”差异
先讲端口。一个PCIe Switch,说白了就是一堆端口的集合。但端口不是平等的,它分两种:上游端口(Upstream Port)和下游端口(Downstream Port)。
怎么区分?很简单。离CPU近的那个叫上游,离设备近的那个叫下游。上游端口通常只有一个,负责和Root Complex(RC)通信。下游端口可以有多个,每个接一个Endpoint(EP)或者另一个Switch。
我在项目中遇到过一种情况:有人把下游设备接到了上游端口上,结果系统死活枚举不出来。嗯,这里要注意——上游端口和下游端口的电气特性虽然一样,但协议层的角色完全不同。上游端口只能连接RC或上游Switch,下游端口只能连接EP或下游Switch。你反过来接,链路能训练成功,但事务层包(TLP)的转发逻辑会乱套。
端口数量怎么选?这取决于你的系统需要挂多少个设备。比如你有一个x16的CPU接口,想接4个x4的NVMe SSD,那你就需要一个至少带1个上游端口和4个下游端口的Switch。但要注意,端口数量越多,Switch内部的Crossbar(交叉开关)越复杂,延迟和功耗也会相应增加。
4.2 通道宽度:x1、x2、x4、x8、x16 怎么选?
通道宽度,就是Lane的数量。x1就是1对差分线(TX+RX),x16就是16对。这个参数直接决定了带宽。
很多人觉得“通道越宽越好”,其实不然。我见过一个项目,CPU只支持x4的接口,结果选了个x16的Switch,白白浪费了12个Lane,还多花了钱。你想想看,通道宽度必须和上下游匹配。
举个例子:
- 上游端口是x8,下游接了4个x4的设备。这时候Switch内部需要做“带宽拆分”——把x8的带宽分给4个x4用。
- 如果上游是x16,下游接了8个x1的设备,那就更浪费了。因为x1设备根本用不完带宽。
我个人习惯的做法是:先算总带宽需求,再反推通道宽度。比如你的下游设备总带宽需要32 GT/s(PCIe 3.0 x8),那上游至少也得是x8,否则就会成为瓶颈。
另外,通道宽度还影响PCB布局。x16需要16对差分线,走线长度要等长,阻抗要控制。我建议你在设计初期就和Layout工程师沟通好,别等到布线时才发现空间不够。
4.3 数据包路由机制:ID路由、地址路由、隐式路由
这部分是Switch的核心中的核心。数据包(TLP)进入Switch后,怎么知道该往哪个端口走?靠的就是路由机制。PCIe定义了三种路由方式:ID路由、地址路由、隐式路由。
4.3.1 ID路由:基于BDF(Bus:Device.Function)
ID路由是最常用的。每个PCIe设备都有一个唯一的BDF号,比如00:00.0。Switch内部维护一张路由表,根据TLP头部的BDF号,决定转发到哪个端口。
我记得有一次调试,发现某个设备总是无法被访问。查了半天,原来是Switch的路由表没有正确配置。说白了,ID路由依赖系统枚举时分配的BDF号。如果枚举顺序乱了,路由表就会出错。
ID路由的优点是精确,缺点是路由表需要动态更新。系统启动时,BIOS或OS会枚举所有设备,然后配置Switch的路由表。这个过程叫“配置空间扫描”。
4.3.2 地址路由:基于内存地址或IO地址
地址路由用于Memory Read/Write和IO Read/Write请求。Switch根据TLP中的目标地址,查找内部地址映射表,决定转发到哪个端口。
举个例子:CPU要写数据到某个设备的BAR空间,地址是0xF000_0000。Switch收到这个TLP后,会检查地址映射表。如果0xF000_0000属于下游端口3的设备,就把包转发到端口3。
地址路由的好处是灵活,不需要知道设备的BDF号。但坏处是,地址映射表需要提前配置好。如果地址冲突,或者映射表没更新,包就会丢。
4.3.3 隐式路由:用于特殊消息
隐式路由最特殊。它不依赖BDF号,也不依赖地址,而是靠TLP头部的“路由类型”字段来决定。主要用于一些特殊消息,比如PME(电源管理事件)、Error Message等。
隐式路由的规则是:所有Switch端口都会收到这个包,但只有符合条件的端口才会处理。比如PME消息,会从下游端口广播到上游端口,最终到达RC。
你想想看,这种路由方式其实很像“广播”。但PCIe不允许随意广播,只有特定类型的消息才能用隐式路由。我刚开始学的时候,总觉得隐式路由很神秘,后来发现它其实就是一种“定向广播”。
4.4 三种路由的协同工作
在实际系统中,这三种路由是同时存在的。一个TLP进入Switch后,Switch会先检查TLP头部,判断用哪种路由方式:
- 如果是Memory/IO请求,用地址路由。
- 如果是Configuration请求,用ID路由。
- 如果是特殊消息,用隐式路由。
Switch内部有一个路由引擎,它会根据TLP类型,自动选择对应的路由表。这个过程是硬件完成的,不需要软件干预。但路由表的内容,必须由软件(BIOS或驱动)在初始化时配置好。
4.5 选型实战建议
最后,我总结一下选型时的核心思路:
- 先定端口数量:数一下你需要挂多少个设备,留1-2个冗余端口。
- 再定通道宽度:计算总带宽需求,确保上游带宽不小于下游总带宽。
- 最后看路由能力:确认Switch支持ID路由和地址路由,并且路由表大小足够。
另外,别忘了看Datasheet里的“路由表深度”参数。有些低端Switch的路由表只有几十条,如果你的系统设备很多,可能会不够用。
嗯,这一章的内容就到这里。下一章我会讲Switch的流控和缓冲区管理,那才是真正考验系统设计能力的地方。咱们下回见。