--
-- TLU Interface
--
-- Matt Warren 2014
--

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library utils;
use utils.pkg_types.all;

library hsio;
use hsio.pkg_core_globals.all;

entity trig_tdcparbus is
   generic(
      EN_ID : integer := 0
   );
   port(
      en_i         : in     std_logic_vector (15 downto 0);
      par_i        : in     std_logic_vector (7 downto 0);
      inv_i        : in     std_logic_vector (15 downto 0);
      ptrig_mask_i : in     std_logic_vector (15 downto 0);
      trig_o       : out    std_logic;
      dbg_trig_o   : out    std_logic;
      tdc_data_o   : out    std_logic_vector (39 downto 0);
      tdc_new_o    : out    std_logic;
      tdc_en_i     : in     std_logic;
      busy_i       : in     std_logic;
      ----
      s40          : in     std_logic;
      clk          : in     std_logic;
      rst          : in     std_logic
   );

-- Declarations

end trig_tdcparbus ;

--
architecture rtl of trig_tdcparbus is

  signal en  : std_logic;
  signal inv : std_logic;

  signal tdc_data : std_logic_vector(39 downto 0);
  signal trans_in : std_logic_vector(7 downto 0);
  signal trans32  : std_logic_vector(31 downto 0);
  signal riseedge : std_logic_vector(15 downto 0);


begin

  en  <= en_i(EN_ID);
  inv <= inv_i(EN_ID);

  -- ser-in  abcdefghijklmnopqrstuvwx
  -- par-in  hgfedcba ponmlkji xwvutsrq
  -- trans   abcdefgh ijklmnop qrstuvwx
  -- bit     32109876 54321098 76543210       
  --            2          1          0

  g_trans : for n in 0 to 7 generate
    trans_in(n) <= par_i(7-n);
  end generate;


  -- build wide stream

  prc_par_in : process (clk)
  begin
    if rising_edge(clk) then

      if (inv = '0') then
        trans32 <= trans32(23 downto 0) & trans_in;

      else
        trans32 <= trans32(23 downto 0) & not(trans_in);

      end if;
    end if;
  end process;




  prc_rising_find : process (clk)
  begin
    if rising_edge(clk) then
      if (s40 = '1') and (en = '1') and (busy_i = '0') then  -- these edges need to be tuned for best latency
        for n in 0 to 15 loop
          if trans32(n+1 downto n) = "01" then
            riseedge(n) <= '1';

          end if;
        end loop;
      end if;
    end if;
  end process;




  tdc_word <= conv_std_logic_vector(TRIG_ID, 4) & "0000" & trans32;

  prc_trig_gen : process (clk)
  begin
    if rising_edge(clk) then
      if (rst = '1') then
        trig_o <= '0';

      else
        --default
        trig_o     <= '0';
        dbg_trig_o <= '0';
        tdc_new_o  <= '0';

        if (s40 = '0') then  -- these edges need to be tuned for correct phasing
          if (riseedge and ptrig_mask_i) /= x"0000" then
            trig_o     <= '1';
            dbg_trig_o <= '1';

            tdc_word_o <= tdc_word;
            if (tdc_en_i = '1') then
              tdc_new_o <= '1';

            end if;
          end if;
        end if;
      end if;
    end if;
  end process;

end architecture rtl;