復位是我們經常用到的,不知道有多少人和我一樣,沒有注意過他的正式的用法,以及其中的奧妙.首先提出一個問題,在FPGA中為什么要有復位?在FPGA上電時我們的FPGA到底處於一個什么樣的狀態呢?在FPGA芯片中,其觸發器、BLOCK RAM等記憶芯片默認,上電時為0(一些廠商)。也有場商的芯片默認為1,還有一些廠商上電時的邏輯狀態根本不統一。因此FPGA中的復位第一為了保證芯片從一個確定的狀態開始工作,FPGA中必須要有一個復位信號;第二確保系統經歷了一次問題后,FPGA的行為能夠恢復正確。
一、復位的方式以及優缺點
同步復位:指的是復位信號在時鍾有效邊沿到來時刻為有效,就只想一次復位。
優點 |
缺點 |
(1)由於同步復位是離散的,因此其非常有利於仿真器的仿真 (2)由於同步復位只有在時鍾有效邊沿到來時才生效,因此可以濾除高於時鍾頻率的毛刺,提高復位操作的可靠性; (3)使用同步復位的系統可以被設計成為純粹的同步時序電路,這樣會大大有利於FPGA項目開發流程中的時序約束與時序分析環節的工作,而且綜合出來的FPGA設計的性能一般也會較高。 |
(1),必須保證復位信號的有效持續時間長度大於一個時鍾周期,否則該復位信號很可能被當做毛刺濾除掉,從而系統將漏掉一次應有的復位動作 (2),由於同步復位信號與時鍾的相關性很大,因此設計和實現時必須要考慮到各種延遲和時間參數,確保其能夠被FPGA設計正確接收並做出相應動作 (3),由於大多數的寄存器都只有異步復位端口,因此,如果采用同步復位,那么編譯器勢會添加額外的細合邏輯,這樣就會消耗較多的邏輯資源。 |
異步復位:無論時鍾信號的有效邊沿是否到來,只要復位信號有效,就執行復位操作,直到復位信號變為無效才停止復位,異步復位是持續的連續的。
優點 | 缺點 |
(1),由於大多數的寄存器都具有異步復位端口,因此采用異步復位可以節省資源。 |
(1),在異步復位信號釋放的時候非常容易出現問題。原因有兩點:第一,當異步復位信號釋放的時刻和時鍾有效邊沿比較接近時,就很容易導致寄存器的輸出出現亞穩態,而亞穩態就是電平信號的電壓較病的狀態,容易導致邏輯誤判:第二,由於復位信號所管轄的寄存器非常之多,而這些寄存器又位於FPGA芯片牧布同地,,因此復位信號到達各個寄存器的路徑延遲肯定是參差不齊的1所以,如果異步復位信號釋改的時刻和時鍾信號有效沿比較接近時,很可能導致一部分寄存器在該時鍾有效治在前完成復位,而另一部分寄存器在該時鍾有效沿之后才完成復位,那么由於這一時鍾周期的 偏差,就很可能會導致后續的邏輯功能出現全面地混亂。 (2),異步復位宿母非常容易受到毛刺等干擾的影響。 |
二、語法以及寄存器比較
異步:Verilog 語法描述 always @(posedge clk or negedge rst_n ),在低電平有效時生成的寄存器。需要的資源如下圖所示:
同步:Verilog描述 always @(posege clk) if(!s_rst_n)。需要的資源如下圖所示:
三、最佳解決辦法---異步復位同步釋放
原理:
所謂異步復位和同步釋放,是指復位信號是異步有效的,即復位的發生與clk無關。后半句“同步釋放”是指復位信號的撤除(釋放)則與clk相關,即同步的。下面說明一下如何實現異步復位和同步釋放的。
RTL 視圖:
異步復位:顯而易見,rst_async_n異步復位后,rst_sync_n將拉低,即實現異步復位。
同步釋放:這個是關鍵,看如何實現同步釋放,即當復位信號rst_async_n撤除時,由於雙緩沖電路的作用,rst_sync_n復位信號不會隨着rst_async_n的撤除而撤除。
分析:假設rst_async_n撤除時發生在clk上升沿,如果不加此電路則可能發生亞穩態事件(在始終上升沿附近rst置1,這時候建立時間還不夠長,數據可能還未打入寄存器,導致輸出不確定)。但是加上此電路以后,假設第一級D觸發器clk上升沿時rst_async_n正好撤除,則D觸發器1輸出高電平“1”,此時第二級觸發器也會更新輸出,但是輸出值為前一級觸發器次clk來之前時的Q1輸出狀態。顯然Q1之前為低電平,顧第二級觸發器輸出保持復位低電平,直到下一個clk來之后,才隨着變為高電平。即同步釋放。
1 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 // Project Name : 3 // Website : https://home.cnblogs.com/lgy-gdeu/ 4 // Author : LGY GUET Uiversity 5 // Weixin : li15226499835 6 // Email : 15277385992@163.com 7 // File : 8 // Create : 2020 9 // Revise : 10 // Editor : sublime text{SUBLIME_VERSION}, tab size ({TABS}) 11 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12 // Modification History: 13 // Date By Version Change Description 14 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 // {DATE} {TIME} LGY 1.0 ++++++++++++++++ 16 // ********************************************************************************* 17 `timescale 1ns/1ns 18 19 module ays_rst_sys_free( 20 21 input wire sclk , 22 input wire s_rst , 23 output wire sys_rst 24 ); 25 26 //============================================================================= 27 //+++++++++++++++++++++++++ Main Code +++++++++++++++++++++++++++++++ 28 //============================================================================= 29 30 reg rst_r0 ; 31 reg rst_r1 ; 32 33 always @(posedge sclk or posedge s_rst ) begin 34 if(s_rst) begin 35 rst_r0 <= 1'b1 ; 36 rst_r1 <= 1'b1 ; 37 end 38 39 else begin 40 rst_r0 <= 1'b0 ; 41 rst_r1 <= rst_r0 ; 42 end 43 end 44 45 46 assign sys_rst = rst_r1 ; 47 48 49 50 endmodule