FIFO使用技巧
我本人是做有线通信的,所做的设计中大量的使用到FIFO,用于报文的缓存。我经常使用一个FIFO存报文内容,另一个FIFO存报文的长度,两者配合使用。
在数据连续读取时,为了能不间断的读出数据而又不导致FIFO为空后还错误的读出数据。可以将FIFO的Empty和Almost_empty以及读使能配合起来使用,来保证能够连续读,并准确的判断FIFO空满状态,提前决定是否能启动读使能。具体的实施办法是:当Empty为1,立即停止读;当Empty为0,Almost_empty为0时,可以放心读;当Empty为0,但是Almost_empty为1时,如果上一拍读使能Read也为1,那么不能读;当Empty为0,但是Almost_empty为1时,如果上一拍读使能Read为0,可以读最后一拍。
在FIFO使用时,使用到Almost_full信号以及读写counter来控制FIFO的读满预警,如果数据不是在空满判断的下一拍写入FIFO,则设计FIFO的满预警时要小心。如果你不确定判断满预警之后要延迟多少拍才能真正写入FIFO,那么尽量让FIFO有足够满预警裕量。例如,在wr_data_count为128才是真的满了,你可以设成wr_data_count为120的时候就给出满预警,可以保证设计的可靠和安全。当然,如果你能准确的算出判断满预警与真正写入FIFO的延迟,可以用精确的满预警阈值。
当需要使用到数据位宽转换时,如将128位的数据转换成64位的数据,最好不要用XILINX自己生成的位宽转换FIFO。可以例化两个64位的FIFO,自己控制128转64。这样可以大大的节省资源,是XILINX CORE生成的FIFO资源的一半。
当Empty为0,但是Almost_empty为1时,如果上一拍读使能Read也为1,那么不能读;当Empty为0,但是Almost_empty为1时,如果上一拍读使能Read为0,可以读最后一拍。
请问这个为什么呢?
这是因为当almost_empty为1时,表示FIFO中仅仅还有一个数据没有被读出来,如果此时读使能同时为1,那么最后的这一个数据正在被读出来了,相当于在下一个时钟沿时,已经没有数据在FIFO中。如果读使能为0,那么最后的那个数据在刚才那个时钟周期没有读出来,可以现在这个时钟周期把它读出来。
写得蛮易懂的,觉得你确实对fifo很有了解呀。
多谢分享~
我也受益。谢谢
学习了,fifo不错。
请问fifo的时序约束该如何添加 是false path 还是multi cycle
嗯,还好,挺好理解的
挺好,将空将慢是做提高FIFO效率的基本做法。
写的不错。
学习了 LZ的分享
很好的经验分享
支持!
多谢分享!
“我经常使用一个FIFO存报文内容,另一个FIFO存报文的长度,两者配合使用。”
请问小编:报文长度用计数器不就可以计算么,为什么要用一个fifo来存储?
如果一个FIFO中存在多个长度不同的报文你该怎么办呢?用计数器不如用FIFO好,计数器也很难控制当前计数值就是下一级电路要取的报文长度,用两个FIFO来计就会变得非常方便且不容易出错。
哦,谢谢哈,用于存数据的fifo和存长度的fifo的深度应该不一样的吧,两者怎么实现同步的呢
代码如下:自己可以去仿真一下看看,在几乎空和空之间读使能的波形
else if(src_ready==1'b1)
begin
fifo_rdreq_2 <= #U_DLY (fifo_rdreq_2==1'b1)?(~fifo_allempty_2)~fifo_empty_2);
end
学习学习
我也受益。THX
位宽转换FIFO相对于两个一半位宽的fifo+自己的控制逻辑,二者相比,哪一个更费资源呢?小编有测试过吗?
不错,支持个。
谢谢小编分享经验
It depends on what device you are using.
The best policy of using is that using the dimension that the FPGA device natively supported.
有个问题可能和fifo本身关系不是很大,我个人比较少用FPGA厂商提供的fifo,而是用自己写的fifo或者干脆用双口ram,好处就在于代码移植比较方便,比如我换了FPGA厂商或者要做asic.
好东西
很好的资料,学习了
多谢分享~
可以用RAM缓存报文,FIFO缓存报文长度及写入RAM的起始地址。顺便说一下 我是想赚信元的 哈哈
