多bit數據流跨時鐘域傳輸
數據流和指示信號不同:
- 數據流大多具有連續性,即背靠背傳輸;
- 數據流要求信號具有較快的傳輸速度
解決方法:
- SRAM : 簡單,不詳述
- 異步FIFO
FIFO(first in first out)
FIFO 是一種先進先出的儲存結構 與普通存儲器的區別:
- 沒有外部讀寫地址線
- 使用簡單
缺點
- 只能順序寫入數據,順序的讀出數據,其數據地址由內部讀寫指針自動加1完成,不能像普通存儲器那樣可以由地址線決定讀取或寫入某個指定的地址。
在IC設計中,模塊與模塊之間的通信設計中,多時鐘的情況已經不可避免;數據在不同時鐘域之間的傳輸很容易引起亞穩態;異步FIFO就是一種簡單、快捷的解決方案。
FIFO的功能類似于一個調節上下游水量的一個 蓄水池 。FIFO的上游結點是FIFO的數據輸入端,在寫信號有效時,數據將被寫入FIFO,由FIFO內部的寫指針控制,并且在FIFO內部,寫指針遞增一個單元,同時FIFO的滿信號(FIFO full Signal)將控制上游結點是否發送數據;FIFO的下游節點是FIFO的數據輸出端,當讀信號有效時,FIFO中的數據將被讀出,由FIFO內部的讀指針控制,并且在FIFO內部讀指針遞增一個單元,同時FIFO空信號(FIFO empty Signal))將控制下游節點是否讀出數據。如果FIFO內部的空間已經被寫滿,則實時生成滿信號,以反壓上游節點,上游節點停止寫新的數據進來,否則就會把已經寫好的數據沖掉。如果FIFO內部的數據全部被讀,則實時生成空信號,控制下游節點不再進行數據讀操作。否則,下游節點就會將讀過的數據重新再讀一遍。從這里也可以看出,空信號和滿信號對于FIFO的控制非常重要。
FIFO用途
- 用異步FIFO讀寫分別采用相互異步的不同時鐘
在現代集成電路芯片中,隨著設計規模的不斷擴大,一個系統中往往含有數個時鐘多時鐘域帶來的一個問題就是,如何設計異步時鐘之間的接口電路。異步FIFO是這個問題的一種簡便、快捷的解決方案,使用異步FIFO可以在兩個不同時鐘系統之間快速而方便地傳輸實時數據。 - 對于不同寬度的數據接口也可以用FIFO 例如單片機位8位數據輸出,而DSP可能是16位數據輸入,在單片機與DSP連接時就可以使用FIFO來達到數據匹配的目的。
FIFO類型
- 同步FIFO : 指讀時鐘和寫時鐘為同一個時鐘,在時鐘沿來臨時同時發生讀寫操作
- 異步FIFO : 指讀寫時鐘不一致,讀寫時鐘是互相獨立的。
FIFO的設計對調節上下游的吞吐量平衡具有非常重要的作用
FIFO常見參數
- FIFO的寬度:即FIFO一次讀寫操作的數據位:
- FIFO的深度:指的是FIFO可以存儲多少個N位的數據(如果寬度為N)。FIFO的深度相當于蓄水池的容量,如果過小,則上游節點總是接收滿信號,使得系統的數據吞吐量降低。如果過大,則浪費空間太多。因此,FIFO的深度是一個很關鍵的參數。
- 滿標志:FIFO已滿或將要滿時由FIFO的狀態電路送出的一個信號,以阻止FIFO的寫操作繼續向FIFO中寫數據而造成溢出(overflow).
- 空標志:FIFO已空或將要空時由FIFO的狀態電路送出的一個信號,以阻止FIFO的讀操作繼續從FIFO中讀出數據而造成無效數據的讀出(underflow)。如我們前面講述,空滿標志非常重要。本節我們重點討論如何設計空滿標志位電路。
- 讀時鐘:讀操作所遵循的時鐘,在每個時鐘沿來臨時讀數據。
- 寫時鐘:寫操作所遵循的時鐘,在每個時鐘沿來臨時寫數據。在FIFO中,這兩個時鐘通常都不相同,而且以異步時鐘。
FIFO的總體結構
結構如下:
image-20221009122620242
- 雙端口SRAM,用來存儲上游節點寫入的數據wdata,下游節點用rdata將其讀出.SRAM的 讀寫地址采用了每次只遞增1的機制 ,保證了寫入和讀出按順序進行,寫和讀到最高地址后,重新返回零地址。
- 在上游節點和SRAM之間有一個 滿信號生成電路 ,這個電路通過判斷寫時鐘域下,寫指針和讀指針的關系,然后實時生成滿信號w1,以通知上游節點停止寫操作。
- 同樣地,在下游節點和SRAM之間有一個 空信號生成電路 ,這個電路通過判斷讀時鐘域下,寫指針和讀指針的關系,然后實時生成空信號empty,以通知下游節點停止讀操作。
- 這兩個模塊的工作機制是我們要重點關注的。這里還需要注意的是,將讀 指針傳遞到寫時鐘域才能產生滿信號 ,將 寫指針傳遞到讀時鐘域才能產生空信號 ,因此,這里就涉及到如何處理信號傳輸的亞穩態問題。
設計關鍵:
- 亞穩態的消除
- 空滿狀態的判斷-> 正確的產生空滿標志是任何FIFO設計的關鍵
- 空滿狀態產生的原則是:寫滿而不溢出,能讀空而不多讀。
空滿狀態的判斷
讀寫指針相等 會觸發滿還是空,得看讀寫的指針方向是怎樣的
空狀態
當讀寫指針相等時,表明FIFO為空,這種情況發生在復位操作時或者當讀指針讀出FIFO中最后一個字后,追趕上了寫指針;
當讀寫地址相等時,說明已經寫入的數據,已經全部被讀走,此時,FIFO還尚未有新的數據寫入,說明FIFO為空,這種情況發生在復位操作時,或者當讀地址讀出FIFO中最后一個字后,追趕上了寫地址。如果兩個指針的MSB相同,則說明兩個指針折回的次數相等。其余位相等,說明FIFO為空
滿狀態
滿狀態。當寫地址超過讀地址,寫到最高地址后,重新從0開始寫,再次追上了讀地址。此時,讀地址已經讀過的地址空間,再一次被寫地址寫入。而讀地址到最高地址之間的數據,還尚未被讀。說明此時FIFO處于滿的狀態。如果兩個指針的MSB不同,說明寫指針比讀指針多折回了一次;如raddr=0000,而w_addr=1000,為滿。
區別滿和空狀態
- 在地址中添加一個額外的位(extra bit),當 寫指針增加并越過最后一個FIFO地址時,就將寫指針這個未用的MSB加1 , 其它位回零 。對讀指針也進行同樣的操作。此時,對于深度為2”的FIFO,需要的讀/寫指針位寬為(n+1)位,如對于深度為8的FIFO,需要采用4bit的計數器,0000
1000、100111111 MSB作為折回標志位,而低3位作為地址指針。 - 如果兩個指針的MSB不同,說明寫指針比讀指針多折回了一次;如r_addr=0000,而w_addr = 1000,為滿。
- 如果兩個指針的MSB相同,則說明兩個指針折回的次數相等。其余位相等,說明FIFO為空。
- 空滿標志生成的前提是:
- 讀指針被傳遞到了寫時鐘域
- 寫指針被傳遞到了讀時鐘域
介入格雷碼
在上一節中說過, 多bit信號是不能直接通過這種打兩拍進行同步的 ,所以我們需要采用格雷碼進行傳輸。傳輸讀寫指針之前,需要將其先由二進制轉為格雷碼,然后再發送到對方的時鐘域下。
格雷碼特點:
- 格雷碼相鄰的2個數值之間只會有一位發生變化,其余各位都相同 ;
- 格雷碼是一種循環碼和最大數(2的n次方減1)之間也只有一位不同。
引用格雷碼之后,相鄰值只有1位發生翻轉,1位翻轉所引起的亞穩態的概率遠遠要小于幾位同時翻轉所引起的概率;因此, 格雷碼能很好的亞穩態出現的概率 。
轉化方法:
- 二進制碼轉化為格雷碼:從最右邊第一位開始,依次將每一位與左鄰一位異或(XOR),作為對應格雷碼該位的值,最左邊一位不變;
- 格雷碼轉化為二進制碼:從左邊第二位起,將每位與左邊一位解碼后的值異或(XOR),作為該位解碼后的值(最左邊一位依然不變)。
格雷碼下的空滿判斷
- 如果采用格雷碼,對于“空"的判斷依然依據二者完全相等。
- 對于“滿"的判斷,由于格雷碼除了MSB外,具有鏡像對稱的特點,當讀指針指向7,寫指針指向8時,注意地址增加到最大地址7時,然后會返回0, 所以此處8和0雖然輪次不同,但是實際上是同一個地址 。此時,除了MSB,其余位皆相同,就不能說它為滿。在格雷碼上判斷為滿必須同時滿足以下3條:wptr和同步過來的rptr的MSB不相等,因為wptr必須比rptr多折回一次;wptr與rptr的次高位不相等;剩下的其余位完全相等。
所以在gray碼上判斷為滿必須同時滿足以下三條:
- wptr和同步過來的rptr的MSB不相等,因為wptr必須比rptr多折回一次。
- wptr與rptr的次高位不相等,如上圖位置7和位置15,轉化為二進制對應的是0111和1111,MSB不同說明多折回一次,111相同代表同一位置。
- 剩下的其余位完全相等。
當FIFO深度不為2的次冪時
當FIFO深度不為2的次冪時,格雷碼的翻轉變化就不是1 bit了
假設FIFO深度為8,則讀寫指針可采用格雷碼進行編碼;
假設FIFO深度為6,如果讀寫指針繼續采用格雷碼,那么當前首尾指針的所有比特位都不相同,此時,如果從尾部返回首部,則無法實現消除亞穩態的目的。
此時,首地址是000,尾地址為111,沒辦法消除亞穩態。解決方法:
- 可將地址為5的指針設定為100,此時其與首地址的指針“000”相差一個bit位,與地址為4的指針“110”也相差一個bit位,滿足消除亞穩態的要求。
怎么設計讀寫指針的編碼
- 并不是一定要用格雷碼做讀寫指針,而是當深度為2次冪的時候,剛好格雷碼滿足消除亞穩態的需求;
- 在非2次冪深度情況下,格雷碼已經不再適用,此時的解決方法通常有:
- 若深度為偶數,可采用最接近的2次冪的格雷碼編碼,在此基礎上修改;
- 深度為一般數值時,可自行設計一種邏輯電路,或者查找表,以實現指針每次只跳變一次的功能;
- 以上方法通常在設計層面較為復雜,若無特定需求,可將FIFO深度設置為2次冪,浪費一些存儲空間,來化簡控制電路的復雜度。
FIFO深度設計
面試題++
例題1
假設FIFO的寫時鐘為100 MHz,讀時鐘為80 MHz。在FIFO輸入側,每100個寫時鐘,寫入80個數據;讀數據側,假定每個時鐘讀走一個數據。
請問FIFO深度設置多少可以保證FIFO不會上溢出和下溢出?
對圖,先找到最重載的情況:
最長burst寫入時間為:
這段時間能 最小讀走的數據量 :
這樣就可以得到在 最差情況下留在FIFO中的數據 :
抽象一下:
寫時鐘頻率為WCLK:讀時鐘頻率為RCLK:寫時每B個時鐘周期內會有A個數據寫入FIFO,說明寫入效率是A/B,讀時每Y個時鐘周期內會有X個數據讀出FIFO,說明讀出效率是X/Y。這種情況下,FIFO的最小深度是多少?
(burst_length/WCLK)表示這個burst的持續時間,持續時間乘以讀時鐘頻率,可知道讀數據在效率100%的時候的讀出數據個數,然后再乘以讀數據效率X/Y)則可知道在bust時間段內讀出了多少數據。burst length與這個讀出數據的差值,FIFO中殘留的數據,這個也就是理論上的FIFO的最小深度。
FIFO中的亞穩態問題
這里會結合上一節對異步FIFO進行分析:
- 亞穩態不能從根本上消除 ,但可以通過采取一定的措施使其對電路造成的影響降低。
為什么優先用格雷碼做讀寫指針編碼
如果指針為格雷碼,失效的后果?
格雷碼一次只有一位數據發生變化,這樣在進行地址同步的時候,只有兩種情況:
也就是地址沒有跳變,但是用這個錯誤的寫地址去做空判斷不會出錯,最多是讓空標志在FIFO不是真正空的時候產生,而不會出現空讀的情形。
所以,gray碼保證的是同步后的讀寫地址即使在出錯的情形下依然能夠保證FIFO功能的正確性,當然同步后的讀寫地址出錯總是存在的。
需要注意gray碼只是在相鄰兩次跳變之間才會出現只有1位數據不一致的情形超過兩個周期則不一定,所以,地址總線bus skew一定不能超過一個周期,否則可能出現gray碼多位數據跳變的情況,這個時候gray碼就失去了作用,因為這時候同步后的地址已經不能保證只有1位跳變了。
兩拍同步或多拍同步的差異
將地址總線打兩拍 -> 為了避免亞穩態傳播
但是并不能消除亞穩態:
- 因為時鐘異步,亞穩態不可避免,但是可以極大降低亞穩態傳播的概率,
在低頻情況下:
STA不需要分析這里的異步時序,因為寄存器都可以在一拍內將亞穩態消除,恢復到正常0/1態。
在高頻情況下:
不一定,尤其在 28nm工藝以下,需要檢查兩級觸發器的延遲 ,保證延遲低,提高系統MTBF。
對多拍同步,能夠進一步將亞穩態出現的概率降低
空滿標志的判斷方法是否漏洞
對打兩拍后,讀寫指針的動作為:
- rptr同步**兩個“wclk”**后,在wclk時鐘域與wptr進行比較,生成full信號
- wptr同步**兩個“rclk”**后,在rclk時鐘域與rptr進行比較,生成empty信號
假設讀寫時鐘頻率接近
這個時候看滿的時候并不是真滿,因為此時又都走了兩個數據
結論:
- 對于full信號的生成機制,同步后的讀地址一定是小于或者等于當前的讀地址,所以此時判斷FIFO為滿不一定是真滿,這樣更保守;
- Empty信號的機制同樣成立,“空”時,不一定是真“空”。
- 異步FIFO通過比較讀寫地址進行滿空判斷,但是讀寫地址屬于不同的時鐘域,所以在比較之前需要先將讀寫地址進行同步處理,此機制保證了FIFO在空滿極限情況下,依然留有余量,存在一定的冗余空間。
頻率相差較大時,同步時間可以
如何對FIFO進行邏輯綜合和靜態時序分析
模塊劃分:
在低頻情況:
- 設置wclk和rclk之間的false path
在高頻情況下:
- 尤其在28 nm工藝以下,需要檢查兩級觸發器的延遲,保證延遲低;
在布局布線(P&R)時
- 要注意將兩級同步器放置在一起,不要被工具自動分開
評論
查看更多