關於非同步fifo的快轉慢的問題
最近一位童鞋跟我聊到一個非同步fifo的問題,還是很有水準的。我貼在這裡給大家看一下:非同步fifo需要將讀寫的pointer作比較產生滿和空信號,但是假如fifo的兩個時鐘域的clk相差特別大,pointer在做跨時鐘域轉換的時候就會出現問題。什麼問題呢?慢時鐘采快時鐘會漏采數據。
舉個栗子:非同步fifo,寫時鐘500M,讀時鐘100M,相差5倍。那麼寫時鐘域的write_pointer就會以500M的頻率增加,但是讀時鐘的read_pointer增加的頻率是100M。現在要判斷滿和空,滿是在寫時鐘域判斷的,空是在讀時鐘域判斷的。下圖所示:
判斷滿的方法是拿write_pointer和做完CDC轉換過來的read_pointer作比較。CDC轉換的方法是採用格雷碼過兩級flip-flop的同步器。由於read_pointer屬於100M的頻率,write時鐘域有500M,屬於快采慢,CDC轉換不會有什麼問題。因此滿的判斷不會有問題。
判斷空的方法是拿read_pointer和做完CDC轉換過來的write_pointer做比較。CDC轉換的方法也是採用格雷碼過兩級flip-flop的同步器。由於write_pointer的變化頻率是500M,而read時鐘域只有100M的clk,屬於慢采快,CDC的轉換就會出問題。
出什麼問題?
因為read時鐘的頻率過低,所以write_pointer做完CDC之後得到的將是零星的離散的採樣值,而非連續的值,比如說可能會採樣到格雷碼的5->10->15,而非連續的格雷碼的5->6->7->8............
那麼該怎麼解決這個問題?
這個問題其實沒法解決,也不需要解決。
為什麼沒法解決?
因為快時鐘往慢時鐘傳數據,要想一個不漏,唯一的辦法就是hold住(通常來講,至少hold住目標時鐘域2T)。把當前數據牢牢keep住,等到數據被取走了再傳下一個。但是很明顯write_pointer屬於自增型的,只要fifo沒有滿,它都可以持續增加,並不會hold不變,所以必然會漏采。
為什麼不需要解決?
因為只要fifo夠大,即便讀到的write_pointer是離散的,也不會影響到fifo判空。只要fifo判空不出錯,非同步fifo的行為就沒有問題,只不過效率可能略微降低。
舉個栗子:
當read時鐘域採樣到write_pointer的值是5的時候,真正的write_pointer的值可能是多少?可能已經是5,6,7,8,9等等了。但絕對不可能比5小。
為什麼不可能比5小?
因為對於write_pointer而言,它從4變到5,這個沿變在跨CDC的時候,只有沒采著和采著兩種可能,沒采著的話,跨完時鐘域得到4,采著了就得到5。絕對不可能得到比5大的值。
也就是說,只要是格雷碼跨CDC,跨過去的值只可能比真實值相等或者小,不可能比真實值大!
所以如果在read時鐘域已經看到write_pointer等於5了,那麼真實的write_pointer必然不小於5。那麼基於write_pointer等於5來判斷空,將會得到一個很保守的空(也可以叫假空)!也就是說非同步fifo明明還有數,讀時鐘域就判斷出空,暫時停止讀取數據。
但是這並不會導致出錯,因為這種保守的空判斷,只是降低了讀的效率,並沒有導致讀出錯誤的數據或者不存在的數據。
所以,即便採樣到的write_pointer是個離散值,但是由於非同步fifo並不會有實際的行為出錯,所以也不需要解決這個問題。
IC免費課:專註晶元設計
推薦閱讀:
※怎樣理解二極體的鉗位電路和穩壓電路?
※龍芯真的不如移動晶元嗎?美國禁止向中國超算提供英特爾晶元後影響會多大?
※985碩士一枚,專業方向射頻集成電路、通信數字接收機集成電路、超大規模集成電路。今後發展方向有哪些?
※數字IC設計領域有哪些聖經?成為一名數字IC設計專家需要怎樣的知識結構和技能?
※中國航天業使用的哪些晶元必須進口,禁售問題如何解決?