Electronics > FPGA

FPGA interface to AT328p debouncing

(1/3) > >>

Hey guys, my first time posting on EEVBlog. I am having problems interfacing an AT328p to an FPGA. The FPGA runs at 3.3 V logic levels, so I required a voltage level shifter between the MCU and the FPGA to drop the voltage from 5 V to 3.3 V. I'm using a push pull voltage follower (NPN and PNP) transistor (see attached diagram) to achieve this and it works well up to 1 MHz, with a rise and fall time of around 20 ns which is more than enough for my application. The problem arises when trying to send a square wave from the AT328 to the FPGA, in this case I have 1 pin connected to the clock input of a shift register on the FPGA and another pin for data. With a single pulse from the AT328 i get multiple shifts on the register in the FPGA. Its not behaving at all stable and seems to give random results (1 clock pulse from the AT328p translates to about 5+ clock pulses on the FPGA shift register). The waveform looks fine on the scope. I'm dumbfounded by this problem, as I've thought of everything and I can't seem to find the cause.

Previously before implementing the NPN/PNP level shifter I was using a resistor voltage divider to drop the voltage from the AT328, that was yielding better results in terms of less bounce (2+ clock pulses for every 1 clock pulse from the AT328). I initially though the bounce was due to a slow rise time (it was around 2 us) hence why I switched to using a transistor level shifter, however as evidenced the shorter rise time causes more clock bounces. Does anyone have insight, is this a normal problem with FPGAs? I can provide scope waveforms etc if required.

Thanks :)

I don't get it.  Why aren't you using a simple resistor divider?
You can try 74LV/LVC logic.  It has 5v tolerant inputs and can run at 3.3v

Also, you seem to be using the Altera simple logic gate equivalent instead of writing HDL code and using a synchronous clock.  With a clocked FPGA, it would be possible to software remove signal bounce on slow input signals.

Also, depending on the chosen FPGA, there are slew rate settings and IO standard settings for each IO pin which may help.  IE, switch the IO from LVTTL to LVCMOS may change the trigger threshold point.

Thanks for the suggestions. I originally was using a resistor divider, then decided to change it because I thought the rise time was too slow. The rise time was limited by the RC constant due to the gate capacitance of the FPGA. I guess I could have used smaller resistors but didn't want them burning up.

I will try changing the IO to LVCMOS and see if that helps. If not I will play with the IO settings and report back


You also have a logic bomb with your 'IN_REG_STORE_SIG'.  It will only occasionally pulse or function randomly within each compile and may potentially pulse for no reason during an increment while you will never know how wide that pulse will end up being.

FPGAs really perform well with clocked synchronous designs and you only reserve piping signals through an FPGA in such an asynchronous/combinational logic method in really controlled circumstances and only when you know what you are doing.


I tried using LVCMOS and no difference, so I tried using your suggestion for a synchronous design. To achieve this I used a D flip flop to gate the 'COMMS_CLK' using the FPGA clock source (25 MHz). The flip flop is reset once the 'COMMS_CLK' goes low. I tested the design in hardware and its working perfectly now.

Thanks for the help :D


[0] Message Index

[#] Next page

There was an error while thanking
Go to full version