143 lines
3.4 KiB
VHDL
143 lines
3.4 KiB
VHDL
-------------------------------------------------
|
|
-- Signal Debouncer
|
|
-- Jeff Bazinet
|
|
-- February 14, 2002
|
|
-----------------------------------------------------------------------
|
|
-- $Header: /tmp/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;
|