----------------------------------------------------------------------------------
-- Company:        CERN, BE-CO-HT 
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    16:00:11 10/12/2011 
-- Design Name:    Basic gc_monostable
-- Module Name:    gc_monostable - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description:    A basic gc_monostable circuit
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity gc_simple_monostable is
  generic(g_PULSE_LENGTH : NATURAL := 20);
  port (
         rst            : in   STD_LOGIC;
         clk            : in   STD_LOGIC;
         input          : in   STD_LOGIC;
         output         : out  STD_LOGIC;
         output_n       : out  STD_LOGIC);
end gc_simple_monostable;

architecture Behavioral of gc_simple_monostable is

   constant c_count_max  : UNSIGNED (63 downto 0) :=
                                 to_unsigned(g_PULSE_LENGTH, 64);

   signal s_count        : UNSIGNED (63 downto 0) := to_unsigned(0, 64);

   signal s_input        : STD_LOGIC := '0';
   signal s_input_d0     : STD_LOGIC := '0';

   signal s_running      : STD_LOGIC := '0';

   signal s_output       : STD_LOGIC := '0';
   signal s_output_n     : STD_LOGIC := '1';

begin

   s_input    <= input;
   output     <= s_output;
   output_n   <= s_output_n;

   p_mono: process(clk)
   begin
      if rising_edge(clk) then
         if rst = '1' then
            s_count      <= to_unsigned(0, 64);
            s_running    <= '0';
            s_input_d0   <= '0';
            s_output     <= '0';
            s_output_n   <= '1';
         else
            s_input_d0 <= s_input;
            s_output     <= '0';
            s_output_n   <= '1';
            s_count      <= to_unsigned(0, 64);
            s_running    <= '0';

            if     (s_input    = '1')
               and (s_input_d0 = '0') then
               s_count      <= s_count + 1;
               s_running    <= '1';
               s_output     <= '1';
               s_output_n   <= '0';
            elsif s_running = '1' then
               if s_count < c_count_max then
                  s_count      <= s_count + 1;
                  s_running    <= '1';
                  s_output     <= '1';
                  s_output_n   <= '0';
               else
                  s_count    <= to_unsigned(0, 64);
                  s_running <= '0';
               end if;
            end if;
         end if;
      end if;
   end process;

end Behavioral;
