FPGA之同步復位與非同步復位(2)
為了避免純粹的同步復位和純粹非同步復位的問題,可以使用一種叫做同步化的非同步復位,我們稱其為第三類復位。這種復位完全結合了非同步復位和同步復位的優勢,我們知道非同步復位的優勢是不參與資料路徑,所以不影響資料路徑速度,而復位幾乎是瞬間起作用;而同步復位的優勢是百分百地同步時序分析且具有抗噪聲效能。這種復位其實就是通常我們所說的非同步復位同步釋放。就如同我之前討論的那樣,非同步地進入復位是最好的,只是非同步地退出復位會導致一些類似亞穩態和由同步電路參與反饋而引起不想要的狀態之類的危害等問題。
後面我們會討論如何來實現這樣的同步化的非同步復位。我先來如圖1所示的電路,同步暫存器(Synchronizer
Register
圖1:帶門控的同步化非同步復位原理圖
一種更好的實現方法如圖2所示,這個電路去除了圖1中復位路徑上閘電路延遲。非同步復位輸入直接連線到同步暫存器(Synchronizer Register)的CLRN埠上,這樣復位立即生效。當復位撤除(釋放)時,一個邏輯“1”從同步器(Synchronizer)被時鐘打出用來同步地釋放後續暫存器的復位。
圖
圖2等效的Verilog程式碼如圖3所示,第一個程序模組用來產生同步復位輸出rst_n,rst_n作為第二個程序模組的非同步復位。兩個程序模組的復位訊號都位於各自的敏感列表中。其實第一個程序模組就是將系統輸入的非同步復位進行同步,產生一個後續邏輯使用的同步化了的非同步復位,所以我們看到第二個程序模組裡將這個已經同步化了的復位訊號當作非同步復位使用。
圖3:同步化非同步復位的Verilog程式碼
同樣,為了減少亞穩態對上述同步器中的兩個暫存器的影響,同時也是為了增加平均無故障時間(MTBF),這兩個暫存器應該在FPGA中被放置的越靠近越好,以儘量減少在器件中的佈線延遲。
儘管reset_n已經進行了上述同步化處理,時序約束的時候還是要使用set_false_path命令將其進行切割,而從同步暫存器輸出的復位rst_n現在可以使用TimeQuest進行準確地Recovery和Removal分析。本設計的SDC約束和非同步復位一樣(如筆者上一篇關於非同步復位博文中圖4所示),所以現在我們在Quartus II中編譯這個設計並執行TimeQuest時序分析器,那麼我們將會得到這個電路的Recovery和Removal的slack報告,如圖4所示。
圖4:同步化非同步復位的Recovery和Removal分析
上述分析結果表明,兩條路徑(reg4到reg1和reg4到reg2)都進行了Recovery和Removal檢查。這個電路的Recovery時間檢查(就象建立時間檢測一樣)差不多有9ns的slack,而Removal(就象保持時間檢查一樣)也有660ps的slack。兩個檢查都得到通過,意味著這個電路沒有時序錯誤路徑。
使用上述同步化非同步復位的一個代價是它們很容易受到噪聲和窄脈衝的干擾。同樣地,如果可能最好對輸入到FPGA的非同步復位先進行濾波和去抖動。圖2中的同步化非同步復位原理圖可以確保同步後的非同步至少有一個時鐘週期的長度,如果需要擴充套件復位長度到n個時鐘週期,那麼可以增加同步器中的暫存器個數到n+1個。請一定確保外部輸入的非同步復位reset_n連線到了所有同步器暫存器的CLRN埠,這樣確保使得產生的同步化非同步復位能夠被非同步地置位。
當有PLL涉及時,有些特殊情況需要考慮。比如我們來如圖5所示的電路。需要同步的復位跟之前一樣直接接到了同步器中暫存器的CLRN埠,而同步後的暫存器也同樣接到了reg1和reg2的CLRN埠,同時也被接到PLL的areset埠。所有暫存器包括同步器中的暫存器的驅動時鐘來自PLL的輸出時鐘。雖然看起來PLL使用了同步後的復位,實際上這是行不通的。當PLL處於復位狀態時,PLL的c0是沒有時鐘輸出的,因此同步器中的暫存器將無法清除復位(意思是復位無法得到釋放)。結果是,這個電路將永遠無法跳出復位。
圖5:使用PLL時不正確實現同步化非同步復位的原理圖
為了解決這個問題,PLL的復位應該使用FPGA原始輸入的非同步復位reset_n(如圖6所示,這裡進行了取反,這主要取決於復位是‘0’有效還是‘1’有效,這裡不討論),而不是同步後的復位。此外,使用PLL的Lock輸出來作為同步器中暫存器的時鐘使能,是個不錯的做法。因為這將防止同步後的復位在PLL的輸出時鐘穩定之前提前釋放。
圖6:使用PLL時正確實現同步化非同步復位的原理圖
圖7顯示了圖6所示是PLL正確實現同步化非同步復位原理圖的Verilog程式碼。
圖7:使用PLL時正確實現同步化非同步復位的Verilog程式碼
注意到上述程式碼中同步器的程序模組中多一個條件,即PLL的Locked訊號,它作為同步器中的暫存器的同步時鐘使能訊號。同時注意下面例化的PLL以及兩個個程序模組的時鐘,這些都是當加入PLL時僅有的變化。
圖8是需要給這個電路加入的SDC時序約束,基本和沒有使用PLL相同,唯一的區別是需要使用create_generated_clock語句為PLL的輸出時鐘加約束(注意其實使用PLL後,可以直接使用語句derive_pll_clocks來簡單地進行約束)。
圖8:使用PLL時實現同步化非同步復位的時序約束
最後,還有一個值得一提的例子。如前所述,設計中的不同時鐘域的暫存器如果需要復位,應該首先將復位同步到當前的時鐘域後再使用,也就是說每個時鐘都需要有一套自己的復位同步器暫存器。而且,有的時候設計的某些部分可能需要比其它部分先從復位狀態釋放,所以這就需要一個復位釋放順序的安排。圖9給出了這樣一個例子,同步暫存器都通過類似菊花鏈方式串起來,我們看到最上面的同步器具有最高優先順序從復位狀態跳出來。圖9所示的電路中,所有的復位都同時有效,但是rst_a_n具有從復位狀態跳出的最高優先順序,接著是rst_b_n具有中等優先順序,rst_c_n是最後被釋放的。當然,如果在不同復位之間需要更長的間隔時間,可以在同步器中新增任意個數暫存器來達到需要的間隔長度。
圖9:不同時鐘域同步化非同步復位釋放優先順序安排
總結
本文以及前面兩篇文章分別介紹了不同復位的優缺點,比如同步復位,非同步復位以及同步化的非同步復位。同步復位需要一個時鐘,所以窄復位脈衝將會被忽略,然後同時增加了系統的抗干擾能力。同步復位是百分之一百的同步電路,所以不存在亞穩態問題。只是同步復位會帶來額外的資源消耗以及資料路徑上的延遲,基於此我們說同步復位不是最佳復位選擇。TimeQuest可以象分析其它資料路徑那樣分析同步復位。
非同步復位通常立即起作用,也容易被實現,而且由於它們不象同步復位那樣會給資料路徑引入額外的延遲,所以復位速度很快。同時相比同步復位,非同步復位消耗更少的邏輯資源。比較不幸的是,它們無法通過TimeQuest來進行時序分析(其它靜態時序分析器也無法分析),而且如果處理不當還會給電路帶來亞穩態問題。非同步復位的最大弱點是它們無法確保所有的暫存器在同一個時鐘沿處跳出復位狀態。這在帶反饋的同步設計中是會有問題的,比如狀態機設計。
在將非同步復位連線到暫存器的非同步輸入埠前給它加入一個同步器,這樣就創造一個叫同步化了的非同步復位。這種復位具有非同步復位那樣的立即將復位作用於電路好處,同時又提高電路速度,因為它們不會給資料路徑帶來額外的延遲。同時,這種復位象同步復位那樣避免了亞穩態問題,而且保證所有的暫存器能夠同時從復位狀態跳出。不象非同步復位,同步化了非同步復位可以在TimeQuest裡分析Recovery和Removal。正是由於這些原因,同步化了的非同步復位是大部分FPGA設計中復位電路首先方法。
####################################### 我是分割線#########################################
一、特點:
同步復位:顧名思義,同步復位就是指復位訊號只有在時鐘上升沿到來時,才能有效。否則,無法完成對系統的復位工作。用Verilog描述如下:
always @ (posedge clk) begin
if (!Rst_n)
...
end
非同步復位:它是指無論時鐘沿是否到來,只要復位訊號有效,就對系統進行復位。用Verilog描述如下:
always @ (posedge clk,negedge Rst_n) begin
if (!Rst_n)
...
end
二、各自的優缺點:
1、總的來說,同步復位的優點大概有3條:
a、有利於模擬器的模擬。
b、可以使所設計的系統成為100%的同步時序電路,這便大大有利於時序分析,而且綜合出來的fmax一般較高。
c、因為他只有在時鐘有效電平到來時才有效,所以可以濾除高於時鐘頻率的毛刺。
他的缺點也有不少,主要有以下幾條:
a、復位訊號的有效時長必須大於時鐘週期,才能真正被系統識別並完成復位任務。同時還要考慮,諸如:clk skew,組合 邏輯路徑延時,復位延時等因素。
b、由於大多數的邏輯器件的目標庫內的DFF都只有非同步復位埠,所以,倘若採用同步復位的話,綜合器就會在暫存器的 資料輸入埠插入組合邏輯,這樣就會耗費較多的邏輯資源。
2、對於非同步復位來說,他的優點也有三條,都是相對應的:
a、大多數目標器件庫的dff都有非同步復位埠,因此採用非同步復位可以節省資源。
b、設計相對簡單。
c、非同步復位訊號識別方便,而且可以很方便的使用FPGA的全域性復位埠GSR。
缺點:
a、在復位訊號釋放(release)的時候容易出現問題。具體就是說:倘若復位釋放時恰恰在時鐘有效沿附近,就很容易使寄 存器輸出出現亞穩態,從而導致亞穩態。
b、復位訊號容易受到毛刺的影響。
三、總結:
所以說,一般都推薦使用非同步復位,同步釋放的方式,而且復位訊號低電平有效。這樣就可以兩全其美了。
**********************************************非同步復位,同步釋放****************************************
以前從來沒有對FPGA的復位可靠性關注過,想當然的認為應該不會有什麼問題。當問題真正出在復位上的時候,才又仔細地對FPGA的復位深入的瞭解了一下。首先我們用的復位管腳不是FPGA的全域性管腳,並且復位訊號上沒有上拉電阻,容易受到干擾而產生毛刺,這對非同步復位是相當有害的。其次,我在FPGA內部對復位的處理過於簡單。
今天在網上看了一些資料,很多是關於同步和非同步復位的優缺點比較。由於我在FPGA內部用的是非同步復位,所以主要看了一下非同步復位的缺點:1)復位訊號在時鐘有效沿或其附近釋放時,容易使暫存器或觸發器進入亞穩態;2)容易受到毛刺的影響;3)難以模擬,難以進行靜態時序分析。上面的前兩條應該對我來說是影響最重要的,而第三條說老實話,我還沒有到哪個階層(嘿嘿)
非同步復位,同步釋放——就可以消除上面的前兩條缺點。所謂非同步復位,同步釋放就是在復位訊號到來的時候不受時鐘訊號的同步,而是在復位訊號釋放的時候受到時鐘訊號的同步。通過一個復位訊號綜合器就可以實現非同步復位,同步釋放。
module ex1 (
output rst_sync_n,
input clk, rst_async_n);
reg rst_s1, rst_s2;
always @ (posedge clk, posedge rst_async_n)
if (rst_async_n)
begin
rst_s1 <= 1'b0;
rst_s2 <= 1'b0;
end
else
begin
rst_s1 <= 1'b1;
rst_s2 <= rst_s1;
end
assign rst_sync_n = rst_s2;
endmodule
非同步復位:顯而易見,rst_async_n非同步復位後,rst_sync_n將拉低,即實現非同步復位。
同步釋放:這個是關鍵,看如何實現同步釋放,即當復位訊號rst_async_n撤除時,由於雙緩衝電路的作用,rst_sync_n復位訊號不會隨著rst_async_n的撤除而撤除。
假設rst_async_n撤除時發生在clk上升沿,如果不加此電路則可能發生亞穩態事件。但是加上此電路以後,假設第一級D觸發器clk上升沿時rst_async_n正好撤除,則D觸發器1輸出高電平“1”,此時第二級觸發器也會更新輸出,但是輸出值為前一級觸發器次clk來之前時的Q1輸出狀態。顯然Q1之前為低電平,顧第二級觸發器輸出保持復位低電平,直到下一個clk來之後,才隨著變為高電平。即同步釋放。