
基于状态机的设计代码
cs
module key_filter(
clk,
rst,
key,
key_p_flag,
key_r_flag,
key_state
);
input clk,rst;
input key;
output reg key_p_flag;
output reg key_r_flag;
output reg key_state;
reg [1:0]r_key; //后面用来判断什么时候pedge,什么时候nedge
always@(posedge clk)
r_key<={r_key[0],key}; //位拼接
wire pedge_key;
assign pedge_key=r_key==2'b01; //识别到key的上升沿
wire nedge_key;
assign nedge_key=r_key==2'b10; //识别到key的下降沿
reg [19:0]cnt;
localparam IDLE=0;
reg [1:0]state;
always@(posedge clk or negedge rst)
if(!rst)begin
state<=0;
key_r_flag<=0;
key_p_flag<=0;
cnt<=0;
key_state<=1;
end
else begin
case (state)
0:
begin
key_r_flag<=0;
if(nedge_key)
state<=1;
else
state<=0;
end
1:
if((pedge_key)&&(cnt<1000000-1))
begin
cnt<=0;
state<=0;
end
else if(cnt>=1000000-1)
begin
state<=2;
cnt<=0; //给计数器清零,为下一次计数做准备
key_p_flag<=1;
key_state<=0;
end
else
begin
state<=1;
cnt<=cnt+1;
end
2:
begin
key_p_flag<=0;
if(pedge_key)
state<=3;
else
state<=2;
end
3:
if((nedge_key)&&(cnt<1000000-1))
begin
state<=2;
state<=0;
end
else if(cnt>=1000000-1)
begin
state<=0;
cnt<=0; //给计数器清零,为下一次计数做准备
key_r_flag<=1;
key_state<=1;
end
else
begin
state<=3;
cnt<=cnt+1;
end
endcase
end
endmodule
testbench代码
cs
`timescale 1ns / 1ps
module key_filter_tb();
reg clk,rst;
reg key;
wire key_p_flag;
wire key_r_flag;
wire key_state;
key_filter key_filter(
clk,
rst,
key,
key_p_flag,
key_r_flag,
key_state
);
initial clk=1;
always #10 clk=~clk;
initial begin
rst=0;
key=1;
#201;
rst=1;
#3000;
key=0;
#20000; //20ns,模拟按键抖动
key=1;
#30000; //30ns,模拟按键抖动
key=0;
#20000; //20ns,模拟按键抖动
key=1;
#30000; //30ns,模拟按键抖动
key=0;
#50000000; //50ms
key=1;
#20000; //20ns,模拟按键抖动
key=0;
#30000; //30ns,模拟按键抖动
key=1;
#20000; //20ns,模拟按键抖动
key=0;
#30000; //30ns,模拟按键抖动
key=1;
#50000000; //50ms
$stop;
end
endmodule
仿真验证波形

在按下抖动的过程中,key在抖动但是p_flag并没有出现高脉冲 ,直到稳定了20ms后p_flag出现了高脉冲。

并只稳定了一个时钟周期后就变为0

R_flag也是同样

在输出端再加入一个key_state,模拟什么时候确定按键按下,什么时候按键释放
