Often we use buttons or switches as inputs of a sequential circuit. The circuit looks like this:
Debouncer
For example, you implement a counter inside your FPGA. When press one button, it increases by one, and when press another one, it decreases by one.
You press the button ten times but the counter increases by 33. It's not nice.
Synchronizer
First, the button signals is asynchronous which means they don't have a associated clock. That will put the register into metastable state.
The solution is to use a synchronizer circuit that will safely bring an asynchronous signal into a clock domain. Here is a simple synchronizer circuit.
1-bit 2 Flip-Flop Synchronizer
Edge Detector
Edge Detector convert the low-to-hign transition of a button press to a clock wide pulse.
an edge detector
Here is the timing diagram.
Edge Detector Timing Diagram
Debouncer
Here is a simple debouncer circuit. Note that we have implemented synchronizer before.
Architecture of a simple debouncer circuit. Source
The basic idea is to use a counter to time how long the switch signal has been high. If the signal has been high continuously for a set amount of time, then it is considered pressed and stable.
How to choose sensible SAMPLE_COUNT_MAX and PULSE_COUNT_MAX?