1
定義
FIFO(First In First Out )先入先出存儲器,在FPG設(shè)計中常用于跨時鐘域的處理,F(xiàn)IFO可簡單分為同步FIFO和異步FIFO。同步FIFO可理解為讀寫時鐘同源且頻率相同的FIFO,異步FIFO為讀寫時鐘不同源,時鐘頻率不一樣的FIFO。
2
同步FIFO的仿真
該仿真基于XIlinx的fifo generator13.2進行設(shè)計,IP core的配置如下。
由圖所示,時鐘模式配置為common clock,F(xiàn)IFO深度為16,F(xiàn)IFO數(shù)據(jù)位寬為36bit,其中32bit為數(shù)據(jù)位寬,4bit為用戶自定義比特tuser。下圖為FIFO例化的IPcore。
理論情況下FIFO的數(shù)據(jù)傳輸時序如下
當(dāng)復(fù)位拉高后,F(xiàn)IFO模塊若沒有滿,s_axis_tready信號會拉高,然后用戶將s_axis_valid信號拉高就可以向FIFO里面寫入有效的數(shù)據(jù)了,這就發(fā)起了寫操作;此時在主端口用戶可將m_axis_tready拉高,F(xiàn)IFO若不為空,則m_tvalid信號會拉高,此時就可以源源不斷的從FIFO里讀出數(shù)據(jù)了,這就發(fā)起了讀操作。
下面討論下在同步FIFO中的兩種情況
2.1 讀寫時鐘為100M,m_axis_tready在m_axis_tvaild后,此時的仿真圖如下所示。
由上圖所示,在用戶側(cè)還未將m_axis_tready拉高之前,valid到來后,F(xiàn)IFO輸出的數(shù)據(jù)就不為0了,而是FIFO中存入的第一個數(shù)據(jù),一直到用戶將m_axis_tready拉高,才會輸出FIFO里的下一個數(shù)據(jù)。所以并不是我們理解的,只有用戶發(fā)起FIFO讀,F(xiàn)IFO才會輸出數(shù)據(jù)。
2.2 讀寫時鐘為100M,m_axis_tready在m_axis_tvaild前,此時的仿真圖如下所示。
由上圖所示,在FIFO的valid數(shù)據(jù)到來之前,我們先將tready拉高,這樣就不會在讀操作之前FIFO就吐出數(shù)據(jù)了。在做設(shè)計時,將復(fù)位拉高后,隨即將tready拉高即可。
3
** 異步FIFO的仿真**
做異步FIFO時,IPCORE的配置如下圖所示
時鐘模式配置為independent clock,F(xiàn)IFO深度為16,F(xiàn)IFO數(shù)據(jù)位寬為36bit,其中32bit為數(shù)據(jù)位寬,4bit為用戶自定義比特tuser。
理論情況下FIFO的數(shù)據(jù)傳輸時序如下
由上圖所示,讀速率是寫速率的1/2,因此寫不是連續(xù)的,讀速率是連續(xù)的。下面分幾個情況進行討論。
3.1 寫為100M讀為30.3M,m_trady在m_tvaild前
由上圖所示,寫數(shù)據(jù)也不連續(xù),s_tready為周期性有效,切換周期和讀時鐘周期一樣,其中高電平時間為一個寫數(shù)據(jù)時鐘周期。
3.2 寫為50M讀為100M,m_trady在m_tvaild前
由上圖所示,此時讀數(shù)據(jù)不連續(xù),m_tvalid為周期性有效,切換周期和寫時鐘周期一樣,其中高電平時間為一個讀數(shù)據(jù)時鐘周期。
4
對不同深度配置進行討論
4.1當(dāng)FIFO深度為16時
由上圖可知,若讀數(shù)據(jù)不及時,比較滯后,則FIFO可以存入15個數(shù)據(jù),當(dāng)FIFO滿后,s_axis_tready拉低,不能繼續(xù)寫FIFO,當(dāng)讀操作開始時,F(xiàn)IFO將從存入的第一個數(shù)據(jù)依次輸出。
4.2 當(dāng)fifo為32時
由上圖可知,若讀數(shù)據(jù)不及時,比較滯后,則FIFO可以存入33個數(shù)據(jù),當(dāng)FIFO滿后,s_axis_tready拉低,不能繼續(xù)寫FIFO,當(dāng)讀操作開始時,F(xiàn)IFO將從存入的第一個數(shù)據(jù)依次輸出。
5
在仿真時遇到的問題
在仿真時提示說t_user管腳找不到,但打開代碼和block_design看了下,該端口是存在的,后面把block_design刪掉,重新例化新模塊后,問題解決,目前不知道是什么問題導(dǎo)致。
6
激勵文件
`timescale 1ns / 1ps
module tb_fifo( );
reg [31:0] s_axis_tdata ;
wire s_axis_tready;
reg s_axis_tvalid;
reg [3:0] s_axis_tuser ;
reg m_aclk ;
reg s_aclk ;
reg s_aresetn ;
wire [31:0] m_axis_tdata ;
reg m_axis_tready;
wire m_axis_tvalid;
wire [3:0] m_axis_tuser ;
initial begin
s_aresetn = 1'b0;
s_axis_tdata = 32'h0000_0001;
s_axis_tvalid = 1'b0;
m_aclk =1'b1;
s_aclk =1'b1;
s_axis_tuser = 4'b1010;
#50
s_aresetn = 1'b1;
#10
s_axis_tvalid = 1'b1;
end
initial begin
m_axis_tready = 1'b0;
#340
m_axis_tready= 1'b1;
end
always #10 s_aclk = ~s_aclk;
always #5 m_aclk = ~m_aclk;
always @(posedge s_aclk) begin
s_axis_tdata = s_axis_tdata +1'b1;
end
design_1_wrapper tb_design_fifo_wrapper (
.S_AXIS_0_tdata (s_axis_tdata ),
.S_AXIS_0_tready(s_axis_tready),
.S_AXIS_0_tvalid(s_axis_tvalid),
.S_AXIS_0_tuser (s_axis_tuser ),
.m_aclk_0 (m_aclk ),
.s_aclk_0 (s_aclk ),
.s_aresetn_0 (s_aresetn ),
.M_AXIS_0_tdata (m_axis_tdata ),
.M_AXIS_0_tready(m_axis_tready),
.M_AXIS_0_tvalid(m_axis_tvalid),
.M_AXIS_0_tuser (m_axis_tuser)
);
endmodule
-
FPGA設(shè)計
+關(guān)注
關(guān)注
9文章
428瀏覽量
26465 -
存儲器
+關(guān)注
關(guān)注
38文章
7430瀏覽量
163514 -
FIFO存儲
+關(guān)注
關(guān)注
0文章
103瀏覽量
5955 -
時鐘源
+關(guān)注
關(guān)注
0文章
92瀏覽量
15921
發(fā)布評論請先 登錄
相關(guān)推薦
評論