首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA篇之带FIFO的UART设计

FPGA篇之带FIFO的UART设计

UART是最常用的串行通信方式,几乎每一款MCU或者处理器都有UART。但是很多MCU的UART都没有带硬件FIFO,而一般嵌入式处理器的UART都带硬件FIFO,可是FIFO的深度常见的是8、16或者32。在一些较大数据包的传输场合,带较大深度FIFO的UART,可以有效提高传输效率和降低CPU的负担。FPGA具有较大容量的嵌入式RAM,适合组成FIFO,比如ALTERA的FPGA,利用Quartus II里的MegaWizard Plug-In Manager工具,很方便就可以生成可定制深度和位宽的FIFO。为构建带FIFO的UART提供有利条件。本文介绍的是一种包含512字节FIFO并且带并行总线的UART设计。


图1

如图1所示,就是一种用FPGA设计的UART 结构图。采用常用的并行总线作为与主机通信的接口,可直接与CPU总线对接。通过总线操作,可以直接访问控制寄存器、状态寄存器和读写数据寄存器。写数据寄存器与发送FIFO相连,总线每写入一个数据,就会相应增加到发送FIFO中。如果使能了发送使能控制位,发送逻辑就会从发送FIFO读出数据到发送移位寄存器,串行数据从TXD发出。同样,如果使能了接收使能控制位,当接收逻辑收到一个数据时,就写入接收FIFO,接收FIFO读端口的第一个字节被映射到读数据寄存器。这样总线每读出一个字节,就相当于从接收FIFO读出一个字节。
该UART还带有接收中断功能,只要设定了中断触发值寄存器,当接收FIFO数据个数达到中断触发值时,就会从INT引脚产生中断信号,通知主机。
波特率的设定是通过设定分频值寄存器,产生波特率时钟。UART采用16倍波特率的采样时钟,所以波特率Baud = sysclk/16/(分频值+1)。由于收发是异步的,所以发送逻辑和接收逻辑使用不同的时钟产生模块。


图2

采用自顶而下的模块化设计方法,分为总线控制、发送逻辑、接收逻辑、时钟产生、发送FIFO、接收FIFO以及FIFO读写控制模块。在Quartus II里综合出来的顶层RTL如图2。
表1
地址
寄存器
描述
读写
0x00
FIFO
W:发送FIFO;
R:接收FIFO
R/W
0x01
分频值
Baud = sysclk/16/(分频值+1)
W
0x02
中断触发值
当接收FIFO有效个数≥中断触发值时,触发中断
W
0x03
状态寄存器
Bit0:接收FIFO空;
Bit1:接收FIFO满;
Bit2:发送FIFO空;
Bit3:发送FIFO满;
Bit4:接收FIFO有效个数第8位;
Bit5:接收FIFO有效个数第9位;
Bit6~ Bit7:保留
R
0x04
接收FIFO有效个数
接收FIFO有效个数0~7位;
R
0x05
控制寄存器
Bit0:发送FIFO清空位;
Bit1:接收FIFO清空位;
Bit2:接收使能位;
Bit3:发送使能位;
Bit4~Bit7:保留
W
总线可操作的内部寄存器以及描述见表1所示。在本例中,发送和接收FIFO的深度都是512字节。发送FIFO和接收FIFO共用了地址0x00。UART使用1位起始位、8位数据位和1位停止位。


使用modelsim进行UART的功能仿真。仿真的方法是采用UART自发自收的方式,把RXD连接到TXD。先通过总线设置好UART的控制寄存器,使能发送和接收,设定中断触发值为5,然后往发送FIFO写入从0x55~0x5e的10个字节。经过一段时间后,读取接收FIFO的数据个数,然后依次把接收到的数据读出。仿真结果见如图3、4、5。


图3

图3是整个仿真截图,可以看到,当写入数据之后,txd引脚就开始输出串行数据,依次是0x55~0x5e。同时数据从rxd输入到接收逻辑,也就是每发送一个数据就相应接收到相同的一个数据。当发送完5个字节后,int_out信号置为高,此时产生中断。


图4

图4是仿真开始时的截图,总线依次写入了中断触发值为5;分频值为1,也就是波特率为主时钟的1/32;清空发送和接收FIFO,并使能了发送和接收;然后依次写入0x55~0x5e到发送FIFO,txd开始有波形,表示开始发送数据。


图5

图5是仿真的末期截图,总线先读取接收FIFO有效数据个数为10,然后依次从接收FIFO读出的数据为0x55~0x5e,说明接收到了发送的10个字节。说明功能仿真通过。
返回列表