首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

XILINX FPGA FIFO使用技巧

XILINX FPGA FIFO使用技巧

FIFO是在FPGA设计中使用的非常频繁,也是影响FPGA设计代码稳定性以及效率等得关键因素。我总结一下我在使用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,那么最后的那个数据在刚才那个时钟周期没有读出来,可以现在这个时钟周期把它读出来。
答二:代码如下:自己可以去仿真一下看看,在几乎空和空之间读使能的波形
else if(src_ready==1'b1)
begin
fifo_rdreq_2 <= #U_DLY (fifo_rdreq_2==1'b1)?(~fifo_allempty_2)

end

问:“我经常使用一个FIFO存报文内容,另一个FIFO存报文的长度,两者配合使用。”

请问楼主:报文长度用计数器不就可以计算么,为什么要用一个fifo来存储?
答一:如果一个FIFO中存在多个长度不同的报文你该怎么办呢?用计数器不如用FIFO好,计数器也很难控制当前计数值就是下一级电路要取的报文长度,用两个FIFO来计就会变得非常方便且不容易出错。
答二:  主要是要在FIFO中存大量的报文,那么报文对应的长度也有很多个,存在另一个FIFO中。这样子读出来的时候,先读报文的长度,然后把报文长度放在一个Counter里面,根据counter里面的长度读取报文内容,每读一次counter减一次。
问:用于存数据的fifo和存长度的fifo的深度应该不一样的吧,两者怎么实现同步的呢?
答:存报文的FIFO与存长度的FIFO的深度之间是有一定换算关系的。如果报文FIFO位宽是128bit,深度为512,而我们存的平均报文长度是512字节(假设),那么对应的存长度的FIFO深度就,(128/8)*512/512=16。
问:位宽转换FIFO相对于两个一半位宽的fifo+自己的控制逻辑,二者相比,哪一个更费资源呢?楼主有测试过吗?
答:有实际测试过,ISE工程跑完以后对比了使用的BLOCK RAM和其他逻辑资源,的确是自己写的用两个一半宽度FIFO的要省资源。BLOCK RAM要省一半。
返回列表