---------------------------------------------------------------------------------
-- Company:        CERN, BE-CO-HT
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    09:58:06 10/12/2011 
-- Design Name:    HDL trigger
-- Module Name:    trigger - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description:    This is the wishbone trigger which receives a debounced input
--                 and outputs a trigger signal for the pulse converter
-- Dependencies:   none
--
-- Revision: 
-- Revision 0.1
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

use work.ctdah_pkg.ALL;

entity basic_trigger_core is
  port (
         wb_rst_i       : in  STD_LOGIC;
         wb_clk_i       : in  STD_LOGIC;

         pulse_i        : in  STD_LOGIC;
         pulse_o        : out STD_LOGIC;
         pulse_n_o      : out STD_LOGIC;

         crop_o         : out STD_LOGIC;

         led_o          : out STD_LOGIC);
end basic_trigger_core;

architecture Behavioral of basic_trigger_core is

   signal s_pulse_meta0         : STD_LOGIC;
   signal s_pulse               : STD_LOGIC;
   signal s_pulse_n             : STD_LOGIC;
   signal s_pulse_o_n           : STD_LOGIC;
   signal s_pulse_o             : STD_LOGIC;

   signal s_pulse_i_reg         : STD_LOGIC_VECTOR(2 downto 0);

   signal s_crop                : STD_LOGIC := '0';

begin

   pulse_o   <= s_pulse_o;
   pulse_n_o <= not(s_pulse_o);

   crop_o    <= s_crop;

   inst_ff: gc_ff
   port map(Q   => s_pulse_meta0, 
            C   => wb_clk_i, 
            CLR => wb_rst_i, 
            D   => pulse_i);

  pulse_monostable : gc_simple_monostable
  generic map (g_PULSE_LENGTH => 16) --! We remove the stages of deglitching
                                     --! to produce 1us sharp at the output
  port map (rst      => wb_rst_i, 
            clk      => wb_clk_i, 
            input    => s_pulse_meta0, 
            output   => s_pulse,
            output_n => s_pulse_n);

  led_monostable : gc_simple_monostable
  generic map (g_PULSE_LENGTH => 2000000) --! 500ms
  port map (
          rst      => wb_rst_i, 
          clk      => wb_clk_i, 
          input    => s_pulse_meta0, 
          output   => led_o);
  --output_n not connected


  p_delays : process(wb_clk_i) is
  begin
     if rising_edge(wb_clk_i) then
        s_pulse_i_reg(0) <= pulse_i;
        for i in 1 to 2 loop
           s_pulse_i_reg(i) <= s_pulse_i_reg(i-1);
        end loop;
     end if;
  end process;

  p_reg_crop : process (wb_clk_i) is
  begin
     if rising_edge(wb_clk_i) then
        if wb_rst_i = '1' then
           s_crop <= '0';
        else
           if s_pulse = '0' then
              s_crop <= '1';
              if s_pulse_i_reg(2) = '0' then --! Not until three clocks the
                 s_crop <= '0';              --! signal is valid.
              end if;
              if pulse_i = '0' then          --! Sharp crop. Metastability
                 s_crop <= '0';              --! problems solved in V2.
              end if;
           end if;
        end if;
     end if;
  end process;

  p_comb_output : process(pulse_i, s_pulse, s_crop) is
  begin
     s_pulse_o    <= '0';
     case s_pulse is
        when '0'    =>
               --! We just have just finished the pulse and must be cropped.

               --! In this case, we assume that the both input sources have an
               --! RC filter, so we can improve jitter performance of the
               --! first edge by bypassing the signal (no clocking).
           if pulse_i = '1' then
              if s_crop = '0' then
                 s_pulse_o     <= '1';
              else
                 s_pulse_o     <= '0';
              end if;
           else
           end if;
        when others =>
               --! In this other case, we should keep on outputing the pulse
           s_pulse_o     <= '1';
     end case;
  end process;


end Behavioral;
