2
\ $ \ begingroup \ $

我试图理解时钟交叉FIFO是如何实现的,我看到的通常答案是将读/写地址指针转换为灰色代码,然后通过同步器电路进入彼此的时钟域,以确定是否有数据包含在FIFO。使用灰码的想法是这样的,另一个时钟域可以检测另一端的亚稳态,事实上,每个地址增量只应该改变一个比特……它可以安全地忽略地址指针,直到它看起来有效为止。

如果写时钟域比慢时钟域快得多,该怎么办呢?如果写地址指针可以在每个读时钟周期中增加很多次,那么在某个点上,灰色代码值将翻转超过1位,这并不一定是一个错误。这种情况通常是如何处理的?

我知道有一个类似的问题在于se,但答案似乎显示了一个例子,写入时钟的一个例子只能比读时钟快2倍,所以也许这种情况从未经历过。

\ \ endgroup \美元
    4.
    \ $ \ begingroup \ $

    在异步FIFO中,一个时钟域与写端口相关联,并且“头”指针(下一个写地址)保持在那个时钟域中。类似地,另一个时钟域与读端口相关联,并且“尾”指针保存在那里。

    问题是,两个时钟域都需要能够跟踪FIFO中的字的数量,而做到这一点的方法是从头指针的值减去尾指针的值,对RAM的大小取模。因此,每个指针都被编码为格雷码,并转移到其他时钟域。

    如果在读取时钟周期期间发生了多于一个写入,或反之亦然,这无关紧要。重点是灰色代码编码,介于之间只有一个比特变化任何对值。如果一个时钟碰巧捕捉到另一个时钟域的转换,最多只能有一位是亚稳态的,而且模糊是在计数器的两个相邻状态之间。

    因此,这是不可能的两个时钟域计算一个错误的值的字在FIFO -它只是成为一个问题,它是否得到更新一个时钟早或晚于它可能有。

    因此,在写侧,头部指针直接增量,增加FIFO的深度,但是来自另一侧的更新的尾针可能被延迟。这只能导致写入侧高估FIFO中的单词数,因此,FIFO永远不会溢出。

    类似地,在读取侧,尾针直接增量,减小FIFO的深度,但是更新的头指针可以延迟。这只能导致读取的侧低估FIFO中的单词数量,因此它永远不会下溢。

    实际上,您可以在灰色代码转移路径中放置任何数量的同步阶段,唯一的效果将通过FIFO增加延迟。这甚至是Xilinx双时钟FIFO发生器中的可配置参数。

    \ \ endgroup \美元
    1
    • 1
      \ $ \ begingroup \ $ 好吧,我想我明白了。所以多个比特可以改变时,计数器被交叉到慢时钟域,但只有1位将构成亚稳态的风险,基于事实,只有1位改变在快域灰编码。所有其他位应该在更长的时间内保持稳定,因此违反慢时钟域寄存器的设置/保持时间的机会减少了。通过双寄存器传递灰色代码值将清除单位亚稳态错误,就像它通常做的那样,你不必担心多位总线反斜。 \ \ endgroup \美元-User2913869. 19年4月12日13:01

    你的答案

    点击“发布答案”,您同意我们的同意服务条款隐私政策Cookie政策

    不是您要找的答案?浏览其他标记的问题问你自己的问题