一、Code
module key_debounce( // input input clk_50, input rst_n, input key3,key2,key1, // output output[7:0] ledg ); reg[2:0] key_rst; always@(posedge clk_50 or negedge rst_n) if(!rst_n) key_rst <= 3'b111; else key_rst <= {key3,key2,key1}; reg[2:0] key_rst_r; always@(posedge clk_50 or negedge rst_n) if(!rst_n) key_rst_r <= 3'b111; else key_rst_r <= key_rst; wire[2:0] key_an; //当寄存器key_rst由1变为0时,key_an的值变为高,维持一个时钟周期 assign key_an = key_rst_r & (~key_rst); /* key_rst 1 1 1 0 0 1 ~key_rst 0 0 0 1 1 0 key_rst_r 1 1 1 0 0 1 //滞后key_rst一个时钟周期 key_an 0 0 1 0 0 //由此可以发现当key_rst的一个周期由1变为0时,key_an由0变为1; */ reg[19:0] cnt; //20ns一周期,20ms为10的6次方,相当于2的20次方=1024x1024>1000x1000; always@(posedge clk_50 or negedge rst_n) if(!rst_n) cnt <= 20'b0; else if(key_an) cnt <= 20'b0; else cnt <= cnt+1'b1; reg[2:0] low_key; always@(posedge clk_50 or negedge rst_n) if(!rst_n) low_key <= 3'b111; else if(cnt==20'hfffff) //满20ms,将按键值锁存到寄存器low_key中 low_key <= {key3,key2,key1}; reg[2:0] low_key_r; //每个时钟的上升沿将low_key信号锁存到low_key_r中 always@(posedge clk_50 or negedge rst_n) if(!rst_n) low_key_r <= 3'b111; else low_key_r <= low_key; wire[2:0] led_ctrl; //当寄存器low_key由1变为0时,led_ctrl的值变高,维持一个时钟周期 /* low_sw 111 111 111 110 110 110 ~low_sw 000 000 000 001 001 001 low_sw_r 111 111 111 110 110 110 led_ctrl 000 000 000 001 000 000 */ assign led_ctrl = low_key_r[2:0] & (~low_key[2:0]); reg ledg3,ledg2,ledg1; always@(posedge clk_50 or negedge rst_n) if(!rst_n) begin ledg3 <= 1'b0; ledg2 <= 1'b0; ledg1 <= 1'b0; end else begin if(led_ctrl[2]) ledg3 <= ~ledg3; //led翻转输出 if(led_ctrl[1]) ledg2 <= ~ledg2; if(led_ctrl[0]) ledg1 <= ~ledg1; end assign ledg[3] = ledg3 ? 1'b1 : 1'b0; assign ledg[2] = ledg2 ? 1'b1 : 1'b0; assign ledg[1] = ledg1 ? 1'b1 : 1'b0; endmodule