module button_trigger # ( parameter CLOCK_FREQUENCY = 100_000_000, parameter DEBOUNCE_MILLIS = 40 ) ( input logic clock, input logic reset, input logic raw_button, output logic trigger_signal ); localparam DEBOUNCE_COUNTER_MAX = (CLOCK_FREQUENCY / 1000) * DEBOUNCE_MILLIS; logic [$clog2(DEBOUNCE_COUNTER_MAX)-1:0] counter; enum logic [1:0] { ST_IDLE, ST_FILTER, ST_RELEASE } state; always_ff @(posedge clock, posedge reset) begin if(reset) begin state <= ST_IDLE; counter <= 'bx; trigger_signal <= '0; end else case(state) ST_IDLE: begin if(raw_button) begin counter <= DEBOUNCE_COUNTER_MAX; state <= ST_FILTER; end end ST_FILTER: begin if(!raw_button) state <= ST_IDLE; else if(counter > 0) counter <= counter - 1; else begin trigger_signal <= '1; state <= ST_RELEASE; end end ST_RELEASE: begin trigger_signal <= '0; if(!raw_button) state <= ST_IDLE; end default: state <= ST_IDLE; endcase end endmodule