异步FIFO设计

异步FIFO常用于实现多bit数据的跨时钟域传输。

同时本篇blog的行文也是基于从无到有的设计思路,更加注重逻辑性。

4.4 Verilog FIFO 设计
异步FIFO设计(非常详细,图文并茂,值得一看!)
异步FIFO设计


1. 功能

可实现快到慢、慢到快的跨时钟域多bit数据传输,具体功能介绍如下:、

● 可对FIFO深度、宽度进行参数化自定义

● 能够实现数据的异步读写功能,且读出的数据是先入先出的顺序

● 能够指示FIFO空、满状态。同时FIFO内部数据量达到配置的参数数目时,拉高一个可配置的满状态信号

● 写数据宽度和读数据宽度可以不一致,但要实现位数拼接和分割

例如写是8bit读是32bit,那么每1次读的数据应当是每4次写的数据。

同理写是32bit读是8bit,那么每1次读的数据应当是每1次写的数据中8bit的那部分。

2. 模块分解与参数描述

首先是异步FIFO的架构,基于自顶向下的设计思路,将功能划分为多个模块,再相互连接

2.1. 顶层模块 async_fifo

由以下几个模块构成:wr_logc、rd_logic和simple dual-port RAM,其中

● Simle dual-port RAM完成数据的存储和读写功能

● wr_logic完成写逻辑的实现,同时产生waddr与双口RAM通信。

rd_logic完成读逻辑的实现,同时产生raddr与双口RAM通信。

注意写逻辑还需要输出full信号,读逻辑需要输出empty信号,这两个信号均与读写指针有关,所以需要wptr和rptr的跨时钟域通信。

在这里插入图片描述

参数描述

先是端口信号描述

Signal Direction Width(bits) Description
rstninput1FIFO异步复位
wclkinput1写时钟
wr_eninput1写使能
wdatainputWDATA_WIDTH写数据
fulloutput1写满标志
pfulloutput1可编程满标志。当FIFO内数据数目达到`PROG_DEPTH时,该信号拉高
rclk input1读时钟
rd_eninput1读使能
rdataoutputRDATA_WIDTH读数据
emptyoutput1读空标志

之后是对FIFO配置参数描述

Parameter Units Description
WDATA_WIDTHbitFIFO写数据宽度,即伪双口RAM的写数据宽度
RDATA_WIDTHbitFIFO读数据宽度,即伪双口RAM的读数据宽度
ASYNC_FIFO_DEPTHbitFIFO深度
PROG_DEPTHbit可编程数据深度。当FIFO内数据数目达到该值时,pfull拉高
ADDR_WIDTHbit用于设定SDRAM地址位宽

2.2. 伪双口RAM sdram

异步FIFO由读写两个逻辑组成,需要对写数据输入输出,所以使用伪双口RAM就行了。

但是注意我们要实现读写数据宽度不同的FIFO,所以此处的RAM读写宽度也不同,相应的读写地址宽度也不同。

注意这几个RAM的区别
单口RAM(Single-port RAM):只有一端一个时钟,可读、写
伪双口RAM(Simple Dual-port RAM):一端只读,另一端只写,且读写时钟不同
真双口RAM(True Dual-port RAM):两个端口都可读、写,且两端口的时钟不同
单端口和双端口RAM的区别

参数描述

先是端口信号描述

Signal Direction Width(bits) Description
rstninput1RAM异步复位
wclkinput1写时钟
wr_eninput1写使能
wdatainputWDATA_WIDTH写数据
waddrinputADDR_WIDTH写地址
rclkinput1读时钟
rd_eninput1读使能
rdataoutputRDATA_WIDTH读数据
raddrinputADDR_WIDTH读地址

之后是对伪双口RAM配置参数描述

Parameter Units Description
WDATA_WIDTHbit伪双口RAM写数据宽度
RDATA_WIDTHbit伪双口RAM读数据宽度
ADDR_WIDTHbit伪双口RAM地址宽度,需要根据FIFO深度和写数据宽度计算得出。注意此处令读写地址位宽相同

2.3. 写逻辑 wr_logic

写逻辑这边主要实现对伪双口RAM的写控制,同时基于读逻辑模块的rptr信号产生FIFO的full和pfull信号

参数描述

端口信号描述

Signal Direction Width(bits) Description
rstninput1异步复位
wclkinput1写时钟
wr_eninput1写使能
wdatainputWDATA_WIDTH写数据
rptr_ginputADDR_WIDTH+1带扩展位的Grey码读指针,注意是rclk域下的信号
Signal Direction Width(bits) Description
wr_en_ramoutput1双口RAM的写使能
waddr_ramoutputADDR_WIDTH双口RAM的写地址
wdata_ramoutputWDATA_WIDTH双口RAM的写数据
fulloutput1FIFO写满标志
pfulloutput1FIFO可编程写满标志
wptr_goutputADDR_WIDTH+1带扩展位的Grey码写指针

之后是需要配置的参数描述

Parameter Units Description
WDATA_WIDTHbit伪双口RAM写数据宽度
ADDR_WIDTHbit伪双口RAM地址宽度,需要根据FIFO深度和写数据宽度计算得出

2.4. 读逻辑 rd_logic

读逻辑这边主要实现对伪双口RAM的读控制,同时基于写逻辑模块的wptr信号产生FIFO的empty信号

参数描述

端口信号描述

Signal Direction Width(bits) Description
rstninput1异步复位
rclkinput1读时钟
rd_eninput1读使能
rdata_raminputRDATA_WIDTH读数据,来自于RAM
wptr_ginputWADDR_WIDTH+1带扩展位的Grey码写指针,注意是wclk域下的信号
Signal Direction Width(bits) Description
rd_en_ramoutput1送入RAM的读使能
raddr_ramoutputADDR_WIDTH双口RAM的读地址
rdataoutputRDATA_WIDTHFIFO读数据
emptyoutput1FIFO读空标志
rptr_goutputADDR_WIDTH+1带扩展位的Grey码读指针

之后是需要配置的参数描述

Parameter Units Description
RDATA_WIDTHbit伪双口RAM读数据宽度
RADDR_WIDTHbit伪双口RAM读地址宽度,需要根据FIFO深度和读数据宽度计算得出

3. 逻辑设计

时序以及代码比较重要,见这个blog

异步FIFO逻辑设计部分

4. 测试

4.1. 写数据位宽 > 读数据位宽 测试

这种测试中,参数定义如下

`define ASYNC_FIFO_DEPTH 	4096
`define WDATA_WIDTH 		16
`define RDATA_WIDTH 		4
`define PROG_DEPTH 			2048
`define ADDR_WIDTH			10			

根据async_fifo_tb.sv的内容,先写再读

使用questasim编译仿真,执行run 13us观察波形

首先,先写入数据

在这里插入图片描述
查看读出的数据

在这里插入图片描述
可以看出写是每拍写16bit、读是每拍读4bit,读的数据可按照先高位后低位拼接成写的数据,并且满足先入先出的顺序。

4.2. 写数据位宽 < 读数据位宽 测试

参数定义如下

`define ASYNC_FIFO_DEPTH 	4096
`define WDATA_WIDTH 		8
`define RDATA_WIDTH 		16
`define PROG_DEPTH 			2048
`define ADDR_WIDTH			9

写数据波形
在这里插入图片描述
读数据波形
在这里插入图片描述
可以看出写是每拍写8bit、读是每拍读16bit,写的数据可按照先高位后低位拼接成读的数据,并且满足先入先出的顺序。

4.3. full、pfull和empty 测试

参数设定如下

`define ASYNC_FIFO_DEPTH 	4096
`define WDATA_WIDTH 		16
`define RDATA_WIDTH 		8
`define PROG_DEPTH 			2048
`define ADDR_WIDTH			9

波形如下图所示,可以看到full、pfull和empty如期变化

在这里插入图片描述

4.4. 写数据位宽 = 读数据位宽 测试

参数设定如下

`define ASYNC_FIFO_DEPTH 	64
`define WDATA_WIDTH 		8
`define RDATA_WIDTH 		8

在Linux环境下,使用VCS进行编译仿真,使用Verdi查看波形。

在这里插入图片描述

图中 wptr_rd_logic表示wr_logic模块向rd_logic模块发送的写指针
rptr_d2表示wr_logic模块收到的来自rd_logic模块的读指针、打拍之后的结果

图中 rptr_wr_logic表示rd_logic模块向wr_logic模块发送的读指针
wptr_d2表示rd_logic模块收到的来自wr_logic模块的写指针、打拍之后的结果

5. 综合

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starry丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值