Verilog之按键检测(一)

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 
上一篇:rst标记语法


下一篇:TCP标志位