一文看懂异步 FIFO 架构(三) 双时钟的异步 FIFO

本文转载自:Linest-5的CSDN博客

注:本文由作者授权转发,如需转载请联系作者本人

在本系列的第一篇文章中,我们看到了 FIFO 的一般架构,并分析了一个时钟的简单情况。该系列的第二部分描述了一种可能的双时钟设计的架构。在第三部分中,我们将探索另一种选择双时钟 FIFO 架构;这种替代架构不一定更好,它只是另一种实现方式。

工作原理
到目前为止,我们已经发现,任何涉及来自不同时钟域的多位二进制量的计算都需要对它们进行格雷编码。这种架构也不例外。它与之前的架构仅在一个方面有所不同,找出导致读写指针相等的条件。

读写指针的相等意味着要么是满条件要么是空条件,这取决于是写还是读(分别)导致相等。在同步 FIFO 的第一种情况下,这很容易确定,因为这两个操作都针对一个公共时钟进行。在第二种架构中,此信息被编码在指针本身中。我们现在探讨双时钟设计的第二种方法。

方向标志
在这个架构中,我们设定一个标志来跟踪导致指针变得相等的原因。让我们将此标志称为“direction_flag”。该标志告诉状态电路 FIFO “当前朝向”的方向。这是基于这样的假设,即写入导致 FIFO 朝着变满的方向“前进”,而读取导致 FIFO 朝着变空的方向前进。

不用说,每一方都必须保留direction_flag的单独信号并以悲观的方式设定它。因此写入端将有自己的direction_flag 将被悲观地维持,它可能会看到延迟读取,并且读取端将维持一个将根据延迟写入计算的方向标志。与之前的双时钟架构一样,这将确保 FIFO 不会吃掉或反流数据,但这样做的代价是会稍微动态缩小 FIFO 大小(性能减小,功能正常)。

FIFO 的满和空标志是根据这些方向标志计算的。这个想法是,如果 FIFO 正朝着变满的方向发展并且指针确实变得相等,那么它确实是满的。如果 FIFO 即将变为空并且指针变为相等,则 FIFO 现在为空。

方向标志的实现
可以通过不同的方式来实现方向标志:一般的想法是,当 FIFO 的字数超过某个预定阈值时,它被认为是“走向满”,而当它的字数低于其他一些预先确定的阈值,它被认为是“走向空”。

一些设计人员选择“走向满”的阈值是 FIFO 大小的 75%,而“走向空”的阈值是 FIFO 大小的 25%。其他设计人员只是为这两个阈值选择 50%。还有一些人选择 80% 和 20%。门槛的选择真的是你的,你可以选择最适合你需要的。可以推导出时钟速度和阈值之间的关系,从而最大限度地减少标志抖动,但我不确定这是否会使您的设计更加稳定。我相信一些滞后可能是好的(滞后意味着阈值不同,并且“满”阈值大于“变空”阈值)。

让我们任意选择阈值是 FIFO 大小的 75% 和 25%。这是有效的,因为只需要比较指针的高两位来确定阈值交叉点(以四位二进制数为例,最高两位为1的话为12,是整个值15的75%的临界值,只要写入计数最高两位刚刚都为1,表示写入数据位数已经达到最大空间的75%,此时写操作的走向满的 direction_flag 可以拉高)。对于其他阈值,您将不得不比较全角指针,这可能会减慢您的设计速度。和以前一样,写端看到写指针和读指针的同步版本,两者都是格雷码的。然后它将两个指针转换为二进制并计算出 FIFO 中有多少数据。如果 FIFO 中的数据量大于“going full”阈值,它将设置其direction_flag。当数据量低于“going empty”阈值时,它会清除其direction_flag。

类似地,读端看到(Gray)读指针和(Gray)写指针的同步版本。在执行到二进制转换后,它会计算 FIFO 中的字数;如果这个字数小于“going empty”阈值,它设置它的direction_flag(现在与写入端的 direction_flag 相反),当字数增加至⾼于“going full”时阈值它清除其direction_flag。

请记住,如果您选择 75% 和 25% 阈值,则不需要对全角指针执行上述计算。仅使用指针的高两位就足够了。

计算满和空
在写入端,如果指针相等并且设置了方向标志,则设置 FIFO 的满标志。类似地,在读取端,如果设置了 direction_flag 并且指针变得相等,则设置 FIFO 的空标志。请注意,这意味着我们不排除同时设置满标志和空标志的可能性。尽管这听起来违反直觉,但这对于 FIFO 来说是一个有效条件。您可能会认为 FIFO 不可能同时是满的和空的。但是如果进一步分析,你会发现“full”只是写端的流控机制,“empty”是读端的流控机制。如果 FIFO 阻塞两个流,那完全没问题,这不会破坏内存或指针。如果 FIFO 在它确实无法接受更多数据时不报告它已满,或者如果它在它确实无法提供更多数据时它不报告它是空的,这是很危险的。对先前架构的仔细分析将向您证明,该架构也不排除这种可能性。

以下是计算任一侧 direction_flag 的一般方程式(请注意,方程式中的指针在适用时同步并转换为二进制):

如图 1 所示,具有 75% 和 25% 阈值的特殊情况。在特殊情况下,上面的字数等式实际上只需要二进制指针的两个最⾼位,并且实际上不需要加 1 来获得精确的字数。只需要知道是否已超过阈值。并且写入端和读取端的阈值不必相同;您可以根据写入和读取时钟的频率调整阈值以优化性能。

结论
这种架构是在同步 FIFO 的情况下呈现的主题的一种变体。同步 FIFO 是这种架构的一个特例,其中阈值等于 (fifo_size ‑ 1),“满”和“空”阈值为 1。

与以前的异步架构相比,此架构是否具有特定优势?不一定!。在某些临界情况下,这种架构可能是一个优势,只要你的时间很紧,将 N 位格雷码转换为二进制是可以的,但 N+1 位格雷码不可以。或者当空间太紧张以至于无法进行 N+1 位转换的额外区域时。

最新文章