123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- 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
|