一、背景
高通量在体神经信号采集系统,随着通道数增加、增加实时刺激需求等,采用以太网传输面临带宽极限,亟需一种更快的传输介质。
目前以太网的带宽极限:实测800Mbit/s左右,[移植并使用Iperf3测试ARM Linux网口带宽]https://www.cnblogs.com/dy-stairmed/p/18796116
在8port 30K采集速率下:16*64*2*8*30k = 491.5Mbit/s接近传输极限。
因此采用USB3.0 传输,理论传输带宽:5Gb/s。通过前期调研,目前USB3.0 PHY方案一般通过 FPGA实现。
二、硬件方案
FT601Q FIFO-USB3.0 Bridge,理论:400MB/s,连接至ZYNQ_PL端。
三、逻辑架构设计
采用两个异步fifo实现多比特跨时钟域处理,将硬件接口转换为 FIFO的读写接口,后续可以根据应用调整为
AXI-STREAM接口。
2. 引脚定义:
3. 拟实现的读写时序
四、代码
点击查看代码[code]/* * file : FT601Q.v * author : D.y * date : 2025-03-19 * version : v0.1 * description : usb3.0 FT601Q-QFN76 write and read control rtl.use 245 Synchronous FIFO mode.first release use async fifo to deal with multi bit cross clock domain actual test result: 380MB/s for read,340MB/s for write * */module FT601Q(input clk, //sysclk,50Mhz at leastinput rst_n, //active low//---------------FT601Q------------------input USB_CLK, //FT601Q phy output clk, configure to 100MHz using FT600ChipConfigurationProgUtility_v1.3.0.2)inout [31:0] USB_D, //32bit data inout,I/Oinout [3:0] USB_BE, //Byte Enable,active high,4'b1111 means using 4 Channelinput USB_TXE, //FT601Q-FIFO write enable?601Q-FIFO not full),active lowinput USB_RXF, //FT601Q-FIFO read enable ?601Q-FIFO not empty),active lowoutput reg USB_OE, //FT601Q Data Output Enable active lowoutput reg USB_RD, //FT601Q-read enable,active lowoutput reg USB_WR, //FT601Q-write enable,active lowinout USB_Wakeup,//Suspend/Remote Wakeup pin by default Low when USB is active, high when USB is in suspend. //Application can drive this pin low in in USB suspend to generate a remote wakeup signal to the USB host.output reg USB_RSTn, //RESET_N,USB_EN,enable useoutput USB_SIWU, //reserved,should pull-upinout USB_GPIO0, //GPIO0 inout USB_GPIO1, //GPIO1//-------------FPGA Control------------------input wr_en, //active highinput [31:0] wrdat,output full,input rd_en, //active highoutput [31:0] rddat,output empty);//-------------------------state define------------------------------localparam RESET = 8'h01;localparam IDLE = 8'h02;localparam WRITE = 8'h04; //write fifo not empty,and USB_TXE keep low ,push data into USBlocalparam READ = 8'h08; //USB_RXF keep low,and read fifo not full,read data to read fifo//-------------------------signal define-----------------------------reg [7:0] state = RESET;reg [7:0] next_state = RESET;wire w_fifo_full;wire w_fifo_empty;wire r_fifo_full;wire r_fifo_empty;reg w_fifo_rden = 1'b0;reg r_fifo_wren = 1'b0;wire fifo_rst;reg [7:0] rst_cnt = 8'd0;assign fifo_rst = ~rst_n;//----------------------------iobuf---------------------------------wire [31:0] USB_D_buf;(* mark_debug = "true" *) reg USB_D_link = 1'b0;assign USB_D = (USB_D_link)? USB_D_buf : 32'dz;wire GPIO0_buf;wire GPIO1_buf;reg GPIO_link = 1'b0;assign GPIO0_buf = 1'b0;assign GPIO1_buf = 1'b0;assign USB_GPIO0 = (GPIO_link)? GPIO0_buf : 1'bz;assign USB_GPIO1 = (GPIO_link)? GPIO1_buf : 1'bz;wire [3:0] USB_BE_buf;reg USB_BE_link = 1'b0;reg [31:0] USB_DATA;reg r_fifo_wren_r1;assign USB_BE_buf = 4'b1111;assign USB_BE = (USB_BE_link)? USB_BE_buf : 4'dz;(* mark_debug = "true" *) wire [31:0] debug_data ;//----------------------------logic---------------------------------// for debud onlyassign debug_data = USB_D;//always @(posedge USB_CLK) begin// if(USB_BE_link)// debug_data |