USB3.0芯片FT601Q简介及FPGA实现

news/2024/10/25 5:18:04/

FT601Q介绍

  FT601Q 是 FTDI 推出的一款超高速 USB3.0 芯片,提供高达 5Gbps 的带宽。该芯片不需要额外的固件开发,共有 4 个写通道和 4 个读通道,每个通道的缓冲大小均为 4KB。FT601Q 具有多种工作模式,本文介绍并实现相对简单的同步 FIFO 模式——245 mode。

  FT601 工作模式在上电时检测 GPIO0/GPIO1 来确定,当 {GPIO1,GPIO0}=2‘b00 时,FT601Q 将进入 245 工作模式。

  首先对 FT601Q 的引脚功能进行介绍,QFN76 封装如下

在这里插入图片描述

  • DATA0 - DATA31,数据引脚,inout
  • BE0 - BE3,Byte Enable 引脚,inout,高电平有效;DATA被分成了4Byte,每个 Byte 占据一个通道,通道间相互独立,通过 BE 引脚进行控制
  • RESET_N,input,控制 FT601Q 的上电
  • SIWU_N,input,保留引脚,必须拉高
  • TXE_N,input,USB FIFO 可写信号,低电平有效
  • RXF_N,input,USB FIFO 可读信号,低电平有效
  • WR_N,input,USB FIFO 写使能,低电平有效
  • RD_N,input,USB FIFO 读使能,低电平有效
  • OE_N,input,USB FIFO DATA OUT Enable,数据输出使能信号,低电平有效
  • WAKEUP_N,inout,指示 FT601 是否处于休眠状态,也可以通过拉低该引脚唤醒 FT601Q
  • GPIO0、GPIO1,inout,功能较多,本文这里只用到上电时确定工作模式,其余不表
  • CLK,output,FT601Q 输出的时钟信号,可配置为 66MHz 或 100MHz,默认 100MHz。有一点需要注意,在 FT601Q 启动后,若没能与上位机建立通信,FT601 将自动休眠,该时钟也会消失!因此必须配合上位机 api 进行使用

  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。

FPGA代码实现

  为了可以简单适配各种读写时钟的情况,可以例化两个异步 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 Channelinput				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-upinout				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) beginif(~rst_n) beginstate		<= RESET;rst_cnt		<= 8'd0;endelse beginstate		<= next_state;if(rst_cnt < 8'd200) beginrst_cnt		<= rst_cnt + 1'b1;endelse beginrst_cnt		<= rst_cnt;endend
endalways @(*) begincase(state)RESET: beginif(rst_cnt >= 8'd200) beginnext_state	<= IDLE;endelse beginnext_state	<= RESET;endendIDLE: beginif((~USB_TXE) && (~w_fifo_empty)) beginnext_state	<= WRITE;endelse if((~USB_RXF) && (~r_fifo_full)) beginnext_state	<= READ;endelse beginnext_state	<= IDLE;endendWRITE: beginif(USB_TXE || w_fifo_empty) beginnext_state	<= IDLE;endelse beginnext_state	<= WRITE;endendREAD: beginif(USB_RXF || r_fifo_full) beginnext_state	<= IDLE;endelse beginnext_state	<= READ;endenddefault: beginnext_state	<= IDLE;endendcase
end//----------------------------Control--------------------------------
assign	full		= w_fifo_full;
assign	empty		= r_fifo_empty;assign	USB_SIWU	= 1'b1;always @(posedge clk) begincase(state)RESET: beginGPIO_link	<= 1'b1;enddefault: beginGPIO_link	<= 1'b0;endendcase
endalways @(*) begincase(state)RESET: beginUSB_RSTn	<= 1'b0;enddefault: beginUSB_RSTn	<= 1'b1;endendcase
endalways @(*) begincase(state)WRITE: beginUSB_D_link	<= 1'b1;enddefault: beginUSB_D_link	<= 1'b0;endendcase
end// ------------USB FIFO write--------------
always @(*) begincase(state)WRITE: beginUSB_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;enddefault: beginUSB_BE_link		<= 1'b0;USB_WR			<= 1'b1;w_fifo_rden		<= 1'b0;endendcase
end// ------------USB FIFO read---------------
always @(*) begincase(state)READ: beginUSB_OE			<= ((~USB_RXF) & (~r_fifo_full))? 1'b0 : 1'b1;USB_RD			<= ((~USB_RXF) & (~r_fifo_full))? 1'b0 : 1'b1;enddefault: beginUSB_OE			<= 1'b1;USB_RD			<= 1'b1;endendcase
endalways @(posedge USB_CLK) begincase(state)READ: beginr_fifo_wren		<= ((~USB_RXF) & (~r_fifo_full))? 1'b1 : 1'b0;enddefault: beginr_fifo_wren		<= 1'b0;endendcase
endendmodule

环回测试

  使用官方提供的上位机 Loopback 测试程序进行测试,结果如下

在这里插入图片描述
在这里插入图片描述

  由测试结果可以看到,FT601Q是小端传输,首先发送 B0(将接收到的第一个字节放在 B0),然后发送 B1(将接收到的第二个字节放在 B1),依次类推 B2、B3 的收发次序。例如本次 LoopBack 测试,发送的 0x764dfffe,在 FPGA 接收到的是 0xfeff4d76,直接转发回上位机,又得 0x764dfffe,实际使用时请务必注意这个问题

something

在这里插入图片描述

  在上位机测试时遇到的一些坑,在此记录:

  • 使用 Python 进行调试(D3XXPython_Release)时提示缺失 dll:需要将 FTD3XXLibray 压缩包中的 FTD3XX.dll 添加到路径
  • 启动 LoopbackDemo、StreamerDemo 后,检测不到 USB 设备,然而查看设备管理器可以看到该设备:是因为缺少 FTDI 驱动,安装驱动(ftdi_ft60x_1.2.0.5)后即可解决

以上压缩包和驱动均能在 FTDI 官网找到。

  FT600ChipConfigurationProgUtility 压缩包中是 FT600/FT601Q 的配置程序,通过该程序可以修改芯片的 VID、PID、Serial Number、Clock Frequency 等。


http://www.ppmy.cn/news/38516.html

相关文章

Spring 中经典的 9 种设计模式

1 简单工厂(非23种设计模式中的一种) 1 1 实现方式&#xff1a; BeanFactory。Spring中的BeanFactory就是简单工厂模式的体现&#xff0c;根据传入一个唯一的标识来获得Bean对象&#xff0c;但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。 1.2 实质&a…

深度学习个人整理

深度学习 概念 DL Deep Learning 机器学习的一个分支 机器学习分类 监督学习 特点&#xff1a;已知类别数据学习 因变量是否连续 分类 连续房价&#xff0c;体重&#xff0c;天气 回归 不连续是否患癌症 算法 k-近邻算法 KNN 决策树 支持向量机 SVM 神经网络 线性模…

设计模式小记

1、设计模式介绍 1.1、设计模式目的 编写软件过程中&#xff0c;程序员面临着来自 耦合性&#xff0c;内聚性以及可维护性&#xff0c;可扩展性&#xff0c;重用性&#xff0c;灵活性 等多方面的挑战&#xff0c;设计模式是为了让程序(软件)&#xff0c;具有更好的 代码重用性…

Spring封装的动态代理

看proxyFactory.addAdvice主要干了什么? 看下继承关系&#xff1a; 将advisor加入advisors 看下如何生成代理对象 org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy org.springframework.aop.framework.DefaultAopProxyFactory#hasNoUserSupplied…

2022国赛22:免密码ssh登录到其他Linux主机

大赛试题内容: 5.所有Linux主机root用户使用完全合格域名免密码ssh登录到其他Linux主机。 解答过程: 在linux-1上设置 [root@host-10-10-70-101 ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): C…

.net C#反编译及脱壳常用工具--小结

1、Reflector --微软自家工具--推荐 Reflector是最为流行的.Net反编译工具。Reflector是由微软员工Lutz Roeder编写的免费程序。Reflector的出现使NET程序员眼前豁然开朗&#xff0c;因为这个免费工具可以将NET程序集中的中间语言反编译成C#或者Visual Basic代码。除了能将IL转…

【Linux】(一.基础:Linux安装,Xshell, Xftp,vim编辑器)

文章目录1.安装CentOS1.1 安装软件VMware1.2 安装CentOS1.3安装vmtools2.Linux目录结构3.Xshell Xftp4.vim编辑器1.安装CentOS 1.1 安装软件VMware 1.2 安装CentOS &#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#…

聊聊MySQL主从延迟

文章目录 MySQL 的高可用是如何实现的呢?二、什么是主备延迟?三、主备延迟常见原因1、备库机器配置差2、备库干私活3、大事务四、主库不可用,主备切换有哪些策略?1、可靠优先2、可用优先实验一实验二3、结论MySQL 的高可用是如何实现的呢? 高可用性(high availability,缩…