異步FIFO設計的一些注意事項


異步FIFO的結構基本上是是按照下面的思路來設計:

1. 讀寫的指針分別用gray code sync到另外一個clock domain,sync的時候至少打2拍。

2. 讀寫指針最高位各加一個bit用來判斷空和慢,對於FIFO來說,永遠是讀指針追寫指針,當指針相同的時候,用加的這個最高bit來

    判斷是誰追上誰,繼而判斷空和滿。

 

除了上面的設計要點,還有以下幾點需要注意:

1. 當兩個時候頻率差別很大時

  • 快時鍾的讀/寫指針sync到慢時鍾時,gray code就不是按照1次變化1個bit的方式進行了,而是有可能一次變化好幾個bit,這樣gray code的好處就體現不出來了
  • 對於這種情況,我們先分析一下對於空滿標志的影響,先假設寫時鍾慢,讀時鍾快的情況,如果在sync的時候不會出現亞穩態,那么sync到寫時鍾的讀指針永遠是1個寫時鍾period之前的值,也就是說永遠是較早的值,這樣對於滿的判斷就會比較保守,也就永遠不會出錯
  • 接着上面的分析,如果在第一級sync register(cycle 1)中出現了亞穩態,表示在cycle 1的時刻,讀時鍾也在變化,這個變化肯定導致至少讀了一個數據出去了,cycle 1時刻,寫與不寫是基於上一個時鍾采樣的值判斷的,也就是說在這個讀數據操作發生之前的情況,所以在cycle 2的時候,這個錯誤的亞穩態sync到寫時鍾域中,如果這個錯誤的值導致full產生,這樣不會導致錯誤發生,但會導致效率降低,如果這個錯誤的值沒有導致full的產生,寫動作繼續,也不會發生錯誤,因為這之前讀動作至少發生一次,所以寫不會覆蓋數據,因此,不管怎樣,都不會出錯
  • 那如果下一拍還是亞穩態呢?沒關系,還是按照之前的分析,讀操作又發生了至少一次了,所以下一次再寫也不會覆蓋數據,因此不管發生幾次亞穩態,由於發生亞穩態的時刻必定是在讀指針變化的時候,這個時刻肯定發生讀了,所以就會騰出空間來寫,而full的判斷是在之后1個cycle發生的,所以才不會導致數據被覆蓋,也就是說,在full等於1的時候,sync過來用於判斷的讀時鍾在第一級sync register的時候必定是穩定的,不可能產生亞穩態。
  • 當sync register基數大於2時,也不會產生錯誤,但是會導致空滿判斷延遲更多,效率降低

2. 怎么在寫端判斷有多少個空間可寫,以及在讀端判斷有多少個數據可讀呢

  • 用sync過來的寫指針判斷肯定不行,設想如果發生亞穩態,那么sync過來的數據對於空滿判斷結果不會導致數據出錯,但是用來計算具體個數的話,肯定會出現偏大或者偏小的情況,如果你用這個數據來做一些trigger的話,肯定會導致錯誤情況發生,即使錯誤概率很低。
  • 有人可能會說我對sync過來的指針采集連續幾拍進行判斷,如果遞增就OK,如果出現先遞增,后變小就是假的,這個數據我就不用,這樣也不行,也有概率會出錯,比如兩次連續亞穩態都是偏大,而且都是遞增呢?
  • 這個時候我覺得可靠的辦法就是在寫端記錄寫了多少個數據,到了一個閾值后,就利用電平雙握手傳遞到讀,然后啟動trigger,在讀端也一樣,先counter讀走多少個數,到一定閾值以后也用電平雙握手傳遞到寫端。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM