1. FIFO基础概念:FIFO的定义、工作原理、同步与异步FIFO的区别
大家好,我是你们的芯片架构课讲师。今天咱们聊聊FIFO——这个在芯片设计里几乎天天打交道的家伙。
FIFO,全称First In First Out,先进先出。说白了就是个排队机制。你想想看,就像食堂打饭,先来的人先打到饭,后来的在后面等着。FIFO干的就是这事儿。
1.1 FIFO的定义
FIFO是一种数据缓冲器。它有两个端口:一个写,一个读。数据从写端口进去,从读端口出来。出来的顺序和进去的顺序一模一样。
我习惯把FIFO想象成一个水管。水从一头流进去,从另一头流出来。先流进去的水,先流出来。就这么简单。
但在芯片里,FIFO可不是水管。它是一块存储空间,配上读写指针和控制逻辑。存储空间可以是寄存器堆,也可以是SRAM。小FIFO用寄存器,大FIFO用SRAM——这是我在项目里常用的选型原则。
核心要点:FIFO的本质是解耦。它把写操作和读操作在时间上解耦了。写的人不用等读的人,读的人也不用等写的人。各干各的,互不干扰。
1.2 FIFO的工作原理
FIFO内部有三个关键角色:写指针、读指针、存储阵列。
- 写指针:指向下一个要写入的位置。每写一次,指针加1。
- 读指针:指向下一个要读取的位置。每读一次,指针加1。
- 存储阵列:存放数据的地方。深度决定了FIFO能存多少个数据。
当写指针追上读指针,FIFO就满了。当读指针追上写指针,FIFO就空了。嗯,这里要注意:判断满和空,是FIFO设计里最容易出错的地方。
我曾经在一个项目里,因为满标志判断逻辑写错了,导致数据覆盖。那是个视频处理芯片,画面出现花屏。查了三天才找到问题——FIFO满标志提前拉高了,写操作被阻塞,数据丢了。从那以后,我对FIFO的满空判断格外小心。
小技巧:判断FIFO满空,最稳妥的方法是比较写指针和读指针的格雷码。格雷码每次只变一位,能有效避免亚稳态问题。我个人的习惯是:同步FIFO用二进制指针,异步FIFO用格雷码指针。
1.3 同步FIFO vs 异步FIFO
这两者的区别,说白了就是时钟域的问题。
| 对比项 | 同步FIFO | 异步FIFO |
|---|---|---|
| 时钟域 | 读写共用同一个时钟 | 读写使用不同时钟 |
| 复杂度 | 低,逻辑简单 | 高,需要跨时钟域处理 |
| 应用场景 | 同一时钟域内的数据缓冲 | 跨时钟域的数据传输 |
| 满空判断 | 直接比较指针即可 | 需要同步指针,有延迟 |
| 面积 | 小 | 稍大(多了同步器) |
同步FIFO:读写都在同一个时钟下工作。你想想看,就像两个人在同一个节奏下干活。写的人写一个,读的人读一个,步调一致。实现起来也简单,一个计数器就能搞定满空判断。
异步FIFO:读写时钟不同。比如写时钟是100MHz,读时钟是50MHz。这时候问题就来了——写指针和读指针不在同一个时钟域,直接比较会出问题。
我记得有个项目,需要把ADC采集的数据从200MHz时钟域传到50MHz时钟域。一开始我图省事,用了同步FIFO,结果数据全乱了。后来换成异步FIFO,加上两级同步器处理指针,问题才解决。
避坑指南:异步FIFO的深度选择要特别小心。我曾经遇到一个情况:写时钟比读时钟快,但FIFO深度选小了,导致频繁溢出。后来我总结了一个经验公式:FIFO深度 ≥ (写速率 - 读速率) × 最大突发长度。这个公式帮我避了不少坑。
1.4 知识体系结构图
下面这张图,是我梳理的FIFO知识体系。你看一眼,心里就有谱了。
这张图把FIFO的知识点串起来了。你从定义出发,理解工作原理,再区分同步和异步。每一步都踩实了,后面学FIFO的带宽分析就不费劲。
总结一下:FIFO就是个排队缓冲区。同步FIFO简单,适合同一时钟域。异步FIFO复杂,但能解决跨时钟域的大问题。选型的时候,先看时钟域,再看深度,最后看面积。这个顺序,是我做了十几个FIFO项目后总结出来的经验。
好了,这一章就到这里。FIFO的基础概念,说白了就是这些。下一章咱们聊聊FIFO的带宽瓶颈——那才是真正让人头疼的地方。
可可精品资料库