復位最佳方式:非同步復位,同步釋放
阿新 • • 發佈:2019-02-07
最近在FPGA討論群裡放入一段程式碼讓精英分析一下可行性,結果被鄙視了,並且引起了精英們的大討論 ,總結一下:
起因是我在一個工程中混雜使用同步復位,非同步復位;
非同步:
always @(posedge clk or negedge rst_n )
if(!rst_n)
(優點:佔用較少邏輯單元
缺點:可能會產生競爭冒險)
同步: always @(posege clk or posedge rst_n)
If(!rst_n)
(優點:可以儘量點少競爭冒險的可能
缺點:會佔用更多的邏輯單元)
Altera 最佳解決辦法:非同步
//非同步復位 同步釋放rtl檢視
原理:
所謂非同步復位和同步釋放,是指復位訊號是非同步有效的,即復位的發生與clk無關。後半句“同步釋放”是指復位訊號的撤除(釋放)則與clk相關,即同步的。
下面說明一下如何實現非同步復位和同步釋放的。
非同步復位:顯而易見,rst_async_n非同步復位後,rst_sync_n將拉低,即實現非同步復位。
同步釋放:這個是關鍵,看如何實現同步釋放,即當復位訊號rst_async_n撤除時,由於雙緩衝電路的作用,rst_sync_n復位訊號不會隨著rst_async_n的撤除而撤除。
假設rst_async_n撤除時發生在clk上升沿,如果不加此電路則可能發生亞穩態事件(在始終上升沿附近rst置1,這時候建立時間還不夠長,資料可能還未打入暫存器,導致輸出不確定)
程式碼實現:(Altera 官方資料)
module reset_best(clk,asyn_reset,syn_reset);input clk;
input asyn_reset;
output syn_reset;
reg rst_s1;
reg rst_s2;
always @( posedge clk ,posedge asyn_reset)
begin
if(asyn_reset)
begin
rst_s1<=1'b0;
rst_s2<=1'b0;
end
else
begin
rst_s1<=1'b1;
rst_s2<=rst_s1;
end
end
assign syn_reset=rst_s2;
endmodule