FPGA設計中,跨時鐘域問題的處理
FPGA設計中,跨時鐘域問題的處理
今天和大俠簡單聊一聊FPGA設計中跨時鐘域問題的處理,話不多說,上貨。
跨時鐘域處理是FPGA設計中經常遇到的問題,而如何處理好跨時鐘域間的資料,可以說是每個FPGA初學者的必修課。如果是還在校的本科生,跨時鐘域處理也是面試中經常常被問到的一個問題。
本次主要介紹3種跨時鐘域處理的方法,這3種方法可以說是FPGA界最常用也最實用的方法,這三種方法包含了單bit和多bit資料的跨時鐘域處理,學會這3招之後,對於FPGA相關的跨時鐘域資料處理便可以手到擒來。
介紹的3種方法跨時鐘域處理方法如下:
- 1、打兩拍;
- 2、非同步雙口RAM;
- 3、格雷碼轉換。
第一種方法:打兩拍
大家很清楚,處理跨時鐘域的資料有單bit和多bit之分,而打兩拍的方式常見於處理單bit資料的跨時鐘域問題。
打兩拍的方式,其實說白了,就是定義兩級暫存器,對輸入的資料進行延拍。如下圖所示:
應該很多人都會問,為什麼是打兩拍呢,打一拍、打三拍行不行呢?
先簡單說下兩級暫存器的原理:兩級寄存是一級寄存的平方,兩級並不能完全消除亞穩態的影響,但是提高了可靠性減少其發生概率。總的來講,就是一級概率很大,三級改善不大。
這樣說可能還是有很多人不夠完全理解,那麼請看下面的時序示意圖:
data是時鐘域1的資料,需要傳到時鐘域2(clk)進行處理,暫存器1和暫存器2使用的時鐘都為clk。假設在clk的上升沿正好採到data的跳變沿(從0變1的上升沿,實際上的資料跳變不可能是瞬時的,所以有短暫的跳變時間),那這時作為
如果再加上第三級暫存器,由於第二級暫存器對於亞穩態的處理已經起到了很大的改善作用,第三級暫存器在很大程度上可以說只是對於第二級暫存器的延拍,所以意義是不大的。
第二種方法:非同步雙口RAM
處理多bit資料的跨時鐘域,一般採用非同步雙口RAM。假設我們現在有一個訊號採集平臺,ADC晶片提供源同步時鐘60MHz,ADC晶片輸出的資料在60MHz的時鐘上升沿變化,而FPGA內部需要使用100MHz的時鐘來處理ADC採集到的資料(多bit)。
在這種類似的場景中,我們便可以使用非同步雙口RAM來做跨時鐘域處理。先利用ADC晶片提供的60MHz時鐘將ADC輸出的資料寫入非同步雙口RAM,然後使用100MHz的時鐘從RAM中讀出。
對於使用非同步雙口RAM來處理多bit資料的跨時鐘域,相信大家還是可以理解的。當然,在能使用非同步雙口RAM來處理跨時鐘域的場景中,也可以使用非同步FIFO來達到同樣的目的。
第三種方法:格雷碼轉換
對於第三種方法,我們依然繼續使用介紹第二種方法中用到的ADC例子,將ADC取樣的資料寫入RAM時,需要產生RAM的寫地址,但我們讀出RAM中的資料時,肯定不是一上電就直接讀取,而是要等RAM中有ADC的資料之後才去讀RAM。這就需要100MHz的時鐘對RAM的寫地址進行判斷,當寫地址大於某個值之後再去讀取RAM。
在這個場景中,其實很多人都是使用直接用100MHz的時鐘與RAM的寫地址進行打兩拍的方式,但RAM的寫地址屬於多bit,如果單純只是打兩拍,那不一定能確保寫地址資料的每一個bit在100MHz的時鐘域變化都是同步的,肯定有一個先後順序。如果在低速的環境中不一定會出錯,在高速的環境下就不一定能保證了。所以更為妥當的一種處理方法就是使用格雷碼轉換。
對於格雷碼,相鄰的兩個數間只有一個bit是不一樣的(格雷碼,在本文中不作詳細介紹),如果先將RAM的寫地址轉為格雷碼,然後再將寫地址的格雷碼進行打兩拍,之後再在RAM的讀時鐘域將格雷碼恢復成10進位制。這種處理就相當於對單bit資料的跨時鐘域處理了。
對於格雷碼與十進位制互換的程式碼,僅提供給大家作參考:程式碼使用的是函式的形式,方便呼叫,op表示編碼或者譯碼,WADDRWIDTH和RADDRWIDTH表示位寬。
完
後續會持續更新,帶來Vivado、 ISE、Quartus II 、candence等安裝相關設計教程,學習資源、專案資源、好文推薦等,希望大俠持續關注。
江湖偌大,繼續闖蕩,願大俠一切安好,有緣再見!
【QQ交流群】
群號:173560979,進群暗語:FPGA技術江湖粉絲。
多年的FPGA企業開發、培訓經驗,各種通俗易懂的學習資料以及學習方法,濃厚的交流學習氛圍,QQ群目前已有1000多名志同道合的小夥伴,無廣告純淨模式,給技術交流一片淨土,從初學小白到行業精英業界大佬等,從軍工領域到民用企業等,從通訊、影象處理到人工智慧等各個方向應有盡有,FPGA技術江湖打造最純淨最專業的技術交流學習平臺。
【微信交流群】
現微信交流群已建立08群,人數已達數千人,歡迎關注“FPGA技術江湖”微信公眾號,可獲取進群方式。