【复位】FGPA的复位 [部分转]

关于FGPA的复位

当初开始学FPGA的时候,总是疑惑:FPGA不是没有复位管教么,但总在always看到有复位信号。这个复位信号(我们暂且称为rst_n)从哪里来?

实际上是可以从两个方面获得的,这与我们的MCU一样。

  1. 上电自动复位
  2. 手动按键复位

考虑到系统的初始化可能需要一定的时间,需要写一段Verilog代码进行延时复位,这段代码综合后就是上电自动复位的过程,上电自动复位也要外部硬件提供一个低电平脉冲,第二种方法要求有按键复位的按键电路。作为一个正常的系统,上电自动复位和手动的按键复位都是必须的,且两者实际上是不可分割的。

上电自动复位

原理上很简单,写一个复位模块,等待一段稳定时间,将复位信号拉低一段足够长的时间,再将复位信号拉高。

如下Verilog源码,外部按键复位也将作为模块的一个引脚输入,用于异步的全局复位操作,正常的复位操作要进行,必须要求外部有一个短暂的脉冲作用在rst_n信号上,这可以通过按键电路中的RC电路实现。

 1 /**************************************
 2 *  功能:上电复位模块
 3 *  输入参数:
 4 *         clk: 50M 时钟输入
 5 *         rst_n:外部按键全局复位信号
 6 *  输出参数:
 7 *         sys_rst_n:系统全局同步复位信号
 8 ***************************************/
 9 module    reset
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

按键手动复位电路

不使用专用芯片的参考低电平复位电路如下:

reset1

电路中的复位管脚一端连接到FPGA的某个普通通用管脚,这样电路中的RC电路将产生上面Verilog代码中的rst_n上电低脉冲,这就是本文开头说自动上电复位和硬件按键复位相辅相成。

请注意两个电阻的值,R21要是R22的两个数量级以上,这样才能保证按键按下后被识别为低电平。

手动复位过程中为保证按键复位的稳定性,还可以修改上面的Verilog代码进行按键消抖检测。下面是抓到的按键在闭合的时候的波形:

key_bounce

按键在几个us之内就能达到低电平,该期间触点抖动比较严重。

 1 module RMV_BJ (
 2     BJ_CLK,    //采集时钟,40Hz
 3     RESET,     //系统复位信号
 4     BUTTON_IN, //按键输入信号
 5     BUTTON_OUT //消抖后的输出信号
 6 );
 7 input B_CLK;
 8 input RESET;
 9 input BUTTON_IN;
10 output BUTTON_OUT;
11 reg BUTTON_IN_Q, BUTTON_IN_2Q, BUTTON_IN_3Q;
12 
13 always @(posedge BJ_CLK or negedge RESET)
14 begin
15     if(~RESET)
16     begin
17         BUTTON_IN_Q <= 1'b1;
18         BUTTON_IN_2Q <= 1'b1;
19         BUTTON_IN_3Q <= 1'b1;
20     end
21     else
22     begin
23         BUTTON_IN_Q <= BUTTON_IN;
24         BUTTON_IN_2Q <= BUTTON_IN_Q;
25         BUTTON_IN_3Q <= BUTTON_IN_2Q;
26     end
27 end
28 
29 wire BUTTON_OUT = BUTTON_IN_2Q | BUTTON_IN_3Q;
30 
31 endmodule

上面的方法不能产生一个时钟脉冲的信号,如下的可以用10ms来采样,同时按键动作会产生一个时钟脉冲的信号,便于后续操作

 1 /*--------------------------------------------------------------------------------------
 2 -- Filename ﹕ debounce_module.v
 3 -- Author ﹕tony-ning
 4 -- Description ﹕按键消抖  
 5 -- Called by ﹕Top module
 6 -- Revision History ﹕15-10-16
 7 -- Revision 1.0
 8 -- Company ﹕ 
 9 -- Copyright(c)  All right reserved
10 ---------------------------------------------------------------------------------------*/
11 
12 
13 module debounce_module 
14 (
15     CLK, //采集时钟,40Hz
16     RSTn, //系统复位信号
17     BUTTON_IN, //按键输入信号
18     BUTTON_OUT //消抖后的输出信号
19 );
20     input CLK;
21     input RSTn;
22     input BUTTON_IN;
23     output BUTTON_OUT;
24 
25     reg key_reg1,key_reg2,key_out;
26     reg [24:0]count2;
27     
28     always @( posedge CLK)//CLK 25M
29         begin
30             count2<=count2+1;
31             if(count2==250000)
32             begin
33                 key_reg1<=BUTTON_IN; 
34                 count2<=0;
35             end
36             key_reg2<=key_reg1; 
37             key_out<=key_reg2&(!key_reg1); 
38         end
39 
40     assign BUTTON_OUT = key_out;
41     
42 endmodule

 

 

除了上面简单的复位电路,还可使用CAT811/TPS3823-33等专门的复位芯片,可以免去按键按键消抖的操作。

posted @ 2015-11-11 11:32  tony_ning  阅读(1068)  评论(0编辑  收藏  举报