一、FIFO
1.1 定義
FIFO(First in First out)為先進(jìn)先出隊(duì)列,具有存儲(chǔ)功能,可用于不同時(shí)鐘域間傳輸數(shù)據(jù)以及不同的數(shù)據(jù)寬度進(jìn)行數(shù)據(jù)匹配。如其名稱,數(shù)據(jù)傳輸為單向,從一側(cè)進(jìn)入,再從另一側(cè)出來,出來的順序和進(jìn)入的順序相同。
1.2 實(shí)現(xiàn)方式
FIFO可由多種不同的實(shí)現(xiàn)方式,可以用塊狀RAM,分布式RAM來實(shí)現(xiàn),也可直接使用IP核,當(dāng)數(shù)據(jù)較小時(shí),建議使用分布式RAM實(shí)現(xiàn),數(shù)據(jù)較大時(shí),用塊狀RAM實(shí)現(xiàn)。
1.3 實(shí)現(xiàn)原理
FIFO組成包含存儲(chǔ)單元,寫時(shí)鐘,讀時(shí)鐘,滿標(biāo)志,空標(biāo)志,讀寫控制信號(hào),當(dāng)讀時(shí)鐘和寫時(shí)鐘都是同一個(gè)時(shí)鐘時(shí),則為同步FIFO,否則為異步FIFO。
a.首先,在復(fù)位操作后,在寫時(shí)鐘控制下,如果狀態(tài)非滿狀態(tài),數(shù)據(jù)可寫入到FIFO中。每寫一次數(shù)據(jù),寫指針加一,寫滿后將不允許再寫入;
b.當(dāng)FIFO中數(shù)據(jù)非空時(shí),在讀時(shí)鐘的控制下,數(shù)據(jù)可從FIFO中讀出。每讀一次數(shù)據(jù),讀時(shí)鐘加一,位于下一個(gè)讀取的位置,在空狀態(tài)下,將不能繼續(xù)讀數(shù)據(jù);
無論是同步FIFO還是異步FIFO,都是以雙口RAM為基礎(chǔ)來實(shí)現(xiàn)。
二、代碼實(shí)現(xiàn)
代碼為書籍《FPGA應(yīng)用技術(shù)及實(shí)踐》中5.3.3 FIFO設(shè)計(jì)中的代碼,相比原代碼中,對(duì)read/write為00時(shí),對(duì)count的值變化進(jìn)行了修改,修改為count<=count更合理,設(shè)計(jì)為實(shí)現(xiàn)4X16的同步FIFO
module FIFO_V(rst,clk,data_in,data_out,read,write,empty,full );
input rst,clk;
input [15:0] data_in;
output reg [15:0] data_out;
input read,write;
output empty,full;
parameter depth=2,max_count=2'b11;
reg empty,full;
reg [depth-1:0] tail;
reg [depth-1:0] head;
reg [depth-1:0] count;
reg [15:0] fifomem [0:max_count];
//讀空判斷
always@(posedge clk)
begin
if(rst==1)
begin
data_out<=16'h0000;
end
else if(read==1'b1&&empty==1'b0)
begin
data_out<=fifomem[tail];
end
end
//寫滿判斷
always@(posedge clk)
begin
if(rst==1'b0&&write==1'b1&&full==1'b0)
fifomem[head]<=data_in;
end
//寫操作
always@(posedge clk)
begin
if(rst==1)
head<=2'b00;
else
begin
if(write==1'b1&&full==1'b0)
head<=head+1;
end
end
//讀操作
always@(posedge clk)
begin
if(rst==1)
begin
tail<=2'b00;
end
else if(read==1'b1&&empty==1'b0)
begin
tail<=tail+1;
end
end
//讀寫操作下的計(jì)數(shù)
always@(posedge clk)
begin
if(rst==1)
begin
count<=2'b00;
end
else
begin
case({read,write})
2'b00:count<=count;
2'b01:if(count!=max_count) count<=count+1;
2'b10:if(count!=2'b00) count<=count-1;
2'b11:count<=count;
endcase
end
end
//隊(duì)列空狀態(tài)判斷
always@(posedge clk)
begin
if(count==2'b00)
empty<=1'b1;
else
empty<=1'b0;
end
//隊(duì)列滿狀態(tài)判斷
always@(posedge clk)
begin
if(count==max_count)
full<=1'b1;
else
full<=1'b0;
end
endmodule
測試代碼
對(duì)于read和write信號(hào),盡量避免在時(shí)鐘上升沿時(shí)進(jìn)行狀態(tài)變化,如此處write翻轉(zhuǎn)在201ns,read翻轉(zhuǎn)在#252,即避免了和時(shí)鐘的上升沿同步,也避免了和write翻轉(zhuǎn)的同步
`timescale 1ns / 1ps
module FIFO_tb( );
reg clk,rst,write,read;
reg [15:0] data_in;
wire [15:0] data_out;
wire empty,full;
FIFO_V FIFO_test (.clk(clk),.rst(rst),.data_in(data_in),.write(write),.read(read),.empty(empty),.full(full),.data_out(data_out));
//初始狀態(tài)賦值
initial
begin
clk=0;
rst=1;
data_in=16'h1111;
#51 rst=0;
end
//寫操作
initial
begin
write=1;
#201 write=1;
#30 write=0;
#200 write=1;
#85 write=0;
//#10 write=1;
//#60 write=0;
end
//讀操作
initial
begin
read=0;
#252 read=1;
#200 read=0;
#100 read=1;
end
//輸入信號(hào)與時(shí)鐘信號(hào)生成
always #20 data_in=data_in+16'h1111;
always #10 clk=~clk;
endmodule
三、仿真結(jié)果
3.1 復(fù)位階段
在起始的50ns內(nèi),復(fù)位信號(hào)rst(紅色標(biāo)注)為1時(shí),進(jìn)行復(fù)位操作,如黃色定位線所示,輸出data_out為0,empty和full標(biāo)志為0;
3.2 寫入階段
在110.1ns時(shí)開始寫入,時(shí)間點(diǎn)不是110ns而是多了0.1ns是由于modelsim默認(rèn)的開始時(shí)刻是0.1ns開始;因?yàn)閏ount原先一直處于初始化狀態(tài)2'b00,在此時(shí)因?yàn)閷懭脒M(jìn)行了empty的邏輯判斷,因?yàn)閑mpty為0;
在clk信號(hào)中1、2、3、4上升沿位置,即為寫入4個(gè)值:6666,7777,8888,9999,寫完后剛好寫滿,因此full標(biāo)志位在170.1ns處變?yōu)?,表示已寫滿無法再寫入。
3.3 讀取階段
在270.1ns時(shí),read/write的值為1/0開始從FIFO中進(jìn)行數(shù)據(jù)讀取,在clk信號(hào)的1,2,3,4讀取了4個(gè)數(shù)值,根據(jù)data_out可知為6666,7777,8888,9999。讀出順序與寫入順序一致,即先入先出。
3.4 同時(shí)讀寫或不讀不寫
在450ns時(shí),read/write都為1,讀寫同時(shí)進(jìn)行,并且empty為1,可知不進(jìn)行讀操作,count的邏輯。但因full為0,可以進(jìn)行寫入,此時(shí)進(jìn)行寫入,在4個(gè)clk周期寫滿,因此在530.1ns時(shí)full標(biāo)志位為1
在530ns和550ns時(shí),read/write都為0,此時(shí)不讀也不寫入,因此輸出狀態(tài)不變,一直為9999,
原文鏈接:https://blog.csdn.net/zyp626/article/details/131620099
-
FPGA
+關(guān)注
關(guān)注
1643文章
21975瀏覽量
614405 -
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4507瀏覽量
87091 -
仿真
+關(guān)注
關(guān)注
51文章
4242瀏覽量
135341 -
fifo
+關(guān)注
關(guān)注
3文章
400瀏覽量
44631 -
代碼
+關(guān)注
關(guān)注
30文章
4890瀏覽量
70291
原文標(biāo)題:FPGA基礎(chǔ)之FIFO實(shí)現(xiàn)
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
基于FPGA的異步FIFO的實(shí)現(xiàn)

異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì)
基于PCI接口芯片外擴(kuò)FIFO的FPGA實(shí)現(xiàn)
高速異步FIFO的設(shè)計(jì)與實(shí)現(xiàn)
基于FPGA的FIFO設(shè)計(jì)和應(yīng)用

基于VHDL和FPGA的非對(duì)稱同步FIFO設(shè)計(jì)實(shí)現(xiàn)
LabVIEW FPGA模塊實(shí)現(xiàn)FIFO深度設(shè)定

異步FIFO在FPGA與DSP通信中的運(yùn)用

基于FPGA的FIFO設(shè)計(jì)和應(yīng)用
異步FIFO結(jié)構(gòu)及FPGA設(shè)計(jì)
異步FIFO在FPGA與DSP通信中的應(yīng)用解析

FPGA的FIFO實(shí)現(xiàn)過程
在FPGA上實(shí)現(xiàn)自行FIFO設(shè)計(jì)的方法

如何在Altera FPGA中使用FIFO實(shí)現(xiàn)功能設(shè)計(jì)?

評(píng)論