2. FIFO深度计算核心公式:深度 = 最大数据量 - 最大读取量,理解背靠背(Back-to-Back)传输模式

各位同学,咱们今天聊点实在的。

FIFO深度怎么算?说白了就一个公式:深度 = 最大数据量 - 最大读取量。嗯,就这么简单。但为什么很多人算出来还是错的?问题出在「最大」这两个字上。

2.1 核心公式的物理意义

我刚开始做FIFO设计时,也犯过傻。以为只要写入速率小于读出速率,FIFO就不会满。结果呢?项目联调时数据丢了,查了三天才发现是背靠背传输搞的鬼。

公式背后的逻辑其实很直白:

  • 最大数据量:写入端在某个时间段内,最多能塞进来多少个数据
  • 最大读取量:同一时间段内,读取端最多能拿走多少个数据
  • 差值:就是FIFO需要暂存的数据量,也就是深度

你想想看,如果写入端一口气发了100个数据,读取端只来得及读走60个,那剩下的40个就得在FIFO里待着。这40,就是深度。

核心要点:深度不是平均差值,而是最坏情况下的差值。

2.2 背靠背传输——深度计算的「罪魁祸首」

什么叫背靠背?我举个例子你就明白了。

假设写入时钟是100MHz,每4个时钟写1个数据。平均下来,每40ns写1个数据。但问题是——写入端不会这么「均匀」地工作。

它可能连续4个时钟周期,每个时钟都写1个数据。这就是背靠背传输。连续写4个,然后歇12个时钟。平均速率没变,但瞬时峰值翻了好几倍。

注意:背靠背传输是FIFO深度计算中最容易被忽略的陷阱。我曾经有个项目,就是因为没考虑背靠背,FIFO深度算小了,结果数据溢出,整个系统跑飞。

为什么会这样?因为写入端通常有数据缓冲。当缓冲满了,它就会一口气把数据全倒出来。你想想看,这不就是背靠背吗?

2.3 深度计算的标准步骤

我个人习惯用三步法,清晰又不容易出错:

  1. 确定最坏情况的时间窗口:找到写入端可能连续写入的最长时间
  2. 计算最大写入量:时间窗口内,写入端最多能写多少数据
  3. 计算最大读取量:同一时间窗口内,读取端最多能读多少数据
  4. 相减:深度 = 最大写入量 - 最大读取量

举个例子:

  • 写入时钟100MHz,每4个时钟写1个数据,但可能连续写4个
  • 读取时钟80MHz,每2个时钟读1个数据
  • 背靠背写入:连续4个数据,耗时4×10ns = 40ns
  • 最大写入量:4个数据
  • 40ns内读取端能读多少?40ns ÷ (2×12.5ns) = 1.6,取整为1个
  • 深度 = 4 - 1 = 3

小技巧:我建议你画个时序图,把写入和读取的波形画出来,一眼就能看出最坏情况。

2.4 背靠背的常见场景

实际项目中,背靠背传输主要出现在以下几种情况:

场景 说明 典型例子
总线突发传输 AHB/AXI等总线支持突发模式,连续传输多个数据 AXI burst length = 16
数据包传输 数据包到达时,所有数据连续写入 以太网帧、USB包
时钟域切换 异步FIFO中,写入时钟可能比读取时钟快很多 200MHz写入,50MHz读取
数据缓冲满 上游模块缓冲满后,一次性释放所有数据 视频行缓冲、音频帧缓冲

2.5 避坑指南——我踩过的坑

我曾经在一个视频处理项目中,FIFO深度算小了。原因是只考虑了平均速率,没考虑背靠背。结果呢?视频画面出现撕裂,查了整整一周才发现是FIFO溢出。

从那以后,我总结了几条经验:

  • 永远假设最坏情况:不要相信「应该不会连续写那么多」这种话
  • 留余量:计算出的深度再加20%~30%,安全第一
  • 仿真验证:用最极端的写入模式跑仿真,看FIFO会不会满
  • 考虑读写时钟的相位关系:异步时钟域中,相位差会导致读取速率波动

切记:深度不是越大越好。深度越大,面积越大,延迟也越大。找到「刚好够用」的深度才是高手。

2.6 知识体系图

下面这张图,把FIFO深度计算的核心逻辑串起来了。我建议你保存下来,每次做FIFO设计时看一眼。

FIFO深度计算核心逻辑 写入时钟频率 写入速率(每N时钟写1个) 背靠背传输长度 读取时钟频率 读取速率(每N时钟读1个) 计算过程 ① 确定时间窗口 ② 计算最大写入量 ③ 计算最大读取量 ④ 深度 = 写入 - 读取 ⑤ 加20%余量 最终深度 FIFO深度 确保不溢出、不浪费 ⚠ 背靠背是关键 深度 = 最大数据量 - 最大读取量 时间窗口 = 背靠背传输持续时间 余量建议:计算值 × 1.2 ~ 1.3

2.7 实战小练习

来,咱们练一个。我当年面试时就被问过类似的问题。

题目:写入时钟120MHz,每3个时钟写1个数据,但可能连续写6个(背靠背)。读取时钟100MHz,每2个时钟读1个数据。求FIFO最小深度。

你自己先算算,然后对照下面的步骤:

  1. 背靠背写入6个数据,耗时6 × (1/120MHz) = 50ns
  2. 最大写入量:6个
  3. 50ns内读取端能读多少?50ns ÷ (2 × 10ns) = 2.5,取整为2个
  4. 深度 = 6 - 2 = 4
  5. 加20%余量:4 × 1.2 = 4.8,取整为5

嗯,答案是5。你算对了吗?

我的建议:实际项目中,我一般会取2的幂次方,比如5取8。这样地址译码简单,而且留了更多余量。当然,如果面积敏感,5也行。

好了,FIFO深度计算的核心就这些。记住:背靠背是魔鬼,余量是护身符。下次做FIFO设计时,多想想最坏情况,别让数据丢了才后悔。

可可精品资料库