|
@@ -0,0 +1,105 @@
|
|
|
+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
|