按键消抖
1. 原理

2. 关键程序实现
always @(posedge clk or negedge rst) beginif(!rst)begincnt_wait <= 26'd0;end else if(flag_nege || flag_pose)begincnt_wait <= 26'd1;end else if(cnt_wait == MAX_CNT) begincnt_wait <= 26'd0;end else if(cnt_wait > 26'd0 && cnt_wait < MAX_CNT)begincnt_wait <= cnt_wait + 26'd1;end
endalways @(posedge clk or negedge rst) beginif(!rst)beginkey_scan1 <= 4'b1111;key_scan2 <= 4'b1111;end else if(cnt_wait == MAX_CNT)beginkey_scan1 <= key_in;key_scan2 <= key_scan1;end else beginkey_scan2 <= key_scan1;end
end
3. 仿真波形

4. 源代码
module key(input clk ,input rst ,input [ 3:0] key_in ,output [ 3:0] key_out_down , output [ 3:0] key_out_up
);wire key_tmp = &key_in ;reg key_in_r2 ;
reg key_in_r1 ;always @(posedge clk or negedge rst)beginif(!rst)beginkey_in_r1 <= 1'b1;key_in_r2 <= 1'b1;end else beginkey_in_r1 <= key_tmp;key_in_r2 <= key_in_r1;end
endwire flag_nege = key_in_r2 & !key_in_r1;
wire flag_pose = !key_in_r2 & key_in_r1;reg [ 25:0] cnt_wait ;
localparam MAX_CNT = 1_000_000 - 1 ;
always @(posedge clk or negedge rst) beginif(!rst)begincnt_wait <= 26'd0;end else if(flag_nege || flag_pose)begincnt_wait <= 26'd1;end else if(cnt_wait == MAX_CNT) begincnt_wait <= 26'd0;end else if(cnt_wait > 26'd0 && cnt_wait < MAX_CNT)begincnt_wait <= cnt_wait + 26'd1;end
endreg [ 3:0] key_scan1 ;
reg [ 3:0] key_scan2 ;
always @(posedge clk or negedge rst) beginif(!rst)beginkey_scan1 <= 4'b1111;key_scan2 <= 4'b1111;end else if(cnt_wait == MAX_CNT)beginkey_scan1 <= key_in;key_scan2 <= key_scan1;end else beginkey_scan2 <= key_scan1;end
end
wire [ 3:0] kay_val_down = ~key_scan1 & key_scan2;
wire [ 3:0] kay_val_up = key_scan1 & ~key_scan2;assign key_out_down = kay_val_down;
assign key_out_up = kay_val_up;endmodule