概述
本文主体翻译自C. E. Cummings and S. Design, “Simulation and Synthesis Techniques for Asynchronous FIFO Design 一文,添加了笔者的个人理解与注释,文中蓝色部分为笔者注或意译。前文链接:异步FIFO设计的仿真与综合技术(1)https://blog.csdn.net/apple_53311083/article/details/132852687 我们书接上文
2.3 二进制FIFO指针注意事项(Binary FIFO pointer considerations)
试图将一个二进制计数值从一个时钟域同步到另一个时钟域是有问题的,因为n位计数器的每一点都有可能同步改变(例如二进制数中的7->8是0111->1000,所有位都改变了)。解决这个问题的一种方法是在保持寄存器中保存周期性的二进制计数值,并将同步的ready信号传递到新的时钟域。当识别ready信号时,接收时钟域向发送时钟域发送同步确认信号。在从接收时钟域接收到确认信号之前,被采样的指针不能改变。使用这种技术,可以将一个具有多个变化位的计数值安全地转移到一个新的时钟域。在接收到确认信号后,发送时钟域被允许清除ready信号并重新采样二进制计数值。
这里笔者把他理解成一种握手信号的形式:(1)发送端将数据驱动到数据总线,并发出ready信号告知接收端数据已经被驱动到了数据总线上(2)将ready信号同步到接收端的时钟域(3)接收器在接收到同步后的ready信号后,锁存数据总线上的数据(4)接收端给出ack信号,表示已经接收到了数据(5)发送端同步ack信号(6)发送端识别ack信号,一次传输结束。但是这样会导致一个问题就是给传输引入了大量的冗余时钟周期,效率大大降低了。
使用这种技术,二进制计数器值定期采样,并不是所有的二进制计数器值都可以传递到一个新的时钟域。问题是,我们需要关注二进制计数器可能增加溢出或下溢出FIFO的情况吗?答案是否定的。
当写指针赶上(被同步和采样过的)读指针时,FIFO满。被同步和采样过的读指针可能不会反映实际读指针的当前值,但写指针将不会尝试进行在同步读指针值之外的计数。不会发生溢出。
当读指针赶上(被同步和采样过的)写指针时,FIFO空。被同步和采样过的写指针可能不会反映实际写指针的当前值,但读指针将不会尝试进行在同步写指针值之外的计数。不会发生下溢出。
这里对上面说的不会发生溢出和下溢出做一下说明:
在我们判断FIFO满的时候,使用的是真实的写指针和同步过的读指针,由于我们的读指针是同步过的,所以它可能不能正确反映此时刻FIFO的状态(可能在进行同步期间,FIFO又进行了读操作,读指针已经更新了,但是同步的读指针还没有更新),所以此时FIFO中的数据只可能少于等于同步后读指针的指示数据,如果此时同步后的读指针与真实的写指针进行判断得出FIFO已经满的结果,那么这个结果实际上是一个“假满”(如满(bushi)),实际上FIFO可能是满或者未满(但是是不可能溢出的),我们想象一下,其实这种情况是可以接受的,毕竟最多只是有可能造成资源上的浪费,但是不会造成错误,这是完全可以接受的。
同样的方法,我们来分析一下判断FIFO空的时候,使用的是真实的读指针和同步过的写指针,由于我们的写指针是同步过的,所以它可能不能正确反映此时刻FIFO的状态(可能在进行同步期间,FIFO又进行了写操作,写指针已经更新了,但是同步的写指针还没有更新),所以此时的FIFO中的数据只可能大于等于同步后写指针指示的数据,如果此时同步后的写指针和真实的读指针进行判断得出FIFO已经空的结果,那么这个结果实际是一个“假空”,实际上FIFO可能是空的或者还没有空(但是不可能是下溢出),这种情况一样是我们可以接受的。
虽然还没有到FIFO的具体设计部分,但是这里的原理对于FIFO的设计至关重要,这里就解释了为什么在异步FIFO的设计过程中,我们经常能看到一种说法是:读指针同步到写时钟域,写指针同步到读时钟域。
使用FIFO计数器指针的一种常用方法是使用格雷码计数器。格雷码只允许每个时钟转换改变一个位,消除了与试图同步同一时钟边缘的多个变化信号相关的问题。
2.4 FIFO测试故障
测试一个FIFO设计的微妙的设计问题几乎是不可能做到的。这个问题源于这样一个事实:即使实现错误,RTL模拟中的FIFO指针表现理想,但是如果在实际的使用中,它们可能导致灾难性的故障。(也就是说就算是有错误,测试也很可能测试不出来,但是一旦使用中出错,问题就大了)
在RTL模拟中,如果设计中包含了二进制计数的FIFO指针,那么所有的FIFO指针位都将同时发生变化;没有机会观察到同步和比较问题。在门级模拟没有注释延迟,只有一个轻微的机会观察问题如果门过渡不同上升和下降边缘信号,即使这样,必须幸运,有正确的比特序列变化之前和之后上升的时钟边缘。对于更高的速度设计,上升和下降的边缘信号之间的延迟差异减小,检测问题的概率也减小。对于具有反向注释延迟的栅极级设计,发现实际的FIFO设计问题是最大的,但即使做这种类型的模拟,发现问题也很难做,而且随着信号传播延迟的减少,观察设计问题的几率会降低。
显然,答案是要认识到存在潜在的FIFO设计问题,并从一开始就正确地进行设计。