歡迎關注個人公眾號摸魚范式
------------------------------------------
版權聲明:
本文作者: 烓圍瑋未
首發於知乎專欄:芯片設計進階之路
轉發無需授權,請保留這段聲明。
------------------------------------------
單bit信號跨時鍾域的處理
信號跨時鍾域,根據兩個異步時鍾之間的關系可以分為:
- 信號從快時鍾域到慢時鍾域;
- 信號從慢時鍾域到快時鍾域;
單bit信號一般采用同步器來做CDC。這里要指出的一點是,由於在CDC時,會在源時鍾域做寄存輸出,所以信號的變化頻率不會超過源時鍾的頻率(請參考《亞穩態和同步器》),所以這里能夠以兩個時鍾之間的快慢來分類。
快時鍾域到慢時鍾域
快時鍾到慢時鍾CDC問題
信號從快時鍾到慢時鍾CDC如下圖所示
上圖顯示了當在一個時鍾域(aclk)中生成的信號adat被送到了另一個時鍾域(bclk)中采樣,由於采樣時間太靠近第二個時鍾的上升沿時,發生的同步失敗。同步失敗是由於輸出bdat1變為亞穩態,而在bdat1再次被采樣時沒有收斂到合法的穩定狀態。
這里注意一下,如果是電平信號進行CDC, 那么不用考慮時鍾快慢,直接用同步器就可以了,因為總能被采樣到。所以,下面考慮的主要是信號位寬有限的CDC。
快時鍾到慢時鍾的(單bit)信號處理,主要問題就是信號在快時鍾域中,可能會多次改變,這樣慢時鍾可能來不及采樣,導致丟失數據。這個問題被稱為信號寬度問題,在CDC檢查工具中,如果快時鍾的信號寬度不足,會報出CDC違例。
快時鍾到慢時鍾的(單bit)信號處理分為兩種:
-
采樣丟失是被允許的。單bit信號一般不會是這種情況,如果是這種情況,直接用同步器同步就可以了。
-
采樣丟失不被允許。這樣就要采樣其他手段來保證數據不丟失。主要原理是保證快時鍾域的信號寬度滿足一定的條件,使得慢時鍾域有足夠時間采樣到。
信號寬度的“三時鍾沿”要求
那么信號在快時鍾域到底需要多寬,才能保證在慢時鍾域安全的被采樣到呢?比較安全的寬度是,快時鍾域的信號寬度必須是慢時鍾域時鍾周期的1.5倍以上。也就是要持續3個時鍾沿以上(上升沿和下降沿都算)。這個被稱為:“三時鍾沿”要求。
下面是一個CDC信號只持續一個周期的例子:
發送時鍾域的頻率高於接收時鍾域,而CDC脈沖在發送時鍾域中只有一個周期寬,這樣CDC信號可以在慢時鍾上升沿之間變動,不會被捕獲到慢時鍾域,如下圖所示
如果CDC信號寬度超過慢時鍾周期,但是不足1.5個周期,也會發生問題。如下圖所示
如上圖所示,信號寬度超過了一個慢時鍾周期,但是可能會setup和hold time違例,導致信號采樣失敗。
信號寬度問題的解決方法
一種最簡單的方法是,通過保證信號寬度滿足超過慢時鍾的時鍾周期1.5倍,來解決這個問題。這種方法是最直接,也是跨時鍾最快的方法。可以通過system Verilog加“斷言”的方式來檢測是否滿足條件。
但是實際中很少用這種方式,因為設計可能會變,設計人員在改變設計時,可能會忘記這個限制,以為是一個通用的解決方法。
所以,常用的還是通過“握手”的方式來保證數據被采樣到。
通常的做法是:是發送一個使能控制信號,將它同步到新的時鍾域,然后通過另一個同步器將同步信號作為確認信號傳回發送時鍾域。如下圖所示:
優點:
同步反饋信號是一種非常安全的技術,可以識別第一個控制信號並將其采樣到新的時鍾域中。
缺點:
在允許控制信號改變之前,在兩個方向上同步控制信號可能會有相當大的延遲。也就是說,在應答信號到來之前,是不允許源信號改變的。
在實際的芯片設計中,脈沖(寬度有限)信號的同步都是采用這種握手機制來處理。
慢時鍾到快時鍾域
慢時鍾域到快時鍾域的CDC, 直接使用信號同步器就可以了。具體邏輯可以參考《亞穩態和同步器》。
但是,這里有一點要指出來,那就是怎么才算慢時鍾域到快時鍾域的CDC呢?這里和平常理解的有點不一樣。
目標時鍾頻率必須是源時鍾頻率1.5倍或者以上,才能算慢時鍾到快時鍾的CDC.
這也很好理解,只有滿足快1.5倍以上,才能滿足“三時鍾沿”的要求,才能保證快時鍾域保證能夠采樣到慢時鍾域的脈沖。
如果目標時鍾域只快一點,比如1~1.5倍之內,為了保險起見,請按照快時鍾到慢時鍾域的處理方法來處理。
另外,有的設計中為了保險和以后修改的方便;或者還不清楚時鍾之間的關系;都會按照快時鍾到慢時鍾域的的方式來進行單bit的CDC處理。
多bit信號跨時鍾域的處理
在兩個時鍾域之間傳遞多個信號,簡單的同步器已經不能滿足要求。
工程師經常容易犯的錯誤是,直接用簡單同步器來同步多個信號。如下圖所示:
這里列出理兩個信號分別通過同步器同步后,在目標時鍾域聚合后使用的三種場景。問題是兩個同步器,跨時鍾的延時可能不一樣,比如信號從2’b00->2’b11, 上面的同步器花了2個周期同步到了目標時鍾域;下面的同步器花了3個周期才同步到目標時鍾域。那么在第二和第三周期之間,就出現了2’b10的值了,即出現了錯誤的采樣信號,這樣功能有可能就不正確了。
如果不明白,為什么同步器的同步延時會不一樣,可以參考可以參考《亞穩態和同步器》。
另外,不同同步器的芯片上的走線也可能不同,導致延時不一樣。即使我們完美的控制后端不同bit同步信號的走線長度一樣,同一個die上面不同芯片之間或者不同制程之間的偏差,都可能引入差異,導致多bit信號的延時不同。而且這樣對后端走線難度增大。
考慮到以上兩點,多個信號的CDC一般不用簡單同步器的方法。在CDC檢查時,會有專門的規則來檢查是否采樣了多bit信號用同步器同步聚合使用的情況。
為了避免多位CDC傾斜采樣的情況,多個信號CDC策略可以分為三種:
-
多個信號合並。在可能的情況下,將多個CDC位合並為1位CDC信號。
-
多周期路徑法。使用同步負載信號安全地傳遞多個CDC位。
-
使用格雷碼傳遞多個CDC位。
-
使用異步FIFO來傳遞多位信號。
多個信號合並
在可能的情況下,將多個CDC信號合並為一個1位的CDC信號。有些時候,並不需要將多個信號來做CDC。下面是兩個多個信號合並為一位信號做CDC的例子。這里
例子1:
下圖所示的簡單示例中,接收時鍾域中的寄存器需要加載信號和使能信號才能將數據值加載到寄存器中。如果負載和使能信號都是在同一個發送時鍾邊緣上驅動的,那么控制信號之間的小偏差就有可能導致兩個信號在接收時鍾域中同步到不同的時鍾周期。在這種情況下,數據不會被加載到寄存器中,就會出問題。
解決方法也很簡單,將控制信號b_load和b_en合起來:b_lden=b_load & b_en 同步到aclk域中。
例子2:
下面是另外一個例子:
下圖中的顯示了兩個使能信號,aen1和aen2,它們從發送時鍾域依次驅動到接收時鍾域,以控制流水線數據寄存器的使能輸入。問題是同步器並不能保證兩個cycle就一定能同步過來,下面的同步器花了3個cycle才同步完成數據,導致流水線寄存器不能“流水”起來。
該問題的解決方案是只向接收時鍾域發送一個控制信號,並在接收時鍾域內生成第二個相移流水線使能信號。如下圖所示:
多周期路徑(Multi-Cycle Path, MCP)
下圖中顯示了在時鍾域之間傳遞的兩個編碼控制信號。如果這兩個編碼信號在采樣時略有偏差,則在接收時鍾域中的一個時鍾周期內可能會產生錯誤的解碼輸出。
多位數據問題可以用“多周期路徑法(MCP)”來解決。
MCP方法是指直接不同步將數據發生到目標時鍾域,但是同時送一個同步過的控制信號到目標時鍾域。數據和控制信號同時發送,允許數據在目標寄存器的輸入端進行設置,同時控制信號在到達目標寄存器的負載輸入端之前做同步。
MCP方法的優點:
(1)不需要在發送時鍾域計算適當的脈沖寬度
(2)發送時鍾域只需要將enable toggle到接收時鍾域,表示數據已經被傳遞完成,已經准備好被加載。使能信號不需要返回到初始邏輯電平。
MCP方法的實質就是,不同步多位的數據,只同步一位的控制信號,通過握手保證控制信號能夠正確傳輸,然后在目標時鍾域通過控制信號來采樣數據。
MCP需要用到“同步脈沖器”:
同步脈沖器的符號表示如下:
多周期路徑法有兩種方法來傳遞多位信號:
帶反饋的MCP
電路圖如下
帶應答反饋的MCP
電路圖如下:
多周期路徑法的思想十分有用,但是實際中用來傳遞多位信號比較少見,因為邏輯過於復雜。但是MCP方法用來傳遞單bit的信號卻十分有用。這里就不展開講了,有興趣的可以參考最后的參考文檔中的描述。
下面是一種利用MCP思想進行跨時鍾處理脈沖,不用考慮源時鍾信號寬度的代碼:
限制就算輸入脈沖不能相隔太近,否則會丟掉中間的脈沖。
格雷碼
對於計數器的CDC, 大部分是不必要的。如果一定需要,那么可以使用格雷碼。
格雷碼每次只允許更改一個位,從而消除了跨時鍾域同步更改多個CDC位所帶來的問題。
格雷碼和二進制碼之間的轉換是一種很成熟的技術,很容易就能找到現成的代碼,這里就不在詳細描述。
需要注意的是:格雷碼必須是計數到2^n才是每次改變一個bit。
如果計數器是從0~5計數,那么從5->0的計數,不止一個bit改變,就失去了只改變一個bit的初衷。
格雷碼最常見的應用是在異步FIFO中,通常異步FIFO的深度都是2N,原因就是上面說的。所以,就算浪費面積,也需要把FIFO深度設置為2N。
通過AFIFO進行多位信號CDC
多位信號CDC的工程上的一般做法都是采用異步FIFO, 異步FIFO的設計請參考:
“Clifford E. Cummings: Simulation and Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer Comparisons”
這篇文章,里面寫的十分清楚,而且給出了詳細的RTL代碼,可以直接使用。把這篇文章搞懂了,AFIFO的知識點基本就清楚了。AFIFO的設計也是芯片設計的基本功,一定要弄清楚。
這里有一個特殊的應用,那就是深度為2的AFIFO,來進行多bit數據的CDC. 如下圖所示:
2個寄存器搭建的AFIFO,地址只需要一位。相比MCP方法,邏輯簡單,可以復用AFIFO代碼(一般公司都有芯片驗證過的AFIFO代碼),而且延時也比MCP方法小。
所以多bit僅僅跨時鍾域,不需要進行數據吞吐率匹配(FIFO的重要功能之一)的情況,推薦用深度為2的AFIFO來實現,而不是MCP方法。
總結
CDC問題是芯片失敗的最常見的問題之一,弄清楚CDC方法也是芯片設計的最重要的事情。常見的CDC方法總結如下:
- 推薦的1-bt CDC技術:
- 慢時鍾到快時鍾:同步器;
- 快時鍾到慢時鍾:MCP方法
- 推薦的multi-bit CDC 技術:
- 多個信號合成一個信號。
- MCP方法(其實用的很少,但是設計思想很好)
- AFIFO
- 2-Depth AFIFO