注意前后消抖
module module_button
(
CLK,RSTn,Pin_In,LED_Out
);
input CLK;
input RSTn;
input [1:0]Pin_In;
output [9:0]LED_Out;
/*************************/
wire [1:0]HL_Sig;
wire [1:0]LH_Sig;
module_detect U1
(
.CLK(CLK),
.RSTn(RSTn),
.Pin_In(Pin_In),
.HL_Sig(HL_Sig),
.LH_Sig(LH_Sig)
);
module_delay U2
(
.CLK(CLK),
.RSTn(RSTn),
.HL_Sig(HL_Sig),
.LH_Sig(LH_Sig),
.LED_Out(LED_Out)
);
endmodule
module module_detect
(
CLK,RSTn,Pin_In,HL_Sig,LH_Sig
);
input [1:0]Pin_In;//按键输入//pin_In[1] key[2],pin[0]key[3]
input CLK;
input RSTn;
output [1:0]HL_Sig;//输出信号
output [1:0]LH_Sig;//输出信号
/*************************************/
reg [3:0]HL_Sig1;
reg [3:0]HL_Sig2;
reg [3:0]LH_Sig1;
reg [3:0]LH_Sig2;
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
HL_Sig1<=2'b11;//高电平到低电平
HL_Sig2<=2'b11;
LH_Sig1<=2'b00;
LH_Sig2<=2'b00;//低电平到高电平
end
else
begin
HL_Sig1[1:0]<=Pin_In[1:0];
HL_Sig2[1:0]<=HL_Sig1[1:0];
LH_Sig1[1:0]<=Pin_In[1:0];
LH_Sig2[1:0]<=LH_Sig1[1:0];
end
assign HL_Sig[0]=(HL_Sig1[0]^HL_Sig2[0]);
assign HL_Sig[1]=(HL_Sig1[1]^HL_Sig2[1]);
assign LH_Sig[0]=(LH_Sig2[0]^LH_Sig1[0]);
assign LH_Sig[1]=(LH_Sig2[1]^LH_Sig1[1]);
endmodule
module module_delay
(
CLK,RSTn,LED_Out,HL_Sig,LH_Sig
);
input CLK;
input RSTn;
input [1:0]HL_Sig;//高到低跳变沿
input [1:0]LH_Sig;//低到高跳变沿
output [9:0]LED_Out;
/******************************/
//计数器 延时10ms
parameter T10MS=20'd499_999;
reg [19:0] Count;
reg isCount;//是否计数
reg isCount1;//
always@(posedge CLK or negedge RSTn)
if(!RSTn)
Count<=20'd0;
else if(Count==T10MS)
Count<=20'd0;
else if(!isCount&&!isCount1)//当一个计数的时候,另一个标志位必定为0,所以当全为0的时候才清0
Count<=20'd0;
else if(isCount||isCount1)//有一个为一则开始计数
Count<=Count+1'b1;
/******************************/
//单独用该模块不好用
/******************************/
reg [1:0]rPin_Out;
reg [2:0]i1;
/*always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
i1<=2'd0;
rPin_Out[1]<=1'b0;
isCount1<=1'd0;
end
else
case(i)
2'd0: if(HL_Sig[1])i1<=2'd1; else if(LH_Sig[1]) i1<=2'd2;
2'd1: if(Count==T10MS)
begin
i1<=2'd0;
isCount1<=1'd0;
rPin_Out[1]<=1'b1;
end
else isCount1<=1'd1;
2'd2:if(Count==T10MS)
begin
i1<=2'd0;
isCount1<=1'd0;
rPin_Out[1]<=1'b0;
end
else isCount1<=1'd1;
endcase
*/
//按键key【2】
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
i1<=3'd0;
rPin_Out[1]<=1'b0;//输出置0
isCount1<=1'b0; //停止计数
end
else
case(i1)
3'd0:
if(HL_Sig[1])i1<=3'd1;else if(LH_Sig[1])i1<=3'd2;
3'd1:begin
if(Count==T10MS) //如果延时结束
begin
isCount1<=1'b0; //停止计数
rPin_Out[1]<=1'd1;//电平拉高
i1<=3'd2; //
end
else isCount1<=1'b1; //不满足延时条件,计数
end
3'd2:begin
rPin_Out[1]<=1'd0;//拉低电平
i1<=3'd0;
end
3'd3:begin
if(Count==T10MS)
begin
isCount1<=1'b0;
i1<=3'd0;
end
else isCount1<=1'b1;
end
endcase
/*************************************/
//单独用这个模块好用
reg[2:0]i;
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
i<=3'd0;
rPin_Out[0]<=1'b0;//输出置0
isCount<=1'b0; //停止计数
end
else
case(i)
3'd0:
if(HL_Sig[0])i<=3'd1;else if(LH_Sig[0])i<=3'd3;
3'd1:begin
if(Count==T10MS) //如果延时结束
begin
isCount<=1'b0; //停止计数
rPin_Out[0]<=1'd1;//电平拉高
i<=3'd2; //
end
else isCount<=1'b1; //不满足延时条件,计数
end
3'd2:begin
rPin_Out[0]<=1'd0;//拉低电平
i<=3'd0;
end
3'd3:begin
if(Count==T10MS)
begin
isCount<=1'b0;
i<=3'd0;
end
else isCount<=1'b1;
end
endcase
/*******************************************/
reg[9:0]rLED_Out;
always@(posedge CLK or negedge RSTn)
if(!RSTn)
rLED_Out<=10'b0000010000;
else if(rPin_Out[0]) rLED_Out<=rLED_Out<<1;
else if(rPin_Out[1]) rLED_Out<=rLED_Out>>1;
else if(rLED_Out==10'b0) rLED_Out<=10'b0000001000;
/****************************************/
assign LED_Out=rLED_Out;
endmodule