同步fifo的設計較為簡單,關鍵在於如何產生空滿訊號
有兩種實現方法:
1.利用計數器判斷,執行一次寫操作+1,讀操作 - 1;
2.將fifo的位址位拓展一位,用最高位來判斷空滿。
**如下:
1.利用計數器計算儲存資料個數
module sync_fifo(
clk,
rst_n,
fifo_wr_en,
fifo_rd_en,
fifo_wr_data,
fifo_full,
fifo_rd_data,
fifo_empty,
fifo_usedw);
parameter fifo_width = 8;
parameter fifo_depth = 512;
parameter fifo_addr = 9;
input clk;
input rst_n;
input fifo_wr_en;
input fifo_rd_en;
input [fifo_width-1:0] fifo_wr_data;
output fifo_full;
output fifo_empty;
output [fifo_width-1:0] fifo_rd_data;
output [fifo_addr-1:0] fifo_usedw;
reg [fifo_addr-1:0] rdaddress;
reg [fifo_addr-1:0] wraddress;
reg [fifo_addr-1:0] data_cnt;
//空滿標誌生成
assign fifo_full = (data_cnt == fifo_depth )?1'b1:1'b0;
assign fifo_empty = (data_cnt == 0)?1'b1:1'b0;
//讀位址
always@(posedge clk or negedge rst_n)
if(!rst_n)
rdaddress <= 0;
else if( fifo_rd_en && ~fifo_empty )
rdaddress <= rdaddress + 1'b1;
//寫位址
always@(posedge clk or negedge rst_n)
if(!rst_n)
wraddress <= 0;
else if( fifo_wr_en && ~fifo_full )
wraddress <= wraddress + 1'b1;
ram ram(
.clock ( clk ),
.data ( fifo_wr_data ),
.rdaddress ( rdaddress ),
.wraddress ( wraddress ),
.wren ( fifo_wr_en ),
.q ( fifo_rd_data )
); //fifo儲存資料個數
always@(posedge clk or negedge rst_n)
if(!rst_n)
data_cnt <= 0;
else if(fifo_wr_en && ~fifo_rd_en && ~fifo_full)
data_cnt <= data_cnt + 1;
else if(fifo_rd_en && ~fifo_wr_en && ~fifo_empty)
data_cnt <= data_cnt - 1;
else
data_cnt <= data_cnt;
assign fifo_usedw = (512-data_cnt);
endmodule
2.最高位判斷空滿
module sync_fifo(
clk,
rst_n,
fifo_wr_en,
fifo_rd_en,
fifo_wr_data,
fifo_full,
fifo_rd_data,
fifo_empty);
parameter fifo_width = 8;
parameter fifo_depth = 512;
parameter fifo_addr = 9;
input clk;
input rst_n;
input fifo_wr_en;
input fifo_rd_en;
input [fifo_width-1:0] fifo_wr_data;
output fifo_full;
output fifo_empty;
output [fifo_width-1:0] fifo_rd_data;
reg [fifo_addr-1:0] rdaddress;
reg [fifo_addr-1:0] wraddress;
reg [fifo_addr:0] rdaddress_e;
reg [fifo_addr:0] wraddress_e;
assign rdaddress = rdaddress_e[fifo_addr-1:0];
assign wraddress = wraddress_e[fifo_addr-1:0];
//空滿標誌生成
assign fifo_full = (rdaddress_e[fifo_addr] != wraddress_e[fifo_addr] && rdaddress == wraddress )?1'b1:1'b0;
assign fifo_empty = (rdaddress_e == wraddress_e)?1'b1:1'b0;
//讀位址
always@(posedge clk or negedge rst_n)
if(!rst_n)
rdaddress_e <= 0;
else if( fifo_rd_en && ~fifo_empty )
rdaddress_e <= rdaddress_e + 1'b1;
//寫位址
always@(posedge clk or negedge rst_n)
if(!rst_n)
rdaddress_e <= 0;
else if( fifo_wr_en && ~fifo_full )
rdaddress_e <= rdaddress_e + 1'b1;
ram ram(
.clock ( clk ),
.data ( fifo_wr_data ),
.rdaddress ( rdaddress ),
.wraddress ( wraddress ),
.wren ( fifo_wr_en ),
.q ( fifo_rd_data )
);endmodule
fifo的rdata 同步FIFO設計
我們常見的同步fifo一般都是固定位寬輸入,固定位寬輸出的,因此他們之間的關係一般來說都是固定的,比較容易理解,網上也有很多類似的 去指導怎麼編寫,在此不再贅述。如果突發奇想,新增乙個選通訊號wstrb呢?那麼這個世界是不是就不太一樣了呀 假設題目如下 編寫 實現如下的同步fifo功能,示意圖如下 ...
同步fifo的串並 同步fifo設計
1.同步fifo的功能點 當fifo寫滿的時候,輸出滿標誌.當fifo讀空的時候,輸出空標誌.寫滿之後不能繼續寫,即有滿標誌,禁止向ram寫入資料,防止資料混亂.讀空之後不能繼續讀,讀完所有資料,禁止重複讀.對於空滿標誌的判斷,設計的思想是,當讀指標等於寫指標加1,且同時有乙個寫使能,這樣,就認為f...
FIFO空滿判斷與位址轉換的思考
非同步fifo通過比較讀寫位址進行滿空判斷,但是讀寫位址屬於不同的時鐘域,所以在比較之前需要先將讀寫位址進行同步處理,將寫位址同步到讀時鐘域再和讀位址比較進行fifo空狀態判斷 同步後的寫位址一定是小於或者等於當前的寫位址,所以此時判斷fifo為空不一定是真空,這樣更保守 將讀位址同步到寫時鐘域再和...