|
FPGA上电复位和按键复位
当初开始学FPGA的时候,总是疑惑:FPGA不是没有复位管教么,但总在always看到有复位信号。这个复位信号(我们暂且称为rst_n)从哪里来?从我们自己搭建的外部复位信号产生电路里来。一个简易的复位电路(既可以实现上电复位又可以实现按键复位)
上电复位:这个电路在系统接电后由3.3V经过R21给C10充电,此时复位管脚上得到低电平.经过一段时间后,C10被充满,复位管脚电平升高.最后稳定在高电平.这是上电时的情况,即上电复位. 
按键复位:当按下B1时,C10经过R22放电到地,复位管脚被瞬间拉到低电平,当按键放开后,C10再次通过R21充电,经过一段时间后稳定到高电平.完成手动复位. 
这个电路上电复位还行,但按键复位是不够的.由于FPGA是高速电路,在按键复位开关按键的时候会产生抖动,生成很多毛刺方波,这对于我们的电路来说是很有害的.可以通过verilog编写防抖程序来消除可能的误动作。
/**************************************
* 功能:上电复位模块(未加消抖程序)
* 输入参数:
* clk: 50M 时钟输入
* rst_n:外部按键全局复位信号
* 输出参数:
* sys_rst_n:系统全局同步复位信号
***************************************/
module reset
(
input clk,
input rst_n,
output sys_rst_n
);
//------------------------------------------
// Delay 100ms for steady state
reg [22:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 0;
else
begin
if(cnt < 23'd50_00000) //100ms
cnt <= cnt+1'b1;
else
cnt <= cnt;
end
end
//------------------------------------------
//rst_n synchronism
reg rst_nr0;
reg rst_nr1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rst_nr0 <= 0;
rst_nr1 <= 0;
end
else if(cnt == 23'd50_00000)
begin
rst_nr0 <= 1;
rst_nr1 <= rst_nr0;
end
else
begin
rst_nr0 <= 0;
rst_nr1 <= 0;
end
end
assign sys_rst_n = rst_nr1;
endmodule
消抖程序可如下设计:
module fangdou(in,clk,out);
input in,clk;
output out;
reg i,out;
initial out=0;
always @(posedge clk) //clk可以是系统时钟分频得到的,其的周期约100ms
begin
if(in==1)
if(i==1)
out<=1; //如果相邻的两个时钟上升沿都是都有in==1,那就说明是按键动作而非干扰,那么把out置1.
else
i<=1;
else
begin
i<=0;
out<=0;
end
end
endmodule
|
|