基于FPGA和VHDL的USB2.0控制器设计
来源:电子工程世界 作者:—— 时间:2010-05-24 09:53
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操作。