一、引言
也许,你的使用疑问可以在这篇文章中得到解答;
在实际应用中,可能经常需要跨时钟域传输以及数据位宽转换,异步fifo模块的出现可以大量减少此类重复性工作,节约大量的时间资源;或者,在面试中,fifo的实现也容易被问及;那么问题来了,如何实现一个异步fifo呢?
二、FIFO的结构
由上图我们可以看出:异步FIFO的设计主要有5部分组成。
(1)双口 RAM 存储数据。
(2)同步读数据指针到写时钟域。
(3)同步写数据指针到读时钟域。
(4)处理写指针和满信号的逻辑。
(5)处理读指针和空信号的逻辑。
三、格雷码的使用
首先,我们了解一下什么是格雷码?
百度百科是这么介绍的:
定义:在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code);
其次,我们为什么要在异步FIFO中使用格雷码?
因为异步FIFO是通过比较读指针和写指针的位置来判断FIFO是否写满或读空,但是他们属于不同时钟域,直接相比可能会产生亚稳态从而引起误判,这就需要将两个指针分别进行跨时钟域处理,然后再判断。但是存在一个问题,自然二进制编码的地址在状态翻转的时候是多位变化,这就可能会产生竞争现象并有可能被另一个时钟域的触发器采样到,从而引发误判。最容易的解决方法就是将自然二进制编码的地址转为格雷码编码的地址。其实可以理解为将一个具有多位位宽的数据中的每一位数据都进行了的跨时钟域处理;但是使用格雷码也存在一些问题,我们后面说。
四、格雷码与二进制的转换
(1)二进制转换为格雷码
自然二进制码转换成二进制格雷码,其法则是保留自然二进制码的最高位作为格雷码的最高位,而次高位格雷码为二进制码的高位与次高位相异或,而格雷码其余各位与次高位的求法相类似。 如下图:
代码如下:
(2)格雷码转换为二进制
二进制格雷码转换成自然二进制码,其法则是保留格雷码的最高位作为自然二进制码的最高位,而次高位自然二进制码为高位自然二进制码与次高位格雷码相异或,而自然二进制码的其余各位与次高位自然二进制码的求法相类似。
参考:(11条消息) 【原创】异步FIFO设计原理详解 (含RTL代码和Testbench代码)_锤王马加爵的博客-CSDN博客_fifo testbench