最早做FPGA板卡那会,我照着参考设计画了一版PCIe,结果上电后系统里死活认不到设备。当时第一反应是驱动问题,折腾了两天,最后发现是REFCLK走线跨了分割、离一个DC-DC电感又太近,时钟质量差到链路训练根本走不完。从那以后,我开始把PCIe相关的PCB设计要求单独整理成备忘,遇到新项目直接翻,能少走很多弯路。
PCIe和普通并行总线、低速串口的设计逻辑完全不一样,它是高速串行总线,链路能不能训练成功,直接取决于PCB上的信号完整性和电源完整性。很多问题不是固件能救的,而是从Layout阶段就埋下了雷。这篇内容主要覆盖:PCIe链路参数与枚举机制对布板的约束、叠层与阻抗控制、走线等长与回流路径、电源时钟布局、mini PCIe和M.2这些接口形态的选型差异、布线布板时的DRC设置,以及上板调试时的排查顺序。适合画过几块板子、想深入理解PCIe硬件设计的工程师,也适合刚接触高速Layout的朋友做参考。
1. 设计起步前必须吃透的PCIe链路参数与枚举机制
1.1 速率代际与通道数量决定布局预算
PCIe代际速率直接决定了你在Layout阶段可以“挥霍”多少预算。先把基本参数列出来:
| 代际 | 每通道速率 | 编码方案 | x1理论带宽 | x16理论带宽 |
|---|---|---|---|---|
| Gen1 | 2.5 GT/s | 8b/10b | 250 MB/s | 4 GB/s |
| Gen2 | 5 GT/s | 8b/10b | 500 MB/s | 8 GB/s |
| Gen3 | 8 GT/s | 128b/130b | 约985 MB/s | 约15.75 GB/s |
| Gen4 | 16 GT/s | 128b/130b | 约1.97 GB/s | 约31.5 GB/s |
| Gen5 | 32 GT/s | 128b/130b | 约3.94 GB/s | 约63 GB/s |
设计的时候要清楚:Gen3以上不能按普通差分线随便画,必须考虑损耗预算。芯片厂商手册里一般会给出建议,例如FPGA或CPU到PCIe插槽的板内走线尽量控制在8到12英寸以内,过孔数量越少越好。PCIe链路对插入损耗、回波损耗都有明确要求,速率越高,走线越长,眼图闭合得越厉害,最后就是协商降速甚至直接训练失败。
通道数方面,x1和x16不只是带宽差别,Layout难度完全不是一个量级。x16插卡的差分对数量很多,加上电源、地、辅助信号,整板走线密度会明显增大,这时候叠层、参考平面、走线分区就要提前规划,不能等布完线再回头调整。
1.2 枚举过程的隐含约束对PCB设计的影响
PCIe系统上电后,根复合体(Root Complex)会发起枚举,遍历总线上的设备,给每个设备分配总线号、设备号、功能号,再读取BAR寄存器完成地址空间分配。这个过程有个前提:LTSSM链路训练状态机必须先完成链路训练。如果物理层训练不稳定,枚举就会卡住,设备在系统里根本看不到。
从PCB设计角度来看,有几个点容易被忽略:
- PERST#复位信号要满足上电时序,在PERST#撤销之前,所有电源轨必须已经稳定。复位走线如果太长、受干扰,会出现偶发复位失败,表现就是设备时有时无。
- REFCLK参考时钟一旦质量差,LTSSM会一直停在Detect或者Polling状态,现象同样是“认不到设备”。
- 链路损耗太大时,链路会自动降速甚至降Lane数,比如协商成Gen1 x1,勉强能用但性能不对。
所以别把枚举失败都归咎于软件。早期布线时,复位、时钟、电源时序这三件事必须按高速PCB的标准对待,而不是当成普通低速信号随意处理。
2. PCB叠层与阻抗控制:PCIe信号的物理基础
2.1 层叠结构选择与参考平面
PCIe板子选几层,主要看成本和速率要求。4层板跑Gen1或Gen2是可行的,走线短、环境干净的话能用,但如果想稳定跑Gen3以上,我建议至少6层起。6层板的好处是信号层可以挨着完整参考平面,电源和地也有独立层,对高速信号的回流和屏蔽都友好。8层以上则更适合Gen4/Gen5,或者板上同时有很多高速接口,需要更灵活的走线规划和隔离。
层叠设计有一条铁律:高速信号所在层必须邻接完整参考平面,最好是地平面。不要让PCIe信号参考到被割裂的电源平面,更不要让关键信号跨越平面分割。如果信号必须换层,要保证换层前后的参考平面是同一个网络,并且在换层过孔旁边放地过孔,让回流电流有顺畅的路径。
2.2 差分阻抗:PCIe要85欧姆,不是100欧姆
这是最容易踩的坑。很多人习惯了USB、HDMI这类接口的90欧姆或100欧姆差分阻抗,但PCIe规范规定的是85欧姆差分阻抗,上下浮动约10%(Gen3及以上更严格)。如果板厂按100欧姆去做阻抗,链路上的反射会明显增大,高速时误码率直接恶化。
设计时用阻抗计算工具(Polar Si9000,或者嘉立创EDA自带的阻抗计算功能)时,需要输入介质厚度、铜厚、目标阻抗、线宽、线距这些参数。举例来说,6层板、板厚1.6mm、表层1oz铜、L2为GND参考层、目标85欧姆差分,通常会算出来类似线宽0.15mm、线距0.15mm的一组值。但请注意,这只是示例,实际必须让板厂按他们的真实叠层去计算,因为不同板厂的PP片组合不一样。
顺带提一句,叠层厚度不是随便定的。板厚1.6mm时,表层到参考层的介质厚度决定走线宽度;如果想把走线做细,可以让板厂调整PP层叠。不要自己拍脑袋改线宽,一定要和板厂确认。
2.3 连接器、焊盘和过孔的阻抗不连续
即便走线阻抗算准了,PCIe插槽焊盘、芯片BGA扇出过孔、连接器引脚本身仍然是阻抗不连续点。工程上能做的优化包括:让差分对以对称方式进入焊盘区,过孔不要离焊盘太近,在连接器区域按需对铜皮做挖空处理,减少寄生电容。
这里就涉及到热词里常出现的“ad20中pcb板铜皮挖空”。比如高速连接器下方,为了降低焊盘和过孔带来的寄生电容,可以在对应层挖掉部分铜皮。操作上用Polygon Pour Cutout在铜皮上画闭合区域即可,但关键是搞清楚你挖的是哪一层、哪些网络,不要好心办坏事把参考平面给破坏了。
3. 走线规则:等长、间距、换层与回流路径
3.1 差分对内部等长与对间等长
PCIe每条Lane是收发分离的差分对。Layout规则一般这么定:
- 对内等长:同一对P/N的长度差控制在5mil以内。差太多会产生共模转换,增加EMI,也影响接收端眼图。
- 对间等长:x4或者x8各Lane之间,总长度差控制在10到20mil以内,Gen3以上建议更严。有人问“PCIe发送差分对间需不需要等长”,严格说PCIe发送端有De-skew机制,可以在一定范围内补偿Lane间的skew,所以不是比特级严格等长。但千万别因此放飞自我,如果Lane之间长度差得离谱,接收端的BufFer会溢出,链路余量也会变差。我的习惯是统一做等长约束,不给调试留隐患。
蛇形绕线的时候注意:绕线间距至少3倍线宽,否则相邻线段会产生耦合,等于白绕。等长不是目的,控制skew和串扰才是目的。
3.2 过孔设计与回流路径控制
过孔对高速信号影响最大的就是stub,也就是过孔残桩。4到6层板的贯穿孔一般问题不大,但8层以上厚板跑Gen4时,残桩对信号的影响就很明显了,必要时得跟板厂确认能不能做背钻。如果不能背钻,那就尽量减少换层次数。
换层时的回流路径非常关键。信号从L2换到L5,如果L2的参考平面是GND,L5的参考平面也是GND,那么换层过孔旁边一定要放地过孔,让回流电流在两个地平面之间平滑切换。否则回流电流绕大圈,会产生共模噪声,严重时直接导致链路误码。
3.3 走线间距与隔离
PCIe差分对与其它信号建议保持3W以上间距(W为线宽),与时钟、电源开关节点这些干扰源至少拉开5W距离。板面实在紧张的话,差分对之间也不要贴得太近,避免串扰。
高速信号不跨分割、不走孤岛铜皮,这些讲过很多次,但每次画板还是能看到有人踩。还有一个容易忽略的点:PCIe差分对尽量不要与其它高速信号平行长距离走线,平行长度越长,串扰越大。
3.4 板内互连和插卡互连的差异
板内芯片到芯片的连接,比如CPU到PCIe Switch,走线短(2到3英寸以内),Gen3以下不用太担心。但经过连接器、线缆或背板的链路就完全不一样了,连接器本身、线缆阻抗、背板过孔都会贡献损耗,这些都要计入链路预算。
设计前期最好用芯片厂商提供的通道预算工具,把板内走线、过孔、连接器、线缆的损耗都估算一遍,看总损耗是否在接收端允许范围内。前期多花半小时做预算,比板子回来之后对着示波器干瞪眼要强得多。
4. 电源与时钟:决定PCIe成败的“命脉”
4.1 电源网络与去耦电容
PCIe设备常见的电源轨有3.3V、12V,还有1.8V、0.9V等芯核电压。电源设计不好,信号完整性再漂亮也没用。电源平面的完整性直接影响参考平面质量,如果PCIe信号的参考平面恰好是某个分割得乱七八糟的电源层,那信号回流路径会非常糟糕。
去耦电容要放在负载引脚附近,而且电容的电源和地过孔要直接打到对应平面,不要绕远路。DC-DC电感底下不要走高速信号,开关节点对临近走线的干扰非常大。电源纹波和时钟抖动之间的关系尤其要注意,热词里也有提到ADC/DAC电路里规避时钟抖动与电源噪声的布局要点,PCIe同理:电源纹波会通过时钟芯片和PHY的PLL转化为抖动,最终劣化眼图。所以REFCLK芯片和PHY/MAC的供电,最好加一级π型滤波或者LC滤波,示波器上测不到纹波不代表PLL端真的干净。
4.2 参考时钟REFCLK的布局要点
PCIe参考时钟是一对100MHz差分信号(REFCLK+/-)。它不像数据信号那样有编码和均衡机制来纠正错误,一旦质量差,PLL直接失锁,整个链路就起不来。
REFCLK的布局要求:
- 走线尽量短、直,从时钟源到每个端点,不要绕大圈。
- 时钟差分对要做包地处理,与其它信号至少保持5W距离。
- 如果需要一颗时钟驱动多个设备,用专门的时钟缓冲器,不要简单并联。
- 时钟芯片下方要留完整地平面,周围不要放开关电源。
我那次调试失败就是因为REFCLK离电感太近,后来把时钟走线挪走并包地,问题就消失了。这种问题用软件查一辈子都查不出来,只能靠Layout规范从源头避免。
4.3 弹性缓冲(Elastic Buffer)和PCB的暗线关系
热词里有一条“别再被时钟频偏搞懵了!手把手拆解pcie弹性缓存(elastic buffer)如何搞定跨时钟域”,这里也展开说一下。
PCIe允许发送端和接收端的参考时钟存在一定频偏。接收端物理层里的Elastic Buffer,本质上是一个FIFO,用来吸收两个时钟域之间的相位和频率差异。协议通过周期性地插入或删除SKP有序符号,避免FIFO溢出。
这个机制在芯片内部就能完成,但很多人忽略了它对PCB设计的影响:EB能容忍的频偏范围是有限的。如果PCB上的REFCLK抖动很大,时钟恢复电路(CDR)输出的恢复时钟质量变差,EB的读写指针就会逼近边界,轻则频繁插入SKP导致效率下降,重则出现误码甚至链路重训练。所以不要把EB当作万能药,Layout时把REFCLK做好,让CDR输入干净,EB才能真正稳。这也是为什么做高速板,时钟布线优先级永远高于普通数据线。
5. 接口形态选型:mini PCIe、M.2与挡板尺寸
5.1 mini PCIe与M.2接口的区别
热词里高频出现“网卡mini pcie接口和m2接口有什么区别”。我做过转接小板,简单说一下。
mini PCIe是早期笔记本和工控机常用的接口,54pin,引脚定义基本沿用PCIe总线,支持PCIe x1,同时复用了USB 2.0信号。很多老式WiFi网卡、3G模块都是这个形态。
M.2是后起之秀,Key有B Key、M Key、B&M Key之分,支持PCIe x2/x4、SATA、USB等多种协议。尺寸规格从2230、2242、2260到2280都有,长度不同,引脚定义也不同。
两者物理上完全不兼容。如果想把M.2设备转接到mini PCIe接口,需要专门的转接板,而且还要注意:
- 接口供电能力,3.3V能不能供够M.2设备的峰值电流。
- NVMe设备引导要求,老平台在BIOS里可能没有NVMe选项。
- WiFi卡的天线射频走线,转接后RF线缆长度和损耗增加,对信号质量有影响。
所以选型阶段就要想清楚到底走哪个形态,而不是画完板子再转接,徒增成本和故障点。
5.2 半高挡板等机械尺寸
做PCIe网卡或加速卡,一定会碰到全高挡板和半高挡板。半高挡板常见高度约79.2mm,全高挡板约120mm,固定孔和PCIe插槽的卡槽位置都有严格公差。画结构件的时候,不要拿卡尺量一下就往3D里放,最好直接找机箱厂或者板厂要挡板图纸。
PCIe插卡PCB的外形也有标准,包括金手指长度、定位卡口位置、元件高度限制。挡板附近的元件高度尤其要注意,有些卡装进机箱才发现元件顶着机箱盖板,那种体验很难受。画板前先确认散热器高度、电容高度,和挡板缺口是否冲突,比打样后再改省太多时间。
6. 布线布板流程中的DRC设置与可制造性检查
6.1 用AD/嘉立创EDA设定PCIe规则
很多Layout工程师习惯先画完再设规则,或者干脆只靠默认规则。PCIe这种高速总线,建议在布线前就把规则写清楚,让软件帮你看住底线。
以AD为例:
- 差分对规则:在Differential Pairs Rules里给PCIe网络创建差分对,设置目标阻抗、线宽、线距。前提是你已经用阻抗工具算好了一组可用参数。
- 长度规则:在Matched Length或者Relative Propagation Delay里,把同组Lane放进同一个时序类,设置Tolerance,等长约束直接交给规则管理。
- 常规规则:Clearance至少3到5mil,线宽按阻抗要求,过孔孔径和环宽按板厂工艺能力填。
嘉立创EDA专业版也支持差分对、长度匹配、阻抗连续这些规则,操作逻辑类似。规则设置得越完整,最后DRC跑出来的问题越少。
6.2 铜皮挖空的实际操作
“AD20中PCB板铜皮挖空”是一个很具体的问题。常见场景有三个:
- 天线净空区,板边需要挖掉整块铜皮。
- 高速连接器焊盘附近,为了减少寄生电容,对反焊盘区域做铜皮挖空。
- 板内高压区域,为了保证爬电距离,把高低压之间的铜皮挖开。
在AD里用Polygon Pour Cutout在铜皮上画闭合区域就能挖空,注意选择正确的层。如果是想挖掉某个网络区域下的铜皮而不影响其它网络,可以用Keepout或规则区域限定。挖空之后一定要重新铺铜,再跑一遍DRC,防止出现尖角铜皮或者意外断路。
6.3 DRC检查与生产文件输出
DRC检查要覆盖电气规则(短路、未连接)、间距规则、孔尺寸、丝印到焊盘距离、铜皮到板边距离。很多时候问题是布线时不小心把地网络截断了,或者过孔盖油把焊盘挡住了,这些都能靠DRC查出来。
输出生产文件方面,AD24可以在Fabrication Outputs里直接生成Gerber和钻孔文件。关键点是导出的层映射要和板厂约定一致:顶层、底层、内层、阻焊、助焊、丝印、钻孔,一个都不能少。导出后用CAM工具或板厂提供的在线Gerber查看器检查一遍,确认文件没问题再丢给板厂,省一次加急费都够吃顿好的。
7. 上板调试阶段常见问题与排查顺序
7.1 链路训练失败的常规检查链路
遇到PCIe设备枚举不出来,先不要怀疑芯片。按照这个顺序排查:
- 供电:用示波器确认各路电源是否按时序稳定,尤其是PERST#释放之前所有电源必须已经OK。
- 复位:量PERST#的高电平时间,看是否被提前释放,或者有没有毛刺。
- 参考时钟:看REFCLK波形,频率稳定在100MHz,幅度符合接收端要求,抖动不能太大。
- 信号完整性:有条件的话用采样示波器看TX眼图;没条件就查PCB阻抗测试报告,确认板厂做出来的阻抗是否在85欧姆±10%范围内。
- 链路协商:Linux下用lspci -vvv看设备有没有枚举到,LinkSta协商到多少速率、多少Lane。
我在第三步栽过跟头,REFCLK走线旁边有根GPIO,GPIO每次翻转,链路就掉一次。硬件上拉开距离、加包地之后恢复正常。这种问题从日志、代码里根本看不到,所以排查别一头扎进软件里。
7.2 带宽测试与性能验证
设备能枚举出来,不代表性能就对。带宽测试通常用两个办法:一个是真实业务验证,比如NVMe SSD跑dd或fio;另一个是用DMA测试例程统计吞吐,典型的就是Xilinx的XDMA Demo,通过PCIe DMA把数据从主机搬到FPGA,再打印速率。
如果实测带宽远低于理论值,优先查两件事:
- Lanes是不是协商到了x4或x8,而不是降级到x1。
- 代际是不是Gen3,而不是降级到Gen1或Gen2。
链路的降级往往发生在系统启动阶段,跑一遍lspci -vvv就能看出来。如果持续掉到低速率,就要回头检查PCB阻抗、REFCLK质量和连接器接触是否可靠了。
7.3 静电、搬运气流和再上电
这类板卡调试时还有几个容易被忽略的琐碎问题。PCIe插槽的热插拔细节很多,普通台式机允许关机插拔,但不代表上电后随便拔插没问题。调试前先放电、确认断电,插卡时均匀用力,别刮伤金手指。
还有一个散热问题:很多PCIe卡带了主动散热风扇,调试时风扇供电来自主板的12V,如果风扇堵转或者电流过大,会影响整条电源轨,导致板卡复位。这种问题看起来像软件故障,实际是电源余量不足。板上要预留好风扇接口的滤波电容,电源选型阶段就把风扇电流算进去。
画板子这件事,细节决定成败。PCIe设计里的每一条规则,背后都是链路预算、回流路径和电磁兼容的问题。把基本盘做对,剩下的就可以交给协议本身的纠错机制去兜底。