[X]关闭
10

初探USB3.0极简方案之FT601Q芯片方案

摘要: 说来惭愧,从米联客开发板硬件上开始支持USB3.0芯片,FTDI600/601Q芯片方案已经快1年了,但是一直没给出非常详细的使用demo。市面上的开发板目前大都采用CY3014方案,那么米联客为什么一定要选择FTDI600/601Q这款开 ...


初探USB3.0极简方案之FT601Q芯片方案-1.jpg

说来惭愧,从米联客开发板硬件上开始支持USB3.0芯片,FTDI600/601Q芯片方案已经快1年了,但是一直没给出非常详细的使用demo。市面上的开发板目前大都采用CY3014方案,那么米联客为什么一定要选择FTDI600/601Q这款开发板方面用的不多的芯片来做USB3.0方案呢?为什么不买个别人的开发板来copy下方案呢?为什么要耗费这么大精力呢?如果从商业经济角度来说,拿现成的方案来做自然是最省事,技术风险也最小,但是米联客作为开发板设计生产厂家,以及原创资料的倡导者,希望能给整个开发板生态做出一份自己的贡献,所以我们做的事情,要能给广大开发者提供一定的帮助,而不是copy。

1、FTDI600/601Q的技术参数:

>>FT600&601Q 芯片是FTDI最新推出的USB3.0 to FIFO interface IC,实现USB3.0与16/32bit并行IO接口之间的数据传输。
>>整个USB通信协议全部由芯片驱动自行完成,开发者无须考虑USB底层固件的编程。
>>兼容支持USB3.0(5Gbps),向下兼容USB2.0(480Mbps and 12Mbps)传输。
>>高达8个可配置Endpoint.
>>支持2种FIFO传输协议,最大传输可达400MB/s。
>>芯片内部有16K字节的缓冲区,可以进行数据的大吞吐量操作。
>>支持远程唤醒功能。
>>芯片支持多种IO电压:1.8V,2.5V.3.3V。
>>通过16bit D[O:15]或32bit D[0:31]并行数据线和读写状态/控制线RXF、TXE、RD、WR,加上时钟CLK,使能OE信号线就可实现与CPU/FPGA的数据交换。
>>该芯片内部集成1.0V LDO,可提供给芯片核心部分使用。
>>工业级芯片,工作温度范围-40 to 85℃。

2、芯片构架
初探USB3.0极简方案之FT601Q芯片方案-2.jpg
3、极简外围设计
初探USB3.0极简方案之FT601Q芯片方案-3.jpg
综上所述,可以看出FTDI600/601Q方案绝对是USB3.0传输中非常好用的方案。

相比官方的FPGA测试程序,自己写的测试程序更加简单,阅读方面,可以直接兼容官方的测试软件进行测试。

FTDI600/601Q支持的传输模式如下说明,其中245 Synchronous FIFO 模式和Multi-Channel FIFO模式是我们最常用的模式。我们这里介绍的demo以245 Synchronous FIFO模式为例


初探USB3.0极简方案之FT601Q芯片方案-4.jpg

245 Synchronous FIFO 模式读时序
初探USB3.0极简方案之FT601Q芯片方案-5.jpg
245 Synchronous FIFO 模式写时序
初探USB3.0极简方案之FT601Q芯片方案-6.jpg
由于本文是初探FT601Q芯片方案,并未涉及上位机软件的编写,当然我们后面肯定会涉及上位机软件编写。这里用官方的测试程序进行测试,主要用到2个测试程序,分别是FT600 Data Loopback.exe和FT600 Data Streamer Application.exe
首先介绍Loopback方式的测试
初探USB3.0极简方案之FT601Q芯片方案-7.jpg
通过在线逻辑分析仪查看数据
初探USB3.0极简方案之FT601Q芯片方案-8.jpg
用winhex查看数据
初探USB3.0极简方案之FT601Q芯片方案-9.jpg
以下是245模式 loopback的FPGA代码

module ft60x_top(
// system control
input                  Rstn_i,//fpga reset
output                 USBSS_EN,//power enable   
// FIFO interface   
input                  CLK_i,
inout [31:0]           DATA_io,
inout [3:0]            BE_io,
input                  RXF_N_i,   // ACK_N
input                  TXE_N_i,
output reg             OE_N_o,
output reg             WR_N_o,    // REQ_N
output                 SIWU_N_o,
output reg             RD_N_o,
output                 WAKEUP_o,
output [1:0]           GPIO_o

);

assign USBSS_EN = 1'b1;   
assign WAKEUP_o = 1'b1;
assign GPIO_o   = 2'b00;   
assign SIWU_N_o = 1'b0;


wire rstn;

(*mark_debug = "true"*) wire [31:0] FIFO_Din;
(*mark_debug = "true"*) wire [31:0] FIFO_Dout;
(*mark_debug = "true"*) (* KEEP = "TRUE" *) wire [3 :0] BE_RD;
(*mark_debug = "true"*) wire [ 3:0] BE_WR;
(*mark_debug = "true"*) wire FIFO_F,FIFO_V;
(*mark_debug = "true"*) reg [1:0] USB_S;
(*mark_debug = "true"*) wire FIFO_WR, FIFO_RD;

//read or write flag
assign FIFO_Din =  (USB_S==2'd1) ? DATA_io   : 32'd0;//read data dir
assign DATA_io  =  (USB_S==2'd2) ? FIFO_Dout : 32'bz;// write data dir
assign BE_RD    =  (USB_S==2'd1) ? BE_io   : 4'd0;
assign BE_io    =  (USB_S==2'd2) ? BE_WR   : 4'bz;// write data dir
assign BE_WR    =  4'b1111;

assign FIFO_WR    = (!RD_N_o)&&(!RXF_N_i);
assign FIFO_RD    = (!WR_N_o)&&(!TXE_N_i);


always @(posedge CLK_i)begin
    if(!rstn)begin
        USB_S <= 2'd0;
        OE_N_o <= 1'b1;
        RD_N_o <= 1'b1;
        WR_N_o <= 1'b1;
    end
    else begin
        case(USB_S)
        0:begin
            OE_N_o <= 1'b1;
            RD_N_o <= 1'b1;
            WR_N_o <= 1'b1;
            if((!RXF_N_i)) begin
                USB_S  <= 2'd1;
                OE_N_o <= 1'b0;  
            end
            else if(!TXE_N_i)begin
                USB_S  <= 2'd2;
            end
        end
        1:begin
            RD_N_o <= 1'b0;  
            if(RXF_N_i) begin
                USB_S  <= 2'd0;
                RD_N_o <= 1'b1;
                OE_N_o <= 1'b1;     
            end
        end
        2:begin
            WR_N_o <= 1'b0;
            if(TXE_N_i) begin
                USB_S  <= 2'd0;
                WR_N_o <= 1'b1;
             end
        end
        3:begin
            USB_S <= 2'd0;
        end
        endcase               
    end
end


// fifo master
fifo_generator_0 fifo_inst (
  .clk(CLK_i),      // input wire clk
  .srst(!rstn),    // input wire srst
  .din(FIFO_Din),      // input wire [15 : 0] din
  .wr_en(FIFO_WR),  // input wire wr_en
  .rd_en(FIFO_RD),  // input wire rd_en
  .dout(FIFO_Dout),    // output wire [15 : 0] dout
  .full(FIFO_F),    // output wire full
// .empty(FIFO_E),  // output wire empty
  .valid(FIFO_V)  // output wire valid
);


Delay_rst #(
    .num(20'hffff0)
)
Delay_rst_inst
(
    .clk_i(CLK_i),
    .rstn_i(Rstn_i),
    .rst_o(rstn)
);


endmodule


再说stream模式,FT600 Data Streamer Application.exe程序可以完成stream流测试,可以看到写的速度达到了366MB/S,而读速度达到了338MB/S 这个传输速度还是非常不错的。
初探USB3.0极简方案之FT601Q芯片方案-10.jpg
以下是245 Stream模式FPGA代码极简设计:

module ft60x_top(
// system control
input                  Rstn_i,//fpga reset
output                 USBSS_EN,//power enable   
// FIFO interface   
input                  CLK_i,
inout [31:0]           DATA_io,
inout [3:0]            BE_io,
input                  RXF_N_i,   // ACK_N
input                  TXE_N_i,
output reg             OE_N_o,
output reg             WR_N_o,    // REQ_N
output                 SIWU_N_o,
output reg             RD_N_o,
output                 WAKEUP_o,
output [1:0]           GPIO_o

);

assign USBSS_EN = 1'b1;   
assign WAKEUP_o = 1'b1;
assign GPIO_o   = 2'b00;   
assign SIWU_N_o = 1'b0;

wire rstn;

(*mark_debug = "true"*) wire [31:0] rd_data;
(*mark_debug = "true"*) wire [31:0] wr_data;
(*mark_debug = "true"*) (* KEEP = "TRUE" *) wire [3 :0] BE_RD;
(*mark_debug = "true"*) wire [ 3:0] BE_WR;
(*mark_debug = "true"*) reg [1:0] USB_S;

//read or write flag
assign rd_data  =  (USB_S==2'd1) ? DATA_io : 32'd0;//read data dir
assign DATA_io  =  (USB_S==2'd2) ? wr_data : 32'bz;// write data dir
assign BE_RD    =  (USB_S==2'd1) ? BE_io   : 4'd0;
assign BE_io    =  (USB_S==2'd2) ? BE_WR   : 4'bz;// write data dir
assign BE_WR    =  4'b1111;


reg [7:0]wr_cnt;

assign wr_data = {wr_cnt,wr_cnt,wr_cnt,wr_cnt};

always @(posedge CLK_i)begin
    if(!rstn)begin
        wr_cnt <= 8'd0;
    end
    else if(WR_N_o) begin
        wr_cnt <= wr_cnt + 1'b1;
    end
end

always @(posedge CLK_i)begin
    if(!rstn)begin
        USB_S <= 2'd0;
        OE_N_o <= 1'b1;
        RD_N_o <= 1'b1;
        WR_N_o <= 1'b1;
    end
    else begin
        case(USB_S)
        0:begin
            OE_N_o <= 1'b1;
            RD_N_o <= 1'b1;
            WR_N_o <= 1'b1;
            if((!RXF_N_i)) begin
                USB_S  <= 2'd1;
                OE_N_o <= 1'b0;  
            end
            else if(!TXE_N_i)begin
                USB_S  <= 2'd2;
            end
        end
        1:begin
            RD_N_o <= 1'b0;  
            if(RXF_N_i) begin
                USB_S  <= 2'd0;
                RD_N_o <= 1'b1;
                OE_N_o <= 1'b1;     
            end
        end
        2:begin
            WR_N_o <= 1'b0;
            if(TXE_N_i) begin
                USB_S  <= 2'd0;
                WR_N_o <= 1'b1;
             end
        end
        3:begin
            USB_S <= 2'd0;
        end
        endcase               
    end
end


Delay_rst #(
    .num(20'hffff0)
)
Delay_rst_inst
(
    .clk_i(CLK_i),
    .rstn_i(Rstn_i),
    .rst_o(rstn)
);


endmodule


完成了基本的测试任务后我们将会开始具体的功能开发,比如完成摄像头的USB3.0采集方案!





路过

雷人

握手

鲜花

鸡蛋
发表评论

最新评论

引用 云海 2020-3-9 17:41
谢谢
引用 云海 2020-3-9 17:41
谢谢
引用 云海 2020-3-9 17:41
谢谢
引用 云海 2020-3-9 17:41
谢谢
引用 云海 2020-3-9 17:41
谢谢
引用 云海 2020-3-9 17:42
谢谢
引用 云海 2020-3-9 17:42
谢谢
引用 云海 2020-3-9 17:42
谢谢
引用 blfukfxc 2021-10-8 14:30
你好,请问我需要用MCU采集AD数据,然后传给FT600,再通过USB3.0存储到U盘,要求速度大于20MByte/s ,请问你们的方案或(FT600)能完成这个工作吗?或你们有板子可以实现吗?谢谢!
引用 rlweobrf 2022-10-31 15:04
你好,请指点一下,我这里发现上电复位了以后,ft601处于245fifo模式下,RXF_N一直处于0电平状态是怎么回事,此时ft601并没有收到数据,怎么会处于一种可读状态呢,谢谢

查看全部评论(10)

本文作者
2019-9-6 18:28
  • 7
    粉丝
  • 7822
    阅读
  • 10
    回复

关注米联客

扫描关注,了解最新资讯

联系人:汤经理
电话:0519-80699907
EMAIL:270682667@qq.com
地址:常州溧阳市天目云谷3号楼北楼201B
相关分类
热门评论
排行榜