一文读懂【FIFO】

FIFO即First In First Out,是一种先进先出数据存储、缓冲器,我们知道一般的存储器是用外部的读写地址来进行读写,而FIFO这种存储器的结构并不需要外部的读写地址而是通过自动的加一操作来控制读写,这也就决定了FIFO只能顺序的读写数据。下面我们就介绍一下 同步FIFO和异步FIFO

1、FIFO分类

同步FIFO,读和写应用同一个时钟。它的作用一般是做交互数据的一个缓冲,也就是说它的主要作用就是一个buffer。
异步FIFO,读写应用不同的时钟,它有两个主要的作用,一个是实现数据在不同时钟域进行传递,另一个作用就是实现不同数据宽度的数据接口。

2、FIFO的主要参数

同步FIFO和异步FIFO略有不同,下面的参数适用于两者。

  • 宽度,用参数FIFO_data_size表示,也就是FIFO存储的数据宽度;
  • 深度,用参数FIFO_addr_size表示,也就是地址的大小,也就是说能存储多少个数据;
  • 满标志full,当FIFO中的数据满了以后将不再能进行数据的写入;
  • 空标志empty,当FIFO为空的时候将不能进行数据的读出;
  • 写地址w_addr,由自动加一生成,将数据写入该地址;
  • 读地址r_addr,由自动加一生成,将该地址上的数据读出;

同步FIFO和异步FIFO的最主要的不同就体现在空满标志产生的方式上,由此引出两者一些不同的参数。
同步FIFO

  • 时钟clk,rst,读写应用同一个时钟;
  • 计数器count,用计数器来进行空满标志的判断;

异步FIFO

  • 时钟clk_w,rst_w,clk_r,rst_r,读写应用不同的时钟;
  • 指针w_pointer_gray,r_pointer_gray,用指针来判断空满标识;
  • 同步指针w_pointer_gray_sync,r_pointer_gray_sync,指针的同步操作,用来做对比产生空满标志符;

3、同步FIFO

FIFO主要的设计难点在于如何产生空满标志,在同步FIFO中,我们定义一个计数器,当计数器的值为0时,产生空标志,当计数器的值为FIFO的深度时,产生满标志。基于以上的思想,可以将同步FIFO划分为以下几个模块:write、read、count、RAM

3.1 模块划分

同步FIFO主要划分为四个模块,RAM模块是用来读取和写入数据;write模块是用来产生写地址;read模块是用来产生读地址;count模块是用来产生空满标志符,每写入一位数,count加一,每读出一位数,count减一。
下面是各个模块的连接框图:

3.2 同步FIFO代码

源文件

       module FIFO_sync(
                 clk,
                 rst,
                 w_en,
                 r_en,
                data_in,
                data_out,
                count,
                full,
                empty
                );

          parameter FIFO_data_size=3,
                 FIFO_addr_size=2;


           input clk,rst;
          input w_en,r_en;
          input[FIFO_data_size-1:0] data_in;
          output[FIFO_data_size-1:0] data_out;
          output full,empty;
          output[FIFO_addr_size:0]count;

          reg [FIFO_data_size-1:0] data_out;
          reg [FIFO_addr_size:0]count;
          reg [FIFO_addr_size-1:0]w_addr,r_addr;
          reg [FIFO_data_size-1:0]mem[{FIFO_addr_size{1'b1}}:0];
          integer i;

          //memory的初始化以及写操作
       always@(posedge clk or negedge rst)
        begin
         if(!rst)
          begin
            w_addr<=0;
            for(i=0;i<={FIFO_addr_size{1'b1}};i=i+1)
                  mem[i]<={FIFO_data_size{1'b0}};
          end
            else if(w_en&(~full))
  
  • 6
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值