module debouncer#( parameter WIDTH = 20, parameter LAG = 250000 )( input wire clk, input wire nrst, input wire butt, output reg filtered ); reg [WIDTH-1:0] cnt; reg prev_butt; reg butt_buff;//just to make button synced with clock always @(posedge clk or negedge nrst) begin if(!nrst) begin cnt<=LAG; butt_buff<=0; prev_butt<=0; filtered<=0; end else begin if (prev_butt == butt_buff) begin if (cnt) begin cnt <= cnt-1; end else begin filtered <= butt_buff; end end else begin cnt <= LAG; end prev_butt <= butt_buff; butt_buff <= butt; end end endmodule module button#( parameter WIDTH = 24,//2^24 corresponds to 0.67s max time parameter DEBOUNCE_LAG = 250000, //250000 = 10ms parameter FIRST_CLICK = 2500000,//100ms -> 2500000 parameter FREQ_START = 8333333,//(1/f) 3Hz -> 333ms -> 8333333 //parameter FREQ_DECREMENT = 12,// hardcoded -> percentage * 16: 12 -> 12/16 = 75% of prev each loop parameter FREQ_MAX = 1250000//(1/f) 20Hz -> 50ms -> 1250000 )( input wire clk, //25MHz input wire nrst, input wire butt, output reg [31:0] press_count ); reg butt_filt; reg [WIDTH-1:0] time_cntr; //reg [WIDTH-1:0] curr_period; reg [WIDTH-1:0] next_period; reg [WIDTH-1:0] period_decremented; reg is_pressed; reg if_increment; debouncer#(.LAG(DEBOUNCE_LAG)) deb( .clk(clk), .nrst(nrst), .butt(butt), .filtered(butt_filt) ); always @(posedge clk or negedge nrst) begin if(!nrst) begin press_count<=0; time_cntr<=FIRST_CLICK; next_period<=FREQ_START; is_pressed<=0; if_increment<=0; end else begin if_increment <= 0; if(is_pressed) begin if (time_cntr==0) begin if_increment <= 1; time_cntr <= next_period; if (period_decremented < FREQ_MAX) begin next_period <= FREQ_MAX; end else begin next_period <= period_decremented; end end else begin time_cntr <= time_cntr-1; end end else begin time_cntr<=FIRST_CLICK; next_period<=FREQ_START; end is_pressed <= butt_filt; press_count <= press_count + (if_increment | (!is_pressed & butt_filt)); //period_decremented <= (next_period>>4)*FREQ_DECREMENT; // we loose some prec here, but who cares with this time resolution //12=0b1100 period_decremented <= ({next_period,1'h0} + {1'h0,next_period})>>2; end end endmodule