------------------------------------------------- -- Signal Debouncer -- Jeff Bazinet -- February 14, 2002 ----------------------------------------------------------------------- -- $Header: D:\usr\cvsroot/VHDL/lib/misc/debounce2.vhd,v 1.1 2008/08/23 08:20:29 Jens Exp $ ----------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; library lpm; use lpm.lpm_components.lpm_counter; entity debounce is generic(BUFFER_WIDTH: positive:= 30; CLOCK_DIV: positive:= 15 ); port( clock: in std_logic; reset: in std_logic; signal_in: in std_logic; signal_out: out std_logic ); end entity debounce; architecture rtl of debounce is --------------------------------------------------------------- -- SIGNAL DECLARATION --------------------------------------------------------------- -- General signal reset_n: std_logic; -- SLOW CLOCK GENERATION signal clock_reg: std_logic_vector(CLOCK_DIV-1 downto 0); signal clock_reg_high: std_logic_vector(CLOCK_DIV-1 downto 1); signal clock_slow: std_logic; signal clock_slow_wire: std_logic; -- DATA BUFFER FILL signal counter_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); signal data_buffer_reg: std_logic_vector(BUFFER_WIDTH-1 downto 0); -- CHECK FOR DEBOUNCE STABILITY signal stable: std_logic; signal stable_old: std_logic; signal stable_state_reg:std_logic_vector(BUFFER_WIDTH-1 downto 0); -- PUSH BUTTON ENABLE signal button_pushed: std_logic; begin --------------------------------------------------------------- -- SLOW CLOCK GENERATION --------------------------------------------------------------- COUNTER_1: lpm_counter generic map (lpm_width => CLOCK_DIV) port map ( clock => clock, sclr => reset_n, cout => clock_slow_wire ); process (clock) is begin clock_slow <= clock_slow_wire; end process; --------------------------------------------------------------- -- DATA BUFFER FILL --------------------------------------------------------------- process (clock) is begin if (reset = '0') then -- Initialization data_buffer_reg <= (others => '1'); elsif rising_edge(clock_slow) then data_buffer_reg <= data_buffer_reg(BUFFER_WIDTH-2 downto 0) & signal_in; end if; end process; --------------------------------------------------------------- -- CHECK FOR DEBOUNCE STABILITY --------------------------------------------------------------- process (clock) is begin if (reset = '0') then -- Initialization stable <= '0'; stable_old <= '0'; stable_state_reg <= (others => '0'); elsif rising_edge(clock) then if (data_buffer_reg = stable_state_reg) then stable <= '1'; stable_state_reg <= (others => '0'); else stable <= '0'; end if; stable_old <= stable; end if; end process; --------------------------------------------------------------- -- PUSH BUTTON ENABLE --------------------------------------------------------------- process (clock) is begin if (reset = '0') then -- Initialization button_pushed <= '0'; elsif rising_edge(clock) then if (stable_old = '0' and stable = '1') then button_pushed <= '1'; else button_pushed <= '0'; end if; end if; end process; --------------------------------------------------------------- --------------------------------------------------------------- signal_out <= button_pushed; reset_n <= not reset; end rtl;