如何计算FIFO深度
经常会遇到一个问题,FIFO深度到底开多少。以一个常见的例子来说明思路。
1. 背景
读取一个I1O1的ram,读信号rd_en,在rd_en_3ff有效时,rd_data才有效。
-- _ _ _ _ _ _ _ _ _ _
-- Clock | |_| |_| |_| |_| |_| |_| |_| |_| |_|
-- ___
-- rd_en ________| |_________________________
-- ___
-- rd_en_3ff ____________________| |_____________
-- ____________________ ___ _____________
-- rd_data ____________________X___X_____________
从读取者角度来看,读的数据流是不连续的,每次读都有“卡顿”
如果我们需要从读取的角度能够连续读取,则需要FIFO
2. 省流结论
1.如果FIFO是直通的,FIFO深度最小为3
2.如果FIFO src到dst有一拍,FIFO深度最小为4
3. 思路
1.FIFO的作用
没有fifo,每次读的时延是要等3拍
有fifo,fifo里面提前准备了mem的数据,则可以把时延消除。
假如fifo深度为1,读2次之后,新的读数据依然没有来,所以深度为1肯定不行。
那深度到底是3还是4?cycle级的老是想不清楚
2.确定FIFO行为
1.直通的FIFO,vld和rdy当拍就可以从一端传到另一端
2.从src到dst需要等一拍的FIFO
我们以第一种举例。
3.什么场景是corner case
1.假设fifo深度为N,dst不接收,先把这个fifo打满,打满后等几拍
2.dst_rdy一直拉高,src_vld一直拉高,构造输入输出满流量的情况,此时不能有断流现象。
4.从场景反推
1.这个场景中,fifo中的cnt是 先上升到满,再下降。下降到一定程度后,因为输入输出同时有效,则不变了。
2.直通FIFO在运行中,最极端情况是cnt=0,且输入输出都有效。那么他能正常运行的最低条件就是cnt = 0。
从cnt =0 反推,cnt = 1,=2,=3。 在=3时rd_en必须要拉起来,这样才能在cnt = 0时输出输出接上。
那么fifo最小值就是3。
可以看下图从右边的0开始倒推
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- Clock | |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
-- ___________ _________________________________
-- rd_en ________| |_______________________|
-- ___________ ______________________
-- rd_en_3ff (src_vld) ____________________| |_______________________|
-- ____________________ ___ ___ ___ _____________________________________________
-- rd_data(src_data) ____________________X___X___X___X_____________________________________________
-- ________________________ ___ ___ _______________ ___ ___ _____________________
-- cnt ____________________0___X_1_X_2_X_______3_______X_2_X_1_X________0____________
-- _________________________________________________________
-- dst_vld ____________________|
-- _________________________________
-- dst_rdy ____________________________________________|
那么同理,带打拍的FIFO,他能输入输出同时打满的情况是cnt = 1。反推回去至少需要深度=4。
见下图。
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- Clock | |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
-- _______________ _________________________________
-- rd_en ________| |___________________|
-- _______________ ______________________
-- rd_en_3ff (src_vld) ____________________| |___________________|
-- ____________________ ___ ___ ___ ___ _________________________________________
-- rd_data(src_data) ___________________X___X___X___X___X_________________________________________
-- ________________________ ___ ___ ___ ___________ ___ ___ _____________________
-- cnt ________________________X_1_X_2_X_3_X_____4_____X_3_X_2_X________1____________
-- _____________________________________________________
-- dst_vld ________________________|
-- _________________________________
-- dst_rdy ____________________________________________|
4. 进阶
上述的例子中,rd_en = (cnt + rd_en_1ff + rd_en_2ff + rd_en_3ff - dst_handshake) < fifo深度
把在途的 rd_en也考虑进去。这种做法可以使得fifo深度用最小
如果换一种方式,用fifo的almost_full来指示rd_en是否有效,会怎么样呢?
rd_en = ~fifo_almost_full
新的问题是,水线设置多少?FIFO深度是多少?
还是倒推,以直通FIFO为例:
计算水线:
- 最终FIFO cnt = 0,从cnt =3 开始,rd_en需要读,才能续上(和之前逻辑一样)
- rd_en = ~fifo_almost_full,意思是cnt = 4 -> 3时,fifo_almost_full跳变
- 所以水线是4
计算深度:
- 在水线为0的情况下,需要深度为3
- 水线为4,代表可以比水线为0的情况,多输入4个
- 因此深度为7
上图
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- Clock | |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
-- ___________________________ _________________________
-- rd_en ________| |___________________________________|
-- ___________________________ _____________
-- rd_en_3ff (src_vld) ____________________| |___________________________________|
-- ________________________ ___ ___ ___ ___ ___ ___ ___________ ___ ___ ___ ___ ___ ___ _____________
-- cnt ______________________0_X_1_X_2_X_3_X_4_X_5_X_6_X_____7_____X_6_X_5_X_4_X_3_X_2_X_1_X__0__________
-- ___________________________________
-- a_full ____________________________________| |_________________________
-- _____________________________________________________________________________
-- dst_vld ____________________|
-- _________________________________________
-- dst_rdy ________________________________________________________|
PS 。打拍FIFO,深度为8,水线为5。图略