同步FIFO的设计,介绍一下FIFO的基础知识
\\\插播一条:
自己在今年整理一套单片机单片机相关论文800余篇
论文制作思维导图
原理图+源代码+开题报告+正文+外文资料
想要的同学私信找我。
本篇文章整理一下同步FIFO的实现。首先介绍一下FIFO的基础知识:
fifo是 first input first output的缩写,即先进先出队列,fifo一般用作不同时钟域的缓冲器。fifo根据读和写的时钟是否为同一时钟分为同步fifo和异步fifo。异步fifo相比同步fifo来说,设计更加复杂一点。本文中先讲同步fifo的一种设计方法。下图是同步fifo的结构图:
设计FIFO的时候一般需要考虑的有两点:
1.FIFO的大小
FIFO的大小指就是双端口ram的大小,这个可以根据设计需要来设置。
2.FIFO空满状态的判断
FIFO空满状态的判断通常有两种方法。
a、FIFO中的ram一般是双端口ram,所以有独立的读写地址。因此可以一种是设置读,写指针,写指针指向下一个要写入数据的地址,读指针指向下一个要读的地址,最后通过比较读指针和写指针的大小来确定空满状态。
b、设置一个计数器,当写使能有效的时候计数器加一;当读使能有效的时候,计数器减一,将计数器与ram的size进行比较来判断fifo的空满状态。这种方法设计比较简单,但是需要的额外的计数器,就会产生额外的资源,而且当fifo比较大时,会降低fifo最终可以达到的速度。
下面的设计是将fifo当做一个整体来进行设计,输入输出端口有基本的代码如下:
`timescale1ns/1ps Company: // Engineer: // // Design Name: Kevin Zhang// Module Name: test_verify_mod// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //modulefifo#(
parameterFIFO_WIDTH=32,
parameterFIFO_DEPTH=16)(
inputclk_i,
inputrst_n,
inputwr_en,
input[FIFO_WIDTH-1:0]wr_data,
outputfifo_full,
outputreg[log2(FIFO_WIDTH)-1:0]fifo_count,
inputrd_en,
outputreg[FIFO_WIDTH-1:0]rd_data,
outputfifo_empty);
//FIFO当前深度always@(posedgeclk_i)begin
if(!rst_n)
fifo_count0;
elsebegin
case({wr_en,rd_en})
2'b00:fifo_countfifo_count;
2'b01:fifo_countfifo_count-1;
2'b10:fifo_countfifo_count+1;
2'b11:fifo_countfifo_count;
endcase
end
end
assignfifo_full=(fifo_count==FIFO_DEPTH-1)?1'b1:1'b0;
assignfifo_empty=(fifo_count==0)?1'b1:1'b0;
//写指针reg[log2(FIFO_WIDTH)-1:0]wr_prt;
always@(posedgeclk_i)begin
if(!rst_n)
wr_prt0;
elsebegin
if(wr_en)begin
ram[wr_prt]wr_data;
if(wr_prt==FIFO_DEPTH-1)
wr_prt0;
else
wr_prtwr_prt+1;
end
end
end
//读指针reg[log2(FIFO_WIDTH)-1:0]rd_prt;
always@(posedgeclk_i)begin
if(!rst_n)
rd_prt0;
elsebegin
if(rd_en)begin
rd_dataram[rd_prt];
if(rd_prt==FIFO_DEPTH-1)
rd_prt0;
else
rd_prtrd_prt+1;
end
end
endendmodule