Verilog实现的多个按键消抖(具体模块可用)

由于前面已经分享过了,这里直接说思路,贴代码。原理等等其他的翻前面的博文。(代码经过验证,可以在板机上使用)

1,逻辑功能

四个独立按键分别对应四个led灯,按键控制led的反转。

2,设计思路

这里的思路其实很简单,基于按键的抖动最长为20ms,所以每20ms取一次按键状态,前后两次进行下降沿检测就行。(有没有很简单,还有一个更简单的!!!后面代码中分享)贴张图

3,实验代码

module key_filter(clk,rst_n,key_in,led 
    );
input clk;
input rst_n;
input [3:0] key_in;

output [3:0] led;
//这两段代码前面分别进行计数和在计数满产生一个高脉冲信号cnt_full
//20ms计数器
reg cnt_full;
reg [19:0] cnt;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		cnt <= 20'd0;
	else if(cnt == 20'd999_999)
			cnt <= 20'd0;
		 else 
			cnt <= cnt + 1'b1; 	 
end
//计数满信号
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		cnt_full <= 1'b0;
	else if(cnt == 20'd999_999)
			cnt_full <= 1'b1;
		 else 
		 	cnt_full <= 1'b0;
end

//这两段代码就是来用实现取前后按键信号的
reg [3:0] key_in_r;
reg [3:0] key_in_r_next;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		key_in_r_next <= 4'b1111;
	else if(cnt_full)
			key_in_r_next <= key_in;
		 else 
		 	key_in_r_next <= key_in_r_next;
end
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		key_in_r <= 4'b1111;
	else
		key_in_r <= key_in_r_next;
end
wire [3:0] key_out;
assign key_out = key_in_r & (~key_in_r_next);

//后面两个单元很简单,控制led翻转
reg [3:0] led_r;
//led翻转
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		led_r <= 4'b0000;
	else 
		begin
			if(key_out == 4'b0001) led_r[0] <= ~led[0];
			if(key_out == 4'b0010) led_r[1] <= ~led[1];
			if(key_out == 4'b0100) led_r[2] <= ~led[2];
			if(key_out == 4'b1000) led_r[3] <= ~led[3];
		end 
end

assign led[0] = led_r[0];
assign led[1] = led_r[1];
assign led[2] = led_r[2];
assign led[3] = led_r[3];
endmodule

4,RTL图

本来不想贴,但是它太漂亮了,,所以分享下,一起感受它的美!!

小惊喜!!!!上边核心代码是不是有点不太好理解??这里有一个新思路,直接计数40ms!!取值两次进行对比即可(两次取值分别在中间和结束,看看和上边图是不是一个意思??)!!!

  • 26
    点赞
  • 124
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值