Verilog之按键检测(一)
使用说明
//单个按键检测,
//功能:当按键按下时,state_out 输出高电平,当按键松开后,state_out 输出低电平
//应用场景:可用于按键检测,中断信号检测
/********************************/
/时钟按照50M计算,检测时延20ms/
正文
module key_detect(
clk,
rst_n,
key_in,
state_out,
);
input wire clk;
input rst_n;
input key_in;
output reg state_out;
/*延时计算*/
parameter Period=32'd1000000 ;
reg [31:0] cunter;
reg time_up;
reg clear; //1: 开始计数 0:清零计数
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cunter<=32'd0;
time_up<=0;
end
else if(!clear)
begin
cunter<=32'd0;
time_up<=0;
end
else if(cunter==Period)
begin
cunter<=32'd0;
time_up<=1;
end
else
cunter<=cunter+1'b1;
end
//按键检测状态机
`define INIT_STATE 3'b000 //初始状态
`define PRESS_STATE 3'b001 //按键按下状态
`define RELEASE_STATE 3'b010 //按键松开状态
reg [3:0] state;
reg [3:0] state_next;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state<=`INIT_STATE;
end
else
begin
state<=state_next;
end
end
wire state_flag;
always @(*)
begin
// state_next=`INIT_STATE;
// state_out=1'b0;
case(state)
`INIT_STATE:
begin
if(key_in)
begin
state_next=`PRESS_STATE;
clear=1'b1; //开始计时
end
else
begin
clear=0;
state_out=1'b0;
state_next=`INIT_STATE;
end
end
`PRESS_STATE:
begin
if(time_up)
begin
if(key_in)
begin
state_out=1'b1;
state_next=`PRESS_STATE;
end
else
begin
clear=0;
state_out=1'b0;
state_next=`RELEASE_STATE;
end
end
else
begin
clear=1'b1;
state_out=1'b0;
state_next=`PRESS_STATE;
end
end
`RELEASE_STATE:
begin
clear=1;
if(time_up)
begin
if(key_in)
begin
state_next=`PRESS_STATE;
end
else
begin
state_out=1'b0;
clear=0;
state_next=`INIT_STATE;
end
end
else
begin
state_next=`RELEASE_STATE;
end
end
default:
begin
clear=0;
state_next=`INIT_STATE;
end
endcase
end
endmodule