# Clock Domain Crossing(CDC)
###### tags: `Digital IC Design`
[回到主頁面](https://hackmd.io/@derek8955/BkK2Nb5Jo/https%3A%2F%2Fhackmd.io%2FdpcBlBL8TlShpQ-wSi9Quw)
建議大家在看這個文章前,先把這個影片看完
https://www.youtube.com/watch?v=kz9NWmc2N6w&list=PLpCkjM331Aa8JNoZ1s1o1txve2wlf9pCP&index=7
### <font color="BLue" > Asynchronous vs. synchronous Clock</font>
Synchronous: Derived from same clock source(Known Edge Relationship)
Asynchronous: Derived from different clock source(No Edge Relationship)
### <font color="BLue" > Why Asynchronous Design is Needed </font>
- Multi-clock Domain: 每個子電路所需的頻率不同,對特定模塊就需給較高的頻率
### <font color="BLue" > What is CDC </font>
電路是由很多 block 組成,每個 block 根據其運算功能不同,而有著不同的 clock period。在整合至一個完整的電路後,一定會有不同 clock 訊號相接的情形,這個狀況稱之為 CDC
| |
|:---:|
|CDC Path|
### <font color="BLue" > Problem of CDC </font>
||
|:---:|
在數位電路設計裡,透過 [STA](https://hackmd.io/BOMX17vmRBumB39IhTR3Eg) 來協助檢查所有 timing path 是否有 violation. 一個正確運作的 flip-flop 應在 clock edge 的前後一段時間內( Setup time & Hold time )都保持穩定的狀態才能確保 flip-flop 所儲存的數值。
以上圖為例,兩個 flip-flop 是由不同的 clock domain 所驅動的,當 adat 最後拉至 0 的瞬間時,由於 adat 的訊號驟降讓 bDFF 沒有足夠的準備時間來完成鎖值(setup time violation),此時就會發生 <font color="red" > metastable (亞穩態) </font>。
### <font color="BLue" > Problem of metastability </font>
||
|:---:|
無法保證後方電路輸出狀態(輸入電流不穩定),造成後方邏輯運算錯誤。
### <font color="BLue" > Resolution of metastability </font>
> 現今沒有個辦法可以完全解決 metastability, 要做的事是大幅度地降低 metastability 產生的概率。所以會使用 MTBF(mean time between failure) 這個指標來衡量電路情形。 MTBF意思是發生兩次錯誤之間的間隔,根據應用場景的不同有不同的要求標準。
針對 metastability 的處理電路可依輸入訊號分為 single/multiple bit,在文後會針對這個部分說明。
- (1) Double flip-flop synchronizer(Single bit)
||
|:---:|
|新增一級由 bclk 所驅動的 flip-flop(bdat2) |
由於沒有足夠的準備時間,導致第二級的 flip-flop 產生 metastable,所以直接在後面多加一級 flip-flop,提共足夠的準備時間。但 double flip 沒辦法完全消除 metastability,只是在一般情況下就已經可以大幅降低 metastability 的產生。
> 第一級與第二級之間的 timing problem 就不需要在合成階段做檢查,可以輸入下方指令
> dc_shell>set_false_path –from aff/CK –to b1ff/D
不過這樣的 synchronizer 還是存在了一個問題,如下圖所示, adata 變化太快, bclk 還沒觸發就改變了,導致後方電路完全不知道 adata 有改變。
||
|:---:|
| Problem of double flip-flop synchronizer |
所以使用這個方法來同步,輸入訊號<font color="red" > 必須至少大於3個 destination clock domain edge</font>。以下圖為例,adata 一開始有個 pulse,但在 bclk domain 只碰到了2個 edge( 一個 falling edge 和 一個 rising edge),所以導致 bata 看不到 adata 有個 pulse.
||
|:---:|
| Limitation of double flip-flop synchronizer|
:::success
所以如果本身 destination clock domain 是 source clock domain 的1.5倍以上,那儘管 input data 是一個很短的 pulse, destination clock domain 還是能偵測到。
:::
- (2) Pulse synchronizer(Single bit)
Double flip-flop synchronizer 對 pulse 的長度有限制,如果小於 destination domain 的 3 個 edge 就不會成功 sync 輸入訊號。
Pulse synchronizer 進而改善這個缺陷,整體流程分為以下三個部分:
1. 將 source clock domain 的 pulse 轉換至 long pulse
2. 同樣用 double flip-flop synchronizer 同步 long pulse
3. 轉換同步後的 long pulse 至 pulse
||
|:---:|
|Pulse synchronizer using XOR |
||
| Result |
雖然說 Pulse synchronizer 可以在 a_p_in 是個 single pulse 的情況也能同步,但轉換至 long pulse(Tq) 也必須要滿足 3 個 destination clock domain edge. 換句話說,就是<font color="red" > a_p_in 發生 pulse 的間隔不可以太近</font>。
確切的大小可以看下圖,a_p_in 最快產生 pulse 的情況即是隔了一個 clock cycle, 如此 a_p_in 則變成 aclk 的 1/2 倍頻, Tq 則變成 aclk 的 1/4 倍頻, 換句話說即是 <font color="red" >Tq 這個 long pulse 維持了 2 個 aclk clock cycle</font>,只要 destination 3個 clock edge 可以滿足在兩個 aclk clock cycle,就可以用這個電路實現
一般來說在 1個Clock Destination Period + Uncertainty(Destinatino Domain Setup Time + Hold Time + Clock Skew)即可滿足輸入pulse太近的問題。所以為了讓條件更寬鬆一點,會建議要間隔1個Sorce Clock Domain Period + 4個Destination Clock Domain Period
||
|:---:|
| Worst case |
:::success
講到這裡,我們知道了可以用 double flip-flop synchronizer 解決 CDC problem. 針對 single pulse, 可以在輸入與輸出加上 XOR gate並搭配轉換後的 long pulse 進行同步。
但以上講的兩個方法都只能在 single input signal(例如 flag, 記憶體讀寫狀態, enable signal ... 等) 的情況下做處理,為何 double flip-flop synchronizer 沒辦法同步 multiple bit ?
答案是因為 <font color = "red">double flip-flop synchronizer 同步到 destination clock domain 的 delay 是隨機的</font>,可能一個 cycle 就同步好,也可能需要 2 個 cycle.
所以可以看到下圖,由於 bdata[0] 比較快同步完成,導致最終邏輯輸出不正確。
:::
||
|:---:|
- (3) Asynchronus FIFO synchronizer(Multiple bit)
在講 Asynchronus FIFO 之前,先科普一下 FIFO。FIFO(First in First out) 即是一個有 入口/出口 的儲存空間,同步 FIFO 即表示在對 FIFO 寫入或讀取是基於同步訊號處裡,所以必須有 read/write 兩個指標。
下圖為 FIFO 操作流程,假設 FIFO 有 8 個 entry, rd_ptr / wr_ptr 皆為 4 bit.
每當對 FIFO PUSH 時, wr_ptr 則會 + 1; 反之 FIFO POP 時,rd_ptr 則會 + 1。當 rd_ptr 追上 wr_ptr 表示目前 FIFO 是空的; 當 wr_ptr 領先 rd_ptr 一圈,表示目前 FIFO 是滿的。
|| |
|:---:|:---:|
| 1. FIFO initial state | 2. FIFO PUSH |
|rd_ptr = 4'b0000, wr_ptr = 4'b0000|rd_ptr = 4'b0000, wr_ptr = 4'b0001|
|||
| 3. FIFO POP| 4. FIFO full state( PUSH 8 次)|
|rd_ptr = 4'b0001, wr_ptr = 4'b0001|rd_ptr = 4'b0001, wr_ptr = 4'b1001|
但異步 FIFO 在 寫入/讀取 是於各自的 clock domain, 沒辦法像同步 FIFO 這樣判斷 FIFO 的儲存狀態(滿/空),導致 FIFO 在 PUSH 時,可能原本的儲存空間已滿,進而導致電路異常; 或者是 FIFO 在 POP 時,可能原本的FIFO 是完全沒有任何東西,結果拿到空的值。所以必須有個方式能夠互相同步 rd_ptr 與 wr_ptr 的資訊給 read control / write control。
<font color="red">解決方法就是使用 gray code 並搭配 double flip-flop synchronizer</font>. 剛剛有提到 double flip-flop synchronizer 沒辦法對 multiple bit 進行同步,但由於 gray code 在相鄰大小之間只有 1 個 bit 不同,如果以 gray code 來當作 counter, 那每次訊號翻轉時,其實只有更動其中 1 個 bit, 這樣在進行同步的時候自然不會出現問題。
那異步 FIFO 要怎麼判斷目前是空或滿呢? 和同步 FIFO 相同,先假設 8 個 entry, rd_ptr / wr_ptr 用 4 bit 表示。
異步 FIFO 為空的判斷方法與同步 FIFO 相同,若 rd_ptr 等於 wr_ptr, 代表此時 FIFO 是空的。
當連續 PUSH 8 次後,此時 FIFO 已滿,且 wr_ptr 變為 4'b1100. 可以發現 wr_ptr 與 rd_ptr 在高 2 位元都不相同, 低 2 位元相同。 於是我們就可以用這個方式判斷 FIFO 的儲存空間是否已滿。
||
|:---:|
| gray code |
講完所有基本知識後,就可以了解 AFIFO 是怎麼運作的,電路圖如下。
||
|:---:|
| AFIFO |
> 1. wptr / rptr 皆是 gray code
> 2. waddr / raddr 皆是 binary code. 因為如果以 gray code 來當作 counter 的時候,可以發現它其實是呈現一個不規律的計數情形,所以在 FIFO memory access 的時候都還是保留用 binary code.
> 3. 為什麼要使用 FIFO 這個 memory?
> 假設一個很快的 clock domain(A) 要同步到一個很慢的 clock domain(B), 但因為 B 處理速度實在太慢了,在當中傳遞可能會損失掉 A 所傳送的部分訊息。所以這裡的 FIFO 是提供了一個 buffer 的環境,讓資料先寫進去,之後 B 要用到的時候再讀出來。
:link: code 實現可以看這篇[文章](https://zhuanlan.zhihu.com/p/149988091)
### <font color="BLue" > Appendix </font>
Double Flip-Flop Sync 需要滿足3個desitination clock domain edge,但一般設計者沒辦法保證這件事情,所以有一個更好的保障方法Closed-Loop Solution
||
|:---:|
原理大致與原先相同,在Clock Sorce Domain多了兩個Flip Flop,接收Sync後的數值,當ap2_dat成功收到Sync後,再通知adat關閉控制訊號,以確保Destination Clock Domain接收成功。
### <font color="BLue" > Reference </font>
- [1] https://ithelp.ithome.com.tw/articles/10232234
- [2] https://anysilicon.com/clock-domain-crossing-cdc/
- <font color = "red">[3] https://www.zhihu.com/people/li-hong-jiang-54/posts (推推推)</font>
- [4] https://blog.csdn.net/guyefeng123321/article/details/80970207
- [5] https://funrtl.wordpress.com/2018/12/12/cdc-clock-domain-crossing/
- [6] http://www.sunburst-design.com/papers/CummingsSNUG2008Boston_CDC.pdf (很完整的Paper)