在基於verilog的FPGA設計中,我們常常可以看到以下形式的進程:
1 reg [19:0] cnt; 2 always@(posedge Clk50M or negedge Rst_n) 3 begin 4 if(!Rst_n) 5 cnt<=20'd0; 6 else if(cnt_able) 7 cnt<=cnt+1'b1; 8 end
信號Rst_n用來對進程中所用變量的初始化,這個復位信號是十分重要的,如果沒有復位,會導致一些寄存器的初始值變得未知,如果此時FPGA就開始工作的話,極易導致錯誤。
那么,這個復位信號來自何處?難道我們做好的系統,每次上電后都要手動按一下reset按鈕么?
答案是否定的!這個復位信號其實是由特定的程序來產生的,系統每次上電,都會由該程序產生一個復位信號,從而避免了手動復位。
在網上找了多種方案,覺得只有這個程序比較簡單實用,轉來如下:
1 /************************************** 2 * 功能:同步復位產生模塊 3 * 輸入參數: 4 * 1. clk: 50M 時鍾輸入 5 * 2. 全局復位信號 6 * 輸出參數: 7 * sys_rst_n:系統全局同步復位信號 8 ***************************************/ 9 module system_ctrl 10 ( 11 input clk, 12 input rst_n, 13 output sys_rst_n 14 ); 15 16 //------------------------------------------ 17 // Delay 100ms for steady state 18 reg [22:0] cnt; 19 always@(posedge clk or negedge rst_n) 20 begin 21 if(!rst_n) 22 cnt <= 0; 23 else 24 begin 25 if(cnt < 23'd50_00000) //100ms 26 cnt <= cnt+1'b1; 27 else 28 cnt <= cnt; 29 end 30 end 31 32 //------------------------------------------ 33 //rst_n synchronism 34 reg rst_nr0; 35 reg rst_nr1; 36 always@(posedge clk or negedge rst_n) 37 begin 38 if(!rst_n) 39 begin 40 rst_nr0 <= 0; 41 rst_nr1 <= 0; 42 end 43 else if(cnt == 23'd50_00000) 44 begin 45 rst_nr0 <= 1; 46 rst_nr1 <= rst_nr0; 47 end 48 else 49 begin 50 rst_nr0 <= 0; 51 rst_nr1 <= 0; 52 end 53 end 54 55 assign sys_rst_n = rst_nr1; 56 57 endmodule
說明:
1.第一個進程用來延時,當上電后,延時100ms,以保證FPGA內部達到穩定狀態;此時sys_rst_n始終為0,也就是系統時鍾處於復位狀態中。
2.當100ms延時結束后,sys_rst_n與系統時鍾同步釋放,即sys_rst_n拉高,復位結束,系統開始正常工作;