顶层模块
module key_filter_led
(
input wire CLK,
input wire RST,
input wire [2:0] KEY,
output wire [3:0] LED
);
wire [2:0] FLAG;
wire [2:0] KEY_VALUE;
key_filter u_key_filter
(
.clk (CLK),
.rst (RST),
.key (KEY),
.flag (FLAG),//判断
.key_value(KEY_VALUE) //消抖后的key
);
led u_led
(
. clk (CLK),
. rst (RST),
.flag (FLAG),
.key_value(KEY_VALUE),
. led (LED)
);
endmodule
按键消抖模块
module key_filter
(
input clk,
input rst,
input wire [2:0] key,
output reg [2:0] flag,//判断
//output reg key_value //消抖后的key
output reg [2:0] key_value //消抖后的key,多个按键消抖
);
parameter delay=20'd999_999;//10ms
reg [19:0] delay_cnt;//延时计数器
reg [2:0]key_reg;//中间变量,存放当前按键信号的寄存器类型的值,用于和下一次信号按键的值作对比
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
begin
delay_cnt <=20'd0;
key_reg[0] <=1'd1; //初始化中间值
key_reg[1] <=1'd1; //初始化中间值
key_reg[2] <=1'd1; //初始化中间值
end
else
begin
key_reg[0] <= key[0];
key_reg[1] <= key[1];
key_reg[2] <= key[2];
if((key_reg[0] !=key[0])||(key_reg[1] !=key[1])||(key_reg[2] !=key[2]) )//不等,此时有抖动
delay_cnt <= delay;//开始倒计时,直到delay_cnt为零为止(开始进入延时消抖状态)
else
begin
if(delay_cnt >20'd0)//如果延时延时寄存器大于0,说明延时未结束,继续倒计时
delay_cnt<= delay_cnt -20'd1;
else
delay_cnt<=20'd0;//如果延时计时器小于等于0,那么延时计时器归0,延时结束
end
end
end
//根据延时寄存器获取key[0]状态及其稳定的信号
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
begin
flag[0] <= 1'b0;//抖动标志,初始化为0
key_value[0] <=1'b1;//记录稳定信号,初始化为1,高电平有效
end
else if(delay_cnt == 20'd0)
begin
flag[0] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
key_value[0] <= key[0];//key_value[0]保存key[0]的稳定信号,
end
else
begin
flag[0] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
key_value[0] <= key_value[0];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
end
end
//根据延时寄存器获取key[1]状态及其稳定的信号
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
begin
flag[1] <= 1'b0;//抖动标志,初始化为0
key_value[1] <=1'b1;//记录稳定信号,初始化为1,高电平有效
end
else if(delay_cnt == 20'd0)
begin
flag[1] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
key_value[1] <= key[1];//key_value区key的稳定信号,
end
else
begin
flag[1] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
key_value[1] <= key_value[1];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
end
end
//根据延时寄存器获取key[2]状态及其稳定的信号
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
begin
flag[2] <= 1'b0;//抖动标志,初始化为0
key_value[2] <=1'b1;//记录稳定信号,初始化为1,高电平有效
end
else if(delay_cnt == 20'd0)
begin
flag[2] <= 1'b1;//已经消抖,延时计时器完成了,改变消抖状态为1
key_value[2] <= key[2];//key_value区key的稳定信号,
end
else
begin
flag[2] <= 1'b0;//消抖未完成,延时计时器未结束,flag仍为0
key_value[2] <= key_value[2];//消抖未完成,延时计时器未结束,key未进入稳定状态,key_value不计key的值,直到key稳定才计入
end
end
endmodule
小灯模块
module led
(
input wire clk,
input wire rst,
input [2:0] flag,
input [2:0] key_value,
output reg [3:0] led
);
reg [25:0] cnt;
parameter T=26'd50_000_000;
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
cnt<= 26'd0;
else if(cnt == T-26'd1)
cnt <=26'd0;
else
cnt <= cnt + 26'd1;
end
//
always @(posedge clk or negedge rst)
begin
if(rst==1'b0)
begin
led <= 4'b1110;
end
else if(flag[0]==1'b1 &&key_value[0] == 1'b0)
begin
if(cnt== T-26'd1)
led <= {led[2:0],led[3]};
else
led<=led;
end
else if(flag[1]==1'b1 &&key_value[1] == 1'b0)
begin
if(cnt== T-26'd1)
led <= ~led;
else
led<=led;
end
else if(flag[2]==1'b1 &&key_value[2] == 1'b0)begin
led <=4'b0101;
end
else begin
led <=4'b1110;
end
end
endmodule