ARTICLE DETAIL

资讯详情

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

FPGA与FX3的USB3.0高速数据传输链路设计:从架构到320MBps实战

FPGA与FX3的USB3.0高速数据传输链路设计:从架构到320MBps实战 搞FPGA和USB3.0数据传输的朋友估计都遇到过类似的场景板上ADC或者传感器数据量一上来UART顶不住千兆网又嫌麻烦这时候USB3.0是性价比最高的出路。不过真想把USB3.0跑到接近带宽上限光靠单片机枚举个U盘级别的速度远远不够。最近我基于CYUSB3014也就是赛普拉斯FX3系列 Xilinx Artix-7 FPGA做了一套高速采集链路最终在Vivado里把FPGA侧的SlaveFIFO接口调通实际持续传输速率稳定在320MBps附近。这篇文章就把整个链路从架构设计到具体配置原原本本拆开讲一遍踩过的坑、调过的寄存器、改过的时序约束都写在里面给正在搭USB3.0高速链路的同学做个参考。这个方案的核心思路其实很直接FPGA不直接处理USB协议而是把CYUSB3014当作一个USB3.0桥接芯片FPGA只需要把数据按约定好的时序塞进FX3的SlaveFIFO接口剩下USB枚举、协议打包、链路管理等脏活累活全都交给FX3完成。这样FPGA侧不用碰USB协议栈开发难度直接降了一个量级但前提是FPGA侧的数据通路设计必须达到320MBps这个吞吐要求否则桥接芯片再快也是白搭。1. 项目全景与数据链路拆解1.1 为什么选择CYUSB3014搭配FPGA市面上能做USB3.0高速传输的方案不少大致分三类一是用自带USB3.0 PHY的MCU比如STM32MP系列、i.MX8系列优点是集成度高但高速模式下CPU占用率感人而且大吞吐场景下经常出现丢包二是直接用FPGA实现USB3.0 PHY和协议栈比如用Xilinx的USB3 IP核配合外部PHY芯片这种方式最灵活但工程量大到让人头皮发麻光是把SuperSpeed的协议状态机调稳定就得花掉几个月的周期第三类就是本文这种FPGA专用桥接芯片的组合CYUSB3014扮演数据搬运工FPGA只负责把用户数据高效喂给桥接芯片两边各干各擅长的活。CYUSB3014是Cypress现在归英飞凌EZ-USB FX3系列里的SuperSpeed控制器内部集成了USB3.0/2.0 PHY、协议引擎和一个ARM926EJ-S内核。这颗芯片最吸引人的地方是它的GPIF II接口这是一个可编程状态机接口最大带宽能到约400MBps足够支撑USB3.0 SuperSpeed的理论极限5Gbps约等于500MBps去掉协议开销实际可用带宽在380到420MBps左右。GPIF II支持同步SlaveFIFO、异步SlaveFIFO、P端口、U端口等多种工作模式和FPGA对接最常用的就是同步SlaveFIFO模式。从成本角度看Artix-7系列FPGA CYUSB3014这套组合在工业采集、机器视觉、软件无线电领域已经是非常成熟的方案了供应链稳定参考设计也多真要出了问题社区里搜一搜基本都有答案比自己去啃USB协议栈划算得多。1.2 整体数据通路架构先画一条完整的数据链路数据源ADC、传感器、图像传感器→ FPGA内部逻辑 → FPGA侧FIFO缓存 → 并行总线 → CYUSB3014的GPIF II接口 → FX3内部DMA缓冲区 → USB3.0 PHY → PC上位机。这里有几个关键点需要提前想清楚。第一FPGA和FX3之间的并行接口位宽一般选32位因为GPIF II原生支持32位总线如果用16位或者8位会浪费带宽320MBps的目标基本就悬了。以100MHz的接口时钟计算32位总线理论带宽是100MHz × 4字节 400MBps留出了足够的余量。第二FX3内部有一个DMA架构GPIF II接口接收到的数据会通过DMA搬运到USB端点缓冲区这个过程不需要ARM核参与所以不会因为固件处理不过来而掉速。第三USB3.0是包传输机制存在协议开销实测场景里有效载荷带宽通常在70%到80%之间所以320MBps这个数值在USB3.0链路下已经是个相当可观的目标了。我实际用的数据源是一块高速ADC板卡采样率120MSps、14bit分辨率输出数据位宽经过拼接后正好是32bit时钟50MHz理论数据率200MBps。加上FPGA内部要做一些实时处理滤波、抽取处理完的吞吐大约在190MBps左右距离320MBps还有点距离。为了把带宽余量拉大我额外用FPGA内部RAM做了一块测试数据生成器在调试阶段直接灌满带宽验证链路极限避免ADC那边数据不够导致误判。2. Vivado工程搭建从芯片选型到管脚锁定2.1 开发环境准备与Vivado版本选择这个项目用的FPGA是Xilinx Artix-7 XC7A75T开发工具是Vivado 2020.2。为什么选这个版本而不是更新的2023.x或者2024.x主要原因有两个一是项目里的IP核和约束文件都是在这个版本下建的升级版本容易触发IP核重新编译浪费时间二是Vivado 2020.2对Artix-7的支持非常成熟没那么多幺蛾子。如果你手头是更新的Virtex UltraScale或者Versal那另说但老老实实用Artix-7做高速接口的话2020.2足够稳。安装Vivado的时候有个容易被忽略的选项——安装组件勾选。默认安装会带上Vivado HL WebPACK版本但对于XC7A75T这种Artix-7芯片WebPACK许可就能覆盖不需要花钱买Vivado HL Design Edition。除非你要用一些高级功能比如System Generator否则WebPACK就够了。安装路径不要带中文和空格这个坑我在别的机器上见过好几次综合阶段报一堆莫名其妙的路径错误根源就是安装路径里有中文。2.2 创建工程与芯片选型打开Vivado后按常规流程创建新工程选择RTL Project目标是Artix-7器件。具体的型号根据你手头的板卡确定我这边选的是xc7a75t-2ffg676封装是FFG676脚位比较多方便扩展。在配置工程的时候有几个设置项需要提前改好。Project Settings → General → Target Language选Verilog或VHDL都行看团队习惯Simulation Language保持一致。重点是Project Settings → Synthesis选项里把Flow属性和综合策略保持默认即可暂时不用动。真正要留意的是Implementation设置里的物理优化选项后面时序紧张的时候再开。工程建好后第一步不是写代码而是先做引脚约束。很多新手喜欢先把RTL写完再随手分配管脚这样很容易在布局布线阶段发现管脚分配不满足BANK电压要求、或与时钟资源冲突返工代价很大。我一般习惯先把约束文件做完这样综合布线之前就知道接口放在哪个BANK、电平标准是什么。2.3 管脚分配与时钟约束配置CYUSB3014和FPGA之间的接口信号大致分四组数据总线SLWR、SLRD、SLOE三个控制信号FLAGA、FLAGB、FLAGC三个状态标志还有接口时钟IFCLK。在FPGA侧对应关系如下信号名方向FPGA视角电平标准说明usb_data[31:0]双向LVCMOS33数据总线接FX3的DQ[31:0]usb_ifclk输入LVCMOS33接口时钟由FX3提供默认100MHzusb_slwr输出LVCMOS33写使能低有效usb_slrd输出LVCMOS33读使能低有效usb_sloe输出LVCMOS33输出使能低有效usb_flaga输入LVCMOS33FX3 FIFO状态标志usb_flagb输入LVCMOS33FX3 FIFO状态标志usb_flagc输入LVCMOS33FX3 FIFO状态标志这里有一个关键决策IFCLK时钟到底由谁提供。FX3的GPIF II接口支持内部时钟FX3自己产生IFCLK输出和外部时钟由FPGA给FX3馈入时钟两种模式。我采用的是FX3内部产生100MHz时钟的模式也就是IFCLK由FX3输出给FPGAFPGA用它作为SlaveFIFO接口的同步时钟。FPGA内部的数据处理逻辑跑在独立的系统时钟域比如200MHz两边通过异步FIFO隔离。PIN规划的时候有几个原则必须遵守第一数据总线最好集中放在同一个BANK的相邻脚位这样布线的等长控制压力小时序容易收敛第二参考电压VREF所在的BANK不要混用不同电平标准第三尽量避开配置相关的专用引脚和GTX高速串行引脚。对于FFG676封装我选的是BANK 13和BANK 14这两个BANK有充足的普通IO且供电为3.3V刚好匹配FX3的LVCMOS33接口。时钟约束方面需要在XDC文件里创建一个主时钟约束create_clock -period 10.000 -name usb_ifclk [get_ports usb_ifclk] set_input_delay -clock usb_ifclk -max 4.000 [get_ports {usb_data[*] usb_flaga usb_flagb usb_flagc}] set_input_delay -clock usb_ifclk -min 1.000 [get_ports {usb_data[*] usb_flaga usb_flagb usb_flagc}] set_output_delay -clock usb_ifclk -max 4.000 [get_ports {usb_slwr usb_slrd usb_sloe}] set_output_delay -clock usb_ifclk -min 1.000 [get_ports {usb_slwr usb_slrd usb_sloe}]输入输出延时数值怎么来的不能拍脑袋要看CYUSB3014数据手册里GPIF II接口的时序参数。FX3的DQ输出相对IFCLK上升沿的建立时间约为3.5ns保持时间约1ns输入给FX3的控制信号则要求建立时间约2ns、保持时间约0.5ns。把这些器件延时和中继走线延时都折算到约束里我取了略微保守的4ns和1ns这样时序分析有足够的裕量又不至于约束太紧导致布局布线做不过去。3. FPGA内部逻辑设计把数据塞进USB3.0的关键技巧3.1 跨时钟域处理与FIFO缓冲设计和FX3对接FPGA侧最核心的模块就是SlaveFIFO主控逻辑和数据FIFO。先说说数据FIFO。因为ADC采集时钟50MHz和FX3接口时钟100MHz不同步直接把ADC数据送到SlaveFIFO接口上肯定出乱子必须用异步FIFO做缓冲。我用的FIFO位宽32bit、深度4096大概是16KB的缓冲空间足够覆盖USB3.0链路突发传输时的排队等待。FIFO的读写侧要注意几件事。写侧时钟是ADC采样时钟域读侧时钟是usb_ifclk100MHzFIFO IP核的读写时钟独立设置。FIFO深度选择不能太浅因为USB3.0传输是按微帧125us调度的PC端USB主控制器可能会在某个微帧里没来得及发出IN令牌导致FX3里的数据往USB端搬不动FPGA侧数据如果继续灌进来就会溢出。16KB的缓冲大概能扛住约80us的持续数据配合FX3内部的DMA多缓冲机制实测可以做到长时间不丢数。还有一点很关键FIFO的复位要确保读写两侧都退出复位状态后再开始传数否则FIFO行为不定。Xilinx的FIFO IP核默认输出一个wr_rst_busy和rd_rst_busy信号需要在逻辑里等这两个信号都拉低之后才能开始读写这个细节在高速传输中尤其重要否则刚上电的那几十个周期内FIFO读写指针错乱会让整个数据流出现毛刺。3.2 SlaveFIFO主控状态机设计SlaveFIFO主控状态机是这整个项目的灵魂。它的任务就是把FIFO读出的数据按照FX3 GPIF II在SlaveFIFO模式下的时序规范一个周期一个周期地写到数据总线上。状态机不复杂但边界条件非常考验细心程度。同步SlaveFIFO写操作的时序大概是这样的FPGA侧先从FLAGA可编程阈值标志判断FX3内部当前DMA缓冲区是否已满如果FLAGA为低表示未满FPGA就把数据放到DQ总线上拉低SLWR信号在usb_ifclk的上升沿FX3采样数据总线并将数据写入内部FIFO。SLWR至少要拉低一个时钟周期如果数据连续可以一直保持SLWR有效每个IFCLK上升沿传一笔数据。我设计的状态机包含IDLE、WAIT_FLAG、WRITE_DATA、FIFO_READY等几个状态。其中关键的一笔是“FLAGA有效之后还需要一个周期的延时才能开始写入”为什么因为FLAGA是组合逻辑输出的标志它拉低表示FX3侧FIFO有空间但数据总线建立需要时间如果你在同一个时钟沿既判断FLAGA又输出数据那数据建立时间是不够的。所以最好状态机这样走检测到FLAGA有效→等一拍→输出数据SLWR拉低→下一拍判断是否继续写。状态机的核心代码骨架是这样简化版always (posedge usb_ifclk or negedge rst_n) begin if (!rst_n) begin current_state IDLE; slwr_reg 1b1; data_out_reg 32d0; end else begin case (current_state) IDLE: begin if (fifo_empty 1b0 flaga 1b0) current_state WRITE_DATA; end WRITE_DATA: begin if (fifo_empty 1b1 || flaga 1b1) begin slwr_reg 1b1; current_state IDLE; end else begin data_out_reg fifo_dout; slwr_reg 1b0; end end endcase end end实际工程中还要加上SLRD和SLOE的控制逻辑、读写方向切换控制、以及异常超时保护。异常超时保护是我后来补上的——如果上位机异常断开FX3不会及时从端点读数据FLAGA会一直有效FPGA的FIFO会在几十微秒内溢出这时候状态机会卡死在等待状态。加一个计数器连续等待超过一定时间就主动复位状态机并报警比让系统死锁强太多。3.3 组合逻辑优化与带宽提升320MBps的带宽要求换算到100MHz接口时钟下等于每个时钟周期平均要搬运3.2字节。缝合一个32位数据总线正好是一个周期4字节理论上只需要80%的占空比就能跑到320MBps。但实际工程里如果主控状态机穿插了过多等待周期效率很容易掉下来。我观察到一个有意思的现象刚开始实现的时候写状态机里加了SLRD的控制逻辑因为想在每次写之前先回读一下FX3的FIFO状态结果每个写周期之间都插入了一拍读操作带宽硬生生砍了一半。后来仔细读GPIF II的规格才发现同步SlaveFIFO模式下只要FPGA侧能保证FLAGA标志不够就等、够就连续写根本不需要在读状态上浪费时间SLRD只在FPGA要从FX3读数据时才需要。删掉多余的回读逻辑后写效率立刻上去了。还有一个容易被忽略的优化点数据总线的输出寄存器。如果DDR寄存器直接用组合逻辑驱动32位数据总线会产生很大的IO延迟时序收敛困难。我建议把data_out_reg的输出再打一拍寄存器虽然多了一个周期的延时但换来了IOB寄存器的使用时序余量能多出1到2ns这在高速接口上非常值得。3.4 综合与实现时的策略调整Vivado综合阶段默认策略对时序收敛未必友好尤其是100MHz的IO接口配合严格的输入输出延时约束时可能需要微调。我第一次跑implementation的时候时序报告里usb_data[*]这条路径的WNS最差负余量是负的大约-0.3ns虽然很小但确实不干净。排查下来发现是数据总线从FIFO输出到IOB寄存器的路径跨了两个SLICE组合逻辑过长。解决方法是两步走第一在综合属性里把数据总线的输出寄存器手动打拍用(* IOB TRUE *)属性强制放到IOB里第二在Implementation设置里打开物理优化Physical Synthesis让Vivado在布局布线阶段自动优化关键路径。这两步做完WNS变成正的0.2ns左右时序完全收敛。还有个小技巧Vivado里Analyze Timing Summary的“报告”不能只看Setup路径Hold路径同样重要。高速接口最容易出现hold违例因为数据变化太快、采样边沿抓不到稳定的数据窗口。我的经验是在XDC里对关键总线加一些分组约束把输入输出延时分得细一点宁可让Setup稍微紧一点也要保证Hold有足够余量。4. FX3固件配置与上位机联调带宽是怎么调到320MBps的4.1 FX3 SlaveFIFO配置要点FPGA侧调完只是完成了链路的一半FX3固件侧的配置同样重要。FX3的固件开发使用Cypress提供的FX3 SDK编程模型是GCC工具链加C语言主要在Windows下用EZ-USB FX3 SDK开发环境。FX3内部的ARM9跑的固件负责初始化GPIF II状态机、配置DMA通道、设置USB端点听起来复杂但Cypress官方提供了slavefifo例程大部分代码可以直接抄。关键配置项我梳理了一下。首先是GPIF II接口的配置需要定义接口位宽是32位、时钟是100MHz内部产生、SlaveFIFO的读写时序参数等等。FX3 SDK里有一个GPIF II Designer工具可以用图形化方式配置状态机图生成C代码后集成到工程里。初次上手GPIF II Designer可能会觉得有些绕但核心其实就是配置好S0/S1两个状态IDLE和WRITE以及FLAGA的高电平有效阈值。然后是DMA通道配置。FX3内部有8个DMA通道GPIF接口的数据需要配置成一个P2U外设到USB的DMA通道。这里有个性能关键点DMA缓冲区的个数和大小直接影响吞吐。FX3内部总共有512KB的SRAM可以划分为多个大小可配置的缓冲区。我配置了8个16KB的缓冲区让GPIF写入的DMA缓冲区和USB上传的DMA缓冲区交替使用实现流水线操作。如果把缓冲区个数配少了一个缓冲区被占住时另一个还没腾出来带宽就会周期性归零Windows那边看到的速率曲线就像锯齿一样跳。USB端点侧的配置相对简单使用BULK IN端点端点号选择EP8或者EP4缓冲区大小设成16KB多次缓冲开启。BULK传输不像ISO传输有实时性要求但USB3.0的BULK带宽已经足够高320MBps的需求用BULK完全能cover没必要上ISO。4.1 Cypress官方例程的修改思路FX3 SDK里自带的slavefifo例子默认配置是2字节宽度的接口改成32位需要在多个地方修改。首先是gpif_interface的配置在GpifConfig结构体里把总线和控制信号的位宽都改为32然后是DMA配置里描述符的size要对应修改最后是应用程序里CY_U3P_DMA_Type_t设置成CY_U3P_DMA_BYTE表示按字节流传输这样数据长度不会受字对齐影响。另外官方例程默认是按USB2.0设备枚举要在固件里明确设置USB3.0的BOS描述符和SuperSpeed端点伴侣描述符。FX3 SDK里的CyU3PUsbSetBOSDescriptor函数需要调用SuperSpeed端点的MaxPacketSize要设成1024这样才能发挥USB3.0的突发传输优势。固件编译烧写也有一点讲究。调试阶段用USB启动模式最方便FX3上电后通过USB线直接下载固件跑起来不用接外部存储。正式使用的时候建议把固件烧到板载SPI Flash里设置为SPI启动模式上电自动加载省得每次插电脑都要手动下载固件。烧写SPI的命令在SDK里有现成工具注意SPI Flash型号要选对否则擦写会报错。4.2 上位机测试与带宽验证硬件和固件都备齐后联调阶段主要靠上位机工具验证带宽。我用的测试工具是Cypress官方提供的Streamer程序StreamerExample这个工具专门用来测试USB3.0传输带宽。界面里选择BULK IN端点设置传输大小和缓冲区数量启动后就能看到实际吞吐率。第一次联调的时候我看到的速率只有190MBps左右——别笑这个数字其实是很多工程里“能用”的水平但离320MBps的目标还差不少。逐项排查后发现瓶颈出在FPGA侧状态机的一个低效分支里在读FIFO数据之前我加了一个等待fifo_empty拉高的判断但FIFO IP核的empty信号是在读请求发出后的下一个周期才更新所以每个数据周期之间都插入了一拍气泡效率损失接近一半。去掉这个多余的等待判断、改成提前预读取一拍之后带宽立刻上到280MBps。剩下40MBps的差距又在哪这回轮到上位机测试程序背锅。StreamerExample默认使用一个比较小的DMA缓冲区64KBWindows USB驱动每完成一次URBUSB请求块都会产生一次中断开销缓冲区太小导致中断频率太高吞吐被系统IO瓶颈限制住了。把URB缓冲区调大到1MB同时增加URB队列深度到8测量的速率终于稳定在318到325MBps之间平均320MBps达标。4.3 长时间稳定性测试与数据校验速率达标只是第一步长时间持续传输不丢数据才是真本事。我用FPGA内部的数据生成器发送递增计数序列0x00000000、0x00000001……依次递增上位机收到数据后做递增校验跑24小时看有没有计数跳变或乱序。这个测试因为数据模式固定能够快速定位传输过程中的位错误和包丢失。跑了8小时后看到错误日志出现一条奇怪的跳变计数序列在某一段少了2000多个数然后又恢复正常。这个现象很典型说明FIFO或DMA缓冲发生了溢出数据被丢弃了一部分但链路本身没断。排查后定位到是FX3端DMA缓冲区配置有一个描述符大小设置错误——缓冲区大小被设成了24KB但FX3内部SRAM的分配策略导致某个大缓冲区被拆分成了多个小段DMA调度时交错出现空档高速持续传输时数据就在这个空档期溢出了。把缓冲区大小统一改成16KB、保证描述符连续后24小时测试零错误。这里多说一句调试这类问题不要在每次出错后盲目重启重测成功率低也浪费时间。最有效的办法是提前设计一个“数据哨兵”机制比如在数据流中周期性插入特殊标记如0xA5A5A5A5上位机校验时如果发现这个标记的位置不对就能很明确地判断数据发生了乱序还是丢弃缩小排查范围。5. 高频问题定位与避坑记录5.1 Vivado开发过程中常见的报错处理写Vivado工程的时候大家遇到最多的一类问题是Implementation实现阶段报错或时序违例。搜热词列表里那条“vivado implement design变红”我这边也碰到过好几次。最典型的一种情况是综合通过、但实现时布局布线失败报错信息指向某个IO标准冲突或时钟资源不够。我遇到过一次400条错误同时爆出来的场面吓得以为工程废了结果仔细看全是同一类问题BANK电压没设置对。FFG676封装里好几个BANK共享VCCO供电我把两个BANK的IO都约束成了LVCMOS33但其中一个BANK的实际供电是2.5VVivado在DRC检查阶段直接判定电压不匹配成片报错。解决办法是回板卡原理图确认每个BANK的供电电压然后把约束改成实际的值。另外“vivado生成比特流失败”也是个高频问题。这个一般分两种情况如果错误发生在bitgen阶段之前多半是时序没收敛看时序报告找出WNS为负的路径优先级最高的那条回到RTL做优化如果bitgen本身报错通常是约束文件里有语法问题或者引用了不存在的引脚打开Messages窗口定位到具体行数就好。5.2 FX3链路调试的排查思路USB链路调不通的时候很多人第一反应是怀疑FPGA逻辑然后疯狂改FPGA代码折腾一通发现没用。我的排查顺序是自底向上的先确认物理链路——USB3.0线缆是否完整SuperSpeed需要线缆支持不要拿USB2.0线凑合、USB口是否真的工作在3.0速率通过设备管理器里的连接速度信息确认然后确认FX3固件是否正常运行——用SDK里的Control Center工具读取设备的USB描述符如果设备管理器能识别出Cypress FX3 USB Streaming Device说明固件已经跑起来了最后才是查FPGA侧逻辑用ILA逻辑分析仪抓FPGA和FX3之间的接口波形重点看FLAGA信号在传输过程中有没有周期性拉高如果有说明FX3侧DMA缓冲不够用需要去调固件。这里强烈建议在FPGA工程里保留一组ILA探针把usb_ifclk、slwr、flaga、fifo_empty这几个关键信号全部拉出来。ILA触发条件可以设成“slwr下降沿”这样抓到的波形正好是一段连续写传输的过程能直观看到每个时钟周期数据是否连续。我记得有一次带宽莫名降到270MBps用ILA一抓发现状态机每个写周期之间都多了一拍闲周期定位到是FIFO读使能和写使能之间插入的组合逻辑判断导致写请求延后了一个周期删掉冗余判断后恢复满速。而且ILA的采样深度要够。传输320MBps的时候别只抓1024个采样点起码配16384点的深度否则只能看到几十微秒的波形很难捕捉到周期性异常。5.3 关于Vivado版本和License的几个提醒前面说这个工程用的Vivado 2020.2再补充两个和版本、许可相关的小问题。一个是“vivado license”报错常见于新机器装完软件之后启动时提示许可证不可用。这个问题大多是环境变量XILINXD_LICENSE_FILE没设置对或者license文件里的主机ID和当前机器不匹配造成的。去许可证管理器里重新添加license文件确认Host ID一致就能解决。另一个是关于Vivado各版本之间的工程目录兼容性。2020.2建的工程直接用2023.1打开Vivado通常会提示升级IP核升级过程中有些第三方定制IP可能会丢失配置参数。所以如果项目进行到一半要换版本一定先备份最好把整个工程目录打包再操作。新版本虽然功能更全但对于这个项目的需求来说并不值得冒险。关于热词里提到的“Vivado如何在连接硬件的情况下生成固化文件”这个其实很简单。生成固化文件bin/mcs本身不需要连接硬件正常跑完Write Bitstream即可。连接硬件的作用是用Hardware Manager下载配置文件到FPGA里在线调试。如果是想生成固化到SPI Flash的镜像在Tools → Program and Debug → Generate Memory Configuration File里选好Flash型号即可和硬件是否连接没关系。只不过建议在线调试通过之后再生成固化文件否则固化进去一个没调通的镜像每次上电都要重新烧Flash挺麻烦的。6. 性能数据的复现条件与扩展思路最后把320MBps这个数字的复现条件写清楚免得有人按本文步骤做出来速度对不上。我这边的运行环境是Artix-7 XC7A75T、Vivado 2020.2FX3接口100MHz、32位总线的同步SlaveFIFO模式FX3固件按上述8个16KB DMA缓冲配置PC端使用Intel原生USB3.0控制器不要用扩展卡上的VL805之类桥接芯片性能打折、Windows 10系统。如果哪一项有出入速率浮动是正常的尤其PC端USB主控制器对吞吐的影响很大Intel和AMD原生的控制器都行但老旧的NEC/Renesas控制器在SuperSpeed下性能会差一些。在实际使用中我体会最深的一点是高速USB3.0传输的瓶颈往往不在某个单一芯片而在于整条链路的缓冲策略是否匹配。FPGA侧FIFO大小、FX3内部DMA缓冲区个数、上位机URB缓冲区大小这三个缓冲层必须彼此协调任何一个环节配小了整体吞吐都会被拖到最慢的那个环节附近。所以调试的时候不要只盯着FPGA时序多想想数据在“FPGA FIFO → FX3 SRAM → PC内存”这段路上会不会堆积。这组方案后续还能往几个方向扩展。一个是把FPGA侧的数据源从测试生成器换成真正的MIPI相机接口做实时图像采集系统320MBps的带宽足够传输1080p30的未压缩图像另一个是加一个PCIe接口或者千兆网口做成多路数据分发系统再有就是FX3的GPIF II接口支持多线程可以同时配置IN和OUT两个方向配合FPGA实现USB3.0双向传输方便做控制指令和数据的全双工交互。如果你正在做一个类似的FPGAUSB3.0项目希望这篇记录能帮你少走一些弯路。等我这边的MIPI相机接口调完再回来继续分享实际图像数据跑320MBps的经验。
返回列表