----------------------------------------------------------------------------------
-- Company:        CERN
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    16:26:32 10/07/2011 
-- Design Name:    Basic debouncer
-- Module Name:    debouncer - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity debouncer is
   generic (
      g_LENGTH              : INTEGER := 6
      );
   port (
      rst         : IN   std_logic;
      clk         : IN   std_logic;
      input       : IN   std_logic;
      output      : OUT  std_logic;
      glitch_mask : IN   std_logic_vector(g_LENGTH-1 downto 0)
      );
end debouncer;

architecture Behavioral of debouncer is
-- Signals

signal meta_ff1   : std_logic;
signal delay_s    : std_logic_vector(g_LENGTH - 1 downto 0);

component gc_ff
  port (
         Q   : out STD_LOGIC;
         C   : in  STD_LOGIC;
         CLR : in  STD_LOGIC;
         D   : in  STD_LOGIC
       );
end component;

begin


  ff1: gc_ff
  port map(
            Q    => meta_ff1,
            C    => clk,
            CLR  => rst,
            D    => input
          );

  ff2: gc_ff
  port map(
            Q    => delay_s(0),
            C    => clk,
            CLR  => rst,
            D    => meta_ff1
          );

   -- Metastability solved here

  delay_line: for i in 1 to g_LENGTH-1 generate
    D_Flip_Flop : gc_ff
    port map (
               Q   => delay_s(i),
               C   => clk,
               CLR => rst,
               D   => delay_s(i-1));
  end generate delay_line;

  process (clk)
  begin
    if rising_edge(clk) then
      if rst = '1' then
        output <= '0';
      else
        if ( (delay_s and glitch_mask) = glitch_mask) then
          output <= '1';
        else
          output <= '0';
        end if;
      end if;
    end if;
  end process;

end Behavioral;
