FIFO基础知识(转)

1.什么是FIFO?
FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

2.什么情况下用FIFO?
FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。

3.FIFO的一些重要参数
FIFO的宽度:也就是英文资料里常看到的THE WIDTH,它只的是FIFO一次读写操作的数据位,就像MCU有8位和16位,ARM 32位等等,FIFO的宽度在单片成品IC中是固定的,也有可选择的,如果用FPGA自己实现一个FIFO,其数据位,也就是宽度是可以自己定义的。

FIFO的深度:THE DEEPTH,它指的是FIFO可以存储多少个N位的数据(如果宽度为N)。如一个8位的FIFO,若深度为8,它可以存储8个8位的数据,深度为12 ,就可以存储12个8位的数据,FIFO的深度可大可小,个人认为FIFO深度的计算并无一个固定的公式。在FIFO实际工作中,其数据的满/空标志可以控制数据的继续写入或读出。在一个具体的应用中也不可能由一些参数算数精确的所需FIFO深度为多少,这在写速度大于读速度的理想状态下是可行的,但在实际中用到的FIFO深度往往要大于计算值。一般来说根据电路的具体情况,在兼顾系统性能和FIFO成本的情况下估算一个大概的宽度和深度就可以了。而对于写速度慢于读速度的应用,FIFO的深度要根据读出的数据结构和读出数据的由那些具体的要求来确定。
满标志:FIFO已满或将要满时由FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO中写数据而造成溢出(overflow)。
空标志:FIFO已空或将要空时由FIFO的状态电路送出的一个信号,以阻止FIFO的读操作继续从FIFO中读出数据而造成无效数据的读出(underflow)。
读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。
写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。
读指针:指向下一个读出地址。读完后自动加1。
写指针:指向下一个要写入的地址的,写完自动加1。
读写指针其实就是读写的地址,只不过这个地址不能任意选择,而是连续的。

4.FIFO的分类
根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

5.FIFO设计的难点
FIFO设计的难点在于怎样判断FIFO的空/满状态。为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。在空的状态下不能进行读操作。怎样判断FIFO的满/空就成了FIFO设计的核心问题。由于同步FIFO几乎很少用到,这里只描述异步FIFO的空/满标志产生问题。
在用到触发器的设计中,不可避免的会遇到亚稳态的问题(关于亚稳态这里不作介绍,可查看相关资料)。在涉及到触发器的电路中,亚稳态无法彻底消除,只能想办法将其发生的概率将到最低。其中的一个方法就是使用格雷码。格雷码在相邻的两个码元之间只由一位变换(二进制码在很多情况下是很多码元在同时变化)。这就会避免计数器与时钟同步的时候发生亚稳态现象。但是格雷码有个缺点就是只能定义2^n的深度,而不能像二进制码那样随意的定义FIFO的深度,因为格雷码必须循环一个2^n,否则就不能保证两个相邻码元之间相差一位的条件,因此也就不是真正的各雷码了。第二就是使用冗余的触发器,假设一个触发器发生亚稳态的概率为P,那么两个及联的触发器发生亚稳态的概率就为P的平方。但这回导致延时的增加。亚稳态的发生会使得FIFO出现错误,读/写时钟采样的地址指针会与真实的值之间不同,这就导致写入或读出的地址错误。由于考虑延时的作用,空/满标志的产生并不一定出现在FIFO真的空/满时才出现。可能FIFO还未空/满时就出现了空/满标志。这并没有什么不好,只要保证FIFO不出现overflow or underflow 就OK了。



另外为什么要用FIFO呢?下面这段文字就解释了:

bobrics@gmail.com 问道: 
    Why do you need a FIFO? Is it similar to GBUF, IBUF for clocks to buffer the signals for stability or more like temporary memory? 
    If it's more like temporary memory, then why not just use intermediate signals to store input signals and delay them (use shift register) a specific number of clocks if needed? 
    意思是,我们都拿FIFO做什么用?是不是FIFO类似于临时存储器?为什么不用中间信号存储输入信号并使用移位寄存器对其进行特定时钟的延时? 
austin <austin@xilinx.com> 答的很好: 
    FIFOs,

    Are useful as a means to synchronize the passing of data between asynchronous clock domains.  If you need to communicate both data, and when the data is ready, between two clock domains that are not the same in both frequency and/or phase, a FIFO is a universal means to allow the two clock domains to communicate without error.

    To synchonize events in one domain, to another domain requires the use of synchronizing circuits which are notorious in that engineers often get them wrong (they implement ones that do not work).  At Intel, there are only a handful of senior engineers who are allowed to do synchronizer circuits.

    One of my first ever crisis cases at Xilinx was one where a cutomer had occasional errors in their application, which seemed to come and go at random.  They blamed it on different lots of our silicon.  Some lots they claimed, were worse, and some were not as bad.

    Well, it turned out that the bad lots were slightly slower (but well within specifications), and the good lots (which still had the problem, but not as often) were slightly faster.

    The speed difference made a poor FIFO design using CLBs have more (or less) frequent problems.  In no case was their FIFO design good.  It was always capable of failing, as they spun their own control, without regard to what an incredibly difficult problem it is.

    For example, what if the FIFO says it is ready with data to read, when it is not?  That leads to a failure.  What if it says it is ready to accept data on a write, when it is full?  Also, a failure.

    Think about your gas gauge saying that you have gas, when you do not: not acceptable.

    But, there is a way to design a FIFO to be foolproof, even though in theory, that is impossible (without latency).  So, if we do it for you (in hard logic), it saves you from making a very common mistake.

    By the way, the secret to low latency synchronization in FIFOs is that the gas gauge could say the tank was empty, when it was not, and then go back to being less than empty without causing any problems (thanks to 
Peter for this analogy).

    If you used our soft core FIFO (previous to V4), you would also be safe.  
    But many looked at the FIFO IP, and said to themselves "I am smarter than that -- look at all the wasted logic to do such a simple job!"

    Sadly, it is not a simple job.  Peter and I were in a 2 day class just last week on just this subject (asynchronous design, and communications between clock domains in large systems).  Heck, Peter 'invented' the FIFO back at Fairchild!

    Even us "more experinced" engineers realize that we can (must) learn new things.

    Since the FIFO is built into the hardware, I imagine it is trivial to instantiate.  Let us know if the HDL primitives are in Webpack. It would make no sense to Xilinx not to promote their use, as they prevent engineers from doing things the wrong way, and allow you to pack more into your design, and achieve higher performance. 

 

另附:altera官网的FIFO文档:http://www.altera.com/literature/ug/ug_fifo.pdf 大家可以自己下载看看。

转载于:https://www.cnblogs.com/hanjiangzhiyuan/archive/2012/04/05/FIFO.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值