// Error using $clog2? // Example: // If sample_count_max == 8, clog2 == 3, meaning we must make sample/sat counter [width:0] instead of // [width-1:0]. If sample_count_max is not pow(2), then we always have an unused MSB? // Isn't the typical way to find bits floor(val) + 1? To account for this edge case? module debouncer #( parameter width = 1, parameter sample_count_max = 25000, parameter pulse_count_max = 150, parameter wrapping_counter_width = $clog2(sample_count_max), // isn't this wrong? parameter saturating_counter_width = $clog2(pulse_count_max)) // should be floor(val) + 1? ( input clk, input [width-1:0] glitchy_signal, output [width-1:0] debounced_signal ); wire sample_now; wire [width-1:0] enable, rst; reg [wrapping_counter_width:0] sample_counter = 0; reg [saturating_counter_width:0] sat_counter [width-1:0]; // Is there not a better way to initialize a 2D array to 0? integer u; initial begin for (u=0; u<width; u=u+1) begin sat_counter[u] = 0; end end /* verilator lint_off WIDTH */ assign sample_now = (sample_counter == sample_count_max); assign enable = {width{sample_now}} & glitchy_signal; assign rst = ~glitchy_signal; // not used, see below always @(posedge clk) begin if (sample_counter == sample_count_max) begin sample_counter <= 0; end else begin sample_counter <= sample_counter + 1; end end genvar i; generate for (i=0; i<width; i=i+1) begin:SATURATE always @(posedge clk) begin if (rst[i]) // why does using rst[i] cause 1 cycle delay?!? sat_counter[i] <= 0; else if (enable[i] && (sat_counter[i] != pulse_count_max)) sat_counter[i] <= sat_counter[i] + 1; else sat_counter[i] <= sat_counter[i]; end assign debounced_signal[i] = (sat_counter[i] == pulse_count_max); end endgenerate /* lint on */ endmodule