No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

debouncer.vhd 3.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. ----------------------------------------------------------------------------
  2. -- debouncer.vhd -- Signal Debouncer
  3. ----------------------------------------------------------------------------
  4. -- Author: Sam Bobrowicz
  5. -- Copyright 2011 Digilent, Inc.
  6. ----------------------------------------------------------------------------
  7. --
  8. ----------------------------------------------------------------------------
  9. -- This component is used to debounce signals. It is designed to
  10. -- independently debounce a variable number of signals, the number of which
  11. -- are set using the PORT_WIDTH generic. Debouncing is done by only
  12. -- registering a change in a button state if it remains constant for
  13. -- the number of clocks determined by the DEBNC_CLOCKS generic.
  14. --
  15. -- Generic Descriptions:
  16. --
  17. -- PORT_WIDTH - The number of signals to debounce. determines the width
  18. -- of the SIGNAL_I and SIGNAL_O std_logic_vectors
  19. -- DEBNC_CLOCKS - The number of clocks (CLK_I) to wait before registering
  20. -- a change.
  21. --
  22. -- Port Descriptions:
  23. --
  24. -- SIGNAL_I - The input signals. A vector of width equal to PORT_WIDTH
  25. -- CLK_I - Input clock
  26. -- SIGNAL_O - The debounced signals. A vector of width equal to PORT_WIDTH
  27. --
  28. ----------------------------------------------------------------------------
  29. --
  30. ----------------------------------------------------------------------------
  31. -- Revision History:
  32. -- 08/08/2011(SamB): Created using Xilinx Tools 13.2
  33. -- 08/29/2013(SamB): Improved reuseability by using generics
  34. ----------------------------------------------------------------------------
  35. library IEEE;
  36. use IEEE.STD_LOGIC_1164.ALL;
  37. use IEEE.std_logic_unsigned.all;
  38. USE IEEE.NUMERIC_STD.ALL;
  39. use IEEE.math_real.all;
  40. entity debouncer is
  41. Generic ( DEBNC_CLOCKS : INTEGER range 2 to (INTEGER'high) := 2**16;
  42. PORT_WIDTH : INTEGER range 1 to (INTEGER'high) := 5);
  43. Port ( SIGNAL_I : in STD_LOGIC_VECTOR ((PORT_WIDTH - 1) downto 0);
  44. CLK_I : in STD_LOGIC;
  45. SIGNAL_O : out STD_LOGIC_VECTOR ((PORT_WIDTH - 1) downto 0));
  46. end debouncer;
  47. architecture Behavioral of debouncer is
  48. constant CNTR_WIDTH : integer := natural(ceil(LOG2(real(DEBNC_CLOCKS))));
  49. constant CNTR_MAX : std_logic_vector((CNTR_WIDTH - 1) downto 0) := std_logic_vector(to_unsigned((DEBNC_CLOCKS - 1), CNTR_WIDTH));
  50. type VECTOR_ARRAY_TYPE is array (integer range <>) of std_logic_vector((CNTR_WIDTH - 1) downto 0);
  51. signal sig_cntrs_ary : VECTOR_ARRAY_TYPE (0 to (PORT_WIDTH - 1)) := (others=>(others=>'0'));
  52. signal sig_out_reg : std_logic_vector((PORT_WIDTH - 1) downto 0) := (others => '0');
  53. begin
  54. debounce_process : process (CLK_I)
  55. begin
  56. if (rising_edge(CLK_I)) then
  57. for index in 0 to (PORT_WIDTH - 1) loop
  58. if (sig_cntrs_ary(index) = CNTR_MAX) then
  59. sig_out_reg(index) <= not(sig_out_reg(index));
  60. end if;
  61. end loop;
  62. end if;
  63. end process;
  64. counter_process : process (CLK_I)
  65. begin
  66. if (rising_edge(CLK_I)) then
  67. for index in 0 to (PORT_WIDTH - 1) loop
  68. if ((sig_out_reg(index) = '1') xor (SIGNAL_I(index) = '1')) then
  69. if (sig_cntrs_ary(index) = CNTR_MAX) then
  70. sig_cntrs_ary(index) <= (others => '0');
  71. else
  72. sig_cntrs_ary(index) <= sig_cntrs_ary(index) + 1;
  73. end if;
  74. else
  75. sig_cntrs_ary(index) <= (others => '0');
  76. end if;
  77. end loop;
  78. end if;
  79. end process;
  80. SIGNAL_O <= sig_out_reg;
  81. end Behavioral;