一起来了解一下FIFO!

一:fifo是什么

         FIFO的完整英文拼写为FirstIn First Out,即先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个存储器,常被用于数据的缓存或者高速异步数据的交互。

 

 

二:FIFO有几种结构

         FIFO从大的情况来分,有两类结构:单时钟FIFO(SCFIFO)和双时钟FIFO(DCFIFO),其中双时钟FIFO又可以分为普通双时钟(DCFIFO)和混合宽度双时钟FIFO (DCFIFO_MIXED_WIDTHS)。三种FIFO结构的英文含义如下所示:

    •      SCFIFO: 单时钟FIFO

    •      DCFIFO:双时钟 FIFO

    •      DCFIFO_MIXED_WIDTHS: 混合宽度双时钟

在没有特别指明的情况下,混合宽度双时钟FIFO和双时钟FIFO统称为双时钟FIFO。

 

 下图为分别为单时钟FIFO和双时钟FIFO的符号图:

图片

  从图中我们可以看到,单时钟FIFO具有一个独立的时钟端口clock,当Clock上升沿到达时,且wrreq有效时,将data[7..0]中的数据写入FIFO;当Clock上升沿到达时,且rdreq有效时,将q[7..0]中的数据输出FIFO;full是满标志位,当FIFO写满时有效,almost_full是将满标志,当快写满时有效,almost_full数值可以配置;同理empty与almost_empty是空标志和将要空标志,自己也可以配置almost_empty。usedw[7..0]是当前FIFO可以使用的数据。sclr是同步清零,当有效时且Clocks上升沿到达时清楚FIFO的数据;aclr是异步清零,当有效时清除FIFO的数据。

  双时钟FIFO和单时钟FIFO基本一样,就是读写分别采用不同的时钟信号。wrfull为写满标志,wrempty为写空标志,当我们想在只有FIFO空的时候才能写入时就用wrempty来判断,wrusedw[8..0]写入多少数据,rdusedw[8..0]能读出多少数据。这里将写入的数据和刻度的数据分开计数的原因是,当我们写入数据长度和读数据长度不同时,比如写的数据长度是16位,读的数据长度是8位,当写入一个数据wrusedw[8..0]=1,而rdusedw[8..0]=2。rdfull是读满标志,当我们要想要只有写满时才可读可根据这个标志判断(读数据包)。rdempty读空标志,当FIFO没有可读数据时有效。aclr异步请零。双时钟FIFO只有异步清零。

 

 

三:不同结构的FIFO各有什么作用

单时钟FIFO:

单时钟FIFO常用于片内数据交互,例如,在FPGA的控制下从外部传感器读取到的一连串传感器数据,首先被写入FIFO中,然后再以UART串口的数据发送速率将数据依次发送出去。由于传感器的单次读取数据可能很快,但并不是时刻都需要采集数据,例如某传感器使用SPI接口的协议,FPGA以2M的SPI数据速率从该传感器中读取20个数据,然后以9600的波特率通过串口发送出去。此过程每秒钟执行一次。因为2M的数据速率远高于串口9600的波特率,因此需要将从传感器中采集到的数据首先用FIFO缓存起来,然后再以串口的数据速率缓慢发送出去。这里,由于传感器数据的读取和串口数据的发送都是可以同步于同一个时钟的,因此可以使用单时钟结构的FIFO来实现此功能。

 

双时钟FIFO:

  双时钟FIFO的一个典型应用就是异步数据的收发。

  所谓异步数据是指数据的发送端和接收端分别同步与不同的时钟域,使用双时钟FIFO的独立的读写时钟结构,能够将不同时钟域中的数据同步到所需的时钟域系统中。例如,在一个视频图像采集系统中,实现将摄像头采集的数据通过VGA在显示器上显示。摄像头输入的数据长度和速度与输出到VGA显示的数据长度和速度都不相同,这种情况下使用双时钟FIFO。

  

 

四:如何在Altera FPGA中使用FIFO实现功能设计

在Altera FPGA中使用FIFO实现用户功能设计主要有三种实现方式,第一种为用户根据需求自己编写FIFO逻辑,当用户对于FIFO的功能有特殊需求时,可以使用此种方式实现,但此种方式要求用户有较高的RTL设计能力。第二种方式为使用第三方提供的开源IP核,此种IP核以源码的形式提供,能够快速的应用到用户系统中,当用户对FIFO功能有特殊需求时,可以在此源码的基础上进行修改,以适应自己的系统需求。第三种方式为使用Quartus II软件提供的免费FIFO IP核,此种方式下,Quartus II软件为用户提供了友好的图形化界面方便用户对FIFO的各种参数和结构进行配置,生成的FIFO IP核针对Altera不同系列的器件,还可以实现结构上的优化。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用VHDL编写FIFO并调用FIFO IP核的示例: 首先,我们需要编写FIFO的VHDL代码。以下是一个简单的FIFO示例: ```vhdl library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fifo is generic ( DATA_WIDTH : integer := 8; DEPTH : integer := 16 ); port ( clk : in std_logic; rst : in std_logic; wr_en : in std_logic; rd_en : in std_logic; din : in std_logic_vector(DATA_WIDTH-1 downto 0); dout : out std_logic_vector(DATA_WIDTH-1 downto 0); full : out std_logic; empty : out std_logic ); end entity fifo; architecture behavioral of fifo is type fifo_mem is array (0 to DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0); signal mem : fifo_mem; signal wr_ptr : integer range 0 to DEPTH-1 := 0; signal rd_ptr : integer range 0 to DEPTH-1 := 0; signal count : integer range 0 to DEPTH := 0; begin process(clk, rst) begin if rst = '1' then mem <= (others => (others => '0')); wr_ptr <= 0; rd_ptr <= 0; count <= 0; elsif rising_edge(clk) then if wr_en = '1' then mem(wr_ptr) <= din; wr_ptr <= wr_ptr + 1; count <= count + 1; end if; if rd_en = '1' then dout <= mem(rd_ptr); rd_ptr <= rd_ptr + 1; count <= count - 1; end if; end if; end process; full <= '1' when count = DEPTH else '0'; empty <= '1' when count = 0 else '0'; end architecture behavioral; ``` 接下来,我们将FIFO IP核实例化到我们的设计中。以下是一个示例代码,展示了如何实例化FIFO IP核并连接到上面的FIFO模块: ```vhdl library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity top_design is port ( clk : in std_logic; rst : in std_logic; wr_en : in std_logic; rd_en : in std_logic; din : in std_logic_vector(7 downto 0); dout : out std_logic_vector(7 downto 0); full : out std_logic; empty : out std_logic ); end entity top_design; architecture behavioral of top_design is component fifo is generic ( DATA_WIDTH : integer := 8; DEPTH : integer := 16 ); port ( clk : in std_logic; rst : in std_logic; wr_en : in std_logic; rd_en : in std_logic; din : in std_logic_vector(DATA_WIDTH-1 downto 0); dout : out std_logic_vector(DATA_WIDTH-1 downto 0); full : out std_logic; empty : out std_logic ); end component fifo; signal fifo_din : std_logic_vector(7 downto 0); signal fifo_dout : std_logic_vector(7 downto 0); signal fifo_full : std_logic; signal fifo_empty : std_logic; begin fifo_inst : fifo generic map ( DATA_WIDTH => 8, DEPTH => 16 ) port map ( clk => clk, rst => rst, wr_en => wr_en, rd_en => rd_en, din => fifo_din, dout => fifo_dout, full => fifo_full, empty => fifo_empty ); -- 连接FIFO IP核的输入和输出接口到其他信号或模块 -- 例如,将FIFO IP核的输入接口连接到顶层设计的输入信号 fifo_din <= din; -- 将FIFO IP核的输出接口连接到顶层设计的输出信号 dout <= fifo_dout; -- 将FIFO IP核的状态信号连接到顶层设计的输出信号 full <= fifo_full; empty <= fifo_empty; end architecture behavioral; ``` 上述示例中,我们通过实例化`fifo`模块,并将FIFO IP核的输入和输出接口与顶层设计的信号连接起来。这样,我们就可以在顶层设计中使用FIFO IP核了。 请注意,具体的实例化过程可能因为使用的工具和FPGA器件而有所不同。确保参考相关文档和用户手册来了解如何正确实例化和调用FIFO IP核。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值