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

entity trigger is port (
	clk, reset, etr, enw, set_trgin, trigger_in, trg_bypass, veto_long: in std_logic;
	add: in std_logic_vector(1 downto 0);
	grp: in std_logic_vector(4 downto 0);
	db_in: in std_logic_vector(15 downto 0);
	db_out: out std_logic_vector (15 downto 0);
	int_trg, trigger_out, trg_dly_p: out std_logic
	);
end trigger ;

architecture arch of trigger is
signal trg_delay, trg_maxcnt, trg_cntin: std_logic_vector(15 downto 0);
signal trg_cntout, trg_cntoutreg: std_logic_vector(31 downto 0);
signal q_in, tr_0, tr_1, tr_2, tr_dly: std_logic;
signal trg_shift: std_logic_vector(15 downto 0);
signal v_0, v_1, v_2: std_logic;
signal end_count: std_logic;

component shift port (
	clk, trigger: in std_logic;
	trg_shift: out std_logic_vector(15 downto 0)
	);
end component;

component cuenta port (
	clk, reset, etr, set_trgin, trigger, enable: in std_logic;
	add: in std_logic_vector(1 downto 0);
	grp: in std_logic_vector(4 downto 0);
	trg_maxcnt: in std_logic_vector(15 downto 0);
	db_out: out std_logic_vector(15 downto 0);
	end_count: out std_logic
	);
end component;

begin
S1: shift port map(clk=>clk, trigger=>tr_2, trg_shift=>trg_shift);
S2: cuenta port map(
	clk=>clk, reset=>reset, etr=>etr, set_trgin=>set_trgin, trigger=>tr_dly, enable=>q_in, --: in std_logic;
	add=>add, --: in std_logic_vector(1 downto 0);
	grp=>grp, --: in std_logic_vector(4 downto 0);
	trg_maxcnt=>trg_maxcnt, --: in std_logic_vector(15 downto 0);
	db_out=>db_out, --: out std_logic_vector(15 downto 0);
	end_count=>end_count --: out std_logic
	);

trigger_out <= tr_dly and (not trg_bypass or q_in); --trg_bypass: active low
tr_2 <= tr_0 and not tr_1;
int_trg <= end_count; --trg_cntin(15);
trg_dly_p <= tr_dly;

process (clk, reset)
begin
	if reset='1' then 
	  tr_0 <= '0';
	  tr_1 <= '0';
	elsif clk'event and clk='1' then
	  tr_1 <= tr_0;
	  tr_0 <= trigger_in;
	end if;
end process;
--veto
v_2 <= v_0 and not v_1;
process (clk, reset)
begin
	if reset='1' then 
	  v_0 <= '0';
	  v_1 <= '0';
	elsif clk'event and clk='1' then
	  v_1 <= v_0;
	  v_0 <= veto_long;
	end if;
end process;

--REGISTROS
-- trigger delay
db_out <= trg_delay when etr='0' and grp(0)='1' and add=1 else (others => 'Z'); --1
process (clk, reset)
begin
	if reset='1' then
--	  trg_delay <= (others =>'0');

--*****NOV2011 QUIERO PONER EN LA CONTROLX de USC
	   trg_delay <= "0000000000001000";
 	elsif clk'event and clk='1' then
	  if enw='1' and grp(0)='1' and add=1 then --1
	    trg_delay <= db_in;
	  end if;
	end if;
end process;

--trigger max count
db_out <= trg_maxcnt when etr='0' and grp(0)='1' and add=2 else (others => 'Z'); --2
process (clk, reset)
begin
	if reset='1' then
	  trg_maxcnt <= (others =>'0');
	elsif clk'event and clk='1' then
	  if enw='1' and grp(0)='1' and add=2 then --2
	    trg_maxcnt <= db_in;
	  end if;
	end if;
end process;

--trigger count in
--db_out <= trg_cntin when etr='0' and add=3 else (others => 'Z');
--process (clk, reset)
--begin
--	if reset='1' then
--	  trg_cntin <= (others =>'1');
--	elsif clk'event and clk='1' then
--	  if set_trgin='1' then
--	    trg_cntin <= trg_maxcnt;
--	  elsif q_in='1' and trigger='1' and trg_cntin(15)='0' then
--	    trg_cntin <= trg_cntin - 1;
--	  end if;
--	end if;
--end process;

--trigger count-out counter
db_out <= trg_cntout(15 downto 0)  when etr='0' and grp(1)='1' and add=2 else (others => 'Z'); --6
db_out <= trg_cntout(31 downto 16) when etr='0' and grp(1)='1' and add=3 else (others => 'Z'); --7
process (clk, reset)
begin
	if reset='1' then
	  trg_cntout <= (others =>'0');
	elsif clk'event and clk='1' then
	  if set_trgin='1' then
	    trg_cntout <= (others => '0');
	  elsif enw='1' and grp(1)='1' and add=2 then --6
	    trg_cntout(15 downto 0) <= db_in;
	  elsif enw='1' and grp(1)='1' and add=3 then --7
	    trg_cntout(31 downto 16) <= db_in;
	  elsif q_in='0' and tr_dly='1' then
	    trg_cntout <= trg_cntout + 1;
	  end if;
	end if;
end process;

--trigger count-out latch register
db_out <= trg_cntoutreg(15 downto 0)  when etr='0' and grp(1)='1' and add=0 else (others => 'Z'); --4
db_out <= trg_cntoutreg(31 downto 16) when etr='0' and grp(1)='1' and add=1 else (others => 'Z'); --5
process (clk, reset)
begin
	if reset='1' then
	  trg_cntoutreg <= (others =>'0');
	elsif clk'event and clk='1' then
	  if set_trgin='1' then
	    trg_cntoutreg  <= trg_cntout;
	  elsif enw='1' and grp(1)='1' and add=0 then --4
	    trg_cntoutreg(15 downto 0) <= db_in;
	  elsif enw='1' and grp(1)='1' and add=1 then --5
	    trg_cntoutreg(31 downto 16) <= db_in;
	  end if;
	end if;
end process;

--toggle in out
process (clk, reset)
begin
	if reset='1' then
	  q_in <= '0';
	elsif clk'event and clk='1' then
	  if set_trgin='1' then
	    q_in <= '1';
	  elsif end_count='1' or v_2='1' then
	    q_in <= '0';
	  end if;
	end if;
end process;

--shift register

tr_dly <=  (((trg_shift(15) and trg_delay(15)) or (trg_shift(14) and trg_delay(14)))
           or
           ((trg_shift(13) and trg_delay(13)) or (trg_shift(12) and trg_delay(12)))
           or
           ((trg_shift(11) and trg_delay(11)) or (trg_shift(10) and trg_delay(10)))
           or
           ((trg_shift(9) and trg_delay(9)) or (trg_shift(8) and trg_delay(8))))
           or
           (((trg_shift(7) and trg_delay(7)) or (trg_shift(6) and trg_delay(6)))
           or
           ((trg_shift(5) and trg_delay(5)) or (trg_shift(4) and trg_delay(4)))
           or
           ((trg_shift(3) and trg_delay(3)) or (trg_shift(2) and trg_delay(2)))
           or
           ((trg_shift(1) and trg_delay(1)) or (trg_shift(0) and trg_delay(0))))
           ;


--tr_dly <= (trg_shift(127) and trg_delay(15)) or
--           (trg_shift(119) and trg_delay(14)) or
--           (trg_shift(111) and trg_delay(13)) or
--           (trg_shift(103) and trg_delay(12)) or
--           (trg_shift(95) and trg_delay(11)) or
--           (trg_shift(87) and trg_delay(10)) or
--           (trg_shift(79) and trg_delay(9)) or
--           (trg_shift(71) and trg_delay(8)) or
--           (trg_shift(63) and trg_delay(7)) or
--           (trg_shift(55) and trg_delay(6)) or
--           (trg_shift(47) and trg_delay(5)) or
--           (trg_shift(39) and trg_delay(4)) or
--           (trg_shift(31) and trg_delay(3)) or
--           (trg_shift(23) and trg_delay(2)) or
--           (trg_shift(15) and trg_delay(1)) or
--           (trg_shift(7) and trg_delay(0));
           
--process (clk, reset)
--begin
--	if reset='1' then
--	  trg_shift <= (others => '0');
--	elsif clk'event and clk='1' then
--	  trg_shift <= trg_shift(126 downto 0) & tr_2;
--	end if;
--end process;

end arch;
	
