library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Pin_Logic is generic ( G_INVERT : std_logic; G_BITS : integer -- must be >= 1 ); port ( i_clk : in std_logic; i_pin : in std_logic; o_pin : out std_logic; o_rise : out std_logic; o_fall : out std_logic ); end Pin_Logic; architecture rtl of Pin_Logic is signal s_initcounter : unsigned(G_BITS + 1 downto 0) := (others => '0'); signal s_pin : std_logic := '0'; signal s_value : unsigned(G_BITS downto 0) := (others => '0'); signal s_debounced : std_logic := '0'; begin s_pin <= i_pin when G_INVERT = '0' else not i_pin; process begin wait until rising_edge(i_clk); if s_pin = '1' then if s_value < 2**(s_value'left + 1) - 1 then s_value <= s_value + 1; end if; else if s_value > 0 then s_value <= s_value - 1; end if; end if; o_rise <= '0'; o_fall <= '0'; o_pin <= i_pin; s_debounced <= s_value(s_value'left); if s_initcounter(s_initcounter'left) = '0' then s_initcounter <= s_initcounter + 1; else o_pin <= s_value(s_value'left); if s_debounced = '0' and s_value(s_value'left) = '1' then o_rise <= '1'; end if; if s_debounced = '1' and s_value(s_value'left) = '0' then o_fall <= '1'; end if; end if; end process; end;