异步FIFO设计
1 异步FIFO结构
异步FIFO的功能可以分为:
- 双端口RAM,负责数据的存储
- 异步FIFO写控制模块,控制FIFO写操作和写满信号(fifo_full)的产生
- 异步FIFO读控制模块,控制FIFO读操作和读空信号(fifo_empty)的产生
- bin_to_gray:自然二进制码转格雷码模块,用于将二进制读写地址转成格雷码读写地址
- gray_to_bin:格雷码转自然二进制码模块
- 跨时钟域同步模块,消除亚稳态
2 异步FIFO的Verilog设计
设计关键:
-
跨时钟传输信号通过打两拍的方式消除亚稳态
-
采用格雷码编码解决多bit数据汇聚问题。由于格雷码每次跳转只有一位发生变化,所以如果出现不确定状态也只会有两种状况,即正确变化了和不变。因此,在读写时钟不一样的情况下,纵使读写地址每bit同步过程中出现延时不一致,也不会使得FIFO在实际空或者实际满之后,FIFO却没有正确地产生空满信号。
-
读比写时钟更快,只会出现实际没满,但误判为满,造成写操作延迟,但不会对数据流造成错误。
-
写比读时钟更快,只会出现实际没空,但误判为空,造成读操作延迟,但不会对功能(数据流)造成错误。
设计顶层:async_fifo
//FileName:async_fifo.v
//Function:异步FIFO设计
//Note:
//基于扩展一位地址位的方式判断空满
//使用格雷码编码解决跨时钟域数据汇聚问题
//使用两级寄存器同步跨时钟域信号
module async_fifo
#(
parameter FIFO_AW = 8, //fifo地址宽度
parameter FIFO_DW = 8 //fifo数据宽度
)
(
wr_clk,
rd_clk,
rstn,
wr_req,
rd_req,
wr_data,
fifo_full,
fifo_empty,
room_avail,
data_avail,
rd_data
);
input wr_clk; //写时钟
input rd_clk; //读时钟
input rstn; //异步复位
input wr_req; //写请求
input rd_req; //读请求
input [FIFO_DW-1:0] wr_data; //写数据
output wire fifo_full; //写满标志
output wire fifo_empty; //读空标志
output wire [FIFO_AW-1:0] room_avail;
output wire [FIFO_AW-1:0] data_avail;
output wire [FIFO_DW-1:0] rd_data; //读数据
localparam FIFO_DEPTH = (1<<FIFO_AW); //FIFO深度
reg [FIFO_DW-1:0] ram_memory [FIFO_DEPTH-1:0]; //开辟一个ram
reg [FIFO_AW:0] fifo_rd_gaddr_sync1; //同步寄存器1
reg [FIFO_AW:0] fifo_rd_gaddr_sync2; //同步寄存器2
reg [FIFO_AW:0] fifo_wr_gaddr_sync1;
reg [FIFO_AW:0] fifo_wr_gaddr_sync2;
reg [FIFO_AW:0] fifo_wr_ad