module sync_debouncer_10ms (

// OUTPUTs
    signal_debounced,          // Synchronized and 10ms debounced signal

// INPUTs
    clk_50mhz,                 // 50MHz clock
    rst,                       // reset
    signal_async               // Asynchonous signal
);

// OUTPUTs
//=========
output     signal_debounced;   // Synchronized and 10ms debounced signal

// INPUTs
//=========
input      clk_50mhz;          // 50MHz clock
input      rst;                // reset
input      signal_async;       // Asynchonous signal


// Synchronize signal
reg [1:0] sync_stage;
always @(posedge clk_50mhz or posedge rst)
  if (rst) sync_stage <= 2'b00;
  else     sync_stage <= {sync_stage[0], signal_async};

wire signal_sync = sync_stage[1];


// Debouncer (10.48ms = 0x7ffff x 50MHz clock cycles)
reg [18:0] debounce_counter;
always @(posedge clk_50mhz or posedge rst)
  if (rst)                               debounce_counter <= 19'h00000;
  else if(signal_debounced==signal_sync) debounce_counter <= 19'h00000;
  else                                   debounce_counter <= debounce_counter+1;

wire debounce_counter_done = (debounce_counter==19'h7ffff);

// Output signal
reg signal_debounced;
always @(posedge clk_50mhz or posedge rst)
  if (rst)                       signal_debounced <= 1'b0;
  else if(debounce_counter_done) signal_debounced <= ~signal_debounced;


endmodule