----------------------------------------------------------------------------------
-- Company:        CERN, BE-CO-HT 
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    16:00:11 10/12/2011 
-- Design Name:    Basic monostable
-- Module Name:    monostable - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description:    A basic 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 monostable is
  port (
         rst            : in   STD_LOGIC;
         clk            : in   STD_LOGIC;
         pulse_len      : in   STD_LOGIC_VECTOR(31 downto 0);
         write_tt_o     : out  STD_LOGIC;
         input          : in   STD_LOGIC;
         output         : out  STD_LOGIC);
end monostable;

architecture Behavioral of monostable is


  type fsm is (S0_WAITING, S1_OK, S2_FORBIDDEN);

  signal blo_pulse_fsm     : fsm;

  signal s_count_max       : UNSIGNED (32 downto 0);
  signal s_count_max2      : UNSIGNED (32 downto 0);

  signal s_count           : UNSIGNED (32 downto 0); 

  signal write_tt_s        : STD_LOGIC;

begin



  process(clk)
  begin
    if rising_edge(clk) then

      write_tt_o   <= write_tt_s;

      if (rst = '1') then
        output            <= '0';
        write_tt_s        <= '0';
        blo_pulse_fsm     <= S0_WAITING;
      else
        case blo_pulse_fsm is

          when S0_WAITING   =>
            if input = '1' then
              blo_pulse_fsm  <= S1_OK;
              s_count_max      <= unsigned('0' & std_logic_vector(pulse_len));
              s_count_max2     <= unsigned(std_logic_vector(pulse_len) & '0');
              s_count(32 downto 1)  <= (others => '0');
              s_count(0)            <= '1';
              output                <= '1';
              write_tt_s            <= '1';
            else
            end if;

          when S1_OK        =>
            s_count           <= s_count + 1;
            write_tt_s        <= '0';
            if  s_count = s_count_max then 
                blo_pulse_fsm <= S2_FORBIDDEN;
                output        <= '0'; 
            else
            end if;

          when S2_FORBIDDEN =>
            s_count           <= s_count + 1;
            if s_count = s_count_max2 then
                blo_pulse_fsm  <= S0_WAITING;
            else
            end if;
          when others =>

        end case;

      end if;

    else
    end if;

  end process;

end Behavioral;
