非同步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。
原文
非同步FIFO格雷碼與空滿
在傳遞讀寫時鐘域的指標使用格雷碼來傳遞,如何把二進位制轉換為格雷碼,格雷碼是如何判斷讀空寫滿呢?二進位製碼轉換成二進位制格雷碼,其法則是保留二進位製碼的最高位作為格雷碼的最高位,而次高位格雷碼為二進位製碼的高位與次高位相異或,而格雷碼其餘各位與次高位的求法相類似。這樣就可以實現二進位製到格雷碼的轉換...
迴圈佇列判斷滿與空
何時隊列為空?何時為滿?由於入隊時尾指標向前追趕頭指標,出隊時頭指標向前追趕尾指標,故隊空和隊滿時頭尾指標均相等。因此,我們無法通過front rear 來判斷佇列 空 還是 滿 注 先進入的為 頭 後進入的為 尾 解決此問題的方法至少有三種 其一是另設乙個布林變數以匹別佇列的空和滿 其二是少用乙個...
棧與佇列 判斷棧 隊列為空 滿
陣列棧 完成int isempty stack s 函式,該函式判斷棧是否已空,如果空返回1,否則返回0。完成int isfull stack s 函式,該函式判斷棧是否已滿,如果滿返回1,否則返回0。typedef int elemtype struct stackrecord typedef s...