ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

自制PCIe转USB3.0扩展板:VL805芯片硬件设计与DIY实战指南

自制PCIe转USB3.0扩展板:VL805芯片硬件设计与DIY实战指南 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/REFCLKn100MHz参考时钟、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/A212V供电、A9/A103.3V供电、A13PERST#复位、A14/A15REFCLK/-参考时钟、B16/B17PER/-接收、A16/A17PET/-发送剩下的主要是SMCLK/SMDATSMBus管理总线、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 W25Q162MB容量就够了接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枚举过程是主机RCRoot 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_1106VLI的PCIe Vendor ID和DEV_3483INF里写清楚了这些匹配关系。通常情况下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 --nameseqread --filename/dev/sdb --rwread --bs1M --size1G --numjobs1 --iodepth32 --direct1跑出来的数据是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参考设计做一块最小系统板点亮之后再逐步加功能。每一步都验证过了再往前走你会发现这些看似复杂的硬件设计其实就是把一个一个的小模块拼起来的过程。
返回列表