異步FIFO爲什麼要使用格雷碼(筆記)

異步FIFO爲什麼要使用格雷碼(筆記)

  • 首先要了解的是異步FIFO使用格雷碼的唯一目的就是:
    “即使在亞穩態進行讀寫指針抽樣也能進行正確的空滿狀態判斷”。

那麼典型的判斷方法是怎樣進行的呢?以滿狀態判斷爲例,先要對讀指針(屬於讀時鐘域)在寫時鐘域進行抽樣,然後才能與寫指針進行比較,如果寫指針趕上了讀指針(多繞一圈),說明已經寫滿,寫操作必須暫停。

爲什麼2進制(binary編碼)指針不適合做空滿判斷。

事實上2進制讀指針在增減時,經常發生多位突變,比如6位地址111111會在下一時刻變成000000,在實際電路中,這個變化過程要持續很長一段時間,會由111111經歷6個狀態轉移到達000000。比如111111-> 101111 -> 100111 ->100110 -> 100100 -> 000100-> 000000。由於寫時鐘與讀時鐘不同步,異步的寫時鐘很可能會在狀態不穩定的中間某個狀態抽樣,這樣就會得到錯誤的讀指針,進而做出錯誤的狀態判斷,導致系統異常。而且由於多位同時突變,憑藉概率論常識可知發生錯誤的可能性很大。

格雷碼(Gray)

那麼怎樣才能避免這個問題的發生呢?顯然,在中間狀態抽樣,這個是不可避免的,這是異步系統天生的缺陷我們的目標是:即使在中間狀態抽樣,也要不影響空滿狀態的判斷
符合這個要求的編碼方法是每次只能有1個比特發生改變。爲什麼這麼說呢?因爲當只有一個比特發生改變時,即使在中間狀態抽樣,其結果也不外乎兩種:遞增前原指針和遞增後新指針。顯然遞增後新指針是最新情況的反映,如果抽樣到這個指針,那麼和我們的設計預期是一致的,如果抽樣到遞增前的原指針,會有什麼結果呢?假設現在抽樣讀指針那麼最壞的情況就是把“不滿”判斷成了“滿”,使得本來被允許的寫操作被禁止了,但是這並不會對邏輯產生影響,只是帶來了寫操作的延遲。同樣的,如果現在抽樣寫指針那麼最壞的情況就是把“不空”判斷成了“空”,使得本來被允許的讀操作被禁止了,但是這也不會對邏輯產生影響,只是帶來了讀操作的延遲。

顯然每次只變化1比特的編碼方案可以有效解決中間狀態下空滿狀態的判斷問題,格雷碼就是這樣的一種編碼。
格雷碼每次只有一位跳變,但也需要使用兩級寄存才安全。如果產生了亞穩態,使用兩級寄存器後數據很大概率會回到某一個穩定狀態,防止亞穩態傳播。

在異步的FIFO中,採用格雷碼進行計數,相鄰的數據僅僅只有1bit變化,這樣在兩個時鐘域同步的時候僅僅可能只有1bit產生亞穩態,通過同步以後,亞穩態可以消除,最壞的情況是這1bit採錯,但是即使是採錯地址也只是相差1個,這對判斷空滿標誌不會產生影響。

其他看法

  1. 回答一:
    格雷碼是的確非常有用。它的特點就是相鄰碼只有一位發生翻轉,比如00->01->11->10->00…
    相比于格雷碼,十進制計數容易產生毛刺。
    編寫狀態機時,我也喜歡用這種相鄰狀態只發生一位翻轉的編碼。這樣從一個狀態切換到下一個狀態,就只有一位寄存器發生變化。這麼做可以帶來降低功耗的好處,因爲寄存器的翻轉是消耗動態功耗的,而這種編碼將翻轉的次數降到最低,所有有利於降低功耗。

    但是這裏降低功耗的前提是,一個狀態到下一個狀態的變化也要遵循格雷碼連續的變化,否則,就不成立了。比如:如你所說,00<->01<->11<->10這樣的變化,確實是有利於降低功耗;但是,狀態的變化不一定就是這樣變化,它有可能是00<->11,01<->10這樣的變化,那麼你說的有利於降低功耗就不成立。

  2. 回答二:
    低功耗設計的內容還是很博大精深的。如何合理的選擇信號形式,以使得系統在發生狀態變化時只有少數信號發生翻轉?所依賴的公式爲
    P=aCV2fP=a*C*V^2*f
    其中a爲信號翻轉率,C爲系統等效電容,V爲電路驅動電壓,f爲時鐘頻率。使用格雷碼降低功耗就是想使a小下來。當然如果電路中做不到嚴格的格雷碼也沒關係,只要是有利於減小a的,就有利於功耗的降低。
    異步FIFO的例子主要是爲了多比特同步,這個例子中功耗是次要的因素。

  3. 回答三:
    格雷碼有兩個作用,一是消除多個比特同時變化帶來的潛在競爭與冒險,二是降低功耗(翻轉次數減少)。在狀態機中通常爲了簡單起見表示現態與次態的狀態參數並不使用格雷碼而是二進制碼,因爲一個狀態的變化可能是發散的而非單向的,就是說不同的條件對應不同的次態,這個時候用格雷碼對狀態進行編碼達不到一次只變化一位的目的,除非在特殊情況下,即狀態機的變化是單向的,總是由S0到S1,再到S2,等等,這個時候用格雷碼就能達到原來的目的。

  4. 回答四:
    但是在實際應用中,往往是將二進制的轉換成gray,同時其轉換的外加邏輯必然會帶來損耗,在多比特的情況,功耗是否會跟多呢?
    Gray碼一般是用在不同時鐘域的連續數值的傳送,即數據必須是遞增或遞減的;這樣,其主要是在asynchronou fifo中使用,感覺功耗並不會下降。


另一個博客

異步FIFO通過比較讀寫地址進行滿空判斷,但是讀寫地址屬於不同的時鐘域,所以在比較之前需要先將讀寫地址進行同步處理,將寫地址同步到讀時鐘域再和讀地址比較進行FIFO空狀態判斷(同步後的寫地址一定是小於或者等於當前的寫地址,所以此時判斷FIFO爲空不一定是真空,這樣更保守),將讀地址同步到寫時鐘域再和寫地址比較進行FIFO滿狀態判斷(同步後的讀地址一定是小於或者等於當前的讀地址,所以此時判斷FIFO爲滿不一定是真空,這樣更保守),這樣可以保證FIFO的特性:FIFO空之後不能繼續讀取,FIFO滿之後不能繼續寫入。

大多數情形下,異步FIFO兩端的時鐘不是同頻的,或者讀快寫慢,或者讀慢寫快,這時候進行地址同步的時候,可能會有地址遺漏。
以讀慢寫快爲例

  • 以讀慢寫快爲例,進行滿標誌判斷的時候需要將讀地址同步到寫時鐘域,因爲讀慢寫快,所以不會有讀地址遺漏,同步後的讀地址滯後當前讀地址,所以可能滿標誌會提前產生。進行空標誌判斷的時候需要將寫地址同步到讀地址,因爲讀慢寫快,所以當讀時鐘同步寫地址的時候,必然會漏掉一部分寫地址(寫時鐘快,寫地址隨寫時鐘翻轉,直到滿標誌出現爲止),那到底讀時鐘會同步到哪個寫地址?不必在意是哪一個,我們關注的是漏掉的地址會不會對FIFO的空標誌產生影響。比如寫地址從0寫到10,期間讀時鐘域只同步到了2,5,7這三個寫地址,漏掉了其他地址。同步到7地址時,真實的寫地址可能已經寫到10地址,相當於“在讀時鐘域還沒來得及覺察的情況下,寫時鐘域可能偷偷寫了數據到FIFO去”,這樣在比較讀寫地址的時候不會產生FIFO“空”讀操作。漏掉的地址也沒有對FIFO的邏輯操作產生影響。

我們可以對異步FIFO的地址採用binary編碼,這樣並不影響異步FIFO的功能,前提是讀寫地址同步時能夠保持正確。這種情況在功能仿真時完全正確,問題只有到時序仿真時纔會遇到。毛刺可以說是異步電路的殺手,一個毛刺被觸發器採樣後會被放大,然後傳播,導致電路功能出錯。

binary編碼的地址總線在跳變時極易產生毛刺,因爲binary編碼是多位跳變,在實現電路時不可能做到所有的地址總線等長,address bus skew必然存在,而且寫地址和讀地址分屬不同時鐘域,讀寫時鐘完全異步,這樣地址總線在進行同步過程中出錯不可避免,比如寫地址在從0111到1000轉換時4條地址線同時跳變,這樣讀時鐘在進行寫地址同步後得到的寫地址可能是0000-1111的某個值,這個完全不能確定,所以用這個同步後的寫地址進行FIFO空判斷的時候難免出錯。

這個時候gray碼體現了價值,一次只有一位數據發生變化,這樣在進行地址同步的時候,只有兩種情況:

1.地址同步正確;
2.地址同步出錯,但是隻有1位出錯;

第一種正確的情況不需要分析,我們關注第二種,假設寫地址從000->001,讀時鐘域同步出錯,寫地址爲000->000,也就是地址沒有跳變,但是用這個錯誤的寫地址去做空判斷不會出錯,最多是讓空標誌在FIFO不是真正空的時候產生,而不會出現空讀的情形。所以gray碼保證的是同步後的讀寫地址即使在出錯的情形下依然能夠保證FIFO功能的正確性,當然同步後的讀寫地址出錯總是存在的(因爲時鐘異步,採樣點不確定)。這裏需要注意gray碼只是在相鄰兩次跳變之間纔會出現只有1位數據不一致的情形,超過兩個週期則不一定,所有地址總線bus skew一定不能超過一個週期,否則可能出現gray碼多位數據跳變的情況,這個時候gray碼就失去了作用,因爲這時候同步後的地址已經不能保證只有1位跳變了。

另外需要將地址總線打兩拍,這是爲了避免亞穩態傳播,理論上將打兩拍不能消除亞穩態現象,因爲時鐘異步,亞穩態不可避免,但是可以極大降低亞穩態傳播的概率,低頻情況下甚至STA不需要分析這裏的異步時序,因爲寄存器都可以在一拍內將亞穩態消除,恢復到正常0/1態。而在高頻情況下則不一定,尤其在28nm工藝以下,需要檢查兩級觸發器的延遲,保證延遲低,這樣可以提高Tr,提高系統MTBF。

參考

1、寫是讀的100倍

  • 需要考慮FIFO的設計深度,考慮突發的寫入任務不會導致FIFO溢出。
  • 寫快讀慢,主要考慮的是寫滿(full)的情況。在寫操作在快時鐘域下,讀地址被寫時鐘同步一拍(從慢時鐘域到快時鐘域,使用兩級寄存器減小亞穩態),如果存在亞穩態,那麼寫入時鐘獲取的是上一次的讀地址,最多出現虛滿的情況(實際上還差一個才滿)。所以這方面不會出現問題。
  • 考慮讀空(empty)的情況,地址從快時鐘到慢時鐘,在讀時鐘下更新地址時,可能已經寫入好幾個數據了,若此時判斷爲空,顯然就是虛空。所以這方面也不會出現問題。

2、讀是寫的100倍

  • 讀快寫慢,所以很容易出現讀空的情況。讀空時數據的有效輸出不是連續的,如果需要進行相關運算的話,就可能會產生影響(比如乘法器就不需要查看有效標誌);如果後續只是數據傳輸,則不會導致數據丟失或出錯等問題。
  • 當然,雖然讀時鐘很快,但是讀使能卻可以拉低讀的頻率(可以假設不讀),這樣也可能導致寫滿,但由於格雷碼的使用,最多出現虛滿或剛好滿的情況,不會導致數據溢出,因此也沒有問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章