無論是數據通訊或者SOC(包括FPGA或者ASIC設計)設計,跨時鐘域(clock domain crossing)處理都是一件讓人很頭疼的事情,無論是在設計的前端或者步入設計的后端,都沒有很好的工具去做保證,只能靠設計人員的經驗進行最大的保證,然而這個問題如果處理不好,你的整個設計可能就完全報廢,而最怕的是你的設計時好時壞,有時穩定,有時出錯,這個時候你甚至很難進行定位(尤其是上了FPGA開發板或者芯片已經tapout了)。
一般而言,處理跨時鐘域的方法有這么幾種(大家在網上也都能找到資料,這些資料大都來自幾篇經典的論文,中文方面的資料大都是翻譯過著理解這幾篇論文而來):少量的數據用邊沿檢測電路,或者脈沖檢測電路,或者電平檢測電路,或者兩級觸發器;比較多的數據時用異步FIFO。
本文側重講解本人對異步FIFO的深入理解,講解兩種經典的異步FIFO的設計方案,這兩種方案來自一篇文章《simulation and synthesis techniques for asynchronous FIFO design》,大家可自行下載,設計思路這篇文章里面介紹的很詳細,解釋的也很出色,我更多的是談談我的部分理解。
1、異步FIFO設計的難點在哪里
1)寫地址和讀地址處于不同的時鐘域,如何比對寫地址和讀地址才能正確的產生空滿信號;
2)當讀寫地址相同時,究竟是讀空了還是寫滿了(因為存在你追我趕的情況,類似于一個圓環)。
2、處理思路
1)對于難點1大家自然想到采用同步處理的方式,具體為將寫地址或者讀地址同步(例如利用兩級觸發器)到對方的時鐘域中,在相同的時鐘域中進行地址的比對,但是由于寫地址和讀地址很多時候并不止1bit,同時進行同步處理會增大錯誤的概率(如地址按0111->1000跳變,此時4bit都在變化,DFF進行同步時就很容易出錯),因而可以先將地址(二進制的)轉換為格雷碼(相鄰數據之間只有一個bit在變化),然后再進行同步,最后進行對比,這樣會大大減少錯誤的概率。
2)對于難點2可以在地址前面添加1bit用于標志位進行區分,例如復位時,讀寫地址的標志位都是0,如果寫完1輪而開始新的一輪時就將寫地址的標志位換為1(讀也同樣道理變換),這樣可以通過判斷標志位加上對比地址判斷是空還是滿,具體為當讀寫地址的標志位相同讀寫地址相同時為讀空,具體為當讀寫地址的標志位不同讀寫地址相同時為寫滿;另外也可以利用格雷碼的最高兩位00->01->10->11進行相位的區分,具體參考我給出的文章或者網絡資料,其實本質上和上面的是一個道理。
3、經典FIFO設計方案的解讀
1)同步讀寫地址(經格雷碼轉換后)到對方的時鐘域
相比于直接同步二信號進制地址(先用握手,然后同步二進制地址)好處是格雷碼相鄰數據之間只有一個bit在變化,而二進制由于寫地址和讀地址很多時候并不止1bit,同時進行同步處理會增大錯誤的概率(如地址按0111->1000跳變,此時4bit都在變化,DFF進行同步時就很容易出錯);利用格雷碼進行同步,即使發生同步的時出錯也不會造成overrun和underrun的情況(因為同步后的數據必定小于等于同步前的數據,即只可能1被同步為0,而不可能0被同步為1),例如當前的讀地址到了6,寫地址到了8,地址8經過同步后出錯而變成了6,這時會出現地址相同而判斷為讀空,不過沒關系,讀空則不讀,至少不會出現underrun的情況,隨著時間的推移地址8總會被采樣到;然而格雷碼也有缺點,只能連續變化遞增或者遞減(如果間隔變化就不符合格雷碼的特點了),所以設計的深度必須是2的n次冪,如果不是的話,需要重新產生編碼格雷碼,否則也會出現間隔變化不符合相鄰之間只有1bit變化的特點。
2)將讀寫地址(經格雷碼轉換后)同步到一個組合邏輯電路中(異步比較)直接比較空滿,然后將空滿信號同步到各自對應的模塊中
雖然這種電路會給fifo帶來不好的狀態,例如已經滿了wfull==1,但是這個時候讀走一個數據,由于同步的延時性,導致這一段時間內wfull==1一直不變(如果沒有同步帶來的延時應該變為0的),rempty也會遇到同樣的問題,但是這種電路不會出現underrun和overrun的情況。
3)2)相比1)可能會節省面積,因為1)同步wptr[n-1:0]和rptr[n-1:0],2)只需要同步afull_n,aempty_n;1)的速率可能較2)會快些,2)中存在異步且組合邏輯比較,不利于時序的優化。
-
fifo
+關注
關注
3文章
389瀏覽量
43857 -
數據通訊
+關注
關注
0文章
45瀏覽量
11909
發布評論請先 登錄
相關推薦
評論