diff --git a/rtl/io/taxi_debounce_switch.sv b/rtl/io/taxi_debounce_switch.sv new file mode 100644 index 0000000..9bcb275 --- /dev/null +++ b/rtl/io/taxi_debounce_switch.sv @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: CERN-OHL-S-2.0 +/* + +Copyright (c) 2014-2025 FPGA Ninja, LLC + +Authors: +- Alex Forencich + +*/ + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Synchronizes switch and button inputs with a slow sampled shift register + */ +module taxi_debounce_switch #( + // width of the input and output signals + parameter WIDTH = 1, + // length of shift register + parameter N = 3, + // clock division factor + parameter RATE = 125000 +) +( + input wire logic clk, + input wire logic rst, + + input wire logic [WIDTH-1:0] in, + output wire logic [WIDTH-1:0] out +); + +localparam CNT_W = $clog2(RATE); + +logic [CNT_W-1:0] cnt_reg = '0; +logic strb_reg = 1'b0; + +logic [N-1:0] debounce_reg[WIDTH-1:0]; + +logic [WIDTH-1:0] state_reg = '0; + +assign out = state_reg; + +always_ff @(posedge clk) begin + strb_reg <= 1'b0; + + if (cnt_reg) begin + cnt_reg <= cnt_reg - 1; + end else begin + cnt_reg <= RATE-1; + strb_reg <= 1'b1; + end + + if (strb_reg) begin + for (integer k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= {debounce_reg[k][N-2:0], in[k]}; + end + end + + for (integer k = 0; k < WIDTH; k = k + 1) begin + if (|debounce_reg[k] == 0) begin + state_reg[k] <= 1'b0; + end else if (&debounce_reg[k] == 1) begin + state_reg[k] <= 1'b1; + end + end + + if (rst) begin + cnt_reg <= '0; + state_reg <= '0; + + for (integer k = 0; k < WIDTH; k = k + 1) begin + debounce_reg[k] <= '0; + end + end +end + +endmodule + +`resetall