Push buttons are made of mechanical components, including contacts and a spring. When a push button is pressed or released, it can briefly suffer of high speed oscillations. If these oscillations are not filtered, a single push can be mistakenly interpreted as several pushes. Those oscillations are also known as contact bouncing, and the filter in charge of cleaning those spurious oscillations, is called a debouncer.
The VHDL code below does exactly that. It debounces a push button input.
The first block of code, shown above, is a clock divider (using the downcounter cnt_deb). The definitions for the clock divider are on the debounce_pack file that is shown below. The clock divider takes the system clock (in this case, 100MHz), and generates a clock_en signal with a period of 500us.
The pushbutton input will be sampled using this enable signal, namely, it will be sampled every 500us.
The logic for the debouncing is to use an up/down counter with saturation (cnt_threshold). Each time the push button input is sampled high, the counter is incremented. If the maximum count is reached, the counter stays at the maximum count. If it is sampled low, the counter is decremented. If zero is reached, the counter stays at the value zero and does not wrap around.
Two thresholds are defined in the package file, a high and a low threshold, one at 10% of the counts and one at 90% of the counts.
Let’s say the push button was depressed for a long time. The counter cnt_threshold with saturation is at its maximum count. Now the push button is pressed. There can be some mechanical oscillations. The counter should start counting down. Because of the oscillations, it could briefly count up again. But once the button is stabilized, a steady down counting is achieved.
Only when the counter reaches 10% of its maximum (3 counts), the output pb_deb changes to low.
When the button is released, the counter starts counting up. When it reaches 27, the output pb_deb changes to high.
The combined use of low speed sampling (500us), a counter, and hysteresis for the decision about the output value, effectively filters contacts bounces.
The source files can be downloaded here.