赞
踩
FT601Q 是 FTDI 推出的一款超高速 USB3.0 芯片,提供高达 5Gbps 的带宽。该芯片不需要额外的固件开发,共有 4 个写通道和 4 个读通道,每个通道的缓冲大小均为 4KB。FT601Q 具有多种工作模式,本文介绍并实现相对简单的同步 FIFO 模式——245 mode。
FT601 工作模式在上电时检测 GPIO0/GPIO1 来确定,当 {GPIO1,GPIO0}=2‘b00 时,FT601Q 将进入 245 工作模式。
首先对 FT601Q 的引脚功能进行介绍,QFN76 封装如下
245 模式下,同步写时序如下图
在检测到 FIFO 可写信号 TXE_N=L 时,FPGA 拉低 WR_N 以开始写 FT601Q 内部的 FIFO,在 CLK 上升沿,数据将被写入 FIFO 中。我们利用全部的 4 个通道,因此 BE 应置为 0b1111。
同步读时序如下图
在检测到 FIFO 可读信号 RXF_N=L 时,FPGA 需要拉低 OE_N 与 RD_N 引脚以开始数据读取(测试表明 RD_N 信号可以和 OE_N 同时有效,而不必如时序图中检测到 OE_N 有效后才拉低),FT601Q 将在 CLK 的下降沿给出数据,因此用户可在上升沿读到稳定的数据。该模式下,读取会用到全部的四个通道,即 USB 芯片给出 BE=0b1111。
为了可以简单适配各种读写时钟的情况,可以例化两个异步 FIFO,一个用于写通道,将写时钟 clk 下的数据写入 FIFO_w,而一旦检测到 FIFO_w 非空,即可将数据推送给 USB FIFO。另一个用于读通道,一旦检测到 USB FIFO 可读,就获取数据并存入 FIFO_r,用户可在读时钟 clk 域下从 FIFO_r 中获取数据。
/*
* file : FT601Q.v
* author : 今朝无言
* Lab : WHU-EIS-LMSWE
* date : 2023-04-03
* version : v2.0
* description : usb3.0 芯片 FT601Q-QFN76 读写控制
* Copyright © 2023 WHU-EIS-LMSWE, All Rights Reserved.
*/
// 两种模式:245 Synchronous FIFO mode、Multi-Channel FIFO mode
// 这里实现 245 Synchronous FIFO mode
module FT601Q(
input clk, //用于复位计时及外部FIFO读写时钟
input rst_n,
//---------------FT601Q------------------
input USB_CLK, //FT601Q输出的时钟,可配置为66MHz或100MHz
//通过官方提供的上位机软件(FT600ChipConfigurationProgUtility_v1.3.0.2),可以配置PID、VID、Clock Freq等一系列属性
inout [31:0] USB_D, //32bit数据总线,I/O
inout [3:0] USB_BE, //Byte Enable,高电平有效 1111 表示使用 4 Channel
input USB_TXE, //FT601Q-FIFO可写信号(即601Q-FIFO非满),低电平有效
input USB_RXF, //FT601Q-FIFO可读信号(即601Q-FIFO非空),低电平有效
output reg USB_OE, //FT601Q-输出使能(Data Output Enable),低电平有效
output reg USB_RD, //FT601Q-读使能,低电平有效
output reg USB_WR, //FT601Q-写使能,低电平有效
inout 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,控制USB的上电
output USB_SIWU, //reserved,should pull-up
inout USB_GPIO0, //GPIO0
inout USB_GPIO1, //GPIO1
//-------------FPGA Control------------------
input wr_en, //高电平有效
input [31:0] wrdat,
output full,
input rd_en, //高电平有效
output [31:0] rddat,
output empty
);
//-------------------------state define------------------------------
localparam RESET = 8'h01;
localparam IDLE = 8'h02;
localparam WRITE = 8'h04; //若write fifo非空,且usb fifo可写,将数据推入USB,写优先
localparam READ = 8'h08; //若usb fifo可读,且read fifo非满,将数据读到read fifo
//------------------------------------------------------------------
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;
assign fifo_rst = ~rst_n;
reg [7:0] rst_cnt = 8'd0;
//----------------------------iobuf---------------------------------
wire [31:0] USB_D_buf;
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;
assign USB_BE_buf = 4'b1111;
assign USB_BE = (USB_BE_link)? USB_BE_buf : 4'dz;
//-------------------------write fifo--------------------------------
//异步FIFO 采用 First Word Fall Through 模式
fifo_generator_ft60x fifo_w(
.rst (fifo_rst),
.wr_clk (clk),
.rd_clk (USB_CLK),
.din (wrdat),
.wr_en (wr_en),
.rd_en (w_fifo_rden),
.dout (USB_D_buf),
.full (w_fifo_full),
.empty (w_fifo_empty)
);
//--------------------------read fifo--------------------------------
//异步FIFO
fifo_generator_ft60x fifo_r(
.rst (fifo_rst),
.wr_clk (USB_CLK),
.rd_clk (clk),
.din (USB_D),
.wr_en (r_fifo_wren),
.rd_en (rd_en),
.dout (rddat),
.full (r_fifo_full),
.empty (r_fifo_empty)
);
//-----------------------------FSM----------------------------------
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
state <= RESET;
rst_cnt <= 8'd0;
end
else begin
state <= next_state;
if(rst_cnt < 8'd200) begin
rst_cnt <= rst_cnt + 1'b1;
end
else begin
rst_cnt <= rst_cnt;
end
end
end
always @(*) begin
case(state)
RESET: begin
if(rst_cnt >= 8'd200) begin
next_state <= IDLE;
end
else begin
next_state <= RESET;
end
end
IDLE: begin
if((~USB_TXE) && (~w_fifo_empty)) begin
next_state <= WRITE;
end
else if((~USB_RXF) && (~r_fifo_full)) begin
next_state <= READ;
end
else begin
next_state <= IDLE;
end
end
WRITE: begin
if(USB_TXE || w_fifo_empty) begin
next_state <= IDLE;
end
else begin
next_state <= WRITE;
end
end
READ: begin
if(USB_RXF || r_fifo_full) begin
next_state <= IDLE;
end
else begin
next_state <= READ;
end
end
default: begin
next_state <= IDLE;
end
endcase
end
//----------------------------Control--------------------------------
assign full = w_fifo_full;
assign empty = r_fifo_empty;
assign USB_SIWU = 1'b1;
always @(posedge clk) begin
case(state)
RESET: begin
GPIO_link <= 1'b1;
end
default: begin
GPIO_link <= 1'b0;
end
endcase
end
always @(*) begin
case(state)
RESET: begin
USB_RSTn <= 1'b0;
end
default: begin
USB_RSTn <= 1'b1;
end
endcase
end
always @(*) begin
case(state)
WRITE: begin
USB_D_link <= 1'b1;
end
default: begin
USB_D_link <= 1'b0;
end
endcase
end
// ------------USB FIFO write--------------
always @(*) begin
case(state)
WRITE: begin
USB_BE_link <= 1'b1;
USB_WR <= ((~USB_TXE) & (~w_fifo_empty))? 1'b0 : 1'b1;
w_fifo_rden <= ((~USB_TXE) & (~w_fifo_empty))? 1'b1 : 1'b0;
end
default: begin
USB_BE_link <= 1'b0;
USB_WR <= 1'b1;
w_fifo_rden <= 1'b0;
end
endcase
end
// ------------USB FIFO read---------------
always @(*) begin
case(state)
READ: begin
USB_OE <= ((~USB_RXF) & (~r_fifo_full))? 1'b0 : 1'b1;
USB_RD <= ((~USB_RXF) & (~r_fifo_full))? 1'b0 : 1'b1;
end
default: begin
USB_OE <= 1'b1;
USB_RD <= 1'b1;
end
endcase
end
always @(posedge USB_CLK) begin
case(state)
READ: begin
r_fifo_wren <= ((~USB_RXF) & (~r_fifo_full))? 1'b1 : 1'b0;
end
default: begin
r_fifo_wren <= 1'b0;
end
endcase
end
endmodule
使用官方提供的上位机 Loopback 测试程序进行测试,结果如下
由测试结果可以看到,FT601Q是小端传输,首先发送 B0(将接收到的第一个字节放在 B0),然后发送 B1(将接收到的第二个字节放在 B1),依次类推 B2、B3 的收发次序。例如本次 LoopBack 测试,发送的 0x764dfffe,在 FPGA 接收到的是 0xfeff4d76,直接转发回上位机,又得 0x764dfffe,实际使用时请务必注意这个问题!
在上位机测试时遇到的一些坑,在此记录:
以上压缩包和驱动均能在 FTDI 官网找到。
FT600ChipConfigurationProgUtility 压缩包中是 FT600/FT601Q 的配置程序,通过该程序可以修改芯片的 VID、PID、Serial Number、Clock Frequency 等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。