EECS151 / fpga_labs_fa20 / lab5 / src / debouncer.v
debouncer.v
Raw
module debouncer #(
    parameter width = 1,
    parameter sample_count_max = 25000,
    parameter pulse_count_max = 150,
    parameter wrapping_counter_width = $clog2(sample_count_max),
    parameter saturating_counter_width = $clog2(pulse_count_max))
(
    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-1:0] sample_counter = 0;
    reg [saturating_counter_width-1:0] sat_counter [width-1: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-1); // sample_count_max cycles
    assign enable = {width{sample_now}} & glitchy_signal;
    assign rst = ~glitchy_signal; 

    always  @(posedge clk) begin 
        if (sample_counter == sample_count_max-1) 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])
                    sat_counter[i] <= 0;
                else if (enable[i] && (sat_counter[i] != pulse_count_max-1))
                    sat_counter[i] <= sat_counter[i] + 1; 
            end

            assign debounced_signal[i] = (sat_counter[i] == pulse_count_max-1);    
        end
    endgenerate
    /* lint on */

endmodule