本文首先對異步 FIFO 設計的重點難點進行分析
最后給出詳細代碼
一、FIFO簡單講解
FIFO的本質(zhì)是RAM, 先進先出
重要參數(shù):fifo深度(簡單來說就是需要存多少個數(shù)據(jù))
fifo位寬(每個數(shù)據(jù)的位寬)
FIFO有同步和異步兩種,同步即讀寫時鐘相同,異步即讀寫時鐘不相同
同步FIFO用的少,可以作為數(shù)據(jù)緩存
異步FIFO可以解決跨時鐘域的問題,在應用時需根據(jù)實際情況考慮好fifo深度即可
本次要設計一個異步FIFO,深度為8,位寬也是8.
代碼是學習Simulation and Synthesis Techniques for Asynchronous FIFO Design Clifford E. Cummings, Sunburst Design, Inc.這篇文章的,
百度搜搜很容易找到,雖然是英文的但是寫的確實值得研究。
下面我會對設計的要點進行分析,也是對自己學習過程的一個總結,希望能和大家交流共同進步。
二、設計要點解析
1、讀空信號如何產(chǎn)生?寫滿信號如何產(chǎn)生?
讀空信號:復位的時候,讀指針和寫指針相等,讀空信號有效(這里所說的指針其實就是讀地址、寫地址)
當讀指針趕上寫指針的時候,寫指針等于讀指針意味著最后一個數(shù)據(jù)被讀完,此時讀空信號有效
寫滿信號:當寫指針比讀指針多一圈時,寫指針等于讀指針意味著寫滿了,此時寫滿信號有效
我們會發(fā)現(xiàn) 讀空的條件是寫指針等于讀指針,寫滿的條件也是寫指針等于讀指針,到底如何區(qū)分呢?
解決方法:將指針的位寬多定義一位
舉個例子說明:假設要設計深度為 8 的異步FIFO,此時定義讀寫指針只需要 3 位(2^3=8)就夠用了,
但是我們在設計時將指針的位寬設計成 4 位,最高位的作用就是區(qū)分是讀空還是寫滿,具體理論 1 如下
當最高位相同,其余位相同認為是讀空
當最高位不同,其余位相同認為是寫滿
知道這個理論就萬事大吉了嗎?重點來啦
由于我們在設計中判斷是讀指針是否等于寫指針的時候,用的是讀寫指針的格雷碼形式(為什么用格雷碼后面解釋),此時若用上面的理論1就會出問題,
因為格雷碼是鏡像對稱的,若只根據(jù)最高位是否相同來區(qū)分是讀空還是寫滿是有問題的,詳情我會慢慢說,請看圖 1
綠色框起來的是0--15的格雷碼,用紅線將格雷碼分為上下兩部分
通過觀察格雷碼相鄰位每次只有1位發(fā)生變化,且上下兩部分,除了最高位相反,其余位全都關于紅線鏡像對稱,
7 --> 8 ,格雷碼從 0100 --> 1100 ,只有最高位發(fā)生變化其余位相同
6 --> 9 , 格雷碼從 0101 --> 1101 , 只有最高位發(fā)生變化其余位相同
以此類推,為什么要說鏡像對稱呢?
試想如果讀指針指向 8,寫指針指向 7 ,我們可以知道此時此刻并不是讀空狀態(tài)也不是寫滿狀態(tài)
但是如果在此刻套用理論 1 來判斷,看會出現(xiàn)什么情況,我們來套一下
7的格雷碼與8的格雷碼的最高位不同,其余位相同,所以判斷出為寫滿。這就出現(xiàn)誤判了,同樣套用在 6 和 9,5 和 10等也會出現(xiàn)誤判。