立创开源PCIe Bifurcation:7款PCIe拆分板卡硬件设计详解与实战应用
入行硬件设计这些年,我越来越发现一个很有意思的现象:很多问题不是芯片不够强,而是接口不够用。明明CPU和主板上有那么大的PCIe通道带宽,但真正拿到手里能用的物理插槽就那么几个。尤其在搞NAS、AI推理、FPGA加速或者多网卡测试的时候,一块显卡位占着x16的槽却只用了x8甚至x4的带宽,旁边想再插个M.2硬盘、采集卡或者光纤网卡,却发现没有槽位了。
PCIe Bifurcation(PCIe拆分)就是为了解决这个问题出现的。简单说,它可以把一个物理的PCIe x16插槽拆成多个独立的逻辑通道组,比如拆成4个x4、8个x2,再通过拆分板卡转接成M.2、U.2、SlimSAS甚至标准PCIe插槽,让一块卡位上同时跑多个设备。我这次整理的是立创开源平台上7款PCIe拆分板卡的硬件设计,从原理到布线、从选型到量产,把能踩的坑和能省的时间都写出来,希望对正在做类似板卡或者想扩展设备的你有参考价值。适合硬件工程师、电子爱好者、NAS玩家以及搞AI服务器扩展的朋友。
1. PCIe Bifurcation 到底是做什么的
很多人第一次接触这个词,第一反应是“这不就是转接线吗”。但从硬件设计角度讲,转接和拆分完全是两码事。转接只是物理上改变接口形态,而拆分是深入到协议层把通道重新分配,涉及CPU、主板BIOS、时钟、复位和电源的完整配合。
1.1 通道拆分的基本逻辑
PCIe链路最基本的组成单位是lane,也就是一对差分收发线。一根lane在Gen3速率下双向带宽大约是985 MB/s左右,Gen4翻倍到约1.97 GB/s,Gen5能达到3.94 GB/s。一个标准PCIe x16插槽就是16对收发差分对,如果只挂一个设备确实浪费。
Bifurcation做的事情,就是把x16这条链路的16个lane按规则拆成n组,每组独立定时和同步,连接不同的下游设备。最常见的拆分方式是 x16拆4个x4、x16拆8个x2、x8拆2个x4、x8拆4个x2。需要注意的是,拆分并不是无限的,每组至少要有x1,而且拆分粒度由CPU的Root Complex(根复合体)和BIOS共同决定,不是板卡上跳线就能随便改的。
我把这个逻辑用大白话翻译一遍:你家入户宽带是1000M,原来只接了一台电脑,现在你想同时接电脑、电视、游戏机,就得有一个路由器把宽带拆成几路。PCIe Bifurcation里的拆分板卡就相当于那个“路由器”,但前提是你家运营商(CPU)允许你这个套餐能拨多路(BIOS里开Bifurcation)。
1.2 哪些平台支持拆分
这是整个方案能不能落地的关键。就我在实际项目中测过和查过资料汇总来看,Intel平台从Z77以后的部分主板开始支持部分拆分,但消费级主板普遍不开放,反而是服务器板子比如X99、C621、W480这一类支持比较完整。AMD从Ryzen一代开始,X370/B350以上芯片组普遍支持,到500系、600系基本成了标配。新款的线程撕裂者(TRX40/TRX50)和EPYC平台更不用说,x16拆x4/x4/x4/x4这种是基本功。
保险的做法是:动手画板之前,先用CPU和主板的规格书确认Bifurcation支持列表。我遇到过最尴尬的一次,板子做出来发现用户是B660主板,BIOS里根本没有Bifurcation选项,整块卡直接识别不到任何设备。后来查资料才知道,B660的PCIe通道拆分被芯片组限制了,只能在特定插槽上支持x4+x4。所以如果有条件,尽量用工作站或服务器平台做验证。
1.3 拆分方式的两条路线:被动式与Switch芯片
市面上的拆分板卡大概分两类。第一类是全被动式,板上没有任何协议芯片,靠CPU Root Port本身对下行端口的管理能力完成拆分,PCB上只要做好高速差分走线、电源、时钟、复位信号的分配就行。第二类是主动式,板上装了一颗PCIe Switch(比如PLX/Broadcom PEX系列、Microchip的Switchtec系列),相当于先把上游x16收进来,再通过芯片内部的交换矩阵分配到下游多端口。
被动式板卡设计简单、成本低、BOM零件少,但下游设备必须是标准PCIe设备,且不能跨拆分域通信,因为拆分域之间的数据交换还得靠CPU内部Root Complex转发。主动式板卡能扩展出几十个设备、支持多主机、可以做非透明桥做故障隔离,但一颗Switch芯片几十片到上百片,外围还要配Flash、电源时序、串口调试接口,设计复杂度高一个量级。
我这次整理的7款开源板卡,绝大多数是被动式Bifurcation方案,属于“用最小成本榨干CPU通道”的路线。这个选择跟开源社区的目标人群有关系——大家做这个东西更多是为了解决实际扩容需求,而不是做企业级可用性。
2. 7款PCIe拆分板卡的硬件设计拆解
这次我选取的7款板卡覆盖了几个典型使用场景:M.2 NVMe硬盘扩展、U.2企业盘转接、PCIe插槽扩展、混合模式、以及SlimSAS/OCuLink形态的线缆式拆分。下面按功能分类逐个拆。
2.1 拆分板卡全览与选型参考
| 编号 | 板卡名称/形态 | 拆分方式 | 下游接口 | 典型场景 |
|---|---|---|---|---|
| #1 | PCIe x16转4路M.2 NVMe | x16拆4x4 | 4个M.2 M-Key | NAS/工作站高速盘阵列 |
| #2 | PCIe x16转8路M.2 NVMe | x16拆8x2 | 8个M.2 M-Key | 大数据缓存盘仓 |
| #3 | PCIe x16转4路U.2 | x16拆4x4 | 4个SFF-8639 | 企业级热插拔盘笼 |
| #4 | PCIe x8转2路M.2 NVMe | x8拆2x4 | 2个M.2 M-Key | 半高卡/小机箱扩容 |
| #5 | PCIe x16转2路PCIe x8插槽 | x16拆2x8 | 2个PCIe x8物理槽 | 双GPU推理/多网卡 |
| #6 | PCIe x16混合拆分卡 | x16拆x8+x4+x4 | 1个M.2 + 2个PCIe x4 | 盘卡混插场景 |
| #7 | PCIe x16转SlimSAS/OCuLink阵列 | x16拆4x4输出 | 4个SlimSAS x4或OCuLink x4 | 外接硬盘笼/服务器直连 |
这7款板卡形态差异挺大,但底层遵循的核心设计逻辑是相通的。我按照“信号完整性→电源完整性→机械结构→散热”四个维度分别展开,这也是我做所有高速板卡时的评审顺序。
2.2 第一款:PCIe x16转4路M.2 NVMe,最经典的流量担当
先说这款,因为它最通用,也是我推荐给新手复刻的第一块拆分卡。它的原理极其直白:金手指拿到x16的16对差分线,按每4对一组分成4组,分别走线到4个M.2插槽的A、B面相关引脚。板上没有任何控制芯片,唯一的“智能”体现在拆分模式选择上。
这里有个很微妙的地方:虽然主流是x16拆4x4,但有些CPU平台不允许直接拆成4x4,只支持x4x4x4x4或者x4x4x8这种带优先级的组合。为了防止做成板后不兼容,设计时可以预留一组拨码开关或0欧电阻来做拆分模式切换,让用户根据CPU能力选择是全速x4还是降级x2。
M.2插槽的机械结构设计也是坑点集中的地方。M.2规格书定义了Key M(支持PCIe x4)和Key B(支持PCIe x2/SATA),NVMe盘几乎都是Key M,所以4个插槽都要做成M-Key,同时要在板上留好M.2固定螺柱的位置,孔位最好按照2230、2242、2260、2280四个长度档位都做了,实测兼容性好很多。固定螺柱高度和型号要选好,我用的是M2x3铜柱加M2x3沉头螺丝,注意不要超高以免顶到上盖或显卡。
走线层面,Gen3板卡用4层板勉强能跑,但Gen4就必须上6层甚至8层。我设计时优先保证M.2插槽那一侧的参考面完整,因为M.2连接器本身是通孔器件,焊盘开窗前后的阻抗连续性是最容易出问题的地方。
2.3 第二款:x16转8路M.2,天生就是攒机神器
8路M.2拆分卡看起来惊艳,但设计难度陡增。难点主要不在PCIe信号,而在电源和空间。一个M.2 NVMe盘峰值功耗大概5W到8W,8块盘同时满载,光硬盘就要吃掉60W左右的12V功耗。PCIe插槽本身规定最大供电75W,所以板卡必须带独立辅助供电接口,我用的是双6pin PCIe电源座,每路最多提供75W,总计理论能到150W,给8块盘留了充足余量。
另一个要命的问题是M.2盘的散热。8个M.2全部在PCIe卡上,气流条件极差。我强烈建议做这种板卡时,要么把盘位对称分布在卡两侧,每侧四个,中间预留一个贯穿风道;要么直接用带主动风扇的散热器方案,否则你组装完毕通电一跑负载,盘温度上70度几乎是几分钟的事。开源PCB文件里有好几版过热问题的修改记录,最夸张的是1.0版跑CDM连续写入,盘掉温度墙降速,整体性能还不到标称的一半。
走线方面,8个x2端口一共16对差分线,从金手指出来必须分两个方向走,不然根本无法在4层板内完成等长和换层。为了避免串扰,不同拆分域之间的差分对间距至少做到15 mil以上,有条件就加地孔墙隔离。如果你用立创EDA做这板,建议直接把布线规则里的差分对线宽/间距设为“0.8mm板厚、JLC7628堆叠、5mil线宽、7mil间距、100欧姆阻抗”,这是低成本板材里最稳的参数之一。
2.4 第三款:x16转4路U.2,企业盘的接入门槛
U.2盘在企业级市场很常见,发热和性能都不错,但在家用的主板生态里几乎没有直连手段,这块卡要解决的问题就是让普通PC能接企业级U.2盘。
U.2接口从电气上看是SFF-8639,它同时兼容PCIe和SATA信号,所以板卡上除了PCIe信号走线外,还要考虑Sideband信号(比如LED控制、热插拔检测、PWM风扇、供电控制等)。开源设计里有一路I2C带了不少传感器,我实际测试下来,如果只做纯数据盘用,不接Sideband也能正常识别和读写,但要在BIOS里把热插拔功能关掉,否则系统日志里会刷满predictive failure相关的警告。
U.2盘的12V功耗更高,企业级NVMe盘标称25W左右,4块就是100W。除了辅助供电外,每一路还要单独做保险丝或者电子熔断器,防止单块盘短路把整块卡甚至主板一起带走。我踩过的坑是某品牌U.2盘的12V引脚上电瞬间冲击电流特别大,不加缓启动电路,板上的固态电容会发出滋滋的响声,甚至直接烧MOS管。后面解决方案是在每个U.2供电座前面加一颗负载开关(比如TI的TPS25921),硬生生把浪涌压住了。
2.5 第四款:x8转2路M.2半高卡,主打小机箱市场
这款卡设计的初衷很简单:很多ITX主板只有一个PCIe x16插槽,外形尺寸也限制在半高卡范围内,插一块显卡后剩余空间只能塞半高扩展卡。x8拆2x4,正好把Gen3 x8的极限带宽分成两块盘跑。
半高挡板的物理空间非常紧张,正常M.2插座的高度在3.6mm左右,两块盘并排需要约40mm宽的布线面积。我建议采用“两块M.2一正一反”的背靠背布局,这样PCB正反两个平面都用上了,既省面积又能顺便做个简单散热。因为卡是半高,很多小机箱的CPU散热器会完全覆盖PCIe区域,风道上几乎没有余量,所以设计时我特意把两个M.2插槽的距离拉开到25mm以上,方便贴小尺寸散热片。
这款x8卡还有一个隐藏价值:很多老平台的PCIe x16插槽实际上只连了x8信号,或者用户把卡插在了第二个x8槽上,这时候x8拆2x4反而刚好对上了,不会出现通道浪费。
2.6 第五款:x16转2路PCIe x8插槽,高带宽设备的并联方案
这款卡不转M.2,而是从PCIe金手指把x16拆成两个x8,分别引到板上的两个PCIe x8物理插槽。典型用途是插两块GPU做推理、插两块25G/100G网卡,或者插一块GPU加一块FPGA加速卡。
这个板卡看起来简单,实际设计时最讲究的两个点,一是插槽布局,二是供电。两个PCIe插槽之间需要有足够间距避免显卡散热冲突,我按双槽位间距设计,也就是相邻两个插槽中心距不小于41mm。PCIe插槽的卡扣和定位结构要选用带金属锁扣的版本,否则重量大的显卡装上去后尾部下垂,长期使用金手指接触会出现间歇性失效。
供电方面,每个PCIe插槽可以按75W设计,两个槽就是150W,除了金手指的供电外,12V辅助供电是必须的。不少用户会问“我显卡自带8pin电源,卡上还要辅助供电吗”,答案是看情况:如果你插的是全高双槽显卡,板卡会通过插槽给显卡主板部分供电,大部分功耗还是从显卡自己的电源口走的;但如果插了不带外接供电的刀卡或转接卡设备,整块板卡上的功耗就必须靠辅助供电兜底。所以稳妥方案是设计时在双PCIe插槽旁边留一个6pin或8pin辅助供电,同时在PCB叠加上标明最大持续电流。
2.7 第六款:x16拆x8+x4+x4混合卡,一个槽解决所有需求
混合卡是最能满足“一张卡干三件事”需求的形态。x16拆出一个x8口插一块显卡,再拆出两个x4口分别接NVMe盘和高速网卡,等于一个插槽位同时输出三类设备。
混合拆分的难点在于拆分模式配置。并不是所有主板都支持x8+x4+x4,有些只支持x8+x8或者x4+x4+x4+x4。为了兼容更多平台,这块卡我加了3组拨码开关,通过组合选择把金手指的16对差分线分配到下游三种端口上。如果你也想做这类卡,建议把拨码开关放在卡尾的档板开口处,这样不用开箱就能切换模式,实测比放板边的DIP开关好用很多。
但要注意,PCIe x8插槽的物理尺寸和x16区别很大,带宽和信号引脚分布也不同。为了兼容不同CPU的拆分能力,这块卡的x8物理插槽实际上放的是x8机械尺寸,但在x4模式下也能作为x4槽正常使用,信号定义完全兼容。我特意在PCB上把x8插槽的差分对走线分组明确打印出来,方便维修时用示波器快速定位链路训练阶段失败的具体lane。
2.8 第七款:x16转SlimSAS/OCuLink阵列,打破物理空间限制
前面6款卡所有的设备都板载在这块PCIe卡上,遇到主板空间不够、机箱位置不理想时就很尴尬。第七款换了个思路:把x16拆成4个x4,通过SlimSAS或OCuLink接口用线缆拉出去,另一端接专门的硬盘笼或机箱背板。
SlimSAS(也叫SFF-8654)和OCuLink(SFF-8612)都是支持PCIe x4信号的高速连接器,带宽和密度都不错。设计时关键要处理好连接器的差分对引脚分配、线缆长度预算和连接器本身的封装占位误差。OCuLink线缆通常能买到30cm到1m长度的,线缆质量好的情况下Gen3信号在30cm内几乎没有眼图劣化,但Gen4最好控制在半米以内并选用品牌线材,不然链路训练时掉LinkTrain的概率大幅上升。
这种外置形态的另一个好处是散热和供电可以放到硬盘笼那一侧,PCIe卡上不用堆一堆电容和功率器件,整板面积能缩小不少。不过这也就意味着卡本身和硬盘笼之间的连接需要有完整的供电链路和状态指示,至少要在接口旁边放上power good和activity两个LED。开源设计里还做了一个非常实用的功能:通过I2C读回每个EP端口的状态,用户在Linux下执行命令就能看到四个端口分别挂在哪个设备、跑了什么速率,排查链路问题省事很多。
3. 从原理图到量产:板卡设计的完整关键环节
7块卡的形态功能各不相同,但抽离出来共性设计点,大致可以归纳成六个关键模块。这一章我按打样、焊接、调试的先后顺序,把每一步怎么想、怎么做、怎么验证讲透。
3.1 金手指选型与边缘连接器设计
PCIe卡的金手指是最容易被忽略却又极其影响稳定性的一环。普通PCB打样用的金手指有“化学沉金”和“电镀硬金”两种工艺,高速板卡的插拔面要求耐磨,所以必须用硬金。立创那边下单时如果选了“金手指”工艺,通常默认就是沉金,但沉金层相对较薄,反复插拔几十次后会露铜,信号触点氧化后链路损耗会明显增加。做样品无所谓,但如果你打算量产或者给客户做测试板,尽量选“镀硬金+镍钨合金过渡层”的方案。
金手指的倒角和圆角也要注意。PCIe卡的金手指前端一般做30°到45°的倒角,防止插入时刮伤插槽内的弹片。同时金手指的焊盘和过孔要避开卡边缘3mm区域,否则拼板后分割时会把走线切断。我见过不少DIY板卡因为金手指区域放了过孔,结果插入插槽后被金属弹片压到过孔,直接短路烧主板。这个教训很贵,我专门记在了设计规则里。
金手指的宽度、间距和长度都有标准可查,PCIe CEM 3.0规范里写得很清楚,引脚间距1.0mm、触片长度最小4.25mm、总长度等。我建议画封装的时候直接去立创EDA的元件库搜标准PCIe金手指封装,别自己画,画错的概率很高。
3.2 差分走线:阻抗、等长、参考平面
PCIe Gen3的信号速率是8GT/s,Gen4是16GT/s。别看速率高,它本质上是又一个“高频模拟”问题。PCB上的差分对要走成100欧姆差分阻抗,差分对内等长差控制在5 mil以内,差分对对间等长差控制在10 mil以内,这个标准是我做Gen3时的底线;做Gen4时差分对内等长差要压到3 mil以内。
阻抗怎么计算?以立创常用的JLC7628 六层板堆叠为例,表层差分100欧姆的参考参数大概是:线宽5 mil、线间距7 mil,参考层为第二层完整地平面。如果走内层,由于参考距离不同,需要把线宽调整到4.5 mil、间距8 mil才能达到同样阻抗。这些数据不是拍脑袋,是可以用阻抗计算工具算的。我习惯是把参数先按理论值定出来,再在下单打样时给PCB厂备注“差分阻抗控制100Ω,请按实际叠层微调”,工厂会帮你复核并修正生产文件,这是免费的。
参考平面是另一个重中之重。差分信号正下方的参考层必须连续,中间不能出现大的开槽、断地、跨分割等情况。M.2插座的过孔区域是重灾区,因为M.2座子焊盘很多、金属壳接地脚密集,容易在PCB内层形成条状开口,一旦差分线从这个开口上方经过,阻抗突变直接导致回波损耗超标,链路训练失败的概率飙升。
过孔换层也是个技术活。PCIe Gen3信号过孔如果选用常规12 mil的孔,每过一次孔等效引入约1.2 dB的损耗,在长链路(金手指+板内走线+过孔+M.2座子走线)中这些损耗是累积的,所以过孔越少越好。最小化过孔的办法是尽量在同层完成走线,到M.2座子确需换层时,每个差分对打一对过孔并紧邻放置地过孔,形成回流回路。线的总长度不要超过10英寸,越短越好。
3.3 拆分模式的电容电阻配置
被动式Bifurcation卡的核心就在“如何把金手指的CTRL和PRSNT信号路由到正确位置”。这里最常用的是PCIE标准里的PRSNT#引脚,它负责告诉系统插槽上设备是否在位。每个拆分后的端口都有自己的PRSNT,同时还要处理PERST#(复位信号)和CLKREQ#(时钟请求信号)。
一块x16卡拆成4路x4时,下游每个M.2插槽都需要独立的PERST#信号。主板的PERST#通常只有一个,需要把单一复位信号分配给四个端口,但时序上要保证同时释放。简单做法是把四路PERST#并联,通过上拉电阻拉到3.3V,再用一个RC延时网络做统一的上电时序控制。这里有个细节:如果有些M.2设备对复位时序要求严格,RC网络的时间常数不能太大也不能太小,我通常取10 kΩ电阻 + 1 μF电容,延时约10ms,实测各家SSD都能正常枚举。
时钟信号REFCLK是一对100MHz差分时钟。x16插槽提供一组REFCLK,拆分时要么把这一组时钟扇出到4个下游设备,要么让每个下游设备使用自己的REFCLK。M.2接口本身就带REFCLK输入,所以做M.2拆分卡时,把主板的REFCLK直接并联到每个插槽就能工作。但并联会增加时钟线上的容性负载,导致时钟信号振铃变差。保险做法是串接交流耦合电容,或者在每路时钟线上加一颗时钟缓冲器(比如IDT的9DB系列),成本增加几块钱但稳定性提升非常大。
3.4 供电系统怎么设计才安全
拆分卡的供电链路分为三个部分:金手指从主板引入的3.3V和12V、板卡本地DC-DC转换、下游设备接口供电。每个部分都有各自的坑。
金手指上12V引脚最大承载电流由CEM规范约束,x16插槽通常能在印刷电路板走线宽度足够的情况下提供5.5A左右电流。3.3V辅助电源(Vaux)只有几百毫安级别,不能作为主供电。所以设计M.2卡时,我先做功耗估算:每块盘按10W算,4块盘就是40W的12V需求,折合电流3.3A左右,金手指12V还能扛;但8块盘必须要辅助供电。
DC-DC部分,板上一般不用把12V降到3.3V,因为M.2接口自己带了3.3V输入脚,多数M.2盘直接吃主板或板卡供的3.3V。但要注意3.3V的电流有限,高性能盘转动瞬间电流可能到2A,如果板卡仅靠金手指的3.3V供电,电压跌落会造成盘掉盘。我设计时每个M.2插座附近都放了至少4颗22μF陶瓷电容做本地去耦,同时在汇流条输入端加了一颗220μF的钽电容来吸收瞬态电流。钽电容耐压至少要选16V,不要图便宜选10V,12V供电时瞬态尖峰很容易超过10V击穿失效。
辅助电源的接法也有讲究:如果做了辅助供电座,一定要在辅助供电输入端串一个防反接二极管(肖特基)或者用MOS管做理想二极管,防止用户插错电源方向直接烧板。过流保护建议每路M.2都串一颗自恢复保险丝,这样单个端口短路不会拖垮整块卡。
3.5 机械尺寸与安装兼容性
做拆分卡前先把你要适配的机箱、主板、散热器的物理空间全部量一遍。PCIe板卡标准全高尺寸是111.15mm x 106.68mm,但为了兼容各种机箱,我把卡长度尽量压缩在105mm以内,这样即使安装大型CPU散热器也不容易顶到。
M.2位置的设计需要重点考虑盘的热风走向。如果四块M.2盘全部朝一个方向排列,上方的盘会被下方盘的热风加热,建议采用两两对向排列。如果空间允许,在PCB下方预留一个40mm x 40mm风扇位(5V供电),夏天跑高负载时会感谢当初的自己。
挡板设计也不能忽视。PCIe挡板的高度和弯曲半径有标准,做样品阶段建议直接用标准件,不用自己开模。挡板上除了外露的M.2螺丝位外,最好开一个大的通风孔,方便卡内热空气排出。挡板边缘的固定螺丝孔间距是固定的,但我见过一些廉价机箱的螺丝孔位公差大,装的时候卡得很费劲,所以选挡板要选厚一点的冷轧钢板材质。
3.6 固件层面需要做什么
被动式拆分卡不需要板载固件程序,但有一类卡例外——需要管理拆分模式、I2C读取能耗数据、或者做LED控制的卡。这种卡通常会放一颗MCU,常见的是STM32或者国产的CH32系列,通过I2C和上位机通讯。如果设计里带MCU,别忘了靠近MCU放好串口调试座,同时把固件刷写口引出,否则每次改程序都要飞线,非常痛苦。
开源硬件里还有一个经常被忽略的点:给卡做EEPROM。PCIe设备有一个能力结构叫VPD(Vital Product Data),里面可以写型号、序列号、厂商信息等。做拆分卡时可以放一颗小的EEPROM挂到SMBus总线上,这样系统能识别到卡的身份信息,比如运行lspci -v时能看到这是你设计的哪个板卡版本,对批量管理和调试很友好。不过这颗EEPROM的地址和总线不要和下游M.2设备的SM BUS冲突,选一个在I2C地址0x50-0x57范围之外的地址,比如0x5E。
4. 实战部署:把拆分卡真正用起来
硬件设计是前半场,能不能稳定高效地跑起来是后半场。这一章重点讲部署验证流程,从BIOS设置到操作系统识别,再到性能测试,完整走一遍。
4.1 BIOS里的Bifurcation设置
拿到一块新的拆分卡,先别急着插到主板上开机。我习惯的顺序是:先把卡插到目标插槽,然后用主板厂商推荐的BIOS更新方式刷新最新BIOS,再进入BIOS的PCIe子系统设置项找到“PCIe Bifurcation Configuration”或“PCIe Slot Configuration”,把对应插槽的拆分模式改成x4x4x4x4或x8x4x4。
不同厂商叫法不同,有的叫“Bifurcation Support”,有的叫“PCIe Lane Split”,还有的干脆集成在“PCIe Slot Link Speed”下面。如果找不到,请先确认你用的CPU是否支持拆分、主板上这个插槽走的到底是CPU通道还是芯片组通道。芯片组通道一般不支持Bifurcation,这一点经常让人白忙活。
如果你发现BIOS里连“Bifurcation”几个字都没有,但是主板和CPU的规格书显示支持,那大概率是BIOS没开放这项设置。有些主板厂商对这个选项是隐藏的,需要修改BIOS文件或通过AMIBCP这类工具把隐藏菜单打开,这种做法有风险,刷挂了就得上编程器,所以我一般不建议新手动这个,最好选一块明确支持拆分的板子。
4.2 系统识别与链路训练验证
BIOS开启拆分模式并保存重启后,观察开机自检画面。正常情况你会看到4个独立的NVMe控制器同时枚举出来,在自检信息列表里能分别看到对应的型号。如果只识别到2个或1个,先别急着改硬件,用排除法做这几步:
- 重新拔插卡,确保金手指完全进入插槽,卡尾固定螺丝锁紧。很多接触不良都是卡没完全插到位。
- 换一块已知正常的M.2盘分别插到四个槽上,如果每个槽都能识别,说明问题在原先那块盘本身。
- 检查辅助供电线缆是否插紧,测量12V电压是否在11.4V到12.6V之间。
- 有条件就用示波器测一下M.2时钟信号的幅值和频率,PCIe REFCLK应该是100MHz ±300ppm。
进入Linux系统后,直接执行lspci -vvv可以看到每个端口的状态。重点关注两个字段:LnkSta(链路状态)和LnkCap(链路能力)。如果看到LnkSta是x4 5GT/s表示链路工作在Gen2 x4,说明你拿到的盘是Gen3盘但链路训练只协商到Gen2,很可能是盘本身掉到Gen2模式,或者信号质量差导致自动降速。排查办法用ethtool的PCIe速度查看命令(配合nvme-cli工具)看盘报告的链路速度,再用smartctl看盘的错误日志。
Windows平台相对麻烦,设备管理器里看不到链路实时速率,只能用第三方工具如HWiNFO64查看PCIe运行带宽。如果你在事件查看器里看到“设备未迁移”或“设备无法启动”相关的警告,大概率是链路训练失败后设备被系统禁用,换一个PCIe插槽或者调低链路速度可以缓解。
4.3 带宽与性能实测
验证识别完成后,下一步是跑压力测试,确认4路设备的带宽能共用满整条x16链路。拿4块Gen4 SSD插在x16拆4x4的卡上举例,理想情况下每一路能跑到Gen4 x4的带宽,也就是约7.8 GB/s(单向)的理论值。但由于拆分后的4个x4共享同一个Root Port的带宽资源,实际并行总吞吐可能达不到4块盘的总和,这跟PCIe交换结构有关,要提前给用户预期。
实测方法很简单,Linux下用fio分别跑单盘和全盘并发。命令参考:
fio --name=seqread --rw=read --bs=1M --iodepth=32 --numjobs=1 --direct=1 --filename=/dev/nvme0n1 --group_reporting fio --name=fullread --rw=read --bs=1M --iodepth=32 --numjobs=4 --direct=1 --filename=/dev/nvme0n1 --filename2=/dev/nvme1n1 --group_reporting如果你的目的是看能不能跑满x16的极限,那么并发读4块盘的总MB/s应该接近单块Gen4盘峰值的3.5倍左右,因为总有调度和管理开销损失一些性能。如果只看单盘,只要不低于直插主板M.2槽位时性能的95%,链路基本就是健康状态。如果低于90%,就要回到布线阻抗和信号完整性去找问题了。
4.4 特种应用场景扩展
拆分管线的价值不仅在NVMe盘。配合FPGA板卡或者多路网卡,它还能解决很多实验室部署问题。举个例子,FPGA开发板上经常只有一个PCIe x16接口,如果同时要跑TSN(时间敏感网络)协议栈和1553B总线模拟,一块FPGA卡不够,就需要在服务器槽位上扩展出多路PCIe接口去接多张FPGA或协议卡,这时候第五款的“x16转2路PCIe x8”卡就有用武之地了。
类似的场景还有工控领域的6U CPCI板卡、VPX板卡。传统CPCI/VPX背板虽然也有自己的交换结构,但板卡尾部连接器的排布标准和尺寸与商用PCIe完全不同,很多时候从设备端引出的PCIe信号只有x4或者x8,通过拆分管卡转成标准接口,就能把实验室里通用的PCIe外设(如高速数据采集卡、GPU计算卡)挂到专用平台上去。设计这类转换板卡时,我和做1553B板卡的同事对过一次需求,最大的难点反而不是PCIe高速信号,而是连接器与电源时序的兼容问题,因为CPCI/VPX板卡的电源域定义和商用PCIe差异很大,供电脚位必须逐一核对。
这个思路也适用51单片机/MCU硬件设计开发板验证、ESP32-C6之类WiFi6 MCU调试板的互连测试——很多MCU开发环境需要外接逻辑分析仪、协议分析仪和高速示波器,PCIe转接卡能在一台普通PC上扩展出多路高速数据通路,把测试效率提上来。虽然受限于PCIe协议,不能直接把MCU的串口、SPI映射到拆分卡上,但配合PCIe转USB3.0/串口桥接卡后,这种方式比USB HUB稳定得多,延迟也要低不少。
4.5 与主流设备形态的交叉比较
这几年做过的PCIe扩展方案里,除了Bifurcation拆分,还有两条路:一是用PCIe Switch延长距离,二是用PCIe Over Cable(例如MCIO/Gen-Z)做机箱间互联。三条路线各有优劣。
| 方案 | 成本 | 功耗 | 延迟 | 灵活性 | 适用场景 |
|---|---|---|---|---|---|
| 被动式Bifurcation拆分卡 | 低,百元内 | 低,5W以下 | 极低,ns级 | 受CPU拆分能力限制 | 单机多设备扩容 |
| PCIe Switch板卡 | 高,芯片几十到几百元 | 中,10-20W | 低,加1-2μs | 高,可做任意拓扑 | 大规模存储扩展 |
| PCIe Over Cable | 中高 | 中高 | 低 | 高,突破机箱限制 | 刀片/存储池互联 |
如果你只是给一台工作站插4块NVMe盘,Bifurcation卡是最优解;如果要做8盘万兆NAS且后面扩展空间有限,我更推荐直接上带Switch芯片的U.2扩展卡,因为它的拓扑管理能力和热插拔策略更成熟。这三条路线不互斥,很多服务器里是先Bifurcation拆到Switch芯片,再从Switch下游端口接硬盘笼。
5. 常见问题与排查技巧实录
下面这些问题,都是我在实打实的测试和社区反馈里收集到的,按出现频率排序,几乎覆盖了90%的拆分卡翻车现场。
| 故障现象 | 可能原因 | 排查思路与处理方案 |
|---|---|---|
| 插卡后不开机或长时间卡自检 | 金手指接触不良或主板上Bifurcation配置不正确 | 重新拔插卡,检查挡板螺丝;进BIOS恢复默认设置后重新设置Bifurcation;临时换一个插槽对比 |
| 只能识别到部分M.2盘 | 某路拆分域链路训练失败,或该盘本身故障 | 交换盘的位置做A/B测试;lspci看哪一路LnkSta异常;如果固定某路失败,检查对应差分走线、参考层、供电 |
| 识别到盘但读写速度异常低 | 链路降速到Gen2/Gen1,或供电不足导致降功耗 | 用带宽测试工具确认运行速率;检查辅助供电插头;温度过高时先降温再测试;确认是否碰到盘体的功耗限制 |
| 跑重负载时蓝屏或主机重启 | 12V供电不足或瞬态跌落严重 | 更换更高规格辅助电源,或调整fio的iodepth降低瞬时功耗;测量12V在负载变化时的纹波情况 |
| 开机后系统报告“Unknown Device” | PCIe枚举过程中设备响应超时 | 断电后短接金手指PRSNT相关引脚做强制在位;检查M.2座子焊盘是否有虚焊;用逻辑分析仪抓PERST与REFCLK时序 |
| 金手指或M.2座温度过高 | 大电流下接触电阻过大 | 检查金手指镀层是否磨损;用热成像确认热点;M.2座优先选带金属加强壳的版本 |
5.1 链路训练失败:现象与排查顺序
链路训练失败是拆分卡最典型的翻车场景,具体表现是某一路或多路设备在lspci里不出现,或者出现但LnkSta显示“Link Up but speed reduced”。排查顺序很有讲究:先看电源再看复位再看时钟,最后才怀疑PCB阻抗本身,不要一开始就推翻重画板。
电源问题是最容易忽略的。M.2盘的3.3V和12V供电不在同一个界面,很多盘内部有多个电源域,如果3.3V上电时序满足不了就能导致内部自检失败。我使用示波器抓过某品牌盘的3.3V和PERST引脚时序,发现官方规格书要求PERST释放必须在电源稳定后100ms,而我的RC电路延时只有10ms,导致盘偶尔能认偶尔不认。后来统一把RC延时调到200ms,问题彻底消失。
复位信号的整齐性也很重要。如果四个M.2口的PERST信号是同一个RC电路分出去的,那么每个口的前级设备可能会因为RC电容差异导致复位释放时间不一致,个别盘对时序敏感就会不启动。最好是在每个口单独放一组RC,并且选择容差±5%的电容。
时钟方面常见问题是主板REFCLK经过长线后信号幅值不达标。PCIe REFCLK标准幅值约0.6V到1.2V,如果你用普通FR4板材走线超过10英寸且没有端接,末端的幅值可能掉到0.4V,设备只能偶发识别。这时候不要强行加放大器,优先把走线缩短或调整拓扑,实在不行再加时钟缓冲器。
5.2 掉盘、性能不稳和温度的关系
掉盘不是只有硬件故障才导致,温度过高同样是首要元凶。NVMe盘在65°C以上时大部分会主动降速,到了80°C以上会有固件级保护动作,直接暂停写入或者掉线。散热条件越差的机箱越容易出现“读写刚开始性能正常,五分钟后掉盘”的现象。
我做了一个实测:同一块Gen4盘,分别插在无散热片的M.2拆分卡和有散热片的卡上,用相同的fio连续读负载跑10分钟,前者的温度比后者高出12°C到15°C,掉盘概率明显升高。所以如果你买的是不带散热片的裸板,强烈建议至少贴一块硅脂垫和铜散热片,有条件就上主动风扇。
5.3 为什么我的主板识别到设备但就是不能启动
这种情况比“不识别”更隐蔽。设备枚举成功、Windows设备管理器里也出现了未知控制器,但OS加载驱动时直接蓝屏或卡死在启动界面。通常原因是设备上报的Class Code/Subclass和驱动不匹配,多见于用MCU做了VPD/Class Code编程但写错了寄存器。
如果你复刻开源板卡时修改过EEPROM或MCU固件,重点检查PCIe配置空间里的Class Code字段。NVMe设备的标准Class Code是01 08 02,如果你填成了01 00 00(VGA兼容设备),系统就会试着挂显示驱动,那启动失败就一点不奇怪。用Linux启动时加pci=realloc或pci=assign-busses参数往往能救回一部分,但根治还是改固件。
5.4 兼容性清单:主板型号到底能不能用
说到底,Bifurcation能不能用,最后还是要落在CPU和主板厂商的支持上。我把自己实测过的平台做了一个简单对照表,方便你选型时少走弯路。
| 平台/芯片组 | 是否支持Bifurcation | 支持级别 |
|---|---|---|
| Intel Z690/Z790 | 部分支持 | 多数只看CPU直连槽,但BIOS选项隐藏较深 |
| Intel W680/W790 | 完全支持 | 工作站级,BIOS里可调 |
| Intel X99/C621 | 完全支持 | 老平台但BIOS成熟稳定 |
| AMD B550/X570 | 完全支持 | Ryzen 3000/5000的CPU直连槽 |
| AMD TRX40/WRX80 | 完全支持 | 线程撕裂者平台,拆分选项丰富 |
| AMD A620/B650 | 部分支持 | 取决于BIOS版本,不保证全部开放 |
| Intel N100/N305工控板 | 部分支持 | 有些嵌入式BIOS直接锁死,不建议做主力验证 |
我有一条经验:用AMD B550/X570平台验证被动式拆分卡的普适性,用W680验证Gen4/Gen5信号质量,用服务器平台(比如C621或EPYC)做极限压力测试。这三个平台覆盖了主流用户和极端性能需求,基本上板子在这三类平台上都能过,适配就八九不离十了。
写在后面
做这7款开源拆分板卡项目的时间跨度不小,从第一块最简单的x16转4路M.2,到最后带MCU管理和传感器监控的SlimSAS阵列卡,中途推翻过的方案和返工的PCB叠加起来快半箱了。我最大的体会是:PCIe Bifurcation板卡的硬件设计门槛并不在于原理图,仿真和理论书本上都写得明白,真正拉开差距的都在细节里——金手指镀层选硬金、差分过孔要加地回流、复位时序要给足200ms、M.2插槽中间要留风道,这些就是高速板卡能不能从“能亮”到“稳定跑满”的差别。
对于想自己动手复刻开源板卡的朋友,我建议第一块选择最简单的x16转4路M.2卡开始,四层板、纯被动设计,把所有精力放在理解差分走线和Bifurcation模式配置上,等这块板跑通了再去碰8路、混合拆分、MCU管理这类复杂形态。按我踩过的坑来算,从零开始做第一块卡的周期大概在一到两周,其中一半时间花在等板子和调试上,真正画图的时间反而不长。
最后再分享一个筛选拆分卡的小技巧:拿到任何一块新卡,先不插盘,只用万用表测量金手指到M.2座子对应引脚的连通性,顺便确认一下12V和GND之间有没有短路。这两项检查过了,再上电,能帮你避免80%的烧板和返工。PCIe拆分卡这个方向看着小众,但它几乎是每个硬件爱好者在存储和扩展路上都要打交道的东西,希望这篇整理能帮你少走一段弯路。