讀書筆記------------------異步FIFO設計

FIFO經常用在跨時鐘域處理多位位寬數據,實際使用中,我們一般是直接例化FIFO的IP核,通過調用IP核來實現FIFO的控制,很少有親自下手寫FIFO的。不過掌握如何自己寫FIFO更能加深自己對FIFO的工作原理的理解。

一、FIFO的設計

FIFO包括同步FIFO和異步FIFO,對於FIFO的設計最大的難點在於如何準確的產生空滿信號,使其空而不讀,滿而不寫。

對於同步FIFO來說,由於讀寫時鐘相同,空滿信號的產生就比較簡單。通過判斷er_en和rd_en來控制ptr的增減,當ptr=0,表示FIFO空;當ptr=FIFO的最大指針,表示FIFO滿。

但是,對於異步FIFO,空滿信號的判斷就沒有這麼簡單,由於異步FIFO讀時鐘rclk和寫時鐘wclk不同,因此就不能通過直接比較讀指針和寫指針來產生空滿信號。這是因爲,空信號是在讀時鐘域產生的,由於讀寫時鐘不同,若要將寫指針與讀指針在讀時鐘域進行比較,需要將寫指針同步到讀時鐘域,由於多位信號不能通過兩級觸發器直接同步,否則可能會產生亞穩態或中間結果。

二、異步FIFO空滿信號判斷

空信號的產生:當讀指針追上寫指針時,此時FIFO爲空;

滿信號的產生:當寫地址追上讀地址時,此時FIFO爲滿。

有一個問題:如何判斷是寫指針追上讀指針還是讀指針追上寫指針呢?

爲進行區分,在設計中,我們通過增加一位指針,來進行空滿信號的判斷。如對於深度爲8的FIFO,我們將讀寫指針的位寬設置成4位,當讀指針追趕上寫指針時,最高位爲0,當寫指針追趕上讀指針時,最高位爲1。

三、格雷碼

由於讀指針不能直接通過兩級觸發器同步到寫時鐘域(同理,寫指針也不能直接通過兩級觸發器同步到讀時鐘域),因此在同步之前,需要將讀寫指針轉化爲格雷碼(因爲格雷碼相鄰時鐘週期只有一位發生變化,因此不會出現亞穩態問題)。二進制與格雷碼的轉化如下圖所示:

 上圖表示深度爲8的FIFO的格雷碼轉化關係(最高位用來判斷是讀追上寫還是寫追上讀)。空信號的產生比較簡單,當瀆指針的格雷碼等於寫指針的格雷碼時,此時FIFO爲空;但是對於滿信號的產生就有一定難度,我們不妨逆向思考一下,當FIFO爲滿時會是什麼條件?當FIFO爲滿時,必定是寫指針超前了讀指針並追上了讀指針,假設此時讀指針爲5(二進制爲4‘b0101,格雷碼爲4'b0111),那麼此時寫指針必定爲13(二進制爲4’b1101,格雷碼爲4'b1011),可以發現,讀寫指針的格雷碼的高兩位是相反的,其餘位相同(對於其它FIFO爲滿的情況也一樣)。因此滿信號的產生標誌就是讀寫指針格雷碼的高兩位相反,其餘位相同。

四、格雷碼計數器

格雷碼計數器的框圖如下圖所示:

 根據此框圖,很容易就可寫出格雷碼計數器verilog,重點是要理解爲什麼要用格雷碼以及格雷碼如何產生空滿信號。

 五、FIFO整體架構

 上圖就是FIFO的整體框圖:由此框圖我們可以將FIFO分成6個模塊。

  1. top模塊,該模塊主要是例化其餘5個模塊;
  2. sync_r2w模塊,該模塊主要將讀指針(格雷碼)同步到寫時鐘域,就是兩級觸發器;
  3. sync_w2r模塊,該模塊主要是將寫指針(格雷碼)同步到讀時鐘域,也是兩級觸發器;
  4. wptr_full模塊,該模塊主要描述第四節所講格雷碼計數器以及滿信號的產生,要注意上圖中waddr是二進制表示的值,wptr是二進制轉化後的格雷碼,且wptr位寬要比waddr多一位;
  5. rptr_empty模塊,該模塊也是用來描述格雷碼計數器以及滿信號的產生,同理,上圖中raddr是二進制表示的值,rptr是二進制轉化後的格雷碼,且rptr位寬要比raddr多一位;
  6. fifo_mem模塊,主要用來存儲數據,可以直接例化雙口RAM,也可以自己寫。

 以上就是FIFO的整體結構描述,通過以上內容分析,就可以自己實現可用的異步FIFO設計。

六、問題總結

關於異步FIFO設計經常會有人問及這樣幾個問題,現總結如下:

  1. 一個需要同步的格雷碼自增兩次,但是僅僅採樣一次,在同步時就會表現出多位同時變化的現象,這是否會導致 多位同步問題呢?

答:不會。對於這個問題首先要明白什麼是多位同步問題,對於多位同步問題,我的理解是若計數器從1記到2,可能會經過01--->11----->10變化過程(由於多位數據同時變化優先後順序),若此時同步器採樣到11就會出現錯誤的結果,這是多位同步問題。但是對於格雷碼,若自增兩次從01-->11-->10(格雷碼),採樣到如何一個格雷碼數值,都是正確的數值,因此不存在多位同步問題。

   2.快時鐘域的格雷碼計數器在一個慢時鐘域(一個週期)會增加多次,這樣會不會導致FIFO信號有效時,快時鐘域的格雷碼計數器仍在計數。(對於empty也一樣)

答:不會。首先對於FIFO滿信號產生,必定是寫時鐘快於讀時鐘,當寫時鐘快於讀時鐘時,滿信號的產生是在寫時鐘域,因此需要將讀指針格雷碼同步到寫時鐘域,此時寫指針是準確的,若此時寫指針跟讀指針的高兩位相反,其餘位相同,則此時FIFO爲滿,因此,滿信號的產生是準確的,且full有效以後,寫指針格雷碼計數器會停止計數,即快時鐘域的格雷碼計數器不會出現上述問題。(對empty分析也一樣)。

  3.由於格雷碼指針需要從一個時鐘域同步到另一個時鐘域,需要消耗幾個時鐘週期,這樣會不會導致FIFO有數據以後空信號仍然有效(虛空),FIFO還沒滿的時候滿信號有效(虛滿),會不會導致FIFO出現問題?

答:會導致FIFO產生虛空和虛滿的現象。虛空:空信號的產生是在讀時鐘域,且讀時鐘快於寫時鐘,需要將寫指針格雷碼同步到讀時鐘域,由於同步器有兩個時鐘週期的延遲,會導致,寫指針已經增加,讀時鐘域的寫指針仍保持原值不變,此時FIFO空信號仍然有效,這種現象叫做虛空。虛空不會導致FIFO的數據丟失,因此FIFO可以正常使用。對於虛滿現象同理。

參考文獻:Clifford E. Cummings:Simulation and Synthesis Techniques for Asynchronous FIFO Design

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章