若要使用开发板上面的四个SW按键来做计数输入,就需要知道一共按了几下按键。
在这种情况下不能像以前设计电路中,简单地使用输入时钟的上升沿来检测按键是否按
下。因为,如果分频以后的时钟频率是10Hz,按键一下按了1 秒钟,那么如果简单地
以时钟的上升沿来检测按键,程序就会认为实际一共按了十下按键。
我们经常使用的键盘也存在这种情况,这里就需要一部分电路来防止上面情况的出
现。
如果要防抖动,就不能用时钟去检测按键的按下状态,而要去检测按键按下或者抬
起的边沿。例如按键按下的时候就检测与按键连接的FPGA 管脚的下降沿,按键松开
的时候就检测与按键连接的FPGA 管脚的上升沿。这样就可以不用理会按键按下的时
间长度,根据按键按下或者抬起的次数来评定计数。
本次实验设计一个防抖动电路,用来检测按键的输入。设置一个计数器,初始数值
为零。用防抖动检测电路来检测SW按键的输入,每检测到一次按键的按下或者抬起,
计数器的数值加一。在数码管显示计数器的数值。
module seg(clk,rst_n,data_in,data_out,data_en); input clk,rst_n ; input [3 :0 ] data_in ; output [7 :0 ] data_out ; output [3 :0 ] data_en ; reg [7 :0 ] data_out ; assign data_en = 4'b1111 ; always @ ( posedge clk or negedge rst_n ) if( !rst_n ) data_out <= 8'b0000_0000 ; else begin case( data_in ) 4'b0000: data_out <= 8'b1111_1100 ; 4'b0000: data_out <= 8'b0110_0000 ; 4'b0000: data_out <= 8'b1101_1010 ; 4'b0000: data_out <= 8'b1111_0010 ; 4'b0000: data_out <= 8'b0110_0110 ; 4'b0000: data_out <= 8'b1011_0110 ; 4'b0000: data_out <= 8'b1011_1110 ; 4'b0000: data_out <= 8'b1110_0000 ; 4'b0000: data_out <= 8'b1111_1110 ; 4'b0000: data_out <= 8'b1111_0110 ; endcase end endmodule
module counter( clk, rst_n, data_in, data_out ); input clk,rst_n ; input data_in ; output [3 :0 ] data_out ; reg [3 :0 ] data_out ; always @ ( posedge clk or negedge rst_n ) if( !rst_n ) data_out <= 4'b0000 ; else begin if( 1'b1 == data_in ) begin if( 4'b1001 <= data_out ) data_out <= 4'b0000 ; else data_out <= data_out + 4'b0001 ; end else data_out <= data_out ; end endmodule
module debounce( clk, rst_n, key_i, key_o ); input clk; input rst_n; input key_i; output key_o; reg key_o; wire key; wire clk_slow; //分频电路 reg [22:0] cnt; reg [25:0] cnt_out; wire key_o_reg ; always @ ( posedge clk or negedge rst_n ) if ( !rst_n ) cnt <= 23'd0; else cnt <= cnt + 1'b1; assign clk_slow = cnt[22]; //防反跳电路 reg temp_r [2:0]; reg key_r; integer i; always @ ( posedge clk_slow or negedge rst_n ) if ( !rst_n ) begin for ( i = 0 ; i < 3; i = i+ 1) temp_r[i] <= 'd0; end else begin temp_r[0] <= key_i; temp_r[1] <= temp_r[0]; temp_r[2] <= temp_r[1]; end assign key = (~temp_r[0]) & temp_r[1] & temp_r[2]; always @ ( posedge clk or negedge rst_n ) if ( !rst_n ) key_r <= 1'b0; else key_r <= key; assign key_o_reg = key & (~key_r); /* always @ ( posedge clk or negedge rst_n ) if( !rst_n ) key_o <= 1'b0 ; else begin if( cnt_out<='d33554432 ) begin if( cnt_out=='d0 ) begin if( key_o_reg ) begin cnt_out <= 'd1 ; key_o <= 1'b1 ; end else begin cnt_out <= 'd0 ; key_o <= 1'b0 ; end end else cnt_out <= cnt_out + 'd1 ; end else cnt_out <= 'd0 ; end */ endmodule
module top_new(clk, key_i, rst_n, data, en); input clk; input key_i; input rst_n; output [7:0] data; output [3:0] en; wire [3:0] XLXN_1; wire XLXN_3; counter XLXI_1 (.clk(clk), .data_in(XLXN_3), .rst_n(rst_n), .data_out(XLXN_1[3:0])); debounce XLXI_2 (.clk(clk), .key_i(key_i), .rst_n(rst_n), .key_o(XLXN_3)); seg XLXI_3 (.clk(clk), .data_in(XLXN_1[3:0]), .rst_n(rst_n), .data_en(en[3:0]), .data_out(data[7:0])); endmodule