AXI4-STREAM DATA FIFO學習



如圖是該fifo的配置圖,vivado版本2018.2.
AXI4-Stream Data FIFO 配置

AXI4-Stream Data FIFO 配置

General Options

Component Name

  • 器件名字

FIFO depth

  • FIFO的深度,可以在16到32768之間變化,具體情況視情況而定,但要是2的n次冪。

Enable packet mode

  • 使能包模式:此項設定需要TLAST信號被使能。FIFO的操作在包模式下被修改為存儲傳送的數據,直到TLAST信號被響應。當TLAST信號被響應或者FIFO滿了,存儲的數據將被送至AXI4-Stream master interface.

Asynchronous Clocks

  • 異步時鍾:啟用后S_AXIS_ACLK和M_AXIS_ACLK將會是異步時鍾。

Synchronization Stages across Cross Clock Domain Logic

  • 當啟用異步時鍾后,才會有該選項,其作用相當於跨時鍾域時的打拍操作。一般默認即可。

ACLKEN Conversion Mode

  • 此選項用來選擇ACLKEN信號的轉換模式。

  • None 沒有和這個IP相關的ACLKEN 信號相關

  • S AXIS Only 有一個與S_AXIS_ACLKEN 相關聯的 S_AXIS_ACLK信號,但沒有M_AXIS_ACLKEN信號

  • M AXIS Only 有一個與M_AXIS_ACLKEN 相關聯的 M_AXIS_ACLK信號,但沒有S_AXIS_ACLKEN 信號

  • S AXIS & M AXIS 兩個時鍾都有與它們相關的ACLKEN信號。

Signal Properties

信號特性:可以看到,軟件可以自動計算,當然我們也可以手動修改。
TDATA width (bytes)

  • 參數指定axi4流上TData信號的寬度(以字節為單位接口。此參數是一個整數,可以從0到512不等。設置為0以忽略TDATA信號。如果省略了tdata信號,則tkeep和tstb信號也會省略。如圖設置為4則可以看到位寬為32bit。
    在這里插入圖片描述

Enable TSTRB

  • 是否使能TSTRB信號,只有當TData width(bytes)參數大於0時,才能啟用此選項。

Enable TKEEP

  • 是否使能TKEEP信號,只有當TData width(bytes)參數大於0時,才能啟用此選項。

Enable TLAST

  • 是否使能TKEEP信號,只有當TData width(bytes)參數大於0時,才能啟用此選項。

TID width (bits)

  • 用來指定TID信號的位寬,0為忽略,1~32為相應的位寬。

TDEST width (bits)

  • 用來指定TDEST 信號的位寬,0為忽略,1~32為相應的位寬。

TUSER Width (bits)

  • 用來指定TUSER 信號的位寬,0為忽略,1~32為相應的位寬。

關於這些信號的具體含義以及時序關系,可以通過仿真觀察。

仿真

起始信號
在這里插入圖片描述初始化,復位以后,等待S_AXIS_tready信號的拉高,然后等待一個寫周期,S_AXIS_tvalid拉高,這個時候,數據便開始寫入FIFO。
在這里插入圖片描述在寫入的時候給了兩次S_AXIS_tlast信號,然后觀察讀出端的情況。

在這里插入圖片描述然后我們可以看到,S_AXIS_tlast被傳遞到讀取端,這個時候將M_AXIS_tready拉低,我們可以看到,讀取被禁止,同時繼續寫入數據,觀察數據寫滿的情況。然后過一段時間后再將M_AXIS_tready拉高,可以看到,S_AXIS_tlast再次被傳遞。
在這里插入圖片描述

S_AXIS_tlas被傳遞

從下圖可以看出,當FIFO寫滿以后,S_AXIS_tready會被拉低,這個時候數據將不能寫入,當M_AXIS_tready被拉高,讀取段開始讀取數據,這時FIFO非滿,S_AXIS_tready又被拉高。
在這里插入圖片描述

同時,我們將S_AXIS_tvalid拉低,可以看到,當數據讀完以后,M_AXIS_tvalid被拉高。
在這里插入圖片描述
通過仿真可以看出只有當 S_AXIS_tvalidS_AXIS_tready同時為高時,數據才能寫入,而S_AXIS_tready表示FIFO非滿,S_AXIS_tvalid由用戶控制。S_AXIS_tlast表示寫入的最后一個數據,讀取端同理,需要注意的是,S_AXIS_tkeep需要保持高電平。
讀取端的控制信號同理。
參考資料:https://www.xilinx.com/support/documentation/ip_documentation/axis_interconnect/v1_1/pg035_axis_interconnect.pdf
以下是仿真代碼

`timescale 1 us / 1 ps

module data_fifo_wrapper
   (M_AXIS_tdata,
    M_AXIS_tkeep,
    M_AXIS_tlast,
    M_AXIS_tvalid,
    S_AXIS_tready,
    axis_data_count,
    axis_rd_data_count,
    axis_wr_data_count
);
  output [15:0]M_AXIS_tdata;
  output [1:0]M_AXIS_tkeep;
  output M_AXIS_tlast;
  reg M_AXIS_tready;
  output M_AXIS_tvalid;
  output S_AXIS_tready;
  output [31:0]axis_data_count;
  output [31:0]axis_rd_data_count;
  output [31:0]axis_wr_data_count;
  
  wire [15:0]M_AXIS_tdata;
  wire [1:0]M_AXIS_tkeep;
  wire M_AXIS_tlast;
  wire M_AXIS_tvalid;
  reg [15:0]S_AXIS_tdata;
  reg [1:0]S_AXIS_tkeep;
  reg S_AXIS_tlast;
  wire S_AXIS_tready;
  reg S_AXIS_tvalid;
  wire [31:0]axis_data_count;
  wire [31:0]axis_rd_data_count;
  wire [31:0]axis_wr_data_count;
  reg m_axis_aclk;
  reg m_axis_aresetn;
  wire s_axis_aclk;
  reg s_axis_aresetn;
  

  initial begin
	m_axis_aclk = 0;
	M_AXIS_tready = 0;
	m_axis_aresetn = 1;
	s_axis_aresetn = 1;
	S_AXIS_tdata = 0;
	S_AXIS_tlast = 0;
	S_AXIS_tvalid = 0;
	S_AXIS_tkeep = 0;
  end
  
  always #5 m_axis_aclk = ~m_axis_aclk;
  
  assign #2.5 s_axis_aclk = m_axis_aclk;//異步時鍾
  
  integer i;
  
  initial begin
	#100;
	m_axis_aresetn = 0;
	s_axis_aresetn = 0;
	#100;
	s_axis_aresetn = 1;
	m_axis_aresetn = 1;


@(posedge S_AXIS_tready);//等待FIFO准備好
@(posedge s_axis_aclk);//對齊時鍾
S_AXIS_tvalid = 1;//寫有效
S_AXIS_tkeep = 2'b11;
for(i=0;i<512;i=i+1)//寫512個數據
begin
	@(posedge s_axis_aclk)
	S_AXIS_tdata = S_AXIS_tdata + 1;
end
@(posedge s_axis_aclk)
S_AXIS_tlast = 1;//寫最后一個數據
S_AXIS_tdata = S_AXIS_tdata + 1;
@(posedge s_axis_aclk)
S_AXIS_tlast = 0;
for(i=0;i<16;i=i+1)
begin
	@(posedge s_axis_aclk)
	S_AXIS_tdata = S_AXIS_tdata + 1;
end
@(posedge s_axis_aclk)
S_AXIS_tlast = 1;
@(posedge s_axis_aclk)
S_AXIS_tlast = 0;
#200;
@(posedge m_axis_aclk)
M_AXIS_tready = 1;//讀數據
# (10*520);
M_AXIS_tready = 0;

for(i=0;i<600;i=i+1)
begin
	@(posedge s_axis_aclk)
	S_AXIS_tdata = S_AXIS_tdata + 1;
end
M_AXIS_tready = 1;
S_AXIS_tvalid = 0;
# (10*1024);
  
  end



  data_fifo data_fifo_i
       (.M_AXIS_tdata(M_AXIS_tdata),
        .M_AXIS_tkeep(M_AXIS_tkeep),
        .M_AXIS_tlast(M_AXIS_tlast),
        .M_AXIS_tready(M_AXIS_tready),
        .M_AXIS_tvalid(M_AXIS_tvalid),
	
    .S_AXIS_tdata(S_AXIS_tdata),
    .S_AXIS_tkeep(S_AXIS_tkeep),
    .S_AXIS_tlast(S_AXIS_tlast),
    .S_AXIS_tready(S_AXIS_tready),
    .S_AXIS_tvalid(S_AXIS_tvalid),
	
    .axis_data_count(axis_data_count),
    .axis_rd_data_count(axis_rd_data_count),
    .axis_wr_data_count(axis_wr_data_count),
	
    .m_axis_aclk(m_axis_aclk),
    .m_axis_aresetn_0(m_axis_aresetn),
	
    .s_axis_aclk(s_axis_aclk),
    .s_axis_aresetn(s_axis_aresetn));

endmodule


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM