1
定義
FIFO(First In First Out )先入先出存儲器,在FPG設計中常用于跨時鐘域的處理,FIFO可簡單分為同步FIFO和異步FIFO。同步FIFO可理解為讀寫時鐘同源且頻率相同的FIFO,異步FIFO為讀寫時鐘不同源,時鐘頻率不一樣的FIFO。
2
同步FIFO的仿真
該仿真基于XIlinx的fifo generator13.2進行設計,IP core的配置如下。
由圖所示,時鐘模式配置為common clock,FIFO深度為16,FIFO數據位寬為36bit,其中32bit為數據位寬,4bit為用戶自定義比特tuser。下圖為FIFO例化的IPcore。
理論情況下FIFO的數據傳輸時序如下
當復位拉高后,FIFO模塊若沒有滿,s_axis_tready信號會拉高,然后用戶將s_axis_valid信號拉高就可以向FIFO里面寫入有效的數據了,這就發起了寫操作;此時在主端口用戶可將m_axis_tready拉高,FIFO若不為空,則m_tvalid信號會拉高,此時就可以源源不斷的從FIFO里讀出數據了,這就發起了讀操作。
下面討論下在同步FIFO中的兩種情況
2.1 讀寫時鐘為100M,m_axis_tready在m_axis_tvaild后,此時的仿真圖如下所示。
由上圖所示,在用戶側還未將m_axis_tready拉高之前,valid到來后,FIFO輸出的數據就不為0了,而是FIFO中存入的第一個數據,一直到用戶將m_axis_tready拉高,才會輸出FIFO里的下一個數據。所以并不是我們理解的,只有用戶發起FIFO讀,FIFO才會輸出數據。
2.2 讀寫時鐘為100M,m_axis_tready在m_axis_tvaild前,此時的仿真圖如下所示。
由上圖所示,在FIFO的valid數據到來之前,我們先將tready拉高,這樣就不會在讀操作之前FIFO就吐出數據了。在做設計時,將復位拉高后,隨即將tready拉高即可。
3
** 異步FIFO的仿真**
做異步FIFO時,IPCORE的配置如下圖所示
時鐘模式配置為independent clock,FIFO深度為16,FIFO數據位寬為36bit,其中32bit為數據位寬,4bit為用戶自定義比特tuser。
理論情況下FIFO的數據傳輸時序如下
由上圖所示,讀速率是寫速率的1/2,因此寫不是連續的,讀速率是連續的。下面分幾個情況進行討論。
3.1 寫為100M讀為30.3M,m_trady在m_tvaild前
由上圖所示,寫數據也不連續,s_tready為周期性有效,切換周期和讀時鐘周期一樣,其中高電平時間為一個寫數據時鐘周期。
3.2 寫為50M讀為100M,m_trady在m_tvaild前
由上圖所示,此時讀數據不連續,m_tvalid為周期性有效,切換周期和寫時鐘周期一樣,其中高電平時間為一個讀數據時鐘周期。
4
對不同深度配置進行討論
4.1當FIFO深度為16時
由上圖可知,若讀數據不及時,比較滯后,則FIFO可以存入15個數據,當FIFO滿后,s_axis_tready拉低,不能繼續寫FIFO,當讀操作開始時,FIFO將從存入的第一個數據依次輸出。
4.2 當fifo為32時
由上圖可知,若讀數據不及時,比較滯后,則FIFO可以存入33個數據,當FIFO滿后,s_axis_tready拉低,不能繼續寫FIFO,當讀操作開始時,FIFO將從存入的第一個數據依次輸出。
5
在仿真時遇到的問題
在仿真時提示說t_user管腳找不到,但打開代碼和block_design看了下,該端口是存在的,后面把block_design刪掉,重新例化新模塊后,問題解決,目前不知道是什么問題導致。
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設計
+關注
關注
9文章
428瀏覽量
26489 -
存儲器
+關注
關注
38文章
7455瀏覽量
163623 -
FIFO存儲
+關注
關注
0文章
103瀏覽量
5965 -
時鐘源
+關注
關注
0文章
93瀏覽量
15938
發布評論請先 登錄
相關推薦
評論