你的位置:EETOP 赛灵思(Xilinx) 社区 >> >> 全部 >> 详细内容

基于FPGA和VHDL的USB2.0控制器设计

发布者:jackzhang 时间:2010-10-20 21:16:50

在视频存储和图像宽带领域中,经常遇到实时高速数据传输的要求。2000年4月,由Intel、Microsoft、NEC、Compaq、Lucent、Phillips等公司共同制订的USB2.0(Universal Serial Bus)传输协议,其速度远远超过了目前使用IEEE1394接口进行视频传输的400Mbps,达到了480Mbps;而且具有即插即用的PnP(Plug And Play)、可进行菊花链式的级联(通过USB HUB进行外围扩展)、可串连多达127个USB设备等优点。应用该协议可支持实时语音、音频和视频数据的传输。

本文针对高速数据传输需求,根据USB2.0的协议规范,利用VHDL语言实现符合该协议的功能控制器,在视频压解系统中使数据在PC与外设之间高速传输。如图1所示由视频A/D采集的原始视频数据,在Philips公司生产的TM1300专用视频处理器中压缩后,通过USB控制器送至PC机。PC机的整个通过USB控制器传输到TM1300,解压后发送至视频D/A。

1 控制器结构原理

USB2.0控制器结构框图如图2所示。控制器主要由两个部分组成,其一为与外设的接口,另一个是内部协议层逻辑PL(Protocol Layer)。内部存储器仲裁器实现对内部DMA和外部总线对存储器访问之间的仲裁。PL则实现USB的数据I/O和控制。

接口有三种:一种是与微控制器之间的功能接口;一种是与单口同步静态存储器(SSRAM)之间的接口;另外一种是与物理层之间的接口。这里符合UTMI(USB Transceiver Macrocell InteRFace)规范定义。

2 控制器实现

控制器接口的信号框图如图3所示。存储器采用标准的单口SRAM,其信号接口由32位数据线SRAM_DATA、15位地址线SRAM_ADDR及读写信号(SRAM_WE和SRAM_RD)组成,系统所需SRAM的容量为2 15×32bit=128KB。

而与微控制器之间的接口信号包括32位数据线DATA、18位地址线ADDR以及DMA请求和响应信号(DMA_REQ和DMA_ACK)。由于要支持到128KB,需要17位地址线,另外还需要一根地址线来选通SSRAM和USB控制器内部的寄存器,总共需要18根地址线addr[17:0]。定义如下:

USB_RF_SEL <= !addr[17];

USB_MEM_SEL <=addr[17];

第18位地址addr[17]为高时选择缓冲存储器,否则选择内部寄存器。地址addr[16:2]直接用于存储器SSRAM的地址。

2.1 UTMI接口

UTMI接口信号包括:与发送数据相关的信号(TxValid、TxReady等),与接收数据相关的信号(RxActive、RxValid、RxError等)以及16位双向数据线。

在物理层,该控制器需要一个外部的USB收发器(Transceiver),本文采用的是Philips公司的ISP1501芯片。该芯片用作USB2.0的模拟前端,从USB电缆来的差分信号进行反转不归零码(NRZI)解码和位解填充转换成16位并行数据;反之,16位并行数据通过一个差分驱动电路经过串行化、位填充和NRZI编码输出到USB电缆上。ISP1501通过管脚MODE0和MODE1决定收发器的工作模式,共有4种工作模式:MODE[1:0]为“00”时,收发器处于断开状态;为“01”时处于全速(Full Speed)模式(此时USB带宽为12Mb/s);为“10”时是高速(High Speed)模式(此时USB最大带宽是480Mb/s);为“11”时是HS chirp模式。

UTMI接口通过译码MODE[1:0]来控制ISP1501在HS和FS之间转变。

If mode_hs='1'then

MODE<='10'

Elsif mode_hs='0'then

MODE<='01'

End if;

 

 

2.2 协议层

控制器的核心逻辑位于PL(Protocl Layer)模块,负责管理所有USB数据I/O和控制通信,其结构如图4所示。

DMA和存储器接口提供随机存储器访问和DMA操作。该模块使PL和外部微控制器采用DMA方式访问SSRAM。当外部总线有访问SRAM的请求时,且PL没有请求访问存储器,控制逻辑如下:req、ack分别对应外部总线和存储器之间的请求和响应信号,din、addr和we分别是外部总线给出的数据、地址和写信号,mreq是内部DMA向存储器发送的请求信号,mdin、maddr和mwe分别是内部DMA给出的数据、地址和写信号。

sel <=(req OR ack_r) AND(NOT mreq);

if sel='1' then

sram_out<=din;

sram_adr<=addr;

sram_we<=req AND we;

else

sram_out<=mdin;

sram_adr<=maddr;

sram_we <=mwe;

end if;

由控制逻辑可看出,内部DMA操作的优先级比外部总线高。

协议引擎(Protocol Engine)处理所有标准的USB握手信号和控制通信。分组组装器组装分组并送入输出FIFO,先组装分组头,插入适当的PID(分组标识)和校验和,然后加入数据域。分组拆装器先解码出PID和序列号以及校验和,再从8位PID取低4位(或高4位取反)得到PID[3:0],通过USB2.0协议的PID类型定义译码出PID名,判断是Token分组(OUT、IN、SOF和SETUP)还是DATA分组(DATA0、DATA1、DATA2和MDATA)。

Pid_Token<=pid_OUT OR pid_IN OR pid_SOF OR pid_SETUP;

Pid_DATA <=pid_DATA OR pid_DATA1 OR pid_DATA2 OR pid_MDATA;

如果是Token分组(格式定义如图5所示),则将后续的16bit数据分别放入两个8bit临时Token寄存器token0和token1,然后取出分组中的7位地址、4位端点号及5位CRC校验码。

Token_fadr<=token0[6:0];

Token_endp<=token1[2:0] & token0[7];

Token_crc5<=token1[7:3];

对于特殊的Token须进行特殊的处理,本文实现的控制器只对SOF这一特殊Token进行操作,解出PID后的11位帧号及5位CRC5校验码。

Frame_no<=token1[2:0] & token0;

Token_crc5<=token1[7:3];

检验校验码是否出错,如果出错等待下一个Token,否则将地址、端点号和帧号等放入相应寄存器。Token类型如果是IN,则执行组装分组并发送寄分组;如果是OUT则拆卸接收到的数据分组。对于其他不支持的Token则视为错误处理:Pid_ERROR<=pid_ACK OR pid_NACK OR pid_STALL OR pid_NYET OR pid_PRE OR pid_ERR OR pid_SPLIT OR pid_PING;如果出错则不进行Token的解码,而等待下一个Token的到来。

如果是DATA分组,则紧接着PID的是最大载荷为1024字节的数据和16位CRC16校验码。对数据的处理先写入端点寄存器,然后通过DMA操作写入SSRAM。下面详细介绍端点寄存器和DMA操作。

2.3 端点操作

数据的传输实际上通过端点(Endpoint)进行,控制器通过写端点的寄存器来配置端点,该控制器最多可有16个端点,每个端点有相应的4个寄存器:Epn_CSR、Epn_INT、Epn_BUF0和Epn_BUF1(这里n=0、1、2或3),其格式如图6所示。本文使用addr[8:2]7根据地址线来访问这些寄存器,addr[8:4]用来选择端点号,其值(16进制)从4到19分别表Epn(n=0...15)。addr[3:2]指定寄存器类型:“00”代表CSR(Control Status Register);“01”代表中断寄存器;“10”指向Buffer0;“11”代表Buffer1。这两个Buffer用来作临时数据存储,Buffer0和Buffer1分别作为专用的输入/输出缓冲器来提高USB的数据吞吐能力。双Buffer能够减少微控制器和驱动软件之间的延迟。其中端点的CSR寄存器指定端点的工作模式并且向控制器报告指定端点的状态。Ep_CSR[31:30]必须初始化为“00”(最初使用Buffer0),通过读这2位可以知道下次所要处理的缓冲器;为“01”时,指定Buffer1。Ep_CSR[27:26]和Ep_CSR[25:24]分别指定端点类型和传输类型,其类型编码参见表1。Ep_CSR[21:18]指定端点号,总共可以有16个端点。Ep_CSR[15]时DMA使能位,为“1”时允许外部DMA操作,否则不允许DMA操作。

表1 类型编码表

当控制器收到中断时,读中断源寄存器(Ep_INT[6:0])来判断中断源和产生的原因。可自定义中断源,如Ep_INT[2]定义为该控制器接收到不支持的PID而产生的中断:Ep_INT[2]<=Pid_ERROR。Ep_INT[4]和Ep_INT[3]分别表示Buffer1和Buffer0的满或空的状态位。

Ep_BUF[31](标记缓冲器是否被使用过)在使用后被控制器置“1”,在清空或重填充该缓冲器后,控制器清除该位。该闰初始化时为“0”。Ep_BUF[30:17]指定缓冲器能容纳的字节数。Ep_BUF[16:0]缓冲器的指针,装载存储器SRAM中数据的地址。

 

 

控制端点(Endpoint0)比较特殊,由于它既要接收也要发送数据,因此对于控制端点,Buffer0用于OUT缓冲器,Buffer1则是IN缓冲器。从SETUP和OUT分组来的数据,写入Buffer0,IN分组的数据则是从Buffer1中获取。

2.4 DMA操作

DMA操作允许控制器与功能接口之间数据的透明传输。一旦设置了DMA操作,则不需要微控制器的干预。每个端点有一对DMA_REQ和DMA_ACK信号。当CSR寄存器中DMA使能信号位(Ep_CSR[15])被置位时,USB控制器使用DMA_REQ和DMA_ACK这两个信号来进行DMA的流控制。当缓冲区有数据或为空需要填充时发送DMA请求信号DMA_REQ,每传输4字节,响应一个DMA_ACK信号。

由于USB2.0协议定义的事务操作以8bit为单位,因此完成一次32bit的DMA操作需要进行4次写8bit。内部DMA采用高效的One-hot状态机设计方法,状态转换如图7所示。当需要将接收到的数据存储到SRAM(rx_dma_en=1)时进入WAIT_MRD状态,在该状态选中一个临时数据寄存器,并向存储器发送请求信号mreq,从存储器中预取4字节(当接收到的数据少于4字节时,保证有4字节的数据写入存储器)到该寄存器中,然后进入MEM_WR状态。当PL的分组拆装器接收到1字节数据时,将该字节写入临时存储器,转入下一状态MEM_WR1;当分组拆装器没数据给DMA仲裁器时则进入MEM_WR2状态,在此状态将临时存储器中的数据写入SRAM,然后回到IDLE状态。在操作过程中,使用计数器adr_cb对传输字节数进行计数,通过addr_cb[1:0]的值标识当前传输的是32bit中的哪个字节。计数器sizu_c每接收1字节数值加1。

在需要读取SRAM中的数据(tx_dma_en=1)时,DMA仲裁器由IDLE状态进入MEM_RD1状态,读取4字节数据到发送缓冲区中,然后进入状态MEM_RD2,再读4字节进入状态MEM_RD3,这8字节轮流使用Buffer0和Buffer1缓冲区:

if((NOT adr_cb[2]) AND mack

then Buffer0<=SRAM_DATA_I;

elsif (adr_cb[2] AND mack)

then Buffer1<=SRAM_DATA_I;

end if;

在MEM_RD3状态判断是否还需要读下一个数据,如果需要再进入状态MEM_RD2,否则在传输完所有字节后,返回到IDLE状态。在发送数据过程中,使用14bit计数器sizd_c决定传输字节数,取自Ep_BUF[30:17],每发送1字节数据,它的值减1。在图7中的各个状态中,由于超时、CRC校验错误或得到的数据发生错误时,PE产生的Abort信号会使当前状态都回到IDLE。

文中阐述了USB2.0功能控制器的一种实现方案。 其VHDL语言实现代码,已在XILINX公司的FPGA Virtex XVV3006fg456中通过了Xilinx ISE的仿真、综合及布局布线。FPGA的规模是32万门,1536个CLB(可配置逻辑单元)。该控制模块占用2050个Slice(66%),使用了1697个Slice触发器(27%)和3047个4输入LUT表(49%)。整个FPGA的速度可达到56.870MHz,完全满足视频数据的高速传输(对32bit数据操作,达到480Mb/s的速度时钟只需15MHz)。该方案实现的控制器便于修改且易于实现,可作为一个功能模块嵌入到SOC中,可使不同情况最大限度地灵活设计片上系统。

最新课程

  • 深入浅出玩儿转FPGA

    本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念

  • 从零开始大战FPGA基础篇

    本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“

  • Verilog基础及典型数字

    课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了