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

entity rob128 is

port(
clk_in, reset_pre, reset_in, data_ready: in std_logic;
trk_adv, trk_rst, trk_tm: in std_logic;
this_board: in std_logic;
TBLED: out std_logic;
byte_id: in std_logic_vector(1 downto 0);
tdc_error: in std_logic_vector(1 to 4);
get_data, valid_data, clk20, rob_error, seu: out std_logic;
--get_data, valid_data, clk20, rob_error, seu: out std_logic;
reset_out: out std_logic;
ena: out std_logic_vector(16 downto 1);
TP1, TP2, TP3, TP4: out std_logic;
sync, pwdn: out std_logic
);
end rob128;

architecture archi of rob128 is

signal clk20_i, error_id, error_c: std_logic;
signal trk_adv_ff0, trk_adv_ff1, trk_adv_ff2, trk_adv_syn: std_logic;
signal trk_rst_ff0, trk_rst_ff1, trk_rst_ff2, trk_rst_syn: std_logic;
signal get_data_i, valid_data_i: std_logic;
signal byte_id_cnt: std_logic_vector(1 downto 0);
signal ena_i: std_logic_vector(16 downto 1);
signal trk_cnt: std_logic_vector(4 downto 0);
signal one, seu_clk, seu_cnt, seu_gd, seu_vd, seu_eid, seu_bid: std_logic;
signal reset, clk, not_clk20: std_logic;
signal gd_ec: std_logic;
signal pd0, pd1, pd2: std_logic; --04-10-01

component trclk20
  port (clk, reset: in std_logic;
        clk20, seu: out std_logic);
end component;

component trff
  port (clk, ce, reset, d: in std_logic;
        q, seu: out std_logic);
end component;

--component trffsr
--  port (clk, ce, sr, reset, d: in std_logic;
--        q, seu: out std_logic);
--end component;

component trcnt5
  port (clk, cnt_ena, sr, reset: in std_logic;
        seu: out std_logic;
        q: out std_logic_vector(4 downto 0));
end component;

component trcnt2 port(clk, cnt_ena, reset: in std_logic;
		seu: out std_logic;
		q: out std_logic_vector(1 downto 0));
end component;

COMPONENT GLOBAL
   PORT (a_in : IN STD_LOGIC;
      a_out: OUT STD_LOGIC);
END COMPONENT;

begin

TP2 <= trk_adv_syn; --board TP6 pin 72
TP3 <= valid_data_i; --board TP7 pin 54; 1-10-2001
TP1 <= one; --; board TP5 pin 25
TP4 <= one; --board TP8 pin 85

TBLED <= not this_board;

reset_out <= not reset_pre;
gbl_rst: global port map (reset_in, reset);
gbl_clk: global port map (clk_in, clk);

sync <= not reset_pre;
--04-10-2001
--pwdn <= reset_pre;
pwdn <= reset_pre or pd0 or pd1 or pd2;
---------------------
one <= '1';

-- 04-10-2001 alargar power down
PR_PD0: process (clk)
begin
	if clk'event and clk='1' then
		pd2 <= pd1;
		pd1 <= pd0;
		pd0 <= reset_pre;
	end if;
end process PR_PD0;
-------------------------------
PR_SEU: process (clk, reset)
begin
	if reset='0' then
		seu <= '0';
	elsif clk'event and clk='1' then
		seu <= seu_clk or seu_cnt or seu_gd or seu_vd or seu_eid or seu_bid;
	end if;
end process PR_SEU;

rob_error <= not (error_id or tdc_error(1) or tdc_error(2) or
		tdc_error(3) or tdc_error(4));
		
GENA:
   for i in 1 to 16 generate
      ena(i) <= ena_i(i) or not trk_tm;
   end generate;

ena_i <= 
	"0000000000000001" when trk_cnt=0 else --0
	"0000000000000011" when trk_cnt=1 else --1
	"0000000000000010" when trk_cnt=2 else --2
	"0000000000000110" when trk_cnt=3 else --3
	"0000000000000100" when trk_cnt=4 else --4
	"0000000000001100" when trk_cnt=5 else --5
	"0000000000001000" when trk_cnt=6 else --6
	"0000000000011000" when trk_cnt=7 else --7
	"0000000000010000" when trk_cnt=8 else --8
	"0000000000110000" when trk_cnt=9 else --9
	"0000000000100000" when trk_cnt=10 else --10
	"0000000001100000" when trk_cnt=11 else --11
	"0000000001000000" when trk_cnt=12 else --12
	"0000000011000000" when trk_cnt=13 else --13
	"0000000010000000" when trk_cnt=14 else --14
	"0000000110000000" when trk_cnt=15 else --15
	"0000000100000000" when trk_cnt=16 else --16
	"0000001100000000" when trk_cnt="10001" else --17
	"0000001000000000" when trk_cnt="10010" else --18
	"0000011000000000" when trk_cnt="10011" else --19
	"0000010000000000" when trk_cnt="10100" else --20
	"0000110000000000" when trk_cnt="10101" else --21
	"0000100000000000" when trk_cnt="10110" else --22
	"0001100000000000" when trk_cnt="10111" else --23
	"0001000000000000" when trk_cnt="11000" else --24
	"0011000000000000" when trk_cnt="11001" else --25
	"0010000000000000" when trk_cnt="11010" else --26
	"0110000000000000" when trk_cnt="11011" else --27
	"0100000000000000" when trk_cnt="11100" else --28
	"1100000000000000" when trk_cnt="11101" else --29
	"1000000000000000" when trk_cnt="11110" else --30
	"0000000000000000";


valid_data <= valid_data_i;
get_data <= get_data_i;
clk20 <= clk20_i;

--CLK 20 MHz
InstCLK20: trclk20
  port map (clk=>clk, reset=>reset, clk20=>clk20_i, seu=>seu_clk);

--Track advace synch and track reset synch
--trk_adv_syn <= trk_adv_ff2 and trk_adv_ff1 and not trk_adv_ff0;
--trk_rst_syn <= trk_rst_ff2 and trk_rst_ff1 and not trk_rst_ff0;
trk_adv_syn <= trk_adv;
trk_rst_syn <= trk_rst;

--TAV1: process (clk, reset)
--begin
--	if reset ='0' then
--	  trk_adv_ff0 <= '0';
--	  trk_adv_ff1 <= '0';
--	  trk_adv_ff2 <= '0';
--	  trk_rst_ff0 <= '0';
--	  trk_rst_ff1 <= '0';
--	  trk_rst_ff2 <= '0';
--	elsif clk'event and clk='1' then
--	  trk_adv_ff0 <= trk_adv_ff1;
--	  trk_adv_ff1 <= trk_adv_ff2;
--	  trk_adv_ff2 <= trk_adv;
--	  trk_rst_ff0 <= trk_rst_ff1;
--	  trk_rst_ff1 <= trk_rst_ff2;
--	  trk_rst_ff2 <= trk_rst;
--	end if;
--end process TAV1;

-- Track sequence counter
InstTrkCnt: trcnt5
  port map (clk=>clk, cnt_ena=>trk_adv_syn, sr=>trk_rst_syn, reset=>reset,
        seu=>seu_cnt, q=>trk_cnt);

-- Get data process
--PR_GD: process (clk, data_ready)
--begin
--	if data_ready='0' then
--	  get_data_i <= '0';
--	elsif clk'event and clk='1' then
--		if valid_data_i='1' then
--			get_data_i <= not clk20_i;
--		end if;
--	end if;
--end process PR_GD;

not_clk20 <= not clk20_i;

InstGD: trff port map (clk=>clk, ce=>valid_data_i, reset=>data_ready, d=>not_clk20,
        q=>get_data_i, seu=>seu_gd);

-- Valid data process
--PR_VD: process (clk, data_ready)
--begin
--	if data_ready='0' then
--	  valid_data_i <= '0';
--	elsif clk'event and clk='1' then
--		if clk20_i='1' then
--			valid_data_i <= '1';
--		end if;
--	end if;		
--end process PR_VD;

InstVD: trff port map (clk=>clk, ce=>clk20_i, reset=>data_ready, d=>one,
        q=>valid_data_i, seu=>seu_vd);

-- Byte ID error register
error_c <= (byte_id(0) xor byte_id_cnt(0)) or 
           (byte_id(1) xor byte_id_cnt(1));
           
--PREID: process (clk, reset)
--begin
--	if reset='0' then
--	  error_id <= '0';
--	elsif clk'event and clk='1' then
--	  if (get_data_i='1' and error_c='1') then
--	    error_id <= '1';
--	  end if;
--	end if;
--end process PREID;

gd_ec <= get_data_i and error_c;
InstEID: trff port map (clk=>clk, ce=>gd_ec, reset=>reset, d=>one,
        q=>error_id, seu=>seu_eid);

-- Byte ID counter
--PRBID: process (clk, reset)
--begin
--	if reset='0' then
--	  byte_id_cnt <= (others => '0');
--	elsif clk'event and clk='1' then
--	  if get_data_i='1' then
--	    byte_id_cnt <= byte_id_cnt + 1;
--	  end if;
--	end if;
--end process PRBID;

InstBID: trcnt2 port map(clk=>clk, cnt_ena=>get_data_i, reset=>reset,
		seu=>seu_bid, q=>byte_id_cnt);

end archi;
