一、FIFO 简介
FIFO(First In, First Out,先进先出)是数字电路设计和计算机体系结构中一种极其基础且重要的数据缓冲模块。可以把它想象成一条单行道的输水管或者超市的结账排队通道:数据像水流或顾客一样,从一端进入,按照严格的顺序从另一端离开。最先进入的数据,必然最先被读出。
1. 核心原理
从硬件实现的角度来看,FIFO 本质上是一个双端口存储器(RAM)加上一套读写指针控制逻辑。
- 存储介质:内部是一块 RAM(在 FPGA 中通常是 Block RAM 或 Distributed RAM/LUTs),用来暂存数据。
- 环形缓冲(Circular Buffer):
- 写指针(Write Pointer):指向下一个要写入数据的位置。每写入一个数据,指针加 1。
- 读指针(Read Pointer):指向下一个要读取数据的位置。每读出一个数据,指针加 1。
- 当指针达到最大深度时,会自动回绕到 0,形成一个环。
- 空/满标志(Flags):
- Empty(空):当读指针追上了写指针(Read == Write),说明没数据了,FIFO 变空。此时禁止读操作。
- Full(满):当写指针绕了一圈追上了读指针(Write == Read + Depth),说明存满了,FIFO 变满。此时禁止写操作,否则会发生'溢出(Overflow)'。
2. 存在的必要性:为什么要用 FIFO?
在简单的电路中,数据直接从模块 A 传到模块 B 即可。但在复杂的数字系统中,模块 A 和模块 B 往往处于不同的'节奏'或'环境'中。FIFO 的核心价值在于'解耦'(Decoupling)。它解决了以下三大核心矛盾:
A. 跨时钟域传输(Clock Domain Crossing, CDC)—— 最重要的功能
这是 FIFO 在 FPGA 设计中存在的最大理由。
- 问题:模块 A 跑在 100MHz,模块 B 跑在 50MHz。如果 A 直接发数据给 B,数据会丢失或产生亚稳态(Metastability),导致系统崩溃。
- 解决:使用异步 FIFO(Asynchronous FIFO)。A 用 100MHz 的时钟把数据写入 FIFO,B 用 50MHz 的时钟从 FIFO 读出。FIFO 内部通过格雷码(Gray Code)和同步器处理了跨时钟域的风险,保证数据安全过河。
B. 吞吐率匹配(带宽平滑)
- 问题:模块 A 产生数据的速度是'突发'的(一阵快一阵慢),而模块 B 处理数据的速度是'匀速'的。例如:ADC 采集数据非常快,但 CPU 处理数据比较慢。
- 解决:FIFO 充当蓄水池。当 A 爆发性写入数据时,FIFO 先把数据暂存起来;然后 B 再以自己的慢速从容地读走。只要长时间平均带宽匹配,数据就不会丢失。
C. 数据位宽转换(Gearbox / 变速箱)
- 问题:模块 A 输出是 32-bit 位宽,但模块 B 输入只能接受 8-bit 位宽。
- 解决:使用支持非对称读写的 FIFO。写入端设为 32-bit,读出端设为 8-bit。FIFO 会自动把一个 32-bit 的字拆成四个 8-bit 的字吐出来,反之亦然。
3. 常见分类
根据读写时钟的关系,FIFO 分为两类:
- 同步 FIFO (Synchronous FIFO / Common Clock):
- 读写使用同一个时钟。
- 用途:仅用于同一时钟域内的数据缓冲,比如暂存一段数据等待后续处理。
- 特点:延迟极低,逻辑简单。
- 异步 FIFO (Asynchronous FIFO / Independent Clocks):


