EECS151 / fpga_labs_fa20 / lab4 / src / debouncer.v
debouncer.v
Raw
// 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