- 异步FIFO
异步FIFO和同步FIFO一样,也需要写使能和读使能来控制FIFO的读写,同样也可以利用读写指针来指示读写地址,每写入一个数据,写指针加一,同样的,每读出一个数据,读指针加一。与同步FIFO不同的是——同步FIFO中只需要对读写地址扩展一位,并将最高位作为指示位,其余位仍然表示读写地址,当最高位不同而其他位相同时表明读地址或写地址多跑了一圈,而显然读地址不可能比写地址多跑一圈,因此就是写地址多跑了一圈,也就表示此时FIFO已经写满了。
而当最高位相同其他位与相同时,读指针追上了写指针或者写指针追上了读指针,而显然写指针应该在前面(不然读啥),因此这种情况只能是读指针追上了写指针,也就表示FIFO被读空了。而异步FIFO中的“写满”或者“读空”的判断要复杂很多。
同步FIFO中利用的是二进制指针来判断“写满”或者“读空”,但异步FIFO中为了减少多bit跨时钟域传输带来的亚稳态问题采用格雷码形式的指针,此时如何判断“写满”或者“读空”呢?
要解决这个问题我们首先得要明白什么是格雷码。格雷码是一种循环二进制码或者叫作反射二进制码。格雷码的特点是从一个数变为相邻的一个数时,只有一个数据位发生跳变,由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码与二进制数的转换如下:
可以看到,如果用二进制形式的指针,指针从0111变为1000时四位指针都要发送变化,这无疑严重增加的出现亚稳态的可能,但是利用格雷码就明显减少了亚稳态的发生。回到刚才的问题,我们还是需要把指针扩展一位,但如果这时候再光看最高位是否相同时明显行不通了,比如5和10处理最高位不同其他几位均相同,但此时明显不能说FIFO写满了。这时候我们就需要观察最高位和次高位是否相等:
- 当最高位和次高位不同,其他位相同时则认为此时FIFO已经写满
- 当最高位和次高位相同,其他位也相同则认为此时FIFO已经读空
当然也可以把格雷码再转换为二进制码再比较最高位。
- FIFO中的同步问题
博主一开始学习异步FIFO的时候,看见资料说需要将读写指针进行同步,进而比较读写指针以判断FIFO的“空”“满”。而实现读写指针同步的方法就是把读指针在写时钟域下打两拍或者将写指针在读时钟域下打两拍。
那为什么打两拍就可以实现同步呢?为什么是打两拍呢?打一拍或者打三拍行不行呢?抱着这个疑问,博主开始广泛的查阅资料,终于找到了答案。下面是我的一知半解,如有不对的地方,欢迎大家批评指正。