BitArt

Ideas Worth Spreading

导航

FPGA的上电复位

Posted on 2012-12-01 16:50  BitArt  阅读(8903)  评论(3编辑  收藏  举报

  在基于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拉高,复位结束,系统开始正常工作;