同步FIFO的設計,介紹一下FIFO的基礎知識
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SNmZWOkFDN2YTMklTYwITZyUWN5ITOyUTO1YDMxcTZj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
\\\插播一條:
自己在今年整理一套單片機單片機相關論文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