關於FIFO的一些問題

2021-08-25 22:45:52 字數 4414 閱讀 4465

q1:rdclk和wrclk差距較大時,是否會造成multi-bit的問題?是否會造成跳過了full而full+1的狀態漏過滿?

a1:總結一下幾點:

1.慢時鐘採快時鐘會出現漏採,雖然不會出現功能錯誤,但是將空滿新號的判斷變得更為保守,效率因此會i降低。

2.由於出現漏採,快時鐘的讀/寫指標sync到慢時鐘時,gray code就不是按照1次變化1個bit的方式進行了,而是有可能一次變化好幾個bit,這樣gray code的好處就體現不出來了。

非同步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,可以把hold理解成將訊號延時)。把當前資料牢牢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並不會有實際的行為出錯,所以也不需要解決這個問題。

q2: 亞穩態真的消除了嗎?如果真的出現亞穩態,你的fifo還能用嗎?

a2: 通過使用格雷碼,我們可以降低亞穩態出現的可能性,但是不能說是真的消除了。   如果出現亞穩態,fifo還是能夠繼續使用,原因很簡單:舉個列子,寫快讀慢,我們來看看full訊號的產生,只有當讀位址變化的時候(觸發器的輸入變化的時候才會出現亞穩態,而且由於是慢到快,就算出現亞穩態,因為相鄰位的格雷碼每次只有一位變化,這個出錯結果實際上也就是讀指標沒有跳變保持不變,),亞穩態才會產生,這個時侯意味著我又讀了乙個資料,所以即使傳遞過去後產生了full訊號,也沒有出現溢位的問題,因為傳遞的時候讀是至少又讀了乙個資料的。(由快到慢就跟不會出現讀空了,寫位址同步過去的時候也會寫好幾次,)

在涉及到觸發器的電路中,亞穩態無法徹底消除,只能想辦法將其發生的概率將到最低。其中的乙個方法就是使用格雷碼。格雷碼在相鄰的兩個碼元之間只由一位變換(二進位製碼在很多情況下是很多碼元在同時變化)。這就會避免計數器與時鐘同步的時候發生亞穩態現象。但是格雷碼有個缺點就是只能定義2^n的深度,而不能像二進位製碼那樣隨意的定義fifo的深度,因為格雷碼必須迴圈乙個2^n,否則就不能保證兩個相鄰碼元之間相差一位的條件,因此也就不是真正的格雷碼了。第二就是使用冗餘的觸發器,假設乙個觸發器發生亞穩態的概率為p,那麼兩個級聯的觸發器發生亞穩態的概率就為p的平方。但這會導致延時的增加。亞穩態的發生會使得fifo出現錯誤,讀/寫時鐘取樣的位址指標會與真實的值之間不同,這就導致寫入或讀出的位址錯誤。由於考慮延時的作用,空/滿標誌的產生並不一定出現在fifo真的空/滿時才出現。可能fifo還未空/滿時就出現了空/滿標誌。這並沒有什麼不好,只要保證fifo不出現overflow or underflow 就ok了。

q3:格雷碼的軸對稱問題

a3:1.映象對稱的原因是為了每乙個相鄰的變化都是只有1bit,為了滿足0000(0)和1000(15)也只有1bit發生變化。

2.格雷碼位址直接比較去判斷寫滿讀空,

當最高位和次高位相同,其餘位相同認為是讀空

當最高位和次高位不同,其餘位相同認為是寫滿

3.格雷碼位址直接當作ram的位址,由於格雷碼遞增時都是唯一的,雖然在ram裡時散亂的排布,但是依舊可以正確儲存

因為格雷碼是映象對稱的,若只根據最高位是否相同來區分是讀空還是寫滿是有問題的,詳情我會慢慢說,請看圖 1

綠色框起來的是0--15的格雷碼,用紅線將格雷碼分為上下兩部分

通過觀察格雷碼相鄰位每次只有1位發生變化,且上下兩部分,除了最高位相反,其餘位全都關於紅線映象對稱,

7 --> 8 ,格雷碼從 0100 --> 1100 ,只有最高位發生變化其餘位相同

6 --> 9  , 格雷碼從 0101 --> 1101 , 只有最高位發生變化其餘位相同

以此類推,為什麼要說映象對稱呢?

試想如果讀指標指向 8,寫指標指向 7 ,我們可以知道此時此刻並不是讀空狀態也不是寫滿狀態

但是如果在此刻套用理論 1 來判斷,看會出現什麼情況,我們來套一下

7的格雷碼與8的格雷碼的最高位不同,其餘位相同,所以判斷出為寫滿。這就出現誤判了,同樣套用在 6 和 9,5 和 10等也會出現誤判。

因此用格雷碼判斷是否為讀空或寫滿時應使用理論 2,看最高位和次高位是否相等,具體如下:

當最高位和次高位相同,其餘位相同認為是讀空

當最高位和次高位不同,其餘位相同認為是寫滿

補:理論2這個判斷方法適用於用格雷碼判斷比較空滿

在實際設計中如果不想用格雷碼比較,就可以利用格雷碼將讀寫位址同步到乙個時鐘域後再將格雷碼再次轉化成二進位制數再用理論1進行比較就好了。。

圖 1

附幾個fifo的問題:

例如:非同步fifo一些要點:

非同步fifo的時序約束也是非常麻煩的,不要認為整個格雷碼跨時鐘域就可搞定,而且是可靠的,那是理想情況,實際的情況每bit延時都是不一樣的,會給時序造成很大困擾。

關於面試的一些問題

面試過程中,面試官會向應聘者發問,而應聘者的回答將成為面試官考慮是否接受他的重要依據。對應聘者而言,了解這些問題背後的 貓膩 至關重要。本文對面試中經常出現的一些典型問題進行了整理,並給出相應的回答思路和參 讀者無需過分關注分析的細節,關鍵是要從這些分析中 悟 出面試的規律及回答問題的思維方式,達到...

關於Labview的一些問題

第一章 虛擬儀器及 labview入門 1 虛擬儀器概述 虛擬儀器 virtual instrumention 是基於計算機的儀器。計算機和儀器的密切結合是目前儀器發展的乙個重要方向。粗略地說這種結合有兩種方式,一種是將計算機裝入儀器,其典型的例子就是所謂智慧型化的儀器。隨著計算機功能的日益強大以及...

關於DropDownList的一些問題

dropdownlist選擇後提示不能在dropdownlist選擇多項 原因在於drop.selected true 用的是item的引用,無法覆蓋上次操作 有2種方法 一種是直接drop.selectvalue value 選定指定資料 另一種是在操作前 呼叫clearselection 方法清...