导师详解:多比特信号的CDC处理方式之异步FIFO
\\\插播一条:
自己在今年整理一套单片机单片机相关论文800余篇
论文制作思维导图
原理图+源代码+开题报告+正文+外文资料
想要的同学私信找我。
异步FIFO是处理多比特信号跨时钟域的最常用方法,简单来说,异步FIFO是双口RAM的一个封装而已,其存储容器本质上还是一个RAM,只不过对其添加了某些控制,使其能够实现先进先出的功能,由于这个功能十分的实用,因此得以广泛应用。真双口RAM可以实现在一端存储,另一端读取的功能,两端的时钟可以不同,将数据存入一个容器,再取出来,这个过程在双口RAM的两端完全不存在亚稳态的问题。由于异步FIFO的实现中也存在数据的存取问题,和双口RAM类似,再加上空满信号的控制,存在跨时钟域的问题,因此只要处理好,空满信号的判断中的跨时钟域问题,就可以使用FIFO解决多比特信号的跨时钟域问题。下面从多个方面来了解一下,异步FIFO的内容,最后会给出异步FIFO的一种普遍的实现方式及其仿真,让我们一起进入今天的内容吧。
异步FIFO的概念
异步FIFO的实现方式有很多种,这里说的实现方式可以理解为实现异步FIFO的技术方式,也可以指使用异步FIFO的选择方式,因为都有很多种!拿实现异步FIFO的技术方式来说,其重难点在于其空满信号的判断,它涉及到内部跨时钟域细节的实现、格雷码的转换以及空满信号的比较等。这里面的实现技术就各有不同了,但殊途同归,只能能巧妙地判断空满就可以凑合着用。下面给出一张异步FIFO的实现架构框图仅供参考:
另外,因为异步FIFO的应用已经太成熟了,手动设计起来破费一番功夫,所以FPGA各大厂家大都提供了专业的IP核供使用,功能齐全且性能良好,鲁棒性强,不用自己设计,在工程应用中,也基本都用IP核,除非想不开或者其他原因?
不妨打开Xilinx的FIFO定制页面:FIFO Generator来看:
可供定制的页面确实及其丰富,各种类型的空满信号、实现的资源选择应有尽有,手动实现这些可是要费大功夫的,没有资本的推动,恐怕很难有人去做这件事吧。
异步FIFO为什么可以解决CDC问题?
异步FIFO的接口如下:
再看其资源使用情况:
以上这两张图片显示的是Xilinx的异步FIFO IP的一种定制情况,可以看到FIFO就是在RAM的基础上的一个产物,通过处理RAM的读写端口来做成先进先出的存储器,实现FIFO的功能。
对于FIFO的读写有独立的时钟,说明读写可以是不同的时钟,因此可以实现不同时钟域数据的传输。
这好像只是说明了一个结论,异步FIFO可以作为处理跨时钟域处理的方法或载体,但是异步FIFO为什么可以用来处理跨时钟域传输问题呢?这和异步FIFO的具体实现有关!下面一起来看异步FIFO的实现!
异步FIFO的RTL实现
通过RTL实现异步FIFO之前,需要明白异步FIFO的几个重要的参数,也是我们设计的重点:
·FIFO的深度:通俗地说,就是异步FIFO可以存多少个数据的意思!
·FIFO的宽度:上面说异步FIFO的深度是表示能存放多少数据的概念,那宽度便是每个数据有多少位,也就是我们通常所说的数据有多宽!
·FIFO空:表示FIFO里面数据被读完了;
·FIFO满:表示FIFO里面填满了数据;
·FIFO写指针:总是指向下一个将要被写入的单元,复位时,指向第1个单元(编号为0);
·FIFO读指针:总是指向当前要被读出的数据,复位时,指向第1个单元(编号为0);
·FIFO读时钟:表示读取数据使用的时钟,一般设计时钟的上升沿为有效沿,有效沿读取数据;
·FIFO写时钟:表示写入数据时使用的时钟,一般上升沿为有效沿,当然也可以设计下降沿为有效沿。
明白了如上的FIFO参数的概念,我们也该具体聊聊FIFO的关键细节了,例如最重要的空满判断条件:上面也说了,FIFO空的意思是FIFO中没有了数据,可以思考,什么情况下FIFO中数据空了,其实FIFO类似一个容器,就水桶吧,倒进去的水,又全部倒了出来,水桶就是空的。FIFO也是如此,写进去的数据,又全部读了出来,表示FIFO空了。如下图:
写进FIFO4个数据,又读出了4个数据,读写指针指向了同一个地方,也就是读写指针相等了,FIFO就空了。这是最简单的情况,我们其往下看:还是用上面的图片,如果继续往FIFO内写数据,写指针不断增加,写到尽头了,指针就会从0继续增加,直到写指针回到了最初的位置,再次与读指针处于同一个位置,这时候读写指针再次相等,但是你能说FIFO还是空的吗?如下图: