当前位置:   article > 正文

FIFO(三)——FIFO高级原理_fifo中异常数据丢弃处理

fifo中异常数据丢弃处理

FIFO高级原理

一、FIFO的大小

  由于FIFO会占用芯片面积,选择容量合适的FIFO显得非常重要。特别是当有多个FIFO时,这种需求更加突出。FIFO过大将导致面积浪费,过小将导致FIFO上溢,造成数据丢失。因此需要根据实际需求合理选择位宽和深度。

二、FIFO的深度

  同步FIFO的深度可以是任何一个正数,取值可能为8、9或12。然而,异步FIFO有一些限制,通常深度是2n,这里n是正数。一些有效的深度数值是2、4、8、16、32、64、128等。这是因为异步FIFO指针传递时使用格雷码进行跨时钟域传送。在格雷码方案中,完整的序列长度通常是2的幂次。如果序列短于这个2的幂次,只有一位发生变化的特性也就不再有,在计数到边界并返回时会有不止一位发生变化。

异步FIFO深度的计算

  两个不同时钟域的模块之间的数据缓冲通常要用到异步FIFO,通常因为写速率大于读速率,造成目的时钟域来不及读取的数据,而造成数据丢失,所以说,FIFO的工作模式应该是,写操作应该是突发写入的形式,而不是连续操作,也就是隔一段时间突发的写一组数据。如果连续写入的话,因为写速率快于读速率,FIFO肯定会写满,FIFO的深度就需要无穷大,才能确保数据不丢失。
  因此需要考虑FIFO中的深度最小值的问题,满足读写流畅不卡顿(数据不丢失)同时,又不多的占用面积。
  背靠背传输:连续写入两个突发长度,中间没有周期间隔,即一次写入2倍的突发长度。

不考虑背靠背传输情况

  数据传输方式明确的情况下不考虑背靠背传输。
  :有一个双端口FIFO设计,输入时钟为Ahz,输出时钟为0.6Ahz。假设输入数据模式固定为,每1000个cycle,前600个cycle连续输入数据,后400个cycle空闲。为了避免FIFO溢出,最小深度设计为多少
  解析:因为题目说的是“输入数据模式是固定的”,所以不用考虑“背靠背”情况,即不考虑在2000个时钟里有1200个时钟连续传输数据,只考虑1000个时钟里连续有600个时钟传数据;
  在连续传输的600个时钟里,写入时钟AHz,每个写入时钟周期 1 A H z {1 \over AHz} AHz1,共需要 600 A H z {600 \over AHz} AHz600 ns;
  读出时钟0.6AHz,读出时钟周期 1 0.6 A H z {1 \over 0.6AHz} 0.6AHz1,在写入600个数据的 600 A H z {600 \over AHz} AHz600 ns的时间段内,能够读出 600 ∗ 0.6 A h z A H z = 360 {600*0.6Ahz \over AHz}= 360 AHz6000.6Ahz=360个;
  需要FIFO深度:600-360 = 240个;若考虑异步FIFO的大小是2n次幂,则最小FIFO深度应为256

考虑背靠背传输情况

  数据传输方式不明确的情况下不考虑背靠背传输。
  :有一个双端口FIFO设计,输入时钟为Ahz,输出时钟为0.6Ahz。假设输入数据模式不固定,仅知每1000个cycle,输入端数据吞吐量为60%。为了避免FIFO溢出,最小深度设计为多少。
  解析:因为题目说的是“输入数据模式不固定的”,所以要考虑“背靠背”情况,即考虑在2000个时钟里有1200个时钟连续传输数据
  在连续传输的1200个时钟里,写入时钟AHz,每个写入时钟周期是 1 A H z {1 \over AHz} AHz1,共需要 1200 A H z {1200 \over AHz} AHz1200 ns;
  读出时钟0.6AHz,读出时钟周期 1 0.6 A H z {1 \over 0.6AHz} 0.6AHz1,在写入1200个数据的 1200/(AHz) ns的时间段内,能够读出 1200 ∗ 0.6 A h z A H z = 960 {1200*0.6Ahz \over AHz}= 960 AHz12000.6Ahz=960个;
  需要FIFO深度:1200-960 = 480个;若考虑异步FIFO的大小是2n次幂,则最小FIFO深度应为512

总结

  对于读写同时进行的FIFO,设写时钟的频率为fw,读时钟的频率为fr,写入数据的方式为每B个时钟写入A个数据,读数据的方式为每X个时钟读出Y个数据,计算深度有个必要条件就是“一段时间内”,写数据的个数等于读数据的个数,即吞吐量要相同,即 A B ∗ f w = Y X ∗ f r {A \over B}*f_w={Y \over X}*f_r BAfw=XYfr。那么FIFO的深度为:

F I F O d e p t h = b u r s t l e n g t h − ( b u r s t l e n g t h f w [ f r ∗ Y X ] FIFO_{depth}=burst_{length}-({burst_{length} \over f_w}[f_r*{Y \over X}] FIFOdepth=burstlength(fwburstlength[frXY]
  即写入的数据减去读出的数据。这里burstlength是连续最多可能写入的数据,要慎重选择,要考虑写入数据的方式。

三、辅助数据或标签

emsp; FIFO主要用来存储数据包或其他需要传送的数据。此外,我们可以在FIFO的每个数据位置上对应地存储一个与之相关的标签或辅助数据。对于传送数据包的协议,如Ethernet或PCle,可以使用一个end-of-packet标签,表明其对应的数据是数据包的最后一个数据。这样,从FIFO中读取数据包时,根据此标签就可以非常容易地确定数据包的尾端。标签的另一个用途是作为字节或字的有效指示,例如,一个FIFO的数据位宽是64位(2个双字),如果输入数据流是32位宽,要求的输出数据流是64位宽。在此情形下,可以将两个32位数据拼接起来构成64位数据写入FIFO中。如果输入的32位数据的个数为单数,那么最后一个64位数中只有32位是有效的,此时可以使用标签说明64位数据中哪32位是有效的。如下图所示为用于FIFO的标签。

在这里插入图片描述

四、快照/回退操作

  FIFO的两个输入信号snapshot wrptr和rollback_wrptr,对于有些应用来说,使用它们非常方便。例如,我们从PCIe设备中接收数据包并写入FIFO中,数据包的最末端,有一个CRC区域,用于检查数据包是否被无差错接收。在接收数据包时,我们同时进行CRC运算,直到接收完最后一个数据,校验电路才能知道本地计算出的CRC结果是否和数据包中传送的CRC值相匹配。此时我们已经将数据写入FIFO中,如果发现数据包校验错误,那么该如何做呢?我们需要找到一种方法以便于从FIFO中删除这个特殊数据包,注意这里不是删除FIFO中所有的数据,因为FIFO中的其他数据可能是正确的,也可能好的数据包恰好在错误的数据包之后,需要存储到FIFO中。
  一种解决办法是增加一个FIFO临时存储数据包,仅当数据包正确时才将其写入主用FIFO。这种方法是非常有效的,但存在一定问题,那就是当数据包在两导致附加的逻辑门以及造成更高的接收处理延时。另一种解决方法是使用没有负面影响的快照-回退技术。
  在新数据包刚到达时,产生具有一个时钟周期宽度的信号snapshot_wrptr,用于将wrptr存储于一个独立的寄存器中。在数据包结束时,如果发现CRC不匹配,我们将产生具有一个时钟周期宽度的rollback_wrptr信号,FIFO将原来寄存的初始指针值赋予FIFO的主wrptr,使wrptr回溯到上一个正确数据包的尾部。这种方式仅仅通过对写指针进行操作就可以有效地将错误数据包从FIFO中清除掉。
  在格雷码编码中,对于顺序变化的指针来说,只有一位会发生变化。然而,在指针回溯操作时,指针值变化较大,将会有多位同时发生变化,这将导致错误。解决办法是指针回溯操作时给出一个包含3到4个时钟周期的时间窗口,在时间窗口内,不去读取full、empty、data avail、room_avail等信号,时间窗口之后,这些信号会进入正确状态。

五、直通交换和存储转发模式

  直通交换和存储转发是网络芯片设计中的常用术语,网络芯片被用于网络设备中,负责在不同端口之间进行数据包的转发。交换芯片会以尽量快的速度实现包的转发,以降低端到端的延迟。在数据包转发期间,它将穿越很多缓冲器(FIFO)。这些数据包带有CRC校验,每个交换设备收到一个数据包后都会进行校验结果检查,以判断数据包是否有错误。在直通交换(cut-thru)操作模式中,接收的数据包写入FIFO的同时,就开始将其读出并向外发送。这有助于减少交换延时,因为不需要接收整个数据包之后才向外发送。
  在存储转发(store-forward)模式中,必须先将完整的数据包接收下来,判断其正确性,然后对正确的数据包进行转发。很明显,存储转发模式增加了每个阶段的延时,但其优点是错误数据包被检测出后会从系统中清除掉,不会继续向下传送从而浪费带宽。与之相反,直通交换模式会将错误数据传送到目的节点从而会造成带宽浪费。至于哪一个更好,取决于具体应用。如果网络环境中误码率较高,存储转发是更好的选择。如果误码率低,直通交换模式更为合适。
  与以太网协议类似,PCIe协议也支持这两种模式,此时,数据包在到达目的地前会穿越多个节点。为改善直通交换模式的性能,PCIe中使用了一种被称为“废止数据包”的技术。当将数据包进入接收FIFO时,可以同时发送该数据包。如果在接收数据时发现有错误,或者存在下溢,发送电路会终止发送并在数据包的尾部插入废止信息。接收端识别出该废止信息后,不需要再继续向上游或下游转发该数据包。另外,这不会被认为是一种错误情况。

六、FIFO指针复位

  上电后,芯片从复位状态开始工作,此时写指针和读指针都为0,FIFO为空。此后,随着数据的写入和读出,指针将持续变化。在有些情形下,可能需要对指针进行复位。FIFO使用两个信号reset_wrptr和reset rdptr,分别对wr_ptr和rd_pr复位。复位操作时要确保当一个指针(写或读)通过reset ptr信号进行复位时,另一个也被复位。reset-wrptr和resetrdptr需要同时有效,这样指针才会同时复位为0。如果只有一个指针复位,FIFO可能会显示为非空,这会造成外部电路对FIFO状态的错误判断,使系统工作出现错误。

七、不同的写入、读取数据宽度

  另外,还存在FIFO输入数据宽度与输出数据宽度不同的情形。例如,FIFO的写人数据位宽是32,读出数据位宽是64。此时,写人侧要每两个时钟周期写入一次,其中一个时钟周期用于收集数据。类似地,当写入数据位宽为64,读出数据位宽为32时,针对每个写入的64位数据,我们需要通过两个时钟周期将其读出。
  下图所示为支持不同读写数据宽度的FIFO。
在这里插入图片描述

八、使用FIFO的缺点

  FIFO是进行数据速率匹配和数据缓冲非常好的电路元件。然而,它也有一些缺点:在数据穿越FIFO时,路径中的延时更长;同时,FIFO中会用到多个计数器,增大了门电路的规模。因此,当构造数据路径时,应分析FIFO是否是必须选择的。另外,在设计中有多个FIFO时,应考虑这些FIFO是否可以合并,从而减少FIFO的数量。

九、基于触发器或者ARAM的FIFO

  FIFO内部使用的是二维存储器阵列。存储器可以采用SRAM(静态RAM)或者由触发器组成。SRAM是存储器单元,类似于DRAM(动态RAM),相对容量较小,但操作速度更快。与DRAM相比,SRAM多用于片内,DRAM多用于片外。存储器单元还可以采用D触发器实现,根据经验,如果存储器容量小于1K位,使用触发器作为存储单元是合适的;如果大于1K位,使用SRAM作为存储器单元更为合适。
  在FIFO中,地址译码器和其他逻辑单元会占用很大的FIFO面积。当FIFO容量很小时,例如,4×16,最好使用基于触发器的FIFO。另一方面,如果FIFO容量为1K×32,使用触发器(一个触发器在面积上近似6到8个与非门)实现时,需要使用的触发器个数将是非常巨大的,FIFO的芯片面积将会远大于使用SRAM的方案。另一个需要考虑的是FIFO的位宽与深度的比值。如果存储器深度过大而宽度过窄,或者宽度很大而深度很窄,SRAM都不是最好的选择。无论选择哪一种存储方案,所需要的控制逻辑的规模都是相同的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/206731
推荐阅读
相关标签
  

闽ICP备14008679号