FPGA-RISC-V-CPU / hardware / src / io_circuits / debouncer.v
debouncer.v
Raw
module debouncer #(
  parameter WIDTH              = 1,
  parameter SAMPLE_CNT_MAX     = 25000,
  parameter PULSE_CNT_MAX      = 150,
  parameter WRAPPING_CNT_WIDTH = $clog2(SAMPLE_CNT_MAX) + 1,
  parameter SAT_CNT_WIDTH      = $clog2(PULSE_CNT_MAX) + 1
) (
  input clk,
  input [WIDTH-1:0] glitchy_signal,
  output [WIDTH-1:0] debounced_signal
);

  // TODO: Your code
  wire en;
    
    reg [WRAPPING_CNT_WIDTH:0] wrapping_counter = 0;
    reg [SAT_CNT_WIDTH:0] saturating_counter [WIDTH-1:0];
    integer k;
    initial begin
        for (k = 0; k < WIDTH; k = k + 1) begin
            saturating_counter[k] = 0;
        end
    end
    assign en = (wrapping_counter >= SAMPLE_CNT_MAX[WRAPPING_CNT_WIDTH:0]);
    always @(posedge clk) begin
        case (en)
            1'b0: wrapping_counter <= wrapping_counter + 1'd1;
            1'b1: wrapping_counter <= 0;
        endcase
    end
    always @(posedge clk) begin
        for (k = 0; k < WIDTH; k = k + 1) begin
            if (en & glitchy_signal[k]) begin
                saturating_counter[k] <= saturating_counter[k] + 1'd1;
            end
            if (~glitchy_signal[k]) begin
                saturating_counter[k] <= 0;
            end
        end
    end

    genvar i;
    generate
    for (i = 0; i < WIDTH; i = i + 1) begin
        assign debounced_signal[i] = (saturating_counter[i] >= PULSE_CNT_MAX[SAT_CNT_WIDTH:0]);
    end
    endgenerate

endmodule