☰
基于FPGA和CH569的USB3.0高速数据采集系统设计与实现
2026/9/27 1:50:58 网站建设 项目流程

一直关注高速数据采集这块的朋友,应该对“FPGA前端采集 + USB3.0桥接芯片上传”这套架构不陌生。以前做USB3.0传输,大家第一反应都是CYUSB3014(FX3)或者FT601,但这两颗芯片要么开发门槛不低,要么资料相对封闭。这次我搭了一套基于沁恒CH569的方案:FPGA做数据采集和预处理,CH569内部的RISC-V内核跑USB3.0协议栈,整条链路从ADC采样到PC端显示全打通,实测连续传输带宽稳定在300MB/s以上,比传统方案少了很多外围电路。这套设计很适合正在搞高速采集、图像传输、软件无线电的工程师参考,也能给想入门RISC-V+USB3.0的朋友一个完整的落地样板。

整个系统解决的核心问题很明确:怎样用最低的硬件复杂度,把FPGA采集到的高速数据实时搬进PC?CH569把USB3.0的PHY和控制逻辑全集成在芯片内部,省掉了外部PHY和繁琐的ULPI接口时序,让我能把精力集中在FPGA逻辑和端到端吞吐优化上。下面我会从方案选型、硬件设计、FPGA逻辑、CH569固件、联合调试这几个维度,把整套系统的设计思路和实操细节完整拆开讲。

1. 方案选型与整体架构设计

1.1 为什么选CH569,而不是FX3或者FPGA直驱USB3.0 PHY

做USB3.0数据传输,圈子里主流方案其实就三条路:FPGA直接外挂USB3.0 PHY芯片(比如TUSB1310)、用赛普拉斯的FX3系列、用带RISC-V内核的CH569。先说说我为什么排除前两个。

FPGA外挂PHY这条路的劝退点在于:USB3.0的物理层标准是5Gbps的SerDes,FPGA里要自己实现PCS层、链路训练、协议层状态机,工程量非常大,而且市面上能买到的USB3.0 PHY芯片本身货源也不多,设计周期拉得很长。老板问你要进度的时候,你敢说自己在调链路训练状态机,那基本就是给自己挖坑。FX3则是ARM9内核加一堆定制接口,资料确实多,但授权、供货、价格这些年都谈不上友好,而且它的GPIF II接口和FPGA对接时,时序要求很严格,信号线上稍有点毛刺就会导致数据错位。

CH569打动我的原因很实在:芯片内部直接集成了USB3.0超高速PHY、USB3.0设备控制器和RISC-V内核,单芯片就能完成协议处理。我只需要把它当成一个带FIFO接口的高速数据通道来用,CPU核主要用于枚举、控制管理和描述符处理,大块的数据搬运交给DMA和硬件FIFO完成。这样FPGA端的接口逻辑就简单得多,不用碰协议栈,整个项目的风险点压缩到可控范围。

1.2 系统架构与数据流分解

整套系统的数据流分为上行和下行两条链路。上行链路是核心,ADC采样数据先进入FPGA,经过必要的预处理后写入FPGA内部的异步FIFO或DDR缓存,然后按突发模式通过并行FIFO接口灌给CH569,CH569再通过USB3.0的Bulk端点把数据发到PC端上位机。下行链路是PC发控制命令(比如采样率切换、增益调节、启动停止),经过CH569转发到FPGA的控制寄存器,实现上位机对采集端的远程控制。

选“FPGA + CH569”而不是“CH569直接采集”,是因为ADC数据率和数据处理复杂度摆在那里。以我用的AD9226为例,12bit/65MSPS,原始数据率约97.5MB/s,这个速率FPGA接收没有任何压力,但如果要做数字下变频、滤波、触发、FFT这些预处理,CH569这种MCU级别的处理能力根本扛不住。FPGA的价值就在前端实时处理,CH569的价值在高速传输,两者分工非常清晰。

1.3 这套系统能做什么,适合谁来参考

这套架构能承载的应用场景很广。我做的是通用数据采集平台,换不同的AD前端就可以变成示波器、逻辑分析仪、软件无线电接收机、图像采集卡。比如你把ADC换成LTC2208这种16bit/130MSPS的片子,数据率约260MB/s,USB3.0链路依然能扛得住;如果你做的是CMOS图像传感器采集,把MIPI信号在FPGA里解析成并行数据,同样可以灌进这条链路。

适合参考这套设计的人有三类:一是做测试测量仪器的电子工程师,需要快速搭建数据采集前端;二是做软件无线电或高速通信基带处理的开发者,需要把FPGA处理完的IQ数据实时上传;三是对RISC-V和USB3.0协议栈感兴趣的嵌入式学习者,CH569给你提供了一条不用写Verilog就能玩转USB3.0的捷径。

2. 硬件设计要点与PCB布局心得

2.1 CH569最小系统搭建细节

CH569的供电和时钟是整个硬件设计的基石,这块省事后面就等着哭。芯片需要三路电源:3.3V IO电源、1.8V(或内部LDO配置)、1.0V核心电源,其中USB3.0 PHY的供电质量直接决定信号完整性。我用的是独立LDO分区供电,数字3.3V和PHY模拟电源之间用电感隔离,地平面则在PHY区域做单点跨接,避免数字噪声串扰到模拟端。

时钟方面,CH569需要外接25MHz晶振,配合内部PLL倍频产生USB3.0需要的5Gbps参考时钟。晶振选型注意精度要优于50ppm,最好是温补晶振,我最初用普通无源晶振,长时间上电后偶发掉枚举,排查半天发现是频率偏差超出了USB协议容限,换成温补晶振后问题消失。复位电路用RC延时加手动复位按键,上电复位时间建议保持至少10ms。

2.2 FPGA与CH569并行FIFO接口专题

这是FPGA和CH569之间的“脐带”,设计时优先保证这一段的信号完整性和时序收敛。我采用的接口定义包括:16位双向数据总线PD[15:0]、FIFO写信号FIFO_WR、FIFO读信号FIFO_RD、FIFO时钟FIFO_CLK、地址/命令选择FIFO_A0、状态输出FIFO_FULL/FIFO_EMPTY,再加上中断请求INT和片选CS。数据总线方向由CH569控制,FPGA在读操作时要把数据总线置为高阻态。

时序上最关键的是FIFO_WR信号的脉宽要满足CH569手册要求,我实际留了30%以上的余量。因为FPGA内部逻辑经过PLL后时钟偏斜和组合逻辑延迟叠加,如果不做时序约束,极端温度下可能会出现写数据建立保持时间不足,导致偶发性丢数据。建议在FPGA工程里对这组接口做完整的set_input_delay和set_output_delay约束。

2.3 USB3.0差分对布线与PCB叠层

USB3.0工作在5Gbps,已经属于高速信号范畴,PCB布线不能再按普通低速逻辑处理。我用的四层板,USB3.0的TX/RX差分对走在顶层,参考平面完整,阻抗控制为90欧姆。差分对内等长控制在5mil以内,对外等长控制在20mil以内,过孔数量尽量少。

特别提醒:CH569的USB3.0引脚和USB座子之间串联的耦合电容不能用普通贴片陶瓷电容混过去,要选高频特性好的0402封装电容,容值0.1uF即可,位置尽量靠近座子。ESD保护器件也要选寄生电容小于1pF的,否则会把信号边沿搞坏。第一次打板我图省事用了常规电容,结果眼图质量差到无法完成USB3.0训练,后来查到是电容ESR偏大导致信号回损超标。

3. FPGA逻辑设计:从采集到接口的完整链路

3.1 ADC采样时序与跨时钟域处理

ADC接口部分,我选的是并行LVCMOS输出的ADC,采样时钟由FPGA内部PLL产生。AD9226要求采样时钟占空比尽量接近50%,我用PLL输出后加ODDR原语做时钟整形,保证进入ADC引脚的时钟边沿足够干净。数据同步采用IDDR原语在时钟双沿采集,这样能降低对时钟占空比的敏感度。

跨时钟域是FPGA设计中最容易翻车的位置之一。ADC采样时钟域(比如65MHz)和CH569 FIFO接口时钟域(我用100MHz)不同步,数据打过去必须经过异步FIFO缓冲。FIFO的读侧指针同步采用两级寄存器打拍加格雷码,杜绝亚稳态传播。这里有个很多新手容易犯的错:直接用异步FIFO的empty信号做逻辑判断时未做同步,导致出现负脉冲毛刺,必须用FIFO的独立同步输出端口或者在逻辑里再做一级同步。

3.2 乒乓缓存与FIFO深度计算方法

理想情况下,ADC数据直接灌进FIFO再发给CH569即可,但USB传输有突发性,链路层重传会导致短时阻塞。如果FIFO不够深,FIFO满了之后ADC数据只能丢掉。我采用了典型的乒乓缓存结构:FPGA内部例化两块独立RAM块,写入端轮流写入,读出端一张存满就切换,同时通知CH569开始读取,这样能吸收掉USB传输的瞬时波动。

FIFO深度怎么算?以数据率100MB/s、USB3.0突发间隔最大约20us(由USB调度决定)为例,需要的缓存深度至少是100MB/s × 20us = 2000字节。这看起来不大,但考虑到上位机处理延迟、系统调度抖动,我实际用了16KB的FPGA内部FIFO,并有配套的“半满”中断信号触发CH569 DMA启动,实测没有出现溢出。如果你跑更高的ADC采样率,还要自己在FPGA外部挂DDR3做海量缓冲,但代价是系统复杂度上了一个台阶。

3.3 命令通道与状态回传设计

除了数据通道,FPGA端还需要一个下行命令接口。我通过CH569的SPI主端口连接FPGA的SPI从端口,PC发过来的控制字由CH569解析后写入FPGA寄存器。SPI通信速率不用很高,1MHz即可,关键是协议要稳定。命令帧格式我设计成“帧头+命令字+参数+校验”,帧头用固定的0x5A5A防止误触发。

状态回传也很重要。FPGA实时采集FIFO水位、ADC过载标志、PLL锁定状态,通过SPI周期上报给CH569,再由CH569把这些状态和采集数据一起组帧发给PC。这样上位机不仅能拿到采样数据,还能看到系统健康度,调试时省了无数时间。

4. CH569固件开发:RISC-V内核上的USB3.0协议栈

4.1 开发环境与工程组织

CH569的固件开发使用的是沁恒官方的MounRiver Studio(MRS),这玩意基于Eclipse加RISC-V GCC工具链,界面和STM32CubeIDE很像,上手成本低。官方SDK里给了丰富的USB3.0例程,包括设备枚举、Bulk传输、UVC等,我强烈建议不要从零写USB协议栈,直接在官方提供的“USB3.0 Bulk双向传输”例程上改。工程结构分三层:应用层(我的自定义命令处理)、USB设备层(描述符和端点管理)、底层寄存器驱动。修改的重点在描述符表和应用层回调函数上。

4.2 设备枚举与描述符配置要点

设备枚举阶段是USB设备最敏感的部分。CH569内置的USB3.0控制器会自动处理大部分协议细节,但描述符还是要自己认真写。我配置为自定义HID还是Bulk?如果是纯高速数据采集,建议使用自定义设备类,端点类型选Bulk批量传输,这样吞吐率最高。注意CH569支持SuperSpeed和HighSpeed双模式,描述符里必须同时提供USB3.0和USB2.0两套端点描述符,否则插USB2.0口无法降速工作。

一个实际经验:描述符中的bMaxPacketSize0字段,SuperSpeed下必须按512字节设置,HighSpeed下是64字节,不能写错。我最初直接把HS的值填到SS描述符里,导致USB3.0 host端一直枚举失败,报“设备无法识别”,查了两天才发现是这里的问题。

4.3 DMA传输路径与性能优化

CH569的数据搬运全部依赖DMA。官方SDK里示例是用的寄存器轮询方式读FIFO,但那样占用CPU开销,传输速度上不去。我改成了DMA链式传输:在内存中维护一个发送描述符数组,每个描述符指向一个数据缓冲区,DMA逐个搬运,搬运完成触发中断并更新描述符队列。CH569内部FIFO配合DMA可以实现高效的流式传输。

传输性能的瓶颈最终落在USB调度和DMA带宽上。实测我这款CH569在Bulk单向传输时,应用层有效带宽能稳定在300MB/s以上,峰值能摸到接近380MB/s。这个数据已经覆盖了绝大多数采集场景。如果还需要更高带宽,就得考虑双端点交错传输或者压缩数据,但这会让系统复杂很多。

4.4 RISC-V应用层控制逻辑实现

应用层我写了一个简单的命令解释器:上位机发8字节命令帧,CH569收到后判断命令类型,是通道配置就转发给FPGA,是启动/停止就置位GPIO控制采集使能,是查询状态就从SPI读取FPGA状态寄存器并组织返回数据。这样RISC-V核实际上扮演“管家”角色,它不碰大数据,只做控制面的事,数据面全交给DMA和硬件FIFO。

这里插一个RISC-V内核使用感受:CH569的青稞V3A内核跑120MHz,做这些控制任务绰绰有余,而且指令集资料齐全。如果你之前只玩过ARM,转RISC-V的适应成本很低,基本就是换个编译器和寄存器描述文件的事。

5. 上位机软件与全链路联调

5.1 上位机框架选择与驱动配置

上位机我用C#配合WinUSB驱动开发。CH569官方提供了INF和驱动安装包,支持WinUSB方式访问,这样就不需要写内核驱动。C#端使用P/Invoke调用WinUSB API,或者直接用LibUsbDotNet库封装好的接口,开发速度很快。

数据接收线程用异步读写模型,开两个线程分别处理Bulk读写。接收缓冲区用环形队列,连续读取128KB大小的数据块,并在状态栏实时显示接收速率和丢包计数。上位机界面很简单:一个波形显示控件用于展示采样数据波形,一个参数面板用于下发控制命令,一个状态栏显示链路速率和错误统计。

5.2 端到端吞吐率实测与瓶颈分析

整条链路联调后,我做了一组基准测试。ADC输出固定频率正弦波,采样率65MSPS,12bit数据,理论数据率97.5MB/s。USB3.0实际传输速率上位机统计为可稳定在96MB/s以上,接近理论极限,丢包为零。把采样率提高到120MSPS后,数据率约180MB/s,实测依然稳定在178MB/s左右。

这个结果说明瓶颈不在USB链路,而在于ADC采样率和FPGA处理位宽。如果你想让系统跑满USB3.0,就得选更高位数和更高速度的ADC。但要注意,当数据率超过200MB/s后,FPGA内部数据总线的处理位宽要相应加大,否则数据搬运逻辑会成为新的瓶颈。

5.3 与官方例程对比和二次开发建议

官方SDK里的Bulk示例实际上已经能跑通基本收发,但若直接用于数据采集,有几个问题要处理:一是官方示例的DMA缓冲是固定大小,不适合流式数据;二是官方例程没有丢包统计,出了问题很难定位;三是官方示例的GPIF接口逻辑是给CH569当外设用,和FPGA对接还需要自行适配时序。我建议你在官方例程基础上,重点改造DMA缓冲区管理、增加丢包计数、完善命令交互协议。

6. 常见问题与调试技巧实录

6.1 枚举失败与驱动加载问题排查

“设备无法识别”是最常见的问题。先区分是硬件问题还是固件问题:插USB2.0口测试,如果USB2.0都枚举不了,大概率是硬件问题;如果USB2.0正常、USB3.0不行,重点看差分对布线和PHY供电。驱动方面,安装官方驱动后如果设备管理器显示“未知设备”,可以手动更新驱动选择WinUSB,或者检查INF文件里的硬件ID是否和你芯片的VID/PID一致。

还有个小坑:CH569有两个USB控制器,一个是USB3.0的SuperSpeed控制器,一个是USB2.0的HS/FS控制器,两者复用了同一组物理引脚。固件初始化时必须正确选择启动模式,否则可能跑在USB2.0模式下面却还报错。

6.2 高速传输数据丢包与FIFO溢出

如果上位机收到的数据偶发丢包,先看FPGA内部FIFO水位是否频繁达到满值。如果在满值附近波动,说明缓存深度不足或CH569 DMA启动不够及时。优化方式:一是把FPGA FIFO深度加大,二是把CH569的DMA搬运粒度调大,减少中断频率,三是确认批量传输的端点缓冲区是否设置得足够大。

另一个隐蔽问题:时钟抖动导致跨时钟域采错数据,表现为偶尔出现整段波形错位但不是丢包。我查过AD9226的数据手册发现采样时钟上升沿时间不足,解决办法是在FPGA中把采样时钟输出经过一个DDR输出寄存器,再做一次1/4周期延时调整采样点位置,让采样点处于数据稳定窗口中央。

6.3 信号完整性问题导致的USB3.0链路退化

USB3.0链路如果训练不成功或者速率自动回退到USB2.0,多半是信号质量问题。用示波器测量TX差分对眼图,确保眼宽和眼高满足USB规范。如果眼图闭合,检查耦合电容、ESD器件、连接器的寄生参数是否超标。PCB走线过孔多的位置,建议改为背钻工艺。

散热问题也值得一提。CH569在持续高速传输时芯片温度上升明显,我在芯片底部加了一块散热焊盘,连接到PCB大面积铜箔做了散热,实测温度从85度降到55度左右。如果你做长时间高负载测试,散热设计一定不能省。

6.4 调试习惯与工具清单分享

这套系统调试时我常用的工具很简单:逻辑分析仪(最好带USB3.0协议解析)、高速示波器、串口打印、自定义的FPGA内部ILA调试核。FPGA端加ILA观察FIFO的写计数和读计数,能快速判断数据是否在FPGA侧丢失;CH569端通过串口打印DMA完成中断计数和错误状态,能确认USB侧是否有异常。

最后分享一个偷懒技巧:联合调试时给上位机加一个“回环测试”模式,也就是FPGA收到数据后原样返回给CH569,上位机校验收发数据是否一致。这个功能排查链路问题时极其高效,能迅速把问题定位到“FPGA→CH569”还是“CH569→PC”这一段,强烈建议做进固件里。按照这套流程,我从零开始调试到全链路跑通,大概花了两周时间,希望这篇文章能帮你把这个周期缩得更短。

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

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

立即咨询