AXI4-STREAM DATA FIFOѧϰ

匿名 (未验证) 提交于 2019-12-02 23:34:01
版权声明:本文为博主原创文章,转载请声明原作者。 https://blog.csdn.net/QQ286615275/article/details/90297888

如图是该fifo的配置图,vivado版本2018.2.

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需要保持高电平。
读取端的控制信号同理。
以下是仿真代码
`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 
文章来源: https://blog.csdn.net/QQ286615275/article/details/90297888
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!