module debounce(clk_in,rst_in,key_in,key_pulse,key_state);
input clk_in;//system clock
input rst_in;//system reset
input key_in;//button input
output key_pulse;//debounce pulse out
output reg key_state;//debounce state out
reg key_reg;
//register key_rst,lock key_in to next clk
//定义一个寄存器对输入信号进行锁存
always @(posedge clk_in or negedge rst_in)
begin
if(!rst_in) key_reg<=1;
else key_reg<=key_in;
end
wire key_an=(key_reg==key_in)?0:1;
reg[18:0] cnt;
/******* 计数器
count the number of clk when a dege of key_in if occured
*******/
always @(posedge clk_in or negedge rst_in)
begin
if(!rst_in) cnt<=0;
else if(key_an) cnt<=0;//由此可见当按键按下信号变化key_an变为1,计数cnt清零,然后重新计数,
else cnt<=cnt+1; //由此可见这个程序是一直计数(相当于一直查询,key_an为1或者复位时cnt清零,重新计数)
end
/*******延时采样******/
reg low_sw;//lock the status to register low_sw when cnt count to 19'd500000(即20ms)
always @(posedge clk_in or negedge rst_in)
begin
if(!rst_in) low_sw<=1'b1;//直接写low_sw<=1;一样
else if(cnt==500000) low_sw<=key_in;
end
/********下降沿检测********************/
reg low_sw_reg;//register low_sw_reg,lock low_sw to next clk
always @(posedge clk_in or negedge rst_in)
begin
if(!rst_in) low_sw_reg<=1;
else low_sw_reg<=low_sw;
end
wire key_pulse;//detect the negedge of low,generate pulse
assign key_pulse=low_sw_reg&(~low_sw);
/******脉冲状态输出*****/
always @(posedge clk_in or negedge rst_in)
begin
if(!rst_in)key_state<=1;
else if(key_pulse)key_state<=~key_state;
else key_state<=key_state;
end
endmodule