FIFO使用及其各条件仿真介绍

电子说

1.3w人已加入

描述

1

定义

FIFO(First In First Out )先入先出存储器,在FPG设计中常用于跨时钟域的处理,FIFO可简单分为同步FIFO和异步FIFO。同步FIFO可理解为读写时钟同源且频率相同的FIFO,异步FIFO为读写时钟不同源,时钟频率不一样的FIFO。

2

同步FIFO的仿真

该仿真基于XIlinx的fifo generator13.2进行设计,IP core的配置如下。

FIFO存储

由图所示,时钟模式配置为common clock,FIFO深度为16,FIFO数据位宽为36bit,其中32bit为数据位宽,4bit为用户自定义比特tuser。下图为FIFO例化的IPcore。

FIFO存储

理论情况下FIFO的数据传输时序如下

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后,此时的仿真图如下所示。

FIFO存储

由上图所示,在用户侧还未将m_axis_tready拉高之前,valid到来后,FIFO输出的数据就不为0了,而是FIFO中存入的第一个数据,一直到用户将m_axis_tready拉高,才会输出FIFO里的下一个数据。所以并不是我们理解的,只有用户发起FIFO读,FIFO才会输出数据。

2.2 读写时钟为100M,m_axis_tready在m_axis_tvaild前,此时的仿真图如下所示。

FIFO存储

由上图所示,在FIFO的valid数据到来之前,我们先将tready拉高,这样就不会在读操作之前FIFO就吐出数据了。在做设计时,将复位拉高后,随即将tready拉高即可。

3

** 异步FIFO的仿真**

做异步FIFO时,IPCORE的配置如下图所示

FIFO存储

时钟模式配置为independent clock,FIFO深度为16,FIFO数据位宽为36bit,其中32bit为数据位宽,4bit为用户自定义比特tuser。

理论情况下FIFO的数据传输时序如下

FIFO存储

由上图所示,读速率是写速率的1/2,因此写不是连续的,读速率是连续的。下面分几个情况进行讨论。

3.1 写为100M读为30.3M,m_trady在m_tvaild前

FIFO存储

由上图所示,写数据也不连续,s_tready为周期性有效,切换周期和读时钟周期一样,其中高电平时间为一个写数据时钟周期。

3.2 写为50M读为100M,m_trady在m_tvaild前

FIFO存储

由上图所示,此时读数据不连续,m_tvalid为周期性有效,切换周期和写时钟周期一样,其中高电平时间为一个读数据时钟周期。

4

对不同深度配置进行讨论

4.1当FIFO深度为16时

FIFO存储

由上图可知,若读数据不及时,比较滞后,则FIFO可以存入15个数据,当FIFO满后,s_axis_tready拉低,不能继续写FIFO,当读操作开始时,FIFO将从存入的第一个数据依次输出。

4.2 当fifo为32时

FIFO存储

由上图可知,若读数据不及时,比较滞后,则FIFO可以存入33个数据,当FIFO满后,s_axis_tready拉低,不能继续写FIFO,当读操作开始时,FIFO将从存入的第一个数据依次输出。

5

在仿真时遇到的问题

FIFO存储

在仿真时提示说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

FIFO存储

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分