☰
自制PCIe转USB3.0扩展板:VL805芯片硬件设计与DIY实战指南
2026/10/7 13:36:48 网站建设 项目流程

1. 为什么费劲去做一块PCIe转USB3.0扩展板

去年我把主力机里的老显卡拆下来换了核显平台,主板那根PCIe x16插槽就这么空着了。说浪费吧,日常用核显确实用不上独显;说利用吧,插槽空在那儿总感觉亏了什么。后来看到角落里堆着几块吃灰的机械硬盘和一堆USB设备,突然冒出一个想法——要是能把PCIe插槽变成一堆高速USB3.0接口,不就一举两得了?

这个想法听着挺野,实际上是完全可行的。PCIe本身就是一个高带宽、低延迟的总线,用它来扩展USB接口,本质上是把PCIe协议转换成USB3.0协议,让外设绕过主板芯片组直接跟CPU对话。市面上成品PCIe转USB3.0扩展卡不少,但自己动手用VL805芯片做一块,既能按需定制接口数量,又能彻底搞明白PCIe和USB3.0之间的转换原理,还能省下买成品卡的钱。对于喜欢折腾硬件、想深入了解PC总线机制的玩家来说,这个项目的性价比相当高。

VL805是VLI(威锋电子)出品的一颗PCIe转USB3.0控制器芯片,一颗芯片就能带出最多5个USB3.0接口,同时向下兼容USB2.0和USB1.1。它通过PCIe x1总线跟主机通信,理论上可以提供接近5Gbps的真实数据传输带宽,跑满单口USB3.0的500MB/s不在话下,多口同时用也能有比较均衡的带宽分配。这颗芯片在市面上很多中高端USB扩展卡、扩展坞里都有身影,方案非常成熟,参考资料也多。做一块VL805扩展板,既能盘活闲置的PCIe插槽,又能获得一组稳定可靠的高速USB接口,属于典型的"低投入、高回报"硬件DIY项目。

这篇文章我会从芯片选型讲到PCB设计,再讲到驱动识别和性能测试,全程把我踩过的坑、走弯路的地方都摊开讲清楚。如果你有基本的焊接能力,能看懂简单的电路图,并且愿意花点时间折腾,那这块扩展板大概率能在你手上一把点亮。

2. VL805芯片方案选型:为什么是它而不是别的

2.1 对比市面上常见的几种方案

决定做PCIe转USB3.0之后,我首先过了一遍市面上能买到的方案芯片,其实可选的就那么几颗:ASMedia的ASM1042A、Fresco Logic的FL1100,再有就是VLI的VL805。ASM1042A算是老将,在很多老款扩展卡上都能看到它,但问题是它只支持PCIe Gen2 x1,原生输出4个USB3.0口,资料相对少一些,芯片本身也比较老了。FL1100同样支持4口,但驱动和兼容性口碑一般,在部分主板上出现过休眠唤醒后设备失联的情况。

VL805的优势在于:第一,它单片支持5个USB3.0口,比同类芯片多一个;第二,它的PCIe接口是Gen2 x1,理论带宽5GT/s,扣除协议开销后刚好能喂饱多个USB3.0口同时传输;第三,这颗芯片在市场上流通量大,采购容易,价格也不贵(零售几十块钱一片),而且有大量成品卡可以参考电路设计。最关键的是,VL805有三种封装版本,分别是QFN48、QFN68和BGA,我选了QFN48小封装版本,适合手工焊接,引脚间距0.5mm,用拖焊法配合助焊剂完全可以搞定。

2.2 VL805的引脚功能与外围电路概览

VL805-QFN48的关键引脚可以分为几组:PCIe侧有PERp/PERn(接收差分对)、PETp/PETn(发送差分对)、REFCLKp/REFCLKn(100MHz参考时钟)、PERST#(复位信号);USB侧有5组USB3.0差分对(SSTXP/SSTXN/SSRXP/SSRXN),每组还带对应的USB2.0差分对(DP/DM);电源引脚包括3.3V主电源、1.05V核心电源以及模拟电源AVCC。此外芯片需要一颗24MHz晶振提供基准时钟,还有一个SPI接口用于外挂Flash存储固件。

PCIe差分信号布线是整个设计里最重要的部分。PCIe Gen2的信号速率是5Gbps,差分对需要做100Ω差分阻抗控制,走线要保持等长,对内等长误差控制在5mil以内,对间等长误差控制在10mil以内。USB3.0侧同样需要90Ω差分阻抗控制,SuperSpeed差分对的等长要求也差不多。这些约束在画PCB的时候就要提前设置好,否则信号质量出问题,轻则降速到USB2.0模式,重则完全识别不到设备。

供电方面,VL805的3.3V可以直接从PCIe插槽取,核心电压1.05V则需要一颗LDO或者DC-DC降压芯片来生成。我用了AMS1117-1.05这颗LDO,虽然效率不如DC-DC,但胜在纹波小、电路简单,对VL805这种功耗不大的芯片来说完全够用。USB口的5V供电建议从PCIe插槽的12V取电,经过一颗降压模块转成5V,或者直接从SATA电源接口引一路5V过来,这样能保证每个口都能输出足额的500mA甚至更高电流。

3. 硬件设计实拆:从PCIe金手指到USB3.0 Type-A口

3.1 画原理图之前必须搞清的PCIe引脚定义

做这块板子之前,我先翻了PCIe金手指的引脚定义。标准PCIe x1插槽虽然物理长度比x16短很多,但电气上只用到一排36个引脚(12对差分信号+电源+地+辅助信号)。关键引脚包括:A1/A2(12V供电)、A9/A10(3.3V供电)、A13(PERST#复位)、A14/A15(REFCLK+/-参考时钟)、B16/B17(PER+/-接收)、A16/A17(PET+/-发送),剩下的主要是SMCLK/SMDAT(SMBus管理总线)、PRSNT#(存在检测)和各种地线。

如果你要做的是x1板卡插进x16插槽使用,金手指可以只做x1的长度,但更好的做法是做x4金手指长度,这样物理上更稳固,也能兼容x4、x8、x16插槽。不过要注意,板卡的PRSNT#引脚要跟金手指上的地线短接,让主板检测到设备在位。PCIe规范里允许短卡插长槽,只要金手指前段的信号完整,后段悬空就行。我第一次打样就吃了这个亏,金手指只画了x1长度,插到x16槽里晃晃悠悠,后来改成了x4长度才稳固。

PCIe插槽的供电能力也要搞清楚:标准x16插槽能提供最高75W的12V供电,x1槽也能提供25W左右,所以同时挂好几个大功率USB设备完全不用慌。但3.3V辅助供电的电流能力有限,VL805本身的功耗不高,直接取3.3V没问题,USB口的外部供电就得另想办法了。

3.2 完整的VL805外围电路搭建流程

原理图设计可以拆成几个模块逐一搞定。第一步是PCIe接口部分,把金手指的PER#、PET#、REFCLK#接到VL805对应的引脚,中间串AC耦合电容(0.1uF/0402封装),参考时钟也需要AC耦合。PERST#复位引脚接一个10k上拉电阻到3.3V,同时并联一个0.1uF电容到地,实现上电延时复位。

第二步是晶振电路。VL805需要24MHz晶振作为基准时钟,晶振两端各接一个18pF负载电容到地,晶振下方要铺地铜皮做隔离,避免干扰其他信号。这里我用的是无源晶振,配合芯片内部的振荡电路工作,如果手头有有源晶振也可以用,CLKOUT引脚输出25MHz给USB2.0 PHY作为参考。晶振这部分看着简单,实际上对PCB布局非常敏感,晶振离芯片越近越好,走线不要太长。

第三步是SPI Flash固件电路。VL805上电后会从外挂的Flash里读取固件,没有固件芯片就只能工作在USB2.0模式。Flash用常见的Winbond W25Q16(2MB容量)就够了,接SPI_CLK、SPI_DOUT、SPI_DIN、SPI_CS四个引脚,再加上3.3V供电和10k上拉。Flash的布局尽量靠近芯片,SPI时钟线最好包地处理。固件文件可以在Linux下用VLI官方工具或者GitHub上的开源刷写工具写入,后面详细说。

第四步是USB口信号和电源。每组USB3.0口包含一对SuperSpeed差分和一对USB2.0差分,从芯片引脚出来后直接接到Type-A母座的对应针脚。每个USB口的5V电源要加一个500mA的自恢复保险丝(PPTC)和22uF去耦电容,防止热插拔瞬间的大电流冲击损坏芯片。如果要做多口扩展,每个口的电源独立走线,不要在板子上串成一路,不然一个口短路会把整块板子的电压拉垮。

供电模块我用了两个方案并联:PCIe 12V经MP1584降压到5V,再并联SATA电源接口的5V输入(用两个肖特基二极管隔离防止倒灌)。这样既能在机箱内通过PCIe供电独立工作,也能在外接SATA电源时提供更充足的电流。降压模块的电感选6.8uH/3A规格,输出电容用两个470uF电解电容,保证USB口大电流输出时纹波可控。

3.3 PCB Layout中那些必须较真的细节

PCB设计我用的四层板方案,叠层顺序是:信号层-地层-电源层-信号层。四层板不仅能提供完整的参考平面,对差分信号的高速回流也帮助很大。PCIe信号的走线全部走在顶层,底层尽量不铺高速信号,保持干净。差分对间距按3W原则(即间距是线宽的三倍)来控制,减少对内耦合损失。

金手指部分我做了沉金工艺(ENIG),提高插拔耐磨性和抗氧化能力。金手指的倒角角度一般是30~45度,方便插入插槽。金手指与PCB板的连接处要加泪滴焊盘,提高机械强度。板卡挡板用标准的1U挡板,固定孔位对齐PCIe插槽的位置。

USB口的布局要注意一点:5个USB口如果全挤在挡板侧面,空间不够,所以我采用了4口上挡板+1口板载排针的方案。4个Type-A口横向排列,间距15mm,正好能塞进标准挡板开口。板载排针预留在内侧,可以飞线引出机箱前面板,或者接一个内置读卡器之类的设备。USB口的ESD保护也很重要,在每个口的DP/DM和SS差分线上各加一颗ESD防护二极管(型号比如TPD4E05U06),这颗料很便宜,但在干燥季节能救你一整块板子。

供电布线要特别注意铜皮宽度:5V走线至少要能承载1A电流,按1盎司铜厚算,最细也要30mil,我实际用了50mil,加宽更稳。1.05V核心电压走线相对细一些,但只要是电源网络,过孔数量一定要打足,每个电源引脚旁边至少打两个过孔连接到内层电源平面。

4. 固件与驱动识别:上电之后Linux和Windows各自怎么认

4.1 第一次上电调试:从抓PCIe枚举开始说起

板子焊接完成后,最紧张的时刻就是上电。我先用万用表量了一遍电源和地之间没有短路,才敢把板子插到主板上。开机后进入Linux系统,执行lspci命令,如果VL805被正确枚举,应该能看到一行类似"VLI Device 3483"或者"VL805 USB Controller"的输出。PCIe枚举过程是主机RC(Root Complex)依次扫描每条总线上的设备,给设备分配总线号、设备号、功能号,然后读取设备的BAR(基地址寄存器)并分配内存映射地址空间。

如果lspci里没看到任何新设备,优先检查几个地方:一是PERST#复位信号是否正常,正常情况下复位拉高后芯片才会启动;二是参考时钟REFCLK是否摆起来了,可以用示波器量金手指上的REFCLK引脚;三是供电是否到位,核心电压1.05V和3.3V都不能缺。我调试时遇到过一次死活枚举不到,折腾了半天发现是SPI Flash里没有固件,芯片起来了但没有正常工作。这个检查顺序排下来能省很多时间。

有意思的是VL805在PCIe枚举阶段显示为一个PCIe到PCIe桥接设备,之后才挂出一个USB控制器。这是这颗芯片的架构特色:它内部其实有一颗PCIe桥,桥下挂着USB xHCI控制器,所以你会看到lspci输出两行,一个是"PCI bridge",另一个是"USB controller",两个都是VL805的设备ID。这种设计让主机把扩展出来的USB口看作一个独立的PCIe设备,带宽管理和中断分配都很清晰。

4.2 USB3.0 INF文件与xHCI驱动的底层匹配逻辑

在Linux下,VL805几乎不需要额外装驱动,内核自带的xhci_hcd模块就能认出来。Windows下则稍微有点讲究:系统自带的USB3.0驱动(USBXHCI.SYS)一般能直接识别,但如果你用的是精简版系统或者老版本Windows,可能需要手动指定INF文件。微软的xHCI驱动遵循USB3.0规范,对标准xHCI控制器都是通用的,VL805作为合规的xHCI控制器,理论上不需要厂商专属驱动也能工作。

如果Windows的设备管理器里出现了未知设备或者带黄色感叹号的设备,可以用VLI官方提供的驱动包里的INF文件手动安装。INF文件本质上是一个硬件配置清单,告诉系统这个设备对应哪个驱动、设备ID是什么、需要加载哪个服务。VL805的设备ID是VEN_1106(VLI的PCIe Vendor ID)和DEV_3483,INF里写清楚了这些匹配关系。通常情况下,Windows Update会自动拉取驱动,断网环境下手动指定一下就行,整个过程不算复杂。

设备识别正常后,USB3.0设备插入对应的Type-A口,传输速率就能达到SuperSpeed模式。判断方法是看系统日志里USB枚举速度,Linux下用dmesg看"new SuperSpeed USB device"的字样,Windows下可以打开USBTreeView工具,它会清清楚楚显示设备连接在哪个根端口、协商速率是5Gbps还是480Mbps。如果查出来只有480Mbps,那说明USB3.0链路没有建立成功,大概率是差分走线或者焊锡短路问题,得回去检查PCB。

4.3 固件烧录细节:没有固件的VL805只能算半个USB2.0 Hub

关于固件这块,我得单独拎出来强调一下,因为这是踩坑最多的地方。VL805出厂时内部是没有固件的,必须从外部SPI Flash加载。如果Flash是空的或者固件不匹配,芯片虽然能被PCIe枚举到,但USB部分可能只工作在USB2.0模式,或者干脆不工作。

烧录固件的方法有两种:一种是先不给芯片供电,用烧录器(比如CH341A)把固件直接写进Flash芯片,再焊到板子上;另一种是先焊上Flash,让VL805处于无固件状态也能被枚举(幸运的是VL805支持这个模式),然后在Linux下用Flashrom工具通过I2C/SPI接口写入。我试过两种方式,发现第二种更方便,能省去反复拆Flash的麻烦。具体做法是先用modprobe加载i2c-dev驱动,然后通过i2c-tools里的i2cget确认芯片的I2C地址,再用flashrom配合linux_spi驱动把固件刷进去。

固件文件可以在GitHub上找开源的VL805固件仓库,比如AndreasGayser维护的vl805_update_tool项目,里面带了多个版本的固件镜像。选固件版本时要注意匹配芯片的硬件版本,QFN48封装的VL805跟QFN68的固件不通用,刷错会变砖(虽然可以通过烧录器重新刷回来,但平白浪费时间)。刷完后重启,再查lspci和dmesg,确认USB控制器变成了xHCI模式,这时候才算真正完工。

5. 性能实测:这块扩展坞到底能跑多快

5.1 用dd和fio把理论带宽拉到实际数字

板子稳定点亮后,我做的第一件事就是测速。这里我不推荐用Windows下的CrystalDiskMark看个热闹,而是用Linux下的fio做更贴近真实负载的测试,数据更有参考意义。测试方案是用一块SATA SSD(实测顺序读速度约550MB/s)接在扩展坞上,分别跑顺序读、顺序写、随机4K读、随机4K写四类场景,跟主板原生USB3.0口做对照。

顺序读写测试用fio一条命令就能搞定:

fio --name=seqread --filename=/dev/sdb --rw=read --bs=1M --size=1G --numjobs=1 --iodepth=32 --direct=1

跑出来的数据是:VL805扩展坞顺序读约495MB/s,顺序写约465MB/s;主板原生USB3.0口顺序读约505MB/s,顺序写约475MB/s。两个差距在2%以内,基本属于正常波动。随机4K读写差异也不大,VL805在QD32队列深度下的随机读约85MB/s,原生口约88MB/s,这个差距更多是CPU调度和系统负载造成的,不是芯片瓶颈。

多点并发测试更能体现VL805的实际实力。我同时挂了三个USB设备:一个移动硬盘跑顺序读、一个U盘跑小文件读、一个USB网卡跑iperf3网络吞吐。三个设备同时工作时,PCIe x1 Gen2的5GT/s带宽大概只用了60%,每个设备都还有不错的吞吐量,没有出现某个口霸占全部带宽的情况。这得益于VL805内部的QoS仲裁机制,它会按优先级和时间片公平分配带宽,不会让持续大流量的设备饿死其他小流量设备。

5.2 热插拔与长时间运行的稳定性观察

除了跑带宽,稳定性测试同样是重点。我连续让这块扩展坞满载运行了72小时:一个移动硬盘持续写数据,一个USB显卡(DisplayLink方案)外接1080p显示器,一个机械硬盘做备份,还有一个USB声卡在播音乐。整个测试期间没有出现设备掉线、速度骤降或者系统卡死的情况。温度方面,用红外测温枪测了芯片表面温度,满载时约62℃,手摸上去温热但不烫手,在有风道的机箱里这个温度完全没问题。

热插拔测试也做了很多轮,每轮都在Linux系统运行状态下插入或拔出USB设备,观察dmesg是否有错误记录。正常轮次中,设备拔掉后系统日志会出现"device descriptor read error"或者正常的usb 1-5: USB disconnect信息,再次插入能顺利枚举。如果遇到热插拔后设备识别异常,多半是ESD防护不到位或者USB口电源的保持电容太小,导致插拔瞬间电压跌落超过USB规范允许的5%范围。我在每个USB口的5V输入处并联了一颗470uF电解电容,热插拔瞬间的电压跌落基本可以忽略不计。

6. 踩坑记录:这些雷区几乎所有人都躲不过

6.1 板子焊好了却不识别,问题竟出在Flash固件版本

这块扩展板我做第二版的时候,遇到了一个非常隐蔽的问题:焊上VL805和Flash之后,插上主板完全枚举不到任何PCIe设备。我用示波器量了PCIe的参考时钟,100MHz方波正常;量了PERST#,上电后有正常的低到高跳变;量了3.3V和1.05V,电压都稳定在标称值。排除了供电、复位、时钟三大基本要素,问题只能在信号链路上。

后来我想起来有个细节没查——Flash里的固件版本。第一版打样时我用烧录器写的是官方旧版固件,第二版换了一颗Flash芯片,烧录时用的还是那颗旧版固件的镜像。但第二版PCB的Flash供电走线跟第一版不太一样,上电时序存在微小差异。VL805在固件加载阶段如果检测到Flash访问异常,会一直停留在等待固件状态,PCIe枚举自然看不到完整设备。解决办法是重新从官网下载新版固件镜像,用flashrom强行擦除后重写,再上电就正常了。

从这个坑里总结出的经验是:VL805的固件版本跟硬件版本有绑定关系,新版本固件大概率解决了一些硬件勘误,尽量用新的;Flash芯片虽然型号看起来兼容,但不同厂商的Flash在时序细节上有差异,选跟参考设计同型号的最稳(我用的W25Q16JVSIQ,这个型号在VLI评估板上能看到)。

6.2 USB3.0口只能跑USB2.0速度,90%原因是差分走线

另一个高频问题就是USB口速率上不去。我第三版打样为了缩小PCB面积,把USB3.0差分对走线缩短了,但走线从顶层换到了底层,中间层跨了一个电源平面分割区。结果就是SuperSpeed链路完全建立不起来,设备只能以480Mbps的USB2.0模式工作。

问题根源在于差分信号跨过了电源平面的缝隙,回流路径被切断,导致信号完整性急剧恶化。PCIe和USB3.0这类高速串行信号对参考平面连续性的要求极高,任何跨越分割区的行为都会让差分阻抗突变、产生反射和串扰。解决方法是重新调整Layout,让所有高速信号走线都在完整的参考平面上方走,尽量不换层,如果必须换层,在换层位置紧挨着打一对回流过孔,为信号提供最短的回流路径。

检查差分质量最简单的方式是用示波器看眼图。USB3.0的SuperSpeed信号眼高要求大于100mV,眼宽要求大于0.4UI(约80ps)。没有高速示波器的话,也可以用矢量网络分析仪测插入损耗与回波损耗,不过这种设备普通人接触不到。我的土办法是:换一块走线规整的板子试同一颗芯片,如果速度正常,那就是Layout问题,集中排查走线和过孔就对了。

6.3 供电不足导致多设备掉盘的排查链路

最后分享一个多设备同时使用时的掉盘问题。我一开始用PCIe插槽12V转5V的方案给USB口供电,接了两个2.5寸移动硬盘和一个3.5寸硬盘盒后,其中一个移动硬盘开始间歇性掉盘,dmesg里全是"usb 1-4: reset high-speed USB device"的报错。3.5寸机械硬盘启动瞬间的电流非常大,能达到2A甚至更高,直接把5V电源轨拉低了。当5V电压掉到4.5V以下,USB设备就会判定电压异常,触发复位。

排查链路是:先量5V轨空载电压(5.03V,正常),再量满载时的电压(掉到4.68V,异常),确认是供电能力不足。然后测12V输入轨电压(12.15V,正常),说明问题出在降压模块上。我这个MP1584降压模块标称输出3A,理论够用,但实际用的是淘宝廉价模块,电解电容缩水严重,动态响应能力差。换了一个用料扎实的模块,输出电容加到1000uF,满载时5V只掉到4.95V,问题解决。

这里顺便说一个更稳妥的替代方案:直接把板卡设计成支持双供电输入,PCIe取电和外置SATA电源并联,两个电源之间用理想二极管控制器(比如LTC4357)隔离,这样即使某个电源掉电,另一个也能无缝顶上。不过对于大多数桌面机箱的应用场景,只要把降压模块选好、电容加足,PCIe单路供电就够用了。

7. 后续还能怎么玩:从扩展坞到一体化多功能卡

这块VL805扩展板做好之后,我并没有就此收手,因为PCIe x1的带宽(5GT/s)在多数应用场景下并没有被充分利用。一个很自然的扩展方向是把PCIe转接卡的思路放大——我用同样的硬件平台,在板载预留了第二路PCIe信号(从金手指的x4引脚里多引了一对),接了一颗ASM1184e PCIe包交换芯片,把一路PCIe扩展成4路,再挂上两块VL805,这样就得到了最多10个USB3.0口。实测同时挂两块移动硬盘对拷,速度都能稳定在400MB/s以上,互不干扰。

如果你不想做这么大的工程,也可以走轻量路线:VL805的预留SPI接口其实还能接一个TPM芯片或者EEPROM,做安全启动密钥存储;板载的I2C总线可以接一颗温度传感器和风扇PWM控制器,做一个全功能的"智能扩展卡"。这些扩展接口在VL805的数据手册里都有说明,Pin脚是现成的,只是默认没接出来而已。

对于手头有树莓派5的朋友,这个项目还有另一个完全不同的玩法。树莓派5自带PCIe接口(通过FPC排线引出),你可以把VL805的PCIe侧信号用转接板接到树莓派5上,做成一个外置USB3.0扩展坞,给树莓派增加5个高速USB口。相比市面上的M.2 HAT扩展板,用VL805方案能多出好几个口,而且芯片本身的驱动兼容性也比那些杂牌桥接芯片强得多。

这个项目做下来,我最大的收获其实不是那几块扩展板本身,而是把PCIe枚举、xHCI驱动、差分信号完整性、供电设计这些平时只停留在书本上的概念,全部用烙铁和示波器过了一遍。如果你也想搞一块,我的建议是:不要一上来就追求10口全功能版,先按标准VL805参考设计做一块最小系统板,点亮之后再逐步加功能。每一步都验证过了再往前走,你会发现这些看似复杂的硬件设计,其实就是把一个一个的小模块拼起来的过程。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询