--------------------------------------------------------------------------- -- switchDebouncer -- -- This VHDL switch debouncer module, which can be used for multiple -- switches, is Dr. Andrew Greensted's VHDL code available at -- http://www.labbookpages.co.uk/electronics/debounce.html. -- -- Nothing in this module should be modified. --------------------------------------------------------------------------- -- This VHDL module synchronizes and debounces one or more asynchronous -- inputs. It may be used with any of the switch inputs (slide or -- pushbutton) of the Nexys 2 board. -- -- CLK_FREQ should be set to the frequency, in HZ, of the input clock. -- NUM_SWITCHES should be set to the number of switches desired. -- -- The "raw" unsychronized, un-debounced inputs are passed in through -- switchesIn. The processed synchronized, debounced outputs are passed -- out through switchesOut. -- -- This circuit employs a synchronous active high reset. Due to the way -- the circuit is designed, the reset signal should not be debounced by -- the same instantiation of this module for which it is being used as a -- reset. -- -- The DebounceGen generate statement below generates the VHDL code for -- the indivdual synchronize/debounce circuits. The inputs are sampled -- every 500 us. The sample pulse is generated by the SampleGen process -- and each switch uses the single instance of this sample signal. -- The debouncer doesn't set its output high until it sees 20 consecutive -- high samples from its input. The debouncer sets its output low upon -- receipt of a single low sample from its input. -- -- Example use, assuming that we have the following raw inputs: enbl and -- upDown and the corresponding debounced "inputs:" dbEnbl and dbUpDown. -- We also assume a 50 MHz clock, which is the frequency used by the -- Nexys 2 board: -- -- switchesIn <= enbl & upDown; -- dbEnbl <= switchesOut(1); -- dbUpDown <= switchesOut(0); -- -- debounce : SwitchDebouncer -- generic map -- ( -- CLK_FREQ => 50000000, -- NUM_SWITCHES => 2 -- ) -- port map -- ( -- clk => clk, -- reset => reset, -- switchesIn => switchesIn, -- switchesOut => switchesOut -- ); -- --------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity SwitchDebouncer is generic (CLK_FREQ : positive; NUM_SWITCHES : positive); port ( clk : in std_logic; reset : in std_logic; switchesIn : in std_logic_vector(NUM_SWITCHES-1 downto 0); switchesOut : out std_logic_vector(NUM_SWITCHES-1 downto 0)); end SwitchDebouncer; architecture Structural of SwitchDebouncer is signal sample : std_logic; begin SampleGen : process(clk) constant SAMPLE_COUNT_MAX : integer := (CLK_FREQ / 2000) - 1; -- 500 us variable counter : integer range 0 to SAMPLE_COUNT_MAX; begin if (clk'event and clk='1') then if (reset='1') then sample <= '0'; counter := 0; else if (counter=SAMPLE_COUNT_MAX) then counter := 0; sample <= '1'; else sample <= '0'; counter := counter + 1; end if; end if; end if; end process; DebounceGen : for sw in 0 to NUM_SWITCHES-1 generate constant PULSE_COUNT_MAX : integer := 20; signal sync : std_logic_vector(1 downto 0); signal counter : integer range 0 to PULSE_COUNT_MAX; begin Debounce : process(clk) begin if (clk'event and clk='1') then if (reset='1') then sync <= (others => '0'); counter <= 0; switchesOut(sw) <= '0'; else sync <= sync(0) & switchesIn(sw); if (sync(1)='0') then -- Switch not pressed counter <= 0; switchesOut(sw) <= '0'; elsif(sample = '1') then -- Switch pressed if (counter=PULSE_COUNT_MAX) then switchesOut(sw) <= '1'; else counter <= counter + 1; end if; end if; end if; end if; end process; end generate; end Structural;