We are making a 4-channel tachometer module. After a bunch of analog stuff, four logic signals run into an FPGA to be processed. The fpga will use a 50 MHz clock for the tach logic.
I used OPA197 opamps as the comparators. Their outputs run through a short ribbon cable from the analog board to the FPGA board. The edges are kinda slow, > 1 us, and might pick up noise, so I figure we should debounce them digitally in the FPGA.
Suggestions?
One could push the signal into a long shift register clocked at 50 MHz. All 1's could set a flop and all 0's could clear it. Maybe 32 flops long? Clumsy.
Or some sort of up/down counter?
Didn't find your answer? Ask the community — no account required.
J
JM
Courtesy of Google AI. Carefull it doesn't burn your house down and run away with your wife.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;
entity debouncer is generic ( -- For a 50 MHz clock, 1,000,000 cycles = 20 ms BOUNCE_LIMIT : integer := 1000000 ); port ( clk : in std_logic; rst : in std_logic; raw_in : in std_logic; clean_out: out std_logic ); end entity debouncer;
architecture rtl of debouncer is -- Synchronizer stages signal sync_0 : std_logic := '0'; signal sync_1 : std_logic := '0'; -- Debounce counter and internal state signal count : integer range 0 to BOUNCE_LIMIT := 0; signal stable_state: std_logic := '0'; begin
-- Output assignment clean_out <= stable_state;
process(clk, rst) begin if rst = '1' then sync_0 <= '0'; sync_1 <= '0'; count <= 0; stable_state <= '0'; elsif rising_edge(clk) then -- 2-stage synchronizer to prevent metastability sync_0 <= raw_in; sync_1 <= sync_0; -- Debounce logic if sync_1 /= stable_state then -- Input changed, start/continue counting if count < BOUNCE_LIMIT then count <= count + 1; else -- Input remained stable long enough stable_state <= sync_1; count <= 0; end if; else -- Input matches current stable state, reset counter count <= 0; end if; end if; Process;
end architecture rtl;
B
Buzz McCool
The "Not Too Shifty!" section of
formatting link
similar to what you propose.
P
Phil Hobbs
Or use an up/down counter on the 50 MHz with the analog input controlling up/down. On state 0, reset the output, and on state N-1, set it.
Load the counter appropriately if it tries to wrap. I could uncoil my rusty Verilog, but it’s a pretty simple gizmo, and probably saves space vs a long register.
Cheers
Phil Hobbs
S
Sergey Kubushyn
8-stage is sufficient. Just don't forget to poison it on startup. Trivial to implement in an FPGA.
If it is news, the shift register thing is a digital LPF.
Here is a many decades old classic, still in production and readily available:
formatting link
D
Don Y
Naw, I think it's got a crush on Claude...
A smarter move is usually to signal the change and THEN debounce. I.e., ignore bouncing AFTER the initial transition
Otherwise, your signal transitions are delayed by the debounce interval.
C
chrisq
Read the state of the contact and log, wait a debounce time, say
20mS, then read again to verify, Play with time delay and > 1 verification cycles to make more robust.
In software, like this, many projects:
Interrupt handler fragment, from system clock tick isr.
C
chrisq
Sorry, cut and paste, lost the formatting.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.