------------------
-- version cris
-- abril 2006
-- 
-- a)modificado el ciclo de datos para poder leer de la fifo y escribir en el transmisor
--   simultanemente: se duplican las señales txena y read_fifo. 
-- b)limitador de palabras en lectura, word_count y max_word_count: valor fijado por 
--   defecto 200 palabres = 800 bytes => 10us @40MHz.
-- c)se leen las 4 primeras palabras en bloque: header y trailer (o dato) 
-- d)se activa lives con cada fifo: cuando esta inactivo debe resetear el contador, como 
--   hace time_start.
-- e)timer sincrono
------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.or_reduce;
use ieee.std_logic_arith.all;
use work.pack.all;

entity cr_ros is
	port (
	clk, reset: in std_logic;
	soft_reset: in std_logic;
-- 
	valen, hastoken, parcheck: in std_logic;
	evid: in std_logic_vector(11 downto 0);
	ceros_id: in std_logic_vector (1 downto 0);
	txena_p, read_fifo_p, ros_done: out std_logic;
	lives: out std_logic;
	fout: in std_logic_vector(15 downto 0);
-- modif
	s_data_p: out std_logic_vector(15 downto 0);
--
	ef, mask: in std_logic_vector(5 downto 0);
	db_in: in std_logic_vector(5 downto 0);
	sel_read_p: out std_logic_vector(5 downto 0);
	hasunlock, paf, ff, ff_reg, lock: in std_logic_vector(5 downto 0);
	timed_out_p: out std_logic_vector(5 downto 0);
	evid_mis_p: out std_logic_vector(5 downto 0);
   enw_evid_mis: in std_logic;
	dis_timo_mask:in std_logic;
	enw_timed_out, dis_paf_warn, dis_evid_wrong, dis_head_trail: in std_logic;
   dis_evid_bloq: in std_logic;
	dis_ffreg_mask: in std_logic; --feb08
   dis_hul_mask: in std_logic; --diciembre 08
	timeout_value: in std_logic_vector(11 downto 0);
	enw_maxw: in std_logic;
	maxw_reached_p: out std_logic_vector (5 downto 0);
	nmaxwords_p: in std_logic_vector (8 downto 0);
	--
	resynch_to_p, resynch_evidmis_p, warn_PAF_p: in std_logic;
	resynch_FF_p, resynch_maxw_p: in std_logic
	);
end cr_ros;

architecture arch of cr_ros is

type state_type_1 is (start_event, do_link, w_trans, event_done);
signal main: state_type_1;
--
type state_type_2 is (w_command, chk_mask,
	s_error_ff0, s_error_ff1, 
--diciembre 08	--s_error_ff2,
	s_warn_paf0, s_warn_paf1, 
--diciembre 08	--s_warn_paf2,
-------------
	w_ef_h0, 
	w_ef_h1, r_header1, w_ef_h2, r_header2,
	w_ef_t1, r_trailer1, r_trailer2,
	w_ef_t2,
	w_ef_ft1,
	s_header1, s_header2, s_dato_first1,
------------- 	 
	wait_token,
--diciembre 08	evid_wrong0,
	evid_wrong1, evid_wrong2, 
--diciembre 08	evid_wrong3,
	send_dato1, send_dato2,
	w_ef_sd1, w_ef_sd2,
	w_ef_st1,
	forz_trailer1, forz_trailer2, 
   s_trailer1, 
-------
	error_fill, 
	s_timeout0, s_timeout1, s_timeout2,
   s_maxwc1, s_maxwc2             
);
signal state: state_type_2;

-- new signals
signal sel_read: std_logic_vector(5 downto 0);
signal rob_id_start, rob_id: std_logic_vector (4 downto 0);
signal fmt_header_1, fmt_header_2, fmt_timeout_1, fmt_timeout_2: std_logic_vector(15 downto 0);
signal fmt_error_ff_1, fmt_error_ff_2: std_logic_vector(15 downto 0);
signal fmt_warn_paf_1, fmt_warn_paf_2: std_logic_vector(15 downto 0);
signal fmt_dato_1, fmt_dato_alt_1: std_logic_vector(15 downto 0);
--signal fmt_dato_2: std_logic_vector(15 downto 0);
signal fmt_evid_wrong_1, fmt_evid_wrong_2: std_logic_vector(15 downto 0);
signal fmt_trailer_1, fmt_trailer_2, fmt_trailer_alt_1:  std_logic_vector(15 downto 0);
signal fmt_maxwc_1, fmt_maxwc_2:  std_logic_vector(15 downto 0);
signal s_data: std_logic_vector(15 downto 0);
signal txena_dir, read_fifo_dir: std_logic;
--signal noes_trailer: std_logic;
--oct 06 signal word_count: std_logic_vector (15 downto 0);
signal word_count: std_logic_vector (11 downto 0);
--constant max_word_count: std_logic_vector(7 downto 0):= X"C8";	--200 palabras
signal max_word_count: std_logic_vector(7 downto 0);	
signal nolimit_maxw: std_logic;
signal maxw_reached: std_logic_vector(5 downto 0);	
--------                                                   
signal header1_reg: std_logic_vector (7 downto 0);
signal header2_reg, trailer_reg: std_logic_vector (15 downto 0);  
signal time_start, time_out: std_logic;
signal new_fifo, this_ef, this_mask: std_logic;
signal this_hasunlock, this_paf, this_ff, this_ff_reg, this_lock, this_timed_out: std_logic;
signal this_maxw: std_logic;

signal timed_out: std_logic_vector ( 5 downto 0);
signal time_counter: std_logic_vector(12 downto 0);
signal trail,this_evid_mis : std_logic;
signal evid_mis: std_logic_vector(5 downto 0);
signal sta_to: std_logic_vector(3 downto 0);
signal error_evid:std_logic;

--diciembre 08
signal fin_synch: std_logic;
signal dontread: std_logic_vector(5 downto 0);
signal vdontread: std_logic_vector(5 downto 0);
signal this_dontread: std_logic;

begin

sel_read_p <= sel_read;


--noes_trailer <= '0' when fout (15 downto 12)="0001" else '1';

read_fifo_p <= read_fifo_dir and not this_ef; 
--read_fifo_p <= read_fifo_dir; 
txena_p <= txena_dir;
s_data_p <= s_data;

timed_out_p <= timed_out;
evid_mis_p <= evid_mis;


max_word_count <= nmaxwords_p(7 downto 0);
nolimit_maxw  <= nmaxwords_p(8);
maxw_reached_p <= maxw_reached;
---- formats ---- 						

-- header y trailer son los del grupo, o sea del TDC master.
-- dato es todo lo demás
fmt_header_1 <= "000" & rob_id & header1_reg;
fmt_header_2 <= header2_reg;

fmt_trailer_1 <= "001" & rob_id & fout(7 downto 0);
fmt_trailer_alt_1 <= "001" & rob_id & trailer_reg(7 downto 0);
fmt_trailer_2 <= fout;

fmt_dato_1 <= fout(14 downto 12) & '0' & parcheck & not(this_paf) & fout(9 downto 0);
fmt_dato_alt_1 <= trailer_reg(14 downto 12) & '0' & parcheck & not(this_paf) & trailer_reg(9 downto 0);
--fmt_dato_2 <= fout;

fmt_error_ff_1 <= "110" & "11111" & "011" & rob_id;
--fmt_error_ff_2 <= X"8000";
fmt_error_ff_2  <= '1' & resynch_FF_p & "00000000" & this_evid_mis & not(this_paf) & this_ef & this_lock & this_hasunlock & this_ff_reg;

fmt_warn_paf_1 <= "110" & "11111" & "010" & rob_id;
fmt_warn_paf_2  <= '1' & warn_PAF_p & "00000000" & this_evid_mis & not(this_paf) & this_ef & this_lock & this_hasunlock & this_ff_reg;

fmt_timeout_1 <= "110" & "11111" & "000" & rob_id;	-- time out 
fmt_timeout_2  <= '1' & resynch_to_p & "00000000" & this_evid_mis & not(this_paf) & this_ef & this_lock & this_hasunlock & this_ff_reg;
 
fmt_evid_wrong_1 <= "110" & "11111" & "001" & rob_id;
fmt_evid_wrong_2 <= '1' & resynch_evidmis_p & "00" & evid;

-- max word count: error tipo 5 
fmt_maxwc_1 <= "110" & "11111" & "101" & rob_id;
fmt_maxwc_2  <= '1' & resynch_maxw_p & "00000000" & this_evid_mis & not(this_paf) & this_ef & this_lock & this_hasunlock & this_ff_reg;
--fmt_maxwc_2  <= word_count;
-- first rob identifier


rob_id_start <= "00000" when ceros_id="00" else	--ceros 0 -> rob 0
			 "00110" when ceros_id="01" else	--ceros 1 -> rob 6
			 "01100" when ceros_id="10" else	--ceros 2 -> rob 12
			 "10010";						--ceros 3 -> rob 18

-- señales del canal seleccionado
this_ef   <= sumprod(ef, sel_read);
this_mask <= sumprod (mask, sel_read);
this_hasunlock <= sumprod (hasunlock, sel_read);	
this_paf <= sumprod (paf, sel_read);	--este paf es directamente de las fifos y es activo baja (si 0 es que se pasa el límite permitido de palabras minimas)
this_ff <= sumprod (ff, sel_read);	
this_ff_reg <= sumprod(ff_reg, sel_read);	
this_lock <= sumprod (lock, sel_read);	
this_timed_out <= sumprod (timed_out, sel_read);	
this_maxw <= sumprod (maxw_reached, sel_read);	
 
this_evid_mis  <= sumprod (evid_mis, sel_read);
this_dontread <= sumprod (dontread, sel_read); --diciembre 08 locura

-- main FSM
mainpr: process (clk, valen)
begin
	if valen='0' then
	  main <= start_event;
	  sel_read <= (others => '0');
	  rob_id <= (others => '0');
	  new_fifo <= '0';
	  ros_done <= '0';
	  vdontread <= dontread; --diciembre08 locura
	elsif clk'event and clk='1' then
	
	case main is
		  
	  when start_event =>
	    sel_read(0) <= '1';
	    rob_id <= rob_id_start;
	    if (vdontread(0)='1') then   --diciembre08 locura
	    	main <= w_trans;		  --diciembre08 locura
		new_fifo <='0';		--diciembre08 locura
		else				   --diciembre08 locura
	    new_fifo <= '1';	    --diciembre08 locura
	    main <= do_link;	   --diciembre08 locura
	    end if;    
	  
	  when do_link =>
	    new_fifo <= '0';
	    main <= w_trans;
	        
	  when w_trans => 
	    --diciembre 08 if state=w_command then
	    if (vdontread(0)='1') then
		    if sel_read (5)='1' then   
		      main <= event_done;
		    	else 
			  main <= w_trans;		  --diciembre08 locura
	            sel_read <= sel_read(4 downto 0) & '0';
		       rob_id <= rob_id +1;
			  vdontread <= '0' & vdontread(5 downto 1);
			end if;
			new_fifo <='0';		--diciembre08 locura
	    elsif (fin_synch='1') then
		    if sel_read (5)='1' then   
		      main <= event_done;
	       else
	         sel_read <= sel_read(4 downto 0) & '0';
		      rob_id <= rob_id +1;
	         new_fifo <= '1';
	         main <= do_link;
			  vdontread <= '0' & vdontread(5 downto 1);
	       end if;
	    end if;
	  
	  when event_done =>
	    sel_read(5) <= '0';
	    ros_done <= '1';
    
	  end case;

	end if;

end process mainpr;
--diciembre 08
--fin_synch <= '1' when (state=r_trailer2 and this_ef='0') or (state=forz_trailer2) or (state=s_maxwc2) or (state=s_trailer1 and this_ef='0') or(state=s_timeout2) else '0';

fin_synch <= '1' when (state=r_trailer2 and this_ef='0') else
			'1' when (state=forz_trailer2) else
			'1' when (state=s_maxwc2)  else
			'1' when (state=s_trailer1 and this_ef='0') else
			'1' when (state=s_timeout2) else
			'1' when (state=s_error_ff1) else
			'1' when (state=w_command and this_dontread='1') else
--			'1' when (state=w_command and vdontread(0)='1') else
			 '0';

--fin_synch <= '1' when (state=w_command) else '0';

--diciembre08 ojo tengo que añadir si salgo de s_error_ff1 o 2

-- sequencer
synch: process (clk, valen)
begin
	if valen='0' then
  	  error_evid<='0';
	  state <= w_command;
--	 fin_synch<='0'; --diciembre 08
	  read_fifo_dir <= '0';
	  txena_dir <= '0';
     word_count <= (others => '0');
 	  time_start <= '0';
	  s_data <= (others => '0');
	  lives <= '0';
	  trail <= '0';
	  sta_to <=(others=>'0');
	elsif clk'event and clk='1' then
	
  	case state is
	  when w_command =>
--		 fin_synch<='0'; --diciembre 08
		  error_evid<='0';
    	  lives <= '0';
		  trail <= '0';
	     time_start <= '0';
	     read_fifo_dir <= '0';
	     txena_dir <= '0';
        word_count <= (others => '0');
 	     sta_to <=(others=>'0');
        if new_fifo='1' then
--	   	if this_dontread='0' then
 --diciembre08 locura           if this_mask='0' and 
 --diciembre08 locura                   (this_timed_out='0' or dis_timo_mask='1') and
--diciembre08 locura                    (this_maxw='0' or dis_timo_mask='1') and
--diciembre08 locura                    this_ff='0' and
--diciembre08 locura                    (this_paf='1' or dis_paf_warn='1')  and 
--diciembre08 locura						  (this_evid_mis='0' or dis_evid_bloq='1') then
			     if this_ff='1' then
			    	 	state <= s_error_ff0;
	    			elsif (this_paf='0' and dis_paf_warn='0') then
	      			state <= s_warn_paf0;
				else
			          state <= w_ef_h0;
				end if;
             else
--diciembre08 locura	             state <= chk_mask;
	    			  state <= w_command;  --diciembre08 locura
 --            end if;
        end if;

-- canales enmascarados
	  when chk_mask =>
	    time_start <= '0';
	    if this_mask='1' or (this_timed_out='1' and dis_timo_mask='0')
		      or (this_maxw='1' and dis_timo_mask='0')
			 or (this_ff_reg='1' and  dis_ffreg_mask='0')	 --feb08
		      or (this_evid_mis='1' and dis_evid_bloq='0') then
	      state <= w_command;
	    elsif this_ff='1' then
	    	 state <= s_error_ff0;
	    elsif (this_paf='0' and dis_paf_warn='0') then
	      state <= s_warn_paf0;
	    else 
	      state <= w_ef_h0;
	    end if;

	  when s_error_ff0 =>
	    if hastoken='1' then
	      txena_dir <= '1';     
		   s_data <= fmt_error_ff_1;
		   state <= s_error_ff1;
	    end if;

	  when s_error_ff1 =>
         txena_dir <= '1';     
	    s_data <= fmt_error_ff_2;
	    time_start <= '0'; --diciembre 08
--diciembre 08	    state <= s_error_ff2;
	    if (dis_ffreg_mask='0')then   --diciembre 08
 		 state <= w_command;	--diciembre 08
--		 fin_synch<='1'; --diciembre 08
	    else 
	      state <= w_ef_h0;
	    end if;


--diciembre 08	  when s_error_ff2 =>
--diciembre 08	    time_start <= '0';
--diciembre 08     txena_dir <= '0';        
--diciembre 08	    if (this_paf='0' and dis_paf_warn='0') then
--diciembre 08	      state <= s_warn_paf0;
--diciembre 08	    if (dis_ffreg_mask='0')then   --diciembre 08
--diciembre 08	    state <= w_command;	--diciembre 08
--		 fin_synch<='1'; --diciembre 08
--diciembre 08	    	    else 
--diciembre 08	    	      state <= w_ef_h0;
--diciembre 08	    	    end if;

	  when s_warn_paf0 =>
	    if hastoken='1' then
	      txena_dir <= '1';       
		   s_data <= fmt_warn_paf_1;
		   state <= s_warn_paf1;
	    end if;

	  when s_warn_paf1 =>
  		 lives <= '0';
	    txena_dir <= '1';       
	    s_data <= fmt_warn_paf_2;
--diciembre 08	    state <= s_warn_paf2;
	    state <= w_ef_h0;
	    time_start <= '0'; --diciembre 08, porque estaba en s_warn_paf2

--	  when s_warn_paf2 =>
--	    txena_dir <= '0';          
--	    state <= w_ef_h0;
--	    time_start <= '0';
	    
	when w_ef_h0 =>
--  espero a que este lista la fifo y cuando tenga algo 
-- almaceno el dato (ya esta listo porque es modo FWFT) y avanzo a la segunda palabra 
-- el read_fifo no lo va a detectar hasta un ciclo de reloj después de activarlo,
--luego la segunda palabra no está lista en el dout hasta r_header2
--De igual modo, el EF por culpa de este read_fifo_dir que activo aqui no se puede detectar 
--hasta r_header2
  --oct06  	lives <= '1';

		txena_dir <= '0'; --diciembre 08 por si vendo de s_warn_paf1

		time_start <= '1';
		if this_ef='0' then
			read_fifo_dir <= '1';     --1er REN, no lo pilla el reloj hasta el siguiente ciclo
      	state <= r_header1;
		elsif time_out='1' then
			state <= s_timeout0;
			sta_to <= "0000";
		end if;

	when r_header1 =>
     	  lives <= '0'; -- que el timeout sea igual al tiempo necesario para procesar un evento
		  time_start <= '0';
		  if this_ef='0' then
            state <= r_header2;
			   read_fifo_dir <= '1';  --2º REN  
  		      header1_reg <= fout(header1_reg'range);  --da igual almacenarla aqui que arriba 
			else 
            state <= w_ef_h1;
			   read_fifo_dir <= '0';    
			end if;

	when w_ef_h1 =>
--	Espero a que este vacia y me vuelvo a r_header1
-- Activo el read_fifo pues así venía de w_ef_h0
--y si la fifo ha pasado a EF pues no ha servido de nada 
--asi que hay que volver a dárselo para estar sincronizados
		time_start <= '1';
		if this_ef='0' then
			state <= r_header1;
		   read_fifo_dir <= '1';    --1º REN por EF
		elsif time_out='1' then
			state <= s_timeout0;
		   read_fifo_dir <= '0';    
			sta_to <= "0001";
		end if;

	when r_header2 =>
		  time_start <= '0';
			header2_reg <= fout;	  
			if this_ef='0' then
	         state <= r_trailer1;
 		   	read_fifo_dir <= '1';   --3º REN 
			else
				state <= w_ef_h2;
 		   	read_fifo_dir <= '0'; 
			end if;


	when w_ef_h2 => 	  --  estado de espera
	   time_start <= '1';
		if this_ef ='0' then
			state <= r_header2;
	   	read_fifo_dir <= '1';   --2º REN por EF, dado en r_header1 pero fue bloqueado por el EF
		elsif time_out='1' then
			state <= s_timeout0;
		   read_fifo_dir <= '0';    
			sta_to <= "0010";
		end if;


	when r_trailer1 =>
			time_start <= '0';
		  if this_ef='0' then
			   if (fout(15 downto 12)="0001")  then --es TRAILER
				     if dis_head_trail='0' then   --TIRO EL EVENTO
					     state <= r_trailer2;	
			           read_fifo_dir <= '1'; --4ª REN way 1   
						  trail<='0';
					  else   --LO ENVIO
					     state <= wait_token;	
 				        trailer_reg <= fout;
 			           read_fifo_dir <= '0'; 
						  trail<='1';
					  end if;
			else	  --ES UN HIT
			        state <= wait_token; --LO ENVIO
 				     trailer_reg <= fout;
				     read_fifo_dir <= '0'; 
					  trail<='0';
				end if;
	    		if evid = header1_reg & header2_reg (15 downto 12) then --diciembre 08
					error_evid<='0';  --diciembre 08
			else
					error_evid<='1';  --diciembre 08
     		end if;
		 else 
            state <= w_ef_t1;
            read_fifo_dir <= '0';    
			   trail<='0';
		 end if;


	when w_ef_t1 =>	  --  estado de espera
	   time_start <= '1';
		if this_ef ='0' then
			state <= r_trailer1;
		   read_fifo_dir <= '1';    --3º REN por EF
		elsif time_out='1' then
			state <= s_timeout0;
		   read_fifo_dir <= '0';    
			sta_to <= "0011";
		end if;

	when r_trailer2 =>  -- termino el evento
      time_start <= '0';
	   read_fifo_dir <= '0';    
		 if this_ef='0' then
		     state <= w_command;	
--			fin_synch<='1'; --diciembre 08
		 else 
           state <= w_ef_t2;
		 end if;

	when w_ef_t2 =>	  --  estado de espera
	   time_start <= '1';
		if this_ef ='0' then
			state <= r_trailer2;
		   read_fifo_dir <= '1';    --4º REN por EF
		elsif time_out='1' then
			state <= s_timeout0;
		   read_fifo_dir <= '0';    
			sta_to <= "0100";
		end if;

-- problema de formatos, a partir de aqui,
-- si trail = 1 --> trailer_reg es trailer_1 y fout es trailer_2
-- si trail = 0 --> trailer_reg es dato_1 y fout es dato_2

-- TOKEN
	  when wait_token =>
	     read_fifo_dir <= '0';   
	     time_start <= '0';
	     if hastoken='1' then
		  		lives <='1';
--diciembre 08	     		if evid = header1_reg & header2_reg (15 downto 12) then
	     		if error_evid='0' then
		   			state <= s_header1;
					error_evid<='0';  --diciembre 08
	     		elsif dis_evid_wrong='1' then
--diciembre 08					state <= evid_wrong0;
					state <= s_header1;  --diciembre 08
					error_evid<='1';  --diciembre 08
				else
		   			state <= evid_wrong1;
					error_evid<='1';  --diciembre 08
	     		end if;
--diciembre 08	     		if evid = header1_reg & header2_reg (15 downto 12) then
--diciembre 08		   			state <= s_header1;
--diciembre 08					error_evid<='0';  --diciembre 08
--diciembre 08	     		elsif dis_evid_wrong='1' then
--diciembre 08--diciembre 08					state <= evid_wrong0;
--diciembre 08					state <= s_header1;  --diciembre 08
--diciembre 08					error_evid<='1';  --diciembre 08
--diciembre 08				else
--diciembre 08		   			state <= evid_wrong1;
--diciembre 08					error_evid<='1';  --diciembre 08
--diciembre 08	     		end if;
        end if;

--diciembre 08	  when evid_wrong0 =>
--diciembre 08		error_evid<='1';
--diciembre 08		txena_dir <= '0';               
--diciembre 08		state <= s_header1;

	  when evid_wrong1 =>
		error_evid<='1';
		s_data <= fmt_evid_wrong_1;
		txena_dir <= '1';               
		state <= evid_wrong2;

	  when evid_wrong2 =>
		s_data <= fmt_evid_wrong_2;
		txena_dir <= '1';               
  --diciembre 08		state <= evid_wrong3;
		state <= s_header1;	   --diciembre 08

  --diciembre 08	  when evid_wrong3 =>
  --diciembre 08		txena_dir <= '0';                
  --diciembre 08		state <= s_header1;
	      
	  when s_header1 =>
	    txena_dir <= '1';                 
	    s_data <= fmt_header_1;
	    state <= s_header2;

	  when s_header2 =>                          
	   time_start <= '0';                      
      txena_dir <= '1';                 
      s_data <= fmt_header_2;                 
		if trail='1' then                       
    	     state <= forz_trailer1;
   	else
		     state <= s_dato_first1;
    	end if;

--ENVIO TRAILER SIN HITS Y TERMINO EL EVENTO
     when forz_trailer1 =>   
	     time_start <= '0';
  	     if this_ef='0' then 
	        	read_fifo_dir <= '1';   --4º REN	way 2
		      txena_dir <= '1';                 
      	   s_data <= fmt_trailer_alt_1;
         	state <= forz_trailer2;
		  else
	        	read_fifo_dir <= '0'; 
		      txena_dir <= '0';                 
         	state <= w_ef_ft1;
		  end if;

	  when w_ef_ft1 =>
	     time_start <= '1';
        txena_dir <= '0'; 
  	     if this_ef='0' then 
	        	read_fifo_dir <= '1';   --4º REN	way 2
         	state <= forz_trailer1;
		  elsif time_out='1' then
         	state <= s_timeout1;
				sta_to <= "0101";
		  end if;
	  		

     when forz_trailer2 => 
        	read_fifo_dir <= '0';  
         txena_dir <= '1';                 
         s_data <= fmt_trailer_2;
         state <= w_command;
-- 		fin_synch<='1'; --diciembre 08

     when s_dato_first1 =>
          s_data <= fmt_dato_alt_1;
		    read_fifo_dir <= '1';   --REN par
	 		 txena_dir <= '1'; 
		  	 state <= send_dato2;
		    
	  when send_dato2 =>
           time_start <= '0';
           s_data <= fout;
--        	  if ((nolimit_maxw='1') or (word_count(15 downto 8) /= max_word_count)) then
        	  --REEMPLAZO EL LIMITE, MIN=8 words, MAX=FFF=4095 words
			  if ((nolimit_maxw='1') or (word_count(11 downto 4) /= max_word_count)) then
			     if this_ef='0' then 
 					  read_fifo_dir <= '1';   --REN par
	 		        txena_dir <= '1'; 
                 state <= send_dato1;
						word_count <= word_count +1;
           else
					  read_fifo_dir <= '0'; 
				     txena_dir <= '0'; 
                 state <= w_ef_sd2;
				  end if;	
			  else
			      read_fifo_dir <= '0';
				   txena_dir <= '1'; 
               state <= s_maxwc1;
           end if;

	  when w_ef_sd2 =>
	     time_start <= '1';
        txena_dir <= '0'; 
	     if this_ef='0' then	                  
               read_fifo_dir <= '1';
               state <= send_dato2;
        elsif time_out='1' then
               state <= error_fill;      
					sta_to <= "0110";
        end if;
	  
	  when send_dato1 =>
          time_start <= '0';
			 if this_ef='0' then
        	    read_fifo_dir <= '1';   --REN impar
             if fout(15 downto 12)="0001" then
               txena_dir <= '1';
               s_data <= fmt_trailer_1;
               state <= s_trailer1;
	          else
               txena_dir <= '1';
               state <= send_dato2; 
   			   s_data <= fmt_dato_1;
             end if;  
			 else 
				  read_fifo_dir <= '0'; 
				  txena_dir <= '0'; 
              state <= w_ef_sd1;
			  end if;


	  when w_ef_sd1 =>
	    time_start <= '1';
       txena_dir <= '0'; 
	    if this_ef='0' then	                    
          read_fifo_dir <= '1';
          state <= send_dato1;
       elsif time_out='1' then
          state <= s_timeout0;      
			 sta_to <= "0111";
       end if;


	  when s_trailer1 => 		
 	       time_start <= '0';                
            read_fifo_dir <= '0';       
    		 if this_ef='0' then
			lives <='1';
			txena_dir <= '1';           
	    	     s_data <= fmt_trailer_2;
	          state <= w_command;
-- 		fin_synch<='1'; --diciembre 08
		    else
			 	lives <='0';
			     txena_dir <= '0';       
			 	state <= w_ef_st1;
			 end if;

	  when w_ef_st1 =>   --estado de espera
	    time_start <= '1';
         txena_dir <= '0'; 
	    if this_ef='0' then	                    
            read_fifo_dir <= '1';
            state <= s_trailer1;
         elsif time_out='1' then
            state <= error_fill;      
		  sta_to <= "1000";
         end if;

--TIMEOUTS
	when error_fill =>
 		time_start <= '0';
		txena_dir <= '1';               
		s_data <= (others=>'0');
		state <= s_timeout1;

	when s_timeout0 =>                    
    		read_fifo_dir <= '0';            
		if hastoken='1' then
			state <= s_timeout1;
		end if;
	
	when s_timeout1 =>
	     lives <='1';
		time_start <='0';
		txena_dir <= '1';                
		s_data <= fmt_timeout_1;
		state <= s_timeout2;

	when s_timeout2 =>
		lives <='0';
		s_data <= fmt_timeout_2;
		state <= w_command;
--		fin_synch<='1'; --diciembre 08

--MAXIMO DE PALABRAS SIN ENCONTRAR TRAILER
     when s_maxwc1 =>
	     lives <='1';
		txena_dir <= '1';     
		s_data <= fmt_maxwc_1;
		state <= s_maxwc2;

	when s_maxwc2 =>
 		lives <='0';
		s_data <= fmt_maxwc_2;
	     state <= w_command;
--		fin_synch<='1'; --diciembre 08
 end case;
end if;
	    
end process synch;


-- channel timed out
process (clk, soft_reset)
begin
	if soft_reset='1' then
	    timed_out <= (others => '0');
	elsif clk'event and clk='1' then
	  if enw_timed_out='1' then
	    timed_out <= db_in;
--diciembre 08	  elsif state=s_timeout2 then      
	  elsif state=s_timeout1 then      
	    timed_out <= timed_out or sel_read(5 downto 0);
	  end if;
	end if;
end process;


-- channel maxwords reached
process (clk, soft_reset)
begin
	if soft_reset='1' then
	    maxw_reached <= (others => '0');
	elsif clk'event and clk='1' then
	  if enw_maxw='1' then
	    maxw_reached <= db_in (5 downto 0);
	  elsif state=s_maxwc1 then      
	    maxw_reached <= maxw_reached or sel_read(5 downto 0);
	  end if;
	end if;
end process;

-- channel evid_mis
process (clk, soft_reset)
begin
	if soft_reset='1' then
	    evid_mis <= (others => '0');
	elsif clk'event and clk='1' then
	  if enw_evid_mis='1' then
	    evid_mis <= (others => '0');
--diciembre 08	  elsif error_evid='1' and (state=forz_trailer2 or state=s_trailer1) then
	  elsif error_evid='1' and (state=r_trailer2 or state=wait_token) then
	    evid_mis <= evid_mis or sel_read(5 downto 0);
	  end if;
	end if;
end process;

-- timer
process(clk, soft_reset) 
begin
 	if soft_reset='1' then
	  time_counter <= (others => '0'); 
	  time_out <= '0';	  
	elsif (clk'event and clk='1') then
	  if time_start='0' then
	    time_counter <= '0' & timeout_value; 
	    time_out <= '0';
	  elsif (this_hasunlock='1' and dis_hul_mask='0') then --diciembre 08
	    time_counter <= '0' & timeout_value; 	--diciembre 08
	    time_out <= '1';	    --diciembre 08
	  elsif time_out='0' then
	    time_counter <= time_counter - 1;
	    time_out <= time_counter(time_counter'high);
       end if;
	end if;
end process;

--diciembre 08 locura
process(clk, soft_reset) 
begin
 	if soft_reset='1' then
	  dontread <= mask; 
	elsif (clk'event and clk='1') then
	  if (state=s_maxwc1 and dis_timo_mask='0')then       --wordcount
	    dontread <= dontread or sel_read(5 downto 0);
	  elsif (error_evid='1' and (state=r_trailer2 or state=wait_token) and dis_evid_bloq='0') then  --evidmis
	    dontread <= dontread or sel_read(5 downto 0);
	  elsif (this_hasunlock='1' and state=s_timeout1 and dis_hul_mask='0') then  --unlock
	    dontread <= dontread or sel_read(5 downto 0);
	  elsif (this_hasunlock='0' and state=s_timeout1 and dis_timo_mask='0') then 	 --timeout
	    dontread <= dontread or sel_read(5 downto 0);
	  elsif (state=s_error_ff1 and dis_ffreg_mask='0') then 	 --fifo full
	    dontread <= dontread or sel_read(5 downto 0);
 	  end if;
	end if;
end process;
end arch;
	
