經常在面試時問到一個問題:對于芯片中的復位信號我們通常會有哪些特殊處理?這個時候我一般希望得到的回答包括:復位消抖、異步復位同步撤離、降頻復位、關斷時鐘復位和復位保護等處理方案。
復位消抖
這篇文章就先聊下復位消抖,在開始之前先說明一下因為我的經驗有限且很多是道聽途說,所以文中難免有所疏漏和錯誤,請大家不吝賜教。
復位信號在使用前一般需要進行消抖處理,也稱為復位濾毛刺。復位的抖動可能會導致芯片產生多次復位動作,給系統帶來不確定性和誤差。消抖的目的是為了確保復位信號的穩定性和可靠性,從而保證系統能夠正常工作。通過消抖,可以消除復位信號的抖動干擾,保證復位信號的可靠性和穩定性,避免系統故障和數據丟失等問題。
舉個例子,如果要消除30ns以下的復位抖動,那么30ns以下的復位信號rst_n拉低操作就會被消抖電路消除,不會對電路產生任何的影響,只有30ns以上的復位拉低操作才能作用于內部電路。
所以復位消抖電路具體長什么樣子呢?目前我了解的有三種方式,不過因為沒有實際參與過CRG模塊的設計與流片,所以以下內容只做參考。我們假定濾毛刺時鐘為100M,需要濾除的復位抖動為30ns以下的信號。
第一種方式通過濾毛刺時鐘+D觸發器來完成,如要濾過30ns的抖動電路圖如下:
D觸發器的數量關系是如何得到的呢?先假設我只有一個延時D觸發器,那么復位信號必須維持L電平在一個clk時鐘周期以上或門才能在時鐘沿處打出一個L信號出來(即時鐘上升沿時rst_n || rst_n_ff1 == 1'b0),如下面的波形圖所示:
同樣的,如果有兩個延時D觸發器,那么復位信號必須維持L電平在兩個clk時鐘周期以上,或門才能在時鐘沿處打出一個L信號出來:
如果有三個延時D觸發器,那么復位信號必須維持L電平在三個clk時鐘周期以上,或門才能在時鐘沿處打出一個L信號出來:
因此,在或們前放置了N個延時D觸發器,就可以濾除N*T(T為消抖時鐘的周期)時長以下的復位毛刺信號。這種方式存在一個巨大隱患,消抖時鐘信號是不受復位控制的,一旦消抖時鐘信號出了什么問題,復位信號將永遠無法從消抖電路傳遞出去。
第二種方式通過累加器來完成,簡單來說就是數一下rst_n連續出現了多少拍,假如需要通過100M消抖時鐘來濾除100ns以下的復位抖動,那么rst_n要連續出現10拍低電平才達到100ns的復位標準。將rst_n打兩拍rst_n_ff1/rst_n_ff2消除亞穩態,當rst_n_ff2持續達到10拍對外輸出復位信號,對應的波形示意如下:
這個消抖方案呢同樣存在上面的問題,消抖時鐘信號是不受復位控制的,所以在芯片內的模塊級別可能會被采用,但是在外部復位消抖時是一般不會使用的。
第三種方式是通過延時器件來實現,要濾去100ns以下毛刺,那么就引入100ns延時器件,組成如下電路:
對應的波形也很簡單:
通過波形可以看出,如果復位時長不夠100ns,prst_n根本不會被觸發。這個電路的隱患在于如何保證延時器件在不同溫度等外部環境干擾下的延時準確性。
異步復位,同步撤離
對于使用異步復位的系統,低電平復位系統時復位信號是允許不與工作時鐘對齊的即純純異步復位;但是在復位撤離時,需要與工作時鐘對齊,即滿足removal time要求(在時鐘有效沿來臨之后,異步復位信號需要繼續保持有效的最短時間),或者說復位的撤離行為是受到時鐘控制的。
既然都已經是異步復位了,為何還要多此一舉呢?
1.對于復位這個操作行為而言,純異步處理是完全可以的,因為所有的元器件都會最終回到初始值。當然了,這里指的是整體復位或者說帶保護的局部復位。你別管這些寄存器誰先復位誰后復位誰出現亞穩態了,只要不是著火了最后都會回到復位值。就像電視劇里說的“反正早晚都是沒,早沒晚沒又有什么區別呢”。所以異步復位出電路是沒有任何問題的。
2.但是對于復位撤銷這個行為就不一樣了。一旦復位撤銷了各個元器件就會開始工作了,但是復位信號如果是純異步的打到某個寄存器接口上的時候可能就撞到亞穩態窗口上了(不滿足removal time),亞穩態就會在電路里開始蔓延搗亂,出現什么情況可就難說了。所以復位撤離這個事必須得是受到時鐘控制的,不能是純異步電路。
這里有一點要注意哈,同步撤離這個操作解決的是異步復位可能的亞穩態問題,并不是說能夠保證所有的寄存器在同一時間收到復位撤離的操作。這個事就類似與信號打3拍同步一樣,咱們先解決亞穩態問題,再處理信號傳的對不對的問題。通過異步復位同步撤離先確保沒有亞穩態,再處理寄存器不能在同一拍接收到復位撤銷導致錯誤的問題。
如何做到異步復位同步撤離呢?請看下面這個電路:
rst_n經過濾波后得到prst_n,因此我們只需要分析prst_n的行為影響即可。
正常工作狀態下,prst_n==1;
異步復位時prst_n由1跳轉為0,兩個D觸發器立刻被復位。也就是說rst_work_n會立即下拉至低電平復位系統,這個下拉顯然時候不受時鐘控制的,因此實現了異步復位;
復位撤離時prst_n由0跳轉為1,兩個D觸發器的復位被撤銷了開始正常工作。但是高電平需要兩個周期才會到達rst_work_n端,這兩個周期足以消除復位帶來的亞穩態并且保證系統感知的復位rst_work_n在時鐘沿上,因此實現了同步撤銷;
借助于這個電路設計,系統的異步復位同步撤離功能就實現了。不過當年我還問了大佬一個問題:這樣的話系統就延時了2個周期才復位的啊,會不會有bug?
大佬的回答是這樣的:你這啥系統啊真的在乎這一兩個周期的事么?早跑幾周期晚跑幾周期有啥關系,只要別跑錯了就行!
解復位的特殊處理
解復位就是復位撤離,系統解復位就是復位結束了系統準備開始工作。
前文咱們提過,復位撤離比復位要復雜一些,因為復位了大家就是一起回到初始狀態去,寄存器也不采樣了,有什么毛刺啊亞穩態啊只要不影響其他系統(這個之后講)都沒關系的。這就相當于晚上回家上床準備上床睡覺,你愛穿啥衣服睡就穿啥衣服不穿也沒人管。但是解復位就不一樣了,這就是起床要出門上班了,怎么著也得準備好才能出去工作,不能穿著秋褲就往外跑。
所以的對于解復位(其實也不光是解復位,局部復位本身也很危險)就需要做跟多的額外工作了,上一篇說的同步撤離之后,還有什么問題需要解決呢?
主要是復位信號到達各個寄存器的時間不一致的問題。復位信號在系統內是有很大的扇出的,連接到所有需要復位的寄存器的復位端。這也就導致了復位在系統中的走線特別長,過長的走線又會導致工具在復位信號上增加buffer以提升驅動能力,那么如果時鐘頻率很高,復位信號最終到達各個寄存器的時間也就無法保證在同一拍。
復位走線到達各個寄存器不在同一拍會有什么后果呢?這個不能一概而論。對于一些復位解除后就開始工作的電路系統比如自動計數取指模塊,各個寄存器之間可能存在依賴關系,如果只部分寄存器被復位或解復位,可能會導致不一致的狀態,從而影響系統的正確運行。同時呢,如果復位方案做的不好,某系統進行復位時一部分復位了一部分沒有復位,也可能會產生毛刺被未復位的寄存器采樣,進而輸出使能影響到其他系統的正常工作。
總之呢,復位走線到各個寄存器不在同一拍,可能存在系統穩定性的風險。因此在對復位還需要對系統的復位做一些特殊的處理。特殊的處理有哪些呢,不同的團隊也有多種多樣的選擇,這里列舉一些我所聽聞過的方案吧。
降頻后復位。
先把時鐘降頻,再進行復位和解復位的操作,再提頻回正常工作時鐘頻率。你不是怕復位走線到各個寄存器的時間不一致導致不在同一拍復位嗎?那好,我把時鐘降頻總可以吧,1GHz太快了降到500M,500M還快降到100M,100M還快到10M總可以了吧,一個周期這么長時間足夠你復位信號慢慢溜達到各個寄存器的。所以采用這種方案時,會在復位前將工作時鐘32分頻或者64分頻(取決于系統的面積和工作時鐘,可以算的),然后進行復位和解復位,之后在將時鐘提頻至工作狀態。
這種方案下,可以在sdc中將復位信號設置為multicycle,檢查其在64個時鐘周期內能夠作用到所有的寄存器復位端。
**關時鐘后復位。**
這個方法更徹底,怕各個寄存器看到復位和解復位的時間不一致導致功能錯亂?那直接把工作時鐘給關斷不久好了,反正是異步復位不用擔心沒有時鐘復位信號作用不到寄存器端。時鐘一關所有寄存器相當于原地停工,這個時候別說復位信號了,啥信號過來都沒事,寄存器都不干了嘛。所以此時復位信號的走線也就不稱問題了,先復位再慢慢悠悠的解復位,都搞定了歇一會再把時鐘打開。
這種方案下,可以在sdc中將復位信號設置為false_path,畢竟相當于準靜態的信號,工作時復位信號不會跳變。
復位保護。
這個方法的思路是,不是擔心我這塊的復位影響其他系統工作嘛,那么不去處理復位和時鐘,而是把系統裹起來。怎么裹起來呢,把所有的對外輸出使能啊、握手啊這類信號都先和低電平與在一起,保證不管一會發生啥事,都不會有關鍵信號發生跳變。保護好之后,再去拉復位信號,過一會再解復位,再等會時間等系統穩定下來了,再把保護電路解除開始正常工作。
這種方案下,也可以在sdc中將復位信號設置為false_path。
復位之后等待一定時間再開始下任務。
這個方案更多的是在任務層面看,也就是說面對解復位后可能存在的系統不穩定性,先不要著急下任務下配置下指令,而是等待一定時間等系統中可能存在的不穩定狀態都結束了,再開始進入工作模式去下任務。
當然了不是說所有系統都適用以上的方法,比如某個系統確實是解復位后就立即開始工作,那用復位保護就沒效果,因為你內部狀態都亂了保護其他系統還有啥用呢。所以說還是具體問題具體分析吧,以上也只是經驗之談難免有所疏漏。
典型的軟復位流程
在聊到復位的時候總會區分兩個概念:硬復位和軟復位。
硬復位就是通常所說的復位,是通過硬件電路或者特殊的硬件信號來觸發的復位過程。當拉低外部復位信號時硬復位被觸發,復位線會直接影響系統的硬件電路與寄存器,將系統的內部狀態恢復到一個已知的初始狀態。硬復位通常是由外部的控制電路或者特定的硬件引腳來觸發,例如按下一個復位按鈕或者通過特定的電路邏輯條件。
軟復位是通過軟件的程序代碼或者寄存器配置等方式觸發的復位過程。當軟復位被觸發時,系統一般需要執行特定的步驟來響應軟復位需求,確認進入待復位狀態后才會進入復位流程,將系統的內部狀態恢復到一個已知的初始狀態。軟復位通常是在程序執行中的某個特定條件下發生,例如檢測到一個錯誤或者需要重新初始化系統時。
硬復位一般是整芯片甚至芯片組復位,這個過程可以說是比較簡單粗暴的。而軟復位一般是芯片的部分系統進行復位重啟,有時也稱為快速復位、動態復位、配置復位,大多是通過一系列的流程來完成的。
本篇中就聊一聊典型的系統軟復位流程。
1.觸發軟復位啟動條件。這一般是系統內部或SOC出現了致命的錯誤比如任務執行超時、總線數據錯誤或安全機制報錯等,上位的MCU或者CPU判斷需要對該系統進行軟復位操作以恢復功能;
2.停止下發任務。判斷需要對系統軟復位后,應當從任務層停止下發新的任務,避免系統錯誤進一步的蔓延影響其他進程;
3.下達軟復位請求。請求可能通過配置系統的寄存器或者從控制接口下發使能信號;
4.系統接收到軟復位的請求后,需要做出一系列的處理。這時一般有兩種方向選擇,一種是主動停止工作,比如停止執行接下來的取指、在指令或者卷積層邊界停止進一步的計算;另一種是被動停止工作,也就是內部邏輯不停止工作,而通過系統邊界的模塊響應軟復位,進而對內部通路進行阻塞或者假握手假接收等行為使內部被動停止工作。
5.系統邊界的模塊監聽所有通路,等待所有已經發出的請求全部收回應答(典型的比如AW請求收回Bresp,AR請求收回Rdata),這樣做的目的是避免本系統的復位對SOC或其他系統產生影響,也避免對解除復位后的本系統產生影響(如未收全,本系統復位解除后總線返回了一筆復位前的Bresp,那本系統直接就亂了);
6.邊界的模塊收全所有應有的返回信息后,或者未能收全但是到達超時閾值后,系統進入待復位狀態;
7.此時如果本系統仍然保留著訪問DDR和sram的備份通路,那么上位機可以通過配置寄存器去間接訪問內存和寄存器進行保留現場。如果沒有規劃該功能,則略過這一步驟;
8.上位機配置復位保護寄存器使能復位保護電路,避免系統復位過程中有毛刺或者使能信號擴散到總線或其他系統;
9.上位機配置對系統進行時鐘降配或者關斷時鐘等操作,這個是可選操作,一般來說如果復位保護做的比較嚴格,這里不對時鐘進行處理也沒關系;
10.配置復位或拉低系統的復位信號,持續一段時間,這個時間沒有太嚴格的要求,按毫秒計時也沒有關系,少的話也得幾十拍確保系統內所有寄存器都完成了復位;
11.復位已經完成,之后配置解復位或拉高系統的復位信號,解除系統的復位狀態,之后等待一段時間等內部電路穩定下來;
12.配置時鐘恢復工作頻率或恢復時鐘,可選;
13.配置復位保護寄存器解除復位保護,恢復總線連接;
14.可以再等待一段時間后,重新下任務或恢復現場,重啟系統完成。
軟復位的流程沒有特別嚴格的規定,通常是根據芯片的需求而規劃,上面所述也只是經驗之談。不過大抵都遵循停任務 - 收應答 - 斷連接 - 復位 - 解復位 - 重連接 - 下任務的思路。
復位保護電路
前面提到了,在一些系統中會通過復位保護的方式來避免復位過程中的“亂象”,所以本章就針對復位保護多聊一下。
復位保護電路,是在系統進行復位的過程中對接口進行硬性邏輯保護,避免毛刺和錯誤對周圍系統產生影響的模塊。通常而言,復位保護電路的開啟應該在復位之前,關閉應該在復位撤離之后。咱們針對握手接口來分類看下如何進行復位保護(使能接口也類似)。
對外輸出valid。
在復位期間由于復位信號到達不同寄存器的時間不同,加之組合邏輯路徑,可能會產生錯誤的valid信號對外輸出。顯然在本系統單獨復位的場景下,是不應該有對外的valid輸出的,因此在復位前,需要將對外輸出的valid信號&&0操作,確保復位和解復位期間沒有valid誤觸發。
對內輸入的ready。
進入復位的階段,對內輸入的ready是可以不做處理的,因為即使復位時出現了對外valid的誤觸發,系統也馬上就會進入復位狀態了不會有任何影響。在解復位階段,如果流程內能夠通過時鐘關斷或時鐘降頻等手段來保證系統內的寄存器同一拍解復位,在內部不產生valid誤觸,對內輸入的ready可以不經過邏輯處理。
如果沒有其他的手段保護,可以考慮對內的in_ready = out_ready || 1來保證在復位撤離階段將誤觸發的valid通過假握手丟棄掉。
對外輸出的ready。
系統復位期間,從業務需求上其他系統理應不對該系統有事務操作。如果真的出現了極端異常場景,那么比較合理的情況是對外輸出的ready保證為1,將事務丟棄,不阻塞其他系統,如果為帶rsp的事務那就等待其他系統的超時中斷。
對內輸入的valid。
在復位和復位期間,一般而言輸入的valid是無需理會的。解復位時最好也是通過其他手段保證不出現內部的ready誤觸,且當本系統單獨復位期間其他系統理應不存在請求到來,因此對內輸入的valid也是不需要經過特殊處理的。
如果沒有其他的手段保護,可以考慮對內的in_valid = out_valid && 0,避免內部誤觸發的ready同in_valid進行了握手。
復位保護電路。
通常而言,復位保護的使能信號從寄存器輸出,作用于RTL,那么同樣存在一個異步路徑的問題。因為使能復位保護和撤銷復位保護時,RTL是沒有處于工作狀態的,且內部電路處于穩態。沒有工作處于穩態時,對外的valid必然為0,ready必然為1(如果不滿足這個條件,請單獨討論)。
對外out_valid = 0 && (~prot_en),此時prot_en由1跳變為0(或0跳變位1),輸出邏輯不會改變,也不存在亞穩態采樣的問題;對外輸出的out_ready = 1 || (prot_en),此時prot_en由1跳變為0(或0跳變位1),輸出邏輯不會改變,同樣不存在亞穩態采樣的問題。因此個人認為,由寄存器輸出的prot_en作用于內部邏輯時,無需經過跨異步處理。
配置復位
本篇仍舊基于工作經驗,難免有疏漏和錯誤。在前文聊過了軟復位和硬復位之后,最后一篇來說說另外一種我遇到的系統復位方案 —— 配置復位,很多情況下我更愿意把配置復位稱作快速復位。粗略的一算復位情況還挺多,硬復位、軟復位、配置復位、快速復位、動態復位等。
一款芯片的復位會分很多級,很大部分的小系統比如加速器這種的都已經接在三級或者四級復位總線了,看到的硬復位已經和很多軟復位&&在了一起,看到的軟復位也可以簡單理解為更上層的“配置復位”。當然我們不在細節上做太深的探究,畫個圖簡單里表示下好了。
配置復位和其他復位的區別主要在哪里呢?最大的一個區別是,系統的配置復位不會復位寄存器單元。想想看就很清晰,配置復位必然是通過配置寄存器單元來完成的,你要用人家就不能給人家復位了對吧。熟悉的配置復位流程和軟復位流程很接近:
1.觸發配置復位啟動條件。如系統內部出現了致命的錯誤、任務執行超時、安全機制報錯等;
2.停止下發任務。從任務層停止下發新的任務,避免系統錯誤進一步的蔓延影響其他進程;
3.通過配置總線下發達配置復位請求;
4.系統接收到配置復位的請求后,停下處理的工作;
5.系統邊界的模塊監聽所有通路,等待所有已經發出的請求全部收回應答;
6.邊界的模塊收全所有應有的返回信息后,或者未能收全但是到達超時閾值后,系統進入待復位狀態;
7.此時如果本系統仍然保留著訪問DDR和sram的備份通路,那么上位機可以通過配置寄存器去間接訪問內存和寄存器進行保留現場。如果沒有規劃該功能,則略過這一步驟;
8.上位機配置復位保護寄存器使能復位保護電路,避免系統復位過程中有毛刺或者使能信號擴散到總線或其他系統;
9.通過系統總線配置時鐘降頻寄存器或關斷核時鐘寄存器;
10.通過系統總線配置復位寄存器,持續一段時間確保系統內所有寄存器都完成了復位;
11.復位完成后配置復位寄存器解除復位,之后等待一段時間;
12.配置時鐘恢復工作頻率或恢復時鐘;
13.配置復位保護寄存器解除復位保護,恢復總線連接;
14.重新下任務或恢復現場,重啟系統完成。
流程這么相似的情況下,配置復位和軟復位最大的區別在哪里呢?我個人的經驗是,配置復位不會將寄存器復位那么所有的配置都得以保留,復位完成后可以不重新下配置的情況下快速的重啟任務,所以我更喜歡將配置復位稱為快速復位。當然,這個區別并不固定,軟復位也可以只復位核部分不復位寄存器部分,連接合理使用得當的情況下都是允許的。
之前面對的最復雜的系統復位場景基本就是下面這樣了:
因為歷史遺留和甩鍋等一些原因吧,我交付的系統中有一部分應該歸屬于NOC系統的總線模塊。這部分總線模塊的引入帶來了一個尷尬的問題,軟復位時候不能將這部分進行復位,否則NOC就掛了!所以最后的系統的復位域分了三個層級:硬復位——復位全系統,軟復位——復位core和reg,配置復位——只復位core,保留配置。光復位方案就要分三套,真是不想回首的痛苦經歷啊。
審核編輯:劉清
-
寄存器
+關注
關注
31文章
5317瀏覽量
120003 -
D觸發器
+關注
關注
3文章
164瀏覽量
47862 -
SDC
+關注
關注
0文章
48瀏覽量
15528 -
CLK
+關注
關注
0文章
127瀏覽量
17125 -
累加器
+關注
關注
0文章
50瀏覽量
9440
原文標題:【芯片設計筆記】復位那些小事(建議收藏)
文章出處:【微信號:IC修真院,微信公眾號:IC修真院】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論