1. 什么是RDC?
RDC,即Reset Domain Crossing,一般是指信號跨越不同的異步復(fù)位域。RDC問題可能會產(chǎn)生亞穩(wěn)態(tài),導(dǎo)致芯片設(shè)計出問題。在設(shè)計時需要注意防范和處理RDC問題。
下面介紹幾個RDC的典型實例。
RDC實例1:
如上圖所示,d1信號先后經(jīng)過了觸發(fā)器F1和F2,F(xiàn)1和F2的復(fù)位域不同,分別為rst1和rst2。由于rst1異步復(fù)位拉低,導(dǎo)致q1信號發(fā)生變化(由高變?yōu)榈停?,這樣就會使觸發(fā)器F2輸出的q2信號可能產(chǎn)生亞穩(wěn)態(tài),導(dǎo)致芯片發(fā)生邏輯錯誤,如下圖。
其實,主要原因是rst1為異步復(fù)位,可能在任意時刻發(fā)生復(fù)位,F(xiàn)1的q1立刻會發(fā)生變化,這個變化如果落在F2的setup/hold時間窗口里,就會導(dǎo)致setup/hold違例, 從而產(chǎn)生亞穩(wěn)態(tài)。還有一個重要原因是:async reset assert的路徑無法被STA約束,因為異步復(fù)位的assert可以在任何時間發(fā)生,所以沒有辦法做STA。
如果將rst1進行同步處理(異步復(fù)位,同步釋放)再給到F1,那么依然是存在RDC問題的,異步復(fù)位的異步是RDC問題,而同步釋放(是否做了同步)則是CDC問題。CDC path和RDC path有可能重疊。
RDC實例2:
在某些情況下,即使只有一個異步復(fù)位也會導(dǎo)致RDC問題。
如下圖所示,rst1異步復(fù)位給到了觸發(fā)器F1和F2,但是在給到F1之前delay了3個時鐘周期,這樣如果rst1的assert持續(xù)時間(例如2個周期)小于delay時間,那么就會產(chǎn)生RDC問題。因為F1發(fā)生復(fù)位時,F(xiàn)2已經(jīng)復(fù)位完成并進入工作狀態(tài)了。
2. RDC問題處理方法
接下來介紹幾種常見的RDC解決方法。首先最簡單直接的方法就是不使用異步復(fù)位,而是用同步復(fù)位。因為同步復(fù)位的assert和deassert都可以被STA給約束,所以不會產(chǎn)生RDC問題。如果無法避免使用異步復(fù)位且RDC問題確實存在,那么可以參考以下幾種方法。
1. 控制復(fù)位順序
例如在RDC實例1中,可以通過硬件設(shè)計或者軟件來控制復(fù)位順序,保證rst2比rst1先assert。這樣在rst1 assert時,觸發(fā)器F2輸出的q2信號會處于穩(wěn)定的復(fù)位值,不會產(chǎn)生亞穩(wěn)態(tài)。
如果保證了復(fù)位順序的話,可以在spyglass中通過如下命令來聲明復(fù)位順序:set_rdc_define_assertion_sequence -from_reset {rst2} -to_reset {rst1}
2. 控制時鐘和復(fù)位順序
例如在RDC實例1中,如果可以在rst1復(fù)位assert之前,將F2的clock給gating住(關(guān)閉),那么也可以解決RDC的問題。
可以在spyglass中通過如下命令來聲明復(fù)位和時鐘的順序:set_rdc_define_assertion_sequence -from_reset {rst2} -to_clock {clk}
3. 加同步器
例如在RDC實例1中,可以在對F1的輸出q1進行打拍同步,再給到F2。這樣F2的輸入就不會產(chǎn)生setup/hold violation了,但是同步器可能會影響原來的邏輯關(guān)系,并且?guī)硪恍┟娣e開銷。
4. clamp鉗位控制
還有一種常用的方法是加鉗位控制。例如下圖,在觸發(fā)器F1的輸出端加一個與門(或者或門),在rst1復(fù)位assert期間,通過clamp信號來控制與門的輸出為0(或門的輸出為1)。這樣當F1異步復(fù)位時,F(xiàn)1輸出的q1的變化不會影響到F2,從而就不會產(chǎn)生亞穩(wěn)態(tài)和RDC問題了。
參考內(nèi)容:
掌握了CDC,你聽說過RDC嗎
https://blog.csdn.net/weixin_45260499/article/details/133920719
https://www.cnblogs.com/lanlancky/p/17400758.html