-- Module Name:    w5300_modul - Behavioral 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library FACT_FAD_lib;
use FACT_FAD_lib.fad_definitions.ALL;

ENTITY w5300_modul IS
  generic(
    RAM_ADDR_WIDTH : integer := 14
  );
   PORT( 
      state          : OUT    std_logic_vector (7 DOWNTO 0);  -- state is encoded here ... useful for debugging.
	  debug_data_ram_empty : OUT    std_logic;
	  debug_data_valid : OUT    std_logic;
	  data_generator_idle_i : IN std_logic;
	  data_ram_not_full :in std_logic;
	  
	  socket_tx_free_out : out std_logic_vector (16 DOWNTO 0);  -- 17bit value .. that's true
     
      clk            : IN     std_logic;
      wiz_reset      : OUT    std_logic                     := '1';
      addr           : OUT    std_logic_vector (9 DOWNTO 0);
      data           : INOUT  std_logic_vector (15 DOWNTO 0);
      cs             : OUT    std_logic                     := '1';
      wr             : OUT    std_logic                     := '1';
      led            : OUT    std_logic_vector (7 DOWNTO 0) := (OTHERS => '0');
      rd             : OUT    std_logic                     := '1';
      int            : IN     std_logic;
      write_length   : IN     std_logic_vector (16 DOWNTO 0);
      ram_start_addr : IN     std_logic_vector (RAM_ADDR_WIDTH-1 DOWNTO 0);
      ram_data       : IN     std_logic_vector (15 DOWNTO 0);
      ram_addr       : OUT    std_logic_vector (RAM_ADDR_WIDTH-1 DOWNTO 0);
      data_valid     : IN     std_logic;
      data_valid_ack : OUT    std_logic := '0';
      busy           : OUT    std_logic                     := '1';
      write_header_flag, write_end_flag : IN std_logic;
      fifo_channels : IN std_logic_vector (3 downto 0);
      -- softtrigger:
      s_trigger : OUT std_logic := '0';
      c_trigger_enable: out std_logic := '0';
      c_trigger_mult: out std_logic_vector (15 DOWNTO 0) := conv_std_logic_vector(0 ,16); --subject to changes
      
      

	  -- FAD configuration signals:
	  ------------------------------------------------------------------------------
		memory_manager_config_start_o	: out std_logic := '0';
		memory_manager_config_valid_i	: in std_logic;
		
		spi_interface_config_start_o	: out std_logic := '0';
		spi_interface_config_valid_i	: in std_logic;
		
		--data_generator_config_start_o	: out std_logic := '0';
		--data_generator_config_valid_i	: in std_logic;
		
		dac_setting						: out dac_array_type := DEFAULT_DAC;		--<<-- default defined in fad_definitions.vhd
		roi_setting						: out roi_array_type := DEFAULT_ROI;		--<<-- default defined in fad_definitions.vhd
		
		runnumber						: out std_logic_vector (31 DOWNTO 0) := conv_std_logic_vector(0 ,32); 
		reset_trigger_id				: out std_logic := '0';

		data_ram_empty 					: IN std_logic;
		
	  ------------------------------------------------------------------------------
      
	  -- MAC/IP calculation signals:
	  ------------------------------------------------------------------------------
      MAC_jumper : in std_logic_vector (1 downto 0);
      BoardID : in std_logic_vector (3 downto 0);
      CrateID : in std_logic_vector (1 downto 0);
	  ------------------------------------------------------------------------------
      
	  -- user controllable enable signals
	  ------------------------------------------------------------------------------
	  trigger_enable : out std_logic; 
	  
      denable : out std_logic := '0'; -- default domino wave on. ... in case if REFCLK error ... REFCLK counter will override.
      dwrite_enable : out std_logic := '1'; -- default DWRITE low.
      sclk_enable : out std_logic := '1'; -- default DWRITE HIGH.
      srclk_enable : out std_logic := '1'; -- default SRCLK on.
      busy_enable : out std_logic := '0';
	  socket_send_mode_out : out std_logic;
	  busy_manual : out std_logic		:= '0';
	  ------------------------------------------------------------------------------
	  
	  -- ADC CLK generator, is able to shift phase with respect to X_50M
	  -- these signals control the behavior of the digital clock manager (DCM)
	  ------------------------------------------------------------------------------
	  ps_direction : out std_logic := '1'; -- default phase shift upwards
      ps_do_phase_shift : out std_logic := '0'; --pulse this to phase shift once
      ps_reset : out std_logic := '0'; -- pulse this to reset the variable phase shift
      ps_ready : in std_logic;
      ------------------------------------------------------------------------------
      	  
	  -- signals used to control FAD LED bahavior:
	  -- one of the three LEDs is used for com-status info
	  ------------------------------------------------------------------------------
      socks_waiting : out std_logic;
      socks_connected: out std_logic
	  ------------------------------------------------------------------------------
	
	
	  
   );
END w5300_modul ;

architecture Behavioral of w5300_modul is 

type single_trigger_gen_state_type is ( IDLE, TRIGGERED);
signal single_trigger_gen_state : single_trigger_gen_state_type := IDLE;
signal trigger_input_sr : std_logic_vector ( 1 downto 0) := (others => '0') ;
signal	single_triggers_to_produce : natural range 0 to 1023 := 0;
signal data_ram_not_full_sr : std_logic_vector (1 downto 0) := (others => '0');
signal single_trigger_sig : std_logic := '0';

type state_init_type is (
	INTERRUPT, RESET, WAIT_AFTER_RESET, WRITE_REG, READ_REG, WRITE_DATA,
	INIT, LOCATE, IM, MT, STX, STX1, STX2, STX3, SRX, SRX1, SRX2, SRX3, MAC, MAC1, MAC2, GW, GW1, SNM, SNM1, IP, IP1, 
	TIMEOUT, 
	--RETRY,
	SI, SI1, SI1b, SI2, SI3, SI4, SI5, SI6,	ESTABLISH, EST1, 
	SEND_1ST_KEEP, SET_Sn_KPALVTR, 
	INITIAL_CONNECTION_MESSAGE_TO_FIFO, INITIAL_CONNECTION_MESSAGE_SET_SIZE_HIGH_BYTE, INITIAL_CONNECTION_MESSAGE_SET_SIZE_LOW_BYTE, INITIAL_CONNECTION_MESSAGE_SEND, 
	
	CONFIG, WAIT_100NS, WAIT_UNTIL_DG_IDLE, 
	CONFIG_MEMORY_MANAGER, WAIT_FOR_CONFIG_MEMORY_MANAGER,
	CONFIG_DATA_GENERATOR, WAIT_FOR_CONFIG_DATA_GENERATOR,
	CONFIG_DAC_ONLY, WAIT_FOR_CONFIG_DAC_ONLY,
	
	GENERATE_1ST_TRIGGER_AFTER_ESTABLISHED,
	WAIT_AFTER_1ST_TRIGGER_AFTER_ESTABLISHED,
	
	MAIN, MAIN1, MAIN2, MAIN3, CHK_RECEIVED, READ_DATA
);
type state_write_type is (
	WR_START, 
	WR_GET_EVT_ID_WAIT1, WR_GET_EVT_ID1, WR_GET_EVT_ID_WAIT2, WR_GET_EVT_ID2,
	WR_MOD7_STARTED, WR_WAIT_FOR_MOD7,
	WR_CHECK_FOR_FIFO_SPACE_01, WR_CHECK_FOR_FIFO_SPACE_02, WR_CHECK_FOR_FIFO_SPACE_03, WR_CHECK_FOR_FIFO_SPACE_04,	
	WR_05, WR_05_PREPARE_LENGTH_INFO, WR_05_POSTPREPARE_LENGTH_INFO,
	WR_05a, WR_05b, WR_06, 
	WR_07, 
	WR_ACK, WR_WAIT_FOR_ACK, WAIT_FOR_DATA_VALID_HIGH_AGAIN,
	WR_FIFO, WR_FIFO1, WR_ADC, WR_ADC1, WR_ADC2,
	WR_ENDFLAG, WR_ENDFLAG1, WR_ENDFLAG2, WR_ENDFLAG3
); 
type state_interrupt_1_type is (IR1_01, IR1_02, IR1_03, IR1_04);
type state_interrupt_2_type is (
	IR2_01, IR2_02, IR2_03, IR2_04, IR2_05, 
	IR2_CHECK_SOCKET_STATE, IR2_WAIT_FOR_SOCKETS_IN_CLOSED_STATE,
	WAIT_BEFORE_IR2_06,
	IR2_06);

type state_read_data_type is (
	RD_1, 
	RD_2, 
	RD_3, 
	RD_4, 
	STATUS_OUT_START					 ,
	STATUS_OUT_CHECK_IF_FIFO_FREE_01     ,
	STATUS_OUT_CHECK_IF_FIFO_FREE_02     ,
	STATUS_OUT_CHECK_IF_FIFO_FREE_03     ,
	STATUS_OUT_CHECK_IF_FIFO_FREE_04     ,
	STATUS_OUT_WRITE_HEAD                ,
	STATUS_OUT_WRITE_CMD_COUNTER         ,
	STATUS_OUT_SET_MESSAGE_LENGTH_01     ,
	STATUS_OUT_SET_MESSAGE_LENGTH_02     ,
	STATUS_OUT_ISSUE_SEND_COMMAND        ,
	WAIT_AFTER_SINGLE_TRIGGER,
	RD_5,
	WAIT_FOR_TRIGGER_ID_RESET_1, WAIT_FOR_TRIGGER_ID_RESET_2,
	RD_6,
	READ_COMMAND_DATA_SECTION,
	PUT_COMMAND_DATA_SECTION,
	EXECUTE,
	RD_END
);

--signal RST_TIME : std_logic_vector(19 downto 0) := X"7A120";
signal RST_TIME : std_logic_vector(23 downto 0) := X"4C4B40";

signal par_addr : std_logic_vector (9 downto 0) := (OTHERS => '0');
signal par_data : std_logic_vector (15 downto 0) := (OTHERS => '0');
signal data_read : std_logic_vector (15 downto 0) := (OTHERS => '0');
signal adc_data_addr : std_logic_vector (RAM_ADDR_WIDTH-1 DOWNTO 0);

signal state_init, next_state , next_state_tmp : state_init_type := RESET;
signal state_after_config : state_init_type := MAIN;
signal count : std_logic_vector (2 downto 0) := "000";
signal state_write : state_write_type := WR_START;
signal state_interrupt_1 : state_interrupt_1_type := IR1_01;
signal state_interrupt_2 : state_interrupt_2_type := IR2_01;
signal state_read_data : state_read_data_type := RD_1;

signal interrupt_ignore : std_logic := '1';
signal int_flag : std_logic := '0';
signal ram_access : std_logic := '0';

--signal zaehler : std_logic_vector (19 downto 0) := (OTHERS => '0');
signal zaehler : std_logic_vector (23 downto 0) := (OTHERS => '0');
signal data_cnt : integer := 0;
signal drs_cnt : integer :=0;
signal channel_cnt : integer range 0 to 9 :=0;
signal socket_cnt : std_logic_vector (2 downto 0) := "000";
signal roi_max : std_logic_vector (10 downto 0);
signal data_end : integer := 0;

signal socket_tx_free : std_logic_vector (16 downto 0) := (others => '0');
signal write_length_bytes : std_logic_vector (16 downto 0);

signal socket_rx_received : std_logic_vector (16 downto 0) := (others => '0');
signal chk_recv_cntr : integer range 0 to 10000 := 0;

-- --
signal wait_cntr : integer range 0 to 10000 := 0;
-- --

signal rx_packets_cnt : std_logic_vector (15 downto 0);

signal update_of_rois : std_logic := '1';
signal update_of_lessimportant : std_logic := '1';


signal trigger_enable_sig : std_logic := '0';
signal trigger_enable_storage_sig : std_logic;

signal local_write_length   : std_logic_vector (16 DOWNTO 0);
signal local_ram_start_addr : std_logic_vector (RAM_ADDR_WIDTH-1 DOWNTO 0);
signal local_ram_addr       : std_logic_vector (RAM_ADDR_WIDTH-1 downto 0);
signal local_socket_nr      : std_logic_vector (2 DOWNTO 0);
signal local_write_header_flag, local_write_end_flag : std_logic;
signal local_fifo_channels : std_logic_vector (3 downto 0);

signal wait_100ns_sig : std_logic_vector (5 downto 0) := "000000";

constant config_addr_max : integer := 47; 
signal config_addr : integer range 0 to config_addr_max;
type config_data_type is array (0 to config_addr_max) of std_logic_vector(15 downto 0); 
signal config_setting : config_data_type := (
--		X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", 		--<<-- ROIs = 10 TESTING ONLY
--		X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", 		--<<-- ROIs = 10 TESTING ONLY
--		X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", 		--<<-- ROIs = 10 TESTING ONLY
--		X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", X"000A", 		--<<-- ROIs = 10 TESTING ONLY

		X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", 		--<<-- ROIs = 1024
		X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", 		--<<-- ROIs = 1024
		X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400",  		--<<-- ROIs = 1024
		X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400", X"0400",  		--<<-- ROIs = 1024

		X"61A8", X"0000", X"0000", X"0000", X"7080", X"7080", X"7080", X"7080",					 --<<-- DACs
		X"0000",
		X"0000", X"0000",  -- MSword // LSword
		X"0000"						-- this is a dummy address; this address is used only, if the user sent an invalid address within a WRITE command
		);
		
		

-- signals used for MAC/IP calculation:
-- these 2 synch in, the jumper state.
signal FAD_in_cam : std_logic := '0';
signal FAD_at_ETHZ : std_logic := '0';
-- these 2 synch in the FMP lines encoding the FAD position in the cam. 
signal bid : std_logic_vector (3 downto 0);
signal cid : std_logic_vector (1 downto 0);

-- for 'send'-serialization
signal FADid : integer range 0 to 39 := 0;    -- 39 = number of FADs in camera minus 1
constant MICROSEC_TO_WAIT_BEFORE_SEND : integer := 25;
signal wait_before_send_counter : integer range 0 to 50*39*MICROSEC_TO_WAIT_BEFORE_SEND := 0;
signal wait_before_send_counter_goal : integer range 0 to 50*39*MICROSEC_TO_WAIT_BEFORE_SEND := 0;

-- these are just used as local variables, to make reading easier.
signal mac_loc : mac_type;
signal ip_loc : ip_type;
signal gateway_loc : ip_type;
signal netmask_loc : ip_type;

	-- signals for synching in asynchronous input signals
		------------------------------------------------------------------------------
		signal w5300_interrupt_sr : std_logic_vector(1 downto 0) := "11";
		signal data_valid_sr : std_logic_vector(1 downto 0) := "00"; 
		------------------------------------------------------------------------------
		-- synch in CONFIG inputs
		signal memory_manager_config_valid_i_sr 	: std_logic_vector(1 downto 0) := "00";
		signal spi_interface_config_valid_i_sr		: std_logic_vector(1 downto 0) := "00";
		--signal data_generator_config_valid_i_sr		: std_logic_vector(1 downto 0) := "00";
		signal data_ram_empty_sr 					: std_logic_vector(1 downto 0) := (OTHERS => '0');


		signal data_generator_idle_sr : std_logic_vector(2 downto 0) := "000";

-- only for debugging
--signal error_cnt : std_logic_vector (7 downto 0) := (others => '0');
--signal last_trigger_id : std_logic_vector (15 downto 0) := (others => '0');
signal DG_run_mode_temp_storage_signal : std_logic;
signal data_generator_run_mode_signal : std_logic := '1'; -- default triggers will be accepted
-- signals for different socket modes: DN 04.01.11
signal socket_send_mode : std_logic := '0'; -- if 0 data is send via socket 0; if 1 data is send via the other sockets.
-- signals for Sockek Number calculation
signal event_number : std_logic_vector(31 downto 0);
signal mod7_start : std_logic := '0';
signal mod7_started : std_logic;
signal mod7_valid : std_logic;
signal mod7_result : std_logic_vector(2 downto 0);


signal state_sig : std_logic_vector(7 downto 0) := X"FF";

signal number_of_words_written_to_fifo :  std_logic_vector(15 downto 0) := (others => '0');
signal number_of_bytes_written_to_fifo :  std_logic_vector(16 downto 0) := (others => '0');



signal wait_for_sockets_closed_counter_overflow : std_logic := '0';
signal wait_for_sockets_closed_counter_enable : std_logic := '0';
signal wfscc_1 : integer range 0 to 50000 := 0;
signal wfscc_2 : integer range 0 to 20000 := 0;

constant wait_after_reset_max : integer := 200000000;  -- this is 4sec at 50Mhz
signal wait_after_reset_sig : integer := 0;

constant initial_message_counter_max : integer := 60;
signal initial_message_counter : integer range 0 to initial_message_counter_max := 0;

constant wait_before_ir2_06_counter_max : integer := 100000;
signal wait_before_ir2_06_counter : integer range 0 to wait_before_ir2_06_counter_max := 0;

signal cmd_counter : std_logic_vector (15 downto 0) := (others => '0');


COMPONENT mod7
	 PORT (
			clk       : IN     std_logic;
			number    : IN     std_logic_vector (31 DOWNTO 0);
			start     : IN     std_logic;
			remainder : OUT    std_logic_vector (2 DOWNTO 0) := (others => '0');
			started   : OUT    std_logic                     := '0';
			valid     : OUT    std_logic                     := '0'
	 );
	 END COMPONENT;



begin
	
	mod7_calculator : mod7
	PORT MAP (
		clk			=>clk	,
		number		=>event_number	,
		start		=>mod7_start	,
		remainder	=>mod7_result	,
		started		=>mod7_started	,
		valid		=>mod7_valid
	);


  --synthesis translate_off
  RST_TIME <= X"00120";
  --synthesis translate_on
  
-- concurrent statemnets
state <= (others => '0');
debug_data_valid <= '0';

-- output config settings as DAC and ROI arrays.
roi_mapping : for i in 0 to 35 generate
	roi_setting(i) <= conv_integer(config_setting(i)) when (conv_integer(config_setting(i)) < 1025) else 1024;
end generate roi_mapping;
dac_mapping : for i in 0 to 7 generate
	dac_setting(i) <= conv_integer(config_setting(i+36));
end generate dac_mapping;
c_trigger_mult <= config_setting(44);



trigger_enable <= trigger_enable_sig;

socket_send_mode_out <= socket_send_mode;

	w5300_proc : process (clk)
	begin
		if rising_edge (clk) then
		--socket_tx_free_out <= socket_tx_free;
		
		
		-- synch asynchronous inputs in:
		memory_manager_config_valid_i_sr	<= memory_manager_config_valid_i_sr(0) 	& memory_manager_config_valid_i;
		spi_interface_config_valid_i_sr		<= spi_interface_config_valid_i_sr(0)	& spi_interface_config_valid_i;
		--data_generator_config_valid_i_sr	<= 	data_generator_config_valid_i_sr(0)	& data_generator_config_valid_i;
		data_ram_empty_sr 					<= data_ram_empty_sr(0) 		& data_ram_empty;		
		data_generator_idle_sr				<= data_generator_idle_sr( 1 downto 0 ) & data_generator_idle_i;
		data_ram_not_full_sr				<= data_ram_not_full_sr(0)	& data_ram_not_full;
		
		w5300_interrupt_sr <= w5300_interrupt_sr(0) & int;
		data_valid_sr <= data_valid_sr(0) & data_valid;
		
			-- interrupt is handled synchronously
			-- W5300 pulls low its interrpt line in case of:
			--	When Sockets time out and 
			-- When sockets receive disconnection request.
			
			if (w5300_interrupt_sr(1) = '0') and (interrupt_ignore = '0') then
				case state_interrupt_1 is
					when IR1_01 =>
					state_sig <= X"FF";
						int_flag <= '1';
						busy <= '1';
						state_interrupt_1 <= IR1_02;  --wait one cycle
					when IR1_02 =>
					state_sig <= X"FE";
						state_interrupt_1 <= IR1_03;
					when IR1_03 =>
					state_sig <= X"FD";
						state_init <= INTERRUPT;
						socket_cnt <= "000";
						ram_access <= '0';
						zaehler <= conv_std_logic_vector(0, zaehler'length);
						count <= "000";			--what is this count counting?
						int_flag <= '0';
						interrupt_ignore <= '1';
						state_interrupt_1 <= IR1_04;  --this state is not existing? bad coding habit???
					when others =>
						state_sig <= X"FC";
						null;
				end case;
			end if; -- int = '0'
			
			if int_flag = '0' then
				case state_init is
					-- Interrupt
					when INTERRUPT =>
						case state_interrupt_2 is
							when IR2_01 =>
							state_sig <= X"FB";
								par_addr <= W5300_IR;
								state_init <= READ_REG;
								next_state <= INTERRUPT;
								state_interrupt_2 <= IR2_02;
								
							-- check if it was a Sx Interrupt of Socket n
							-- therfor: loop over all channel.
							-- if the loop ended but no Sx Interrupt was found --> IR2_06
							-- if an Sx Interrupt was found go to --> IR2_03 and check what happened.
							when IR2_02 => 
							state_sig <= X"FA";
								if (data_read (conv_integer(socket_cnt)) = '1') then -- Sx Interrupt
									state_interrupt_2 <= IR2_03;
								else
									socket_cnt <= socket_cnt + 1;
									if (socket_cnt = 7) then
										state_interrupt_2 <= IR2_05;
									else
										state_interrupt_2 <= IR2_02;  -- go on with loop
									end if; 
								end if;
								
							-- check the Interrupt register of the Socket, which caused the Interrupt.
							when IR2_03 =>
							state_sig <= X"F9";
								par_addr <= W5300_S0_IR + socket_cnt * W5300_S_INC; -- Sx Interrupt Register
								state_init <= READ_REG;
								next_state <= INTERRUPT;
								state_interrupt_2 <= IR2_04;
							-- before checking what happened, clear the Interrupt register, so we can proceed.
							when IR2_04 =>
							state_sig <= X"F8";
								par_addr <= W5300_S0_IR + socket_cnt * W5300_S_INC;
								par_data <= data_read; -- clear Interrupts
								state_init <= WRITE_REG;
								next_state <= INTERRUPT;
								state_interrupt_2 <= IR2_05;
							-- send the command to close this socket
							-- then go back and read the main Interrupt register again, 
							-- if this was not Socket 7 ... if it was Socket 7, we're done anyway.
							when IR2_05 =>
								state_sig <= X"F7";
								par_addr <= W5300_S0_CR + socket_cnt * W5300_S_INC;
								--par_data <= X"0010"; -- CLOSE
								par_data <= X"0008"; -- DISCON
								state_init <= WRITE_REG;
								next_state <= INTERRUPT;
								socket_cnt <= socket_cnt + 1;
								if (socket_cnt = 7) then
									socket_cnt <= "000";
									--state_interrupt_2 <= IR2_06;
									state_interrupt_2 <= WAIT_BEFORE_IR2_06;
								else
								  state_interrupt_2 <= IR2_01;
								end if; 

							when IR2_CHECK_SOCKET_STATE =>
								wait_for_sockets_closed_counter_enable <= '1';
								
								par_addr <= W5300_S0_SSR + socket_cnt * W5300_S_INC; -- READ Socket Status Register
								state_init <= READ_REG;
								next_state <= INTERRUPT;
								state_interrupt_2 <= IR2_WAIT_FOR_SOCKETS_IN_CLOSED_STATE;
							
							when IR2_WAIT_FOR_SOCKETS_IN_CLOSED_STATE =>
								if ( wait_for_sockets_closed_counter_overflow = '1') then
									wait_for_sockets_closed_counter_enable <= '0';
									socket_cnt <= "000";
									state_interrupt_2 <= IR2_06;
								else 
									if ( data_read(7 downto 0) = SOCKET_CLOSED ) then
										if ( socket_cnt = 7 ) then 
											socket_cnt <= "000";
											state_interrupt_2 <= IR2_06;
										else
											socket_cnt <= socket_cnt + 1;
											state_interrupt_2 <= IR2_CHECK_SOCKET_STATE;
										end if;
									else 
										state_interrupt_2 <= IR2_CHECK_SOCKET_STATE;
									end if;
								end if;
								
							when WAIT_BEFORE_IR2_06 => 
								state_interrupt_2 <= WAIT_BEFORE_IR2_06;
								wait_before_ir2_06_counter <= wait_before_ir2_06_counter + 1;
								if (wait_before_ir2_06_counter = wait_before_ir2_06_counter_max) then
									wait_before_ir2_06_counter <= 0;
									state_interrupt_2 <= IR2_06;
								end if;
								
								
							-- we go on and reset, the W5300 and this entire state machine.
							when IR2_06 =>
							state_sig <= X"F6";
								state_interrupt_1 <= IR1_01;
								state_interrupt_2 <= IR2_01;
								socket_cnt <= "000";
								state_init <= RESET;
							when others =>
								state_interrupt_1 <= IR1_01;
								state_interrupt_2 <= IR2_01;
								socket_cnt <= "000";
								state_init <= RESET;
						end case;
						
					-- reset W5300
					when RESET =>
					  state_sig <= X"01";
						c_trigger_enable <= '0';
						trigger_enable_sig <= '0';
						busy_enable <= '0';
						busy_manual <= '0';
						socket_send_mode <= '0';
						busy <= '1';
						zaehler <= zaehler + 1;
						socks_waiting <= '0';
						socks_connected <= '0';
						wiz_reset <= '0';
						--led <= X"FF";
						if (zaehler >= conv_std_logic_vector(200, zaehler'length) ) then -- wait 2µs
							wiz_reset <= '1';
						end if;	
						if (zaehler = RST_TIME) then -- wait 10ms
							zaehler <= conv_std_logic_vector (0, zaehler'length);
							socket_cnt <= "000";
							count <= "000";
							ram_access <= '0';
							interrupt_ignore <= '0';
							rd <= '1';
							wr <= '1';
							cs <= '1';
							state_write <= WR_START;
							--state_init <= INIT;
							
							-- I do this early configuration here, in order to get rid of all events in RAM.
							-- in order to end up, with disabled trigger lines, I set trigger enable to 0.
							-- So busy should vanish, once we are here.
							
							
							state_init <= CONFIG;
							state_after_config <= INIT;
							--state_init <= WAIT_AFTER_RESET;
						end if;
						
					when WAIT_AFTER_RESET =>  -- waits macroscopic time ... 4sec currently.
						wait_after_reset_sig <= wait_after_reset_sig + 1;
						if (wait_after_reset_sig = wait_after_reset_max) then
							wait_after_reset_sig <= 0;
							state_init <= CONFIG;
							state_after_config <= INIT;
						end if;
				
						
					-- Init
					when INIT =>
					  state_sig <= X"02";
						-- status of MAC jumpers is synched in
						-- and Board- and CrateID are synched in
						FAD_in_cam <= MAC_jumper(1); -- see position of jumpers in FACT logbook
						FAD_at_ETHZ <= MAC_jumper(0); -- MAC_jumper(1) is where D_T(7) was; MAC_jumper(0) is where D_T(6) was;
						bid <= BoardID;
						cid <= CrateID;
						par_addr <= W5300_MR;
						par_data <= X"0000";
						state_init <= WRITE_REG;
						next_state <= LOCATE;
				
					when LOCATE =>
						state_sig <= X"03";					  
						state_init <= IM;
						
						-- calculate FADid for 'send'-ing serialization
						FADid <= conv_integer(cid)*10+conv_integer(bid);

						if (FAD_in_cam = '1') then
							if (bid = "1111" and cid="11") then
								-- if BID = "1111" and CID="11" then FAD is not really in cam
								-- I don't know what to do now.
								-- I could wait a long time, and then just assume, I was not in cam.
								-- this should never happen!!!!!
								-- impossible to find this out, if in cam
								gateway_loc <= ETHZ_GATEWAY;
								netmask_loc <= ETHZ_NETMASK;					        
								mac_loc <= MAC_FAD2; 
								ip_loc <= IP_ETHZ_FAD2;
								--state_init <= INIT;
							else -- everything is fine
								-- IP & MAC are calculated from BID & CID
								-- code here
								gateway_loc <= CAM_GATEWAY;
								netmask_loc <= CAM_NETMASK;					        
								mac_loc <= (CAM_MAC_prefix (0), CAM_MAC_prefix (1)  , conv_std_logic_vector ( conv_integer(cid)*10+conv_integer(bid)  , 16)   ); 
								ip_loc <= ( CAM_IP_PREFIX(0) , CAM_IP_PREFIX(1) , IP_offset + conv_integer(cid) , IP_offset + conv_integer(bid) );
							end if;
						else -- FAD is tested, either at ETHZ or at TUDO AND either with FMP or without.
							if ( FAD_at_ETHZ = '0' ) then
								-- easy FAD is at TUDO -> only one choice.
								mac_loc <= MAC_FAD0;
								ip_loc <= IP_TUDO;
								gateway_loc <= TUDO_GATEWAY;
								netmask_loc <= TUDO_NETMASK;
							else -- FAD is at ETHZ but not in cam --> IP lookup table is needed.
								if (bid = "1111" and cid="11") then -- FAD is not in crate
									mac_loc <= MAC_FAD0;
									ip_loc <= IP_ETHZ_FAD0;
									gateway_loc <= ETHZ_GATEWAY;
									netmask_loc <= ETHZ_NETMASK;					        
								else
									-- FAD is at ETHZ and in crate:
									-- crate ID is not of importance.
									-- we only have 3 MACs and IPs so far, so only the first boardIDs are allowed.
									if ( conv_integer(bid) < MAC_LIST'length) then
										gateway_loc <= ETHZ_GATEWAY;
										netmask_loc <= ETHZ_NETMASK;					        
										mac_loc <= MAC_LIST(conv_integer(bid));
										ip_loc <= IP_LIST(conv_integer(bid));
									end if; -- conv_integer
								end if; -- bid=1111 & cid=11
							end if; --FAD_at_ETHZ = 0
						end if; --FAD_in_cam = 1
						
					-- Interrupt Mask
					when IM =>
					  state_sig <= X"04";
						par_addr <= W5300_IMR;
						par_data <= X"00FF"; -- S0-S7 Interrupts
						state_init <= WRITE_REG;
						next_state <= MT;
						
					-- Memory Type
					when MT =>
					  par_addr <=	W5300_MTYPER;
					  par_data <= X"7FFF"; -- 8K RX, 120K TX-Buffer
					  state_init <= WRITE_REG;
					  next_state <= STX;
					  
					-- Socket TX Memory Size
					when STX =>
					  par_data <= X"0F0F"; -- 15K TX

					 	par_addr <= W5300_TMS01R;
					 	state_init <=WRITE_REG;
					 	next_state <= STX1;
          when STX1 =>
            par_addr <= W5300_TMS23R;
            state_init <=WRITE_REG;
            next_state <= STX2;
          when STX2 =>
            par_addr <= W5300_TMS45R;
            state_init <=WRITE_REG;
            next_state <= STX3;
          when STX3 =>
            par_addr <= W5300_TMS67R;
            state_init <=WRITE_REG;
            next_state <= SRX;
			 		
          -- Socket RX Memory Size
          when SRX =>
            par_data <= X"0101"; -- 1K RX
             
            par_addr <= W5300_RMS01R;
            state_init <=WRITE_REG;
            next_state <= SRX1;
          when SRX1 =>
            par_addr <= W5300_RMS23R;
            state_init <=WRITE_REG;
            next_state <= SRX2;
          when SRX2 =>
            par_addr <= W5300_RMS45R;
            state_init <=WRITE_REG;
            next_state <= SRX3;
          when SRX3 =>
            par_addr <= W5300_RMS67R;
            state_init <=WRITE_REG;
            next_state <= MAC;
	  
					-- MAC
					when MAC =>
						par_addr <= W5300_SHAR;
						par_data <= mac_loc(0);
						state_init <= WRITE_REG;
						next_state <= MAC1;
					when MAC1 =>
						par_addr <= W5300_SHAR + 2;
						par_data <= mac_loc(1);
						state_init <= WRITE_REG;
						next_state <= MAC2;
					when MAC2 =>
						par_addr <= W5300_SHAR + 4;
						par_data <= mac_loc(2);
						state_init <= WRITE_REG;
						next_state <= GW;
						
					-- Gateway
					when GW =>
						par_addr <= W5300_GAR;
						par_data (15 downto 8) <= conv_std_logic_vector(gateway_loc(0),8);
						par_data (7 downto 0) <= conv_std_logic_vector(gateway_loc(1),8);
						state_init <= WRITE_REG;
						next_state <= GW1;
					when GW1 =>
						par_addr <= W5300_GAR + 2;
						par_data (15 downto 8) <= conv_std_logic_vector(gateway_loc(2),8);
						par_data (7 downto 0) <= conv_std_logic_vector(gateway_loc(3),8);
						state_init <= WRITE_REG;
						next_state <= SNM;
						
					-- Subnet Mask
					when SNM =>
						par_addr <= W5300_SUBR;
						par_data (15 downto 8) <= conv_std_logic_vector(netmask_loc(0),8);
						par_data (7 downto 0) <= conv_std_logic_vector(netmask_loc(1),8);
						state_init <= WRITE_REG;
						next_state <= SNM1;
					when SNM1 =>
						par_addr <= W5300_SUBR + 2;
						par_data (15 downto 8) <= conv_std_logic_vector(netmask_loc(2),8);
						par_data (7 downto 0) <= conv_std_logic_vector(netmask_loc(3),8);
						state_init <= WRITE_REG;
						next_state <= IP;
					-- Own IP-Address
					when IP =>
						par_addr <= W5300_SIPR;
						par_data (15 downto 8) <= conv_std_logic_vector(ip_loc(0),8);
						par_data (7 downto 0) <= conv_std_logic_vector(ip_loc(1),8);
						state_init <= WRITE_REG;
						next_state <= IP1;
					when IP1 =>
						par_addr <= W5300_SIPR + 2;
						par_data (15 downto 8) <= conv_std_logic_vector(ip_loc(2),8);
						par_data (7 downto 0) <= conv_std_logic_vector(ip_loc(3),8);
						state_init <= WRITE_REG;
						--next_state <= SI;
						next_state <= TIMEOUT;
					when TIMEOUT =>
						par_addr <=	W5300_RTR;
						--par_data <= X"07D0"; -- 0x07D0 = 200ms
						par_data <= X"07D0"; -- unit is 100us, so 0x000A = 10 stands for 1ms.
						state_init <= WRITE_REG;
						next_state <= SI;
--          when RETRY =>
--            par_addr <=	W5300_RCR;
--            par_data <= X"0008";
--            state_init <= WRITE_REG;
--            next_state <= SI;
--					  

					-- Socket Init
					when SI =>
					  state_sig <= X"05";
						par_addr <= W5300_S0_MR + socket_cnt * W5300_S_INC;
						par_data <= X"0101"; -- ALIGN, TCP
						state_init <= WRITE_REG;
						next_state <= SI1;
					-- Sx Interrupt Mask
					when SI1 =>
						par_addr <= W5300_S0_IMR + socket_cnt * W5300_S_INC;
						par_data <= X"000A"; -- TIMEOUT, DISCON
						state_init <= WRITE_REG;
						next_state <= SI1b;
					when SI1b =>
						par_addr <= W5300_S0_KPALVTR + socket_cnt * W5300_S_INC;
						par_data <= X"0200"; 			-- set KPALVTR to 0 so the manual SEND_KEEP is enabled.
						state_init <= WRITE_REG;
						next_state <= SI2;						
					when SI2 =>
						par_addr <= W5300_S0_PORTR + socket_cnt * W5300_S_INC;
						par_data <= conv_std_logic_vector(FIRST_PORT + unsigned (socket_cnt), 16);
						state_init <= WRITE_REG;
						next_state <= SI3;
					when SI3 =>
						par_addr <= W5300_S0_CR + socket_cnt * W5300_S_INC;
						par_data <= X"0001"; -- OPEN
						state_init <= WRITE_REG;
						next_state <= SI4;
					when SI4 =>
						par_addr <= W5300_S0_SSR + socket_cnt * W5300_S_INC;
						state_init <= READ_REG;
						next_state <= SI5;
					when SI5 =>
						if (data_read (7 downto 0) = X"13") then -- is open?
							state_init <= SI6;
						else
							state_init <= SI4;
						end if;
					when SI6 =>
						par_addr <= W5300_S0_CR + socket_cnt * W5300_S_INC;
						par_data <= X"0002"; -- LISTEN
						state_init <= WRITE_REG;
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
						  socket_cnt <= "000";
						  next_state <= ESTABLISH; -- All Sockets open
						else
						  next_state <= SI; -- Next Socket
						end if;
				  -- End Socket Init
						
					when ESTABLISH =>
						state_sig <= X"07";
						socks_waiting <= '1';
						socks_connected <= '0';
						par_addr <= W5300_S0_SSR + socket_cnt * W5300_S_INC;
						state_init <= READ_REG;
						next_state <= EST1;
					when EST1 =>
						state_sig <= X"08";
						case data_read (7 downto 0) is
							when X"17" => -- established
								if (socket_cnt = 7) then
								  socket_cnt <= "000";
								  busy <= '0';
								  state_init <= MAIN;
								  --state_init <= SEND_1ST_KEEP;
								--state_init <= INITIAL_CONNECTION_MESSAGE_TO_FIFO;
								  --state_init <= CONFIG_MEMORY_MANAGER;
								else
								  socket_cnt <= socket_cnt + 1;
								  state_init <= ESTABLISH;
								end if;
							when others =>
								state_init <= ESTABLISH;
						end case;
						
					-- the following two states were intended to get the W5300 to send 
					--a first keep alive package after the connection was established.
					-- The reason was, that the W5300 is not sending any keep alive messages before not a single byte was send to the peer.
					-- --
					-- But this did not work.
					-- the next idea is, to send a single message of 60 bytes, all 0x00 to the peer.
					-- this is done for each of the 7 seockets.
					-- 
					--
					when SEND_1ST_KEEP =>
						next_state <= SEND_1ST_KEEP; -- Next Socket
						par_addr <= W5300_S0_CR + socket_cnt * W5300_S_INC;
						par_data <= X"0022"; -- SEND_KEEP
						state_init <= WRITE_REG;
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
						  socket_cnt <= "000";
						  next_state <= SET_Sn_KPALVTR; 
						end if;
					
					when SET_Sn_KPALVTR => -- send automatic KEEP ALIVE every 10s.
						next_state <= SET_Sn_KPALVTR;
						par_addr <= W5300_S0_KPALVTR + socket_cnt * W5300_S_INC;
						par_data <= X"0200"; 			-- send automatic KEEP ALIVE every 10s.
						state_init <= WRITE_REG;
						
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
						  socket_cnt <= "000";
						  next_state <= MAIN; 
						end if;
						
					when INITIAL_CONNECTION_MESSAGE_TO_FIFO =>
						-- the state is only reached, when just resetted the W5300 so the TX_FIFO is empty.
						-- additionally not SEND action can take place right now.
						-- so I can start writing 0x00 into the fifo
						par_addr <= W5300_S0_TX_FIFOR + socket_cnt * W5300_S_INC;
						par_data <= conv_std_logic_vector(initial_message_counter, 13)&socket_cnt; 
						ram_access <= '0';
						state_init <= WRITE_REG;
						next_state <= INITIAL_CONNECTION_MESSAGE_TO_FIFO;
						initial_message_counter <= initial_message_counter + 1;
						if (initial_message_counter = initial_message_counter_max) then
							initial_message_counter <= 0;
							socket_cnt <= socket_cnt + 1;
							if (socket_cnt = 7) then
							  socket_cnt <= "000";
							  next_state <= INITIAL_CONNECTION_MESSAGE_SET_SIZE_HIGH_BYTE; 
							end if;
						end if;
					
					when INITIAL_CONNECTION_MESSAGE_SET_SIZE_HIGH_BYTE =>
						ram_access <= '0';
						par_addr <= W5300_S0_TX_WRSR + socket_cnt * W5300_S_INC;
						par_data <= (others => '0');
						state_init <= WRITE_REG;
						next_state <= INITIAL_CONNECTION_MESSAGE_SET_SIZE_HIGH_BYTE;
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
							socket_cnt <= "000";
							next_state <= INITIAL_CONNECTION_MESSAGE_SET_SIZE_LOW_BYTE;
						end if;
					
					when INITIAL_CONNECTION_MESSAGE_SET_SIZE_LOW_BYTE =>
						ram_access <= '0';
						par_addr <= W5300_S0_TX_WRSR + (socket_cnt * W5300_S_INC) + X"2";
						par_data <= conv_std_logic_vector(initial_message_counter_max+40, 16);
						state_init <= WRITE_REG;
						next_state <= INITIAL_CONNECTION_MESSAGE_SET_SIZE_LOW_BYTE;		
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
							socket_cnt <= "000";
							next_state <= INITIAL_CONNECTION_MESSAGE_SEND;
						end if;
								
					
					when INITIAL_CONNECTION_MESSAGE_SEND =>
						par_addr <= W5300_S0_CR + socket_cnt * W5300_S_INC;
						par_data <= X"0020"; -- Send
						state_init <= WRITE_REG;
						next_state <= INITIAL_CONNECTION_MESSAGE_SEND;
						socket_cnt <= socket_cnt + 1;
						if (socket_cnt = 7) then
							socket_cnt <= "000";
							next_state <= MAIN;
						end if;
						
					when CONFIG =>   -- Triggers are disabled here!
					  state_sig <= X"06";
						trigger_enable_storage_sig <= trigger_enable_sig; 				-- store last value of this signal.
						trigger_enable_sig <= '0'; 										--no triggers must occur, while configurating.
						state_init <= WAIT_100NS;	 									
						
					when WAIT_100NS =>
						state_sig <= X"15";
						wait_100ns_sig <= wait_100ns_sig + 1;
						if (wait_100ns_sig = "110010") then
							wait_100ns_sig <= "000000";
							state_init <= WAIT_UNTIL_DG_IDLE;	
						end if;
						
					when WAIT_UNTIL_DG_IDLE =>
						state_sig <= X"16";
						if (data_generator_idle_sr = "111") then
							state_init <= CONFIG_MEMORY_MANAGER;
						end if;
					
					
					when CONFIG_MEMORY_MANAGER =>
					  state_sig <= X"18";
						memory_manager_config_start_o <= '1';
						if (memory_manager_config_valid_i_sr = "00") then
							state_init <= WAIT_FOR_CONFIG_MEMORY_MANAGER;
						end if;
					
					when WAIT_FOR_CONFIG_MEMORY_MANAGER =>
					  state_sig <= X"19";
						memory_manager_config_start_o <= '0';
						if (memory_manager_config_valid_i_sr(1) = '1') then
							--state_init <= CONFIG_DATA_GENERATOR;
							trigger_enable_sig <= trigger_enable_storage_sig;
							state_init <= state_after_config;
							--state_init <= MAIN;
						end if;
						
						
						when CONFIG_DAC_ONLY =>
						  state_sig <= X"1C";
							spi_interface_config_start_o <= '1';
							if (spi_interface_config_valid_i_sr ="00") then
								state_init <= WAIT_FOR_CONFIG_DAC_ONLY;
							end if;
						
						when WAIT_FOR_CONFIG_DAC_ONLY =>
						  state_sig <= X"1D";
							spi_interface_config_start_o <= '0';
							if (spi_interface_config_valid_i_sr ="11") then
								state_init <= MAIN;
							end if;
							
----------------------------------------------------------------------------------
-- MAIN "loop" -------------------------------------------------------------------
----------------------------------------------------------------------------------

					when GENERATE_1ST_TRIGGER_AFTER_ESTABLISHED =>
						zaehler <= conv_std_logic_vector(0, zaehler'length);
						single_trigger_sig <= '1';
						state_init <= WAIT_AFTER_1ST_TRIGGER_AFTER_ESTABLISHED;
					
					when WAIT_AFTER_1ST_TRIGGER_AFTER_ESTABLISHED =>
						zaehler <= zaehler + 1;
						if (zaehler = conv_std_logic_vector(3, zaehler'length) ) then
							single_trigger_sig <= '0';
							state_init <= MAIN;
						end if;
						state_init <= WAIT_AFTER_1ST_TRIGGER_AFTER_ESTABLISHED;


          
					when MAIN =>
					state_sig <= X"20";
					socks_waiting <= '0';
					socks_connected <= '1';
					ps_do_phase_shift <= '0';
					ps_reset <= '0';
					data_valid_ack <= '0';
					
						
						if (update_of_rois = '1') then
							update_of_rois <= '0';
							
							state_after_config <= MAIN;  --this needs to be set to main, in order to return here, after configuration
							state_init <= CONFIG;
--							if (trigger_enable_sig = '1') then 
--								trigger_enable_storage_sig <= trigger_enable_sig;
--							end if;
--							trigger_enable_sig <= '0';
--
--							update_of_rois <= '0';
--							state_init <= CONFIG_MEMORY_MANAGER;
--							if (data_ram_empty_sr(1) = '1') then
--								update_of_rois <= '0';
--								state_init <= CONFIG_MEMORY_MANAGER;
--							else 
--								state_init <= MAIN2;
--							end if;
							
						elsif (update_of_lessimportant = '1') then				
							update_of_lessimportant <= '0';
							state_init <= CONFIG_DAC_ONLY;
						else -- update_of_rois='0' and update_of_lessimportant='0' 
							state_init <= MAIN1;
							--data_valid_int <= data_valid;
						end if;
			
					when MAIN1 =>
					  state_sig <= X"21";
						if (chk_recv_cntr = 1000) then
							chk_recv_cntr <= 0;
							state_read_data <= RD_1;
							state_init <= READ_DATA;
							busy <= '1';
						else
							chk_recv_cntr <= chk_recv_cntr + 1;  
							state_init <= MAIN2;
						end if;
					when MAIN2 =>
					  state_sig <= X"22";
						busy <= '0';
						--if (data_valid = '1') then
						if (data_valid_sr(1) = '1') then
							--data_valid_int <= '0';
							busy <= '1';
							local_write_length <= write_length;
							local_ram_start_addr <= ram_start_addr;
							local_ram_addr <= (others => '0');
							local_write_header_flag <= write_header_flag;
							local_write_end_flag <= write_end_flag;
							local_fifo_channels <= fifo_channels;
							--                data_valid_ack <= '1';
							--                next_state <= MAIN;
							--                state_init <= WRITE_DATA;
							state_init <= MAIN3;
						else
							state_init <= MAIN1; 
						end if;
					when MAIN3 =>
						debug_data_ram_empty <= local_write_end_flag;
					  state_sig <= X"23";
						-- needed for the check: if there is enough space in W5300 FIFO
						write_length_bytes <= (local_write_length (15 downto 0) & '0')   ; -- shift left (*2) 
						
						next_state <= MAIN;
						state_init <= WRITE_DATA;
						
						
----------------------------------------------------------------------------------
-- END OF MAIN         -----------------------------------------------------------
----------------------------------------------------------------------------------

					-- read data from socket 0  
					when READ_DATA =>
						case state_read_data is
						when RD_1 =>
						  state_sig <= X"30";
							par_addr <= W5300_S0_RX_RSR;
							state_init <= READ_REG;
							next_state <= READ_DATA;
							state_read_data <= RD_2;
						when RD_2 =>
						  state_sig <= X"31";
							socket_rx_received (16) <= data_read(0);
							par_addr <= W5300_S0_RX_RSR + X"2";
							state_init <= READ_REG;
							next_state <= READ_DATA;
							state_read_data <= RD_3;
						when RD_3 =>
						  state_sig <= X"32";
							socket_rx_received (15 downto 0) <= data_read;
							state_read_data <= RD_4;
						when RD_4 =>
						  state_sig <= X"33";
							if (socket_rx_received (16 downto 0) > ('0' & X"000")) then
								rx_packets_cnt <= socket_rx_received (16 downto 1); -- socket_rx_received / 2
								state_read_data <= RD_5;
							else
								busy <= '0';
								state_init <= MAIN;
							end if;
						when RD_5 =>
						  state_sig <= X"34";
							s_trigger <='0';
							single_trigger_sig <= '0';
							ps_do_phase_shift <= '0';
							reset_trigger_id <= '0';
							
							if (rx_packets_cnt > 0) then
								rx_packets_cnt <= rx_packets_cnt - '1';
								par_addr <= W5300_S0_RX_FIFOR;
								state_init <= READ_REG;
								next_state <= READ_DATA;
								state_read_data <= RD_6;
							else
								state_read_data <= RD_END;
							end if;
							
						when RD_6 =>
						  state_sig <= X"35";
							-- The next 16bit word is assumed to contain a 'command' so it is 
							-- beeing parsed in this state
							case data_read (15 downto 8) is
							when CMD_START =>
								
								state_read_data <= RD_5;
							when CMD_STOP => 
								
								state_read_data <= RD_5;
							when CMD_MODE_ALL_SOCKETS =>  -- all data will be send via socket 1..7 
								socket_send_mode <= '1';
								state_read_data <= RD_5;
							when CMD_MODE_COMMAND => -- all data will be send via socket 0
								socket_send_mode <= '0';
								state_read_data <= RD_5;   
							when CMD_TRIGGER =>
								zaehler <= conv_std_logic_vector(0, zaehler'length);
								s_trigger <= '1';
								single_trigger_sig <= '1';
								state_read_data <= RD_5;
								--state_read_data <= WAIT_AFTER_SINGLE_TRIGGER;
							when CMD_DWRITE_RUN =>
								dwrite_enable <= '1';
								state_read_data <= RD_5;
							when CMD_DWRITE_STOP =>
								dwrite_enable <= '0';
								state_read_data <= RD_5;
							when CMD_SCLK_ON =>
								sclk_enable <= '1';
								state_read_data <= RD_5;
							when CMD_SCLK_OFF =>
								sclk_enable <= '0';
								state_read_data <= RD_5;
								
								
							when CMD_MANUAL_BUSY_ON =>
								busy_manual <= '1';
								state_read_data <= RD_5;
							when CMD_MANUAL_BUSY_OFF =>
								busy_manual <= '0';
								state_read_data <= RD_5;
					
							when CMD_DENABLE =>
								denable <= '1';
								state_read_data <= RD_5;
							when CMD_DDISABLE =>
								denable <= '0';
								state_read_data <= RD_5;
								
							when CMD_BUSY_ON =>
								busy_enable <= '1';
								state_read_data <= RD_5;
							when CMD_BUSY_OFF =>
								busy_enable <= '0';
								state_read_data <= RD_5;
								
							when CMD_STATUS =>
								state_read_data <= STATUS_OUT_START;

								
							when CMD_TRIGGER_C =>
								c_trigger_enable <= '1';
								state_read_data <= RD_5;
							when CMD_TRIGGER_S =>
							  c_trigger_enable <= '0';
							  state_read_data <= RD_5;

							-- phase shift commands here:
							when CMD_PS_DO =>
							  ps_do_phase_shift <= '1';
							  state_read_data <= RD_5;
							when CMD_PS_DIRINC =>
							  ps_direction <= '1';
							  state_read_data <= RD_5;
							when CMD_PS_RESET =>
							  ps_reset <= '1';
							  state_read_data <= RD_5;
							when CMD_SRCLK_ON =>
							  srclk_enable <= '1';
							  state_read_data <= RD_5;
							when CMD_SRCLK_OFF =>
							  srclk_enable <= '0';
							  state_read_data <= RD_5;
							when CMD_TRIGGERS_ON =>
							  trigger_enable_sig <= '1';
							  state_read_data <= RD_5;
							when CMD_TRIGGERS_OFF =>
							  trigger_enable_sig <= '0';
							  state_read_data <= RD_5;
							when CMD_PS_DIRDEC =>
							  ps_direction <= '0';
							  state_read_data <= RD_5;
							  
							when CMD_RESET_TRIGGER_ID =>
								reset_trigger_id <= '1';
								state_read_data <= WAIT_FOR_TRIGGER_ID_RESET_1;
								
							when CMD_WRITE =>
								if ( (conv_integer(data_read (7 downto 0)) >= 0) and (conv_integer(data_read (7 downto 0)) <= config_addr_max-1) ) then
									config_addr <= conv_integer(data_read (7 downto 0));
									state_read_data <= READ_COMMAND_DATA_SECTION;
								else
									config_addr <= config_addr_max;
									state_read_data <= READ_COMMAND_DATA_SECTION;
								end if;
								
							when CMD_EXECUTE =>
								state_read_data <= EXECUTE;
								
							when others =>
								state_read_data <= RD_5;
							end case;
                -- read data
				
						when WAIT_FOR_TRIGGER_ID_RESET_1 =>
						  state_sig <= X"36";
							state_read_data <= WAIT_FOR_TRIGGER_ID_RESET_2;
						when WAIT_FOR_TRIGGER_ID_RESET_2 =>
						  state_sig <= X"37";
							state_read_data <= RD_5;
							
						when WAIT_AFTER_SINGLE_TRIGGER =>
							zaehler <= zaehler + 1;
							if (zaehler = conv_std_logic_vector(3, zaehler'length) ) then
								single_trigger_sig <= '0';
								state_read_data <= RD_5;
							end if;
							state_read_data <= WAIT_AFTER_SINGLE_TRIGGER;
							
			-- these states are beeing processed, if the 'command' was a 'write command'
			--	so it is assumed, that some data in config RAM changed, and we need full (re)config
			when READ_COMMAND_DATA_SECTION =>
			  state_sig <= X"38";
				if (rx_packets_cnt > 0) then
					rx_packets_cnt <= rx_packets_cnt - '1';
					par_addr <= W5300_S0_RX_FIFOR;
					state_init <= READ_REG;
					next_state <= READ_DATA;
					state_read_data <= PUT_COMMAND_DATA_SECTION;
				else
					state_read_data <= RD_END;
				end if;
			
			when PUT_COMMAND_DATA_SECTION =>
			  state_sig <= X"39";
				config_setting(config_addr) <= data_read;
				
--				if (config_addr < 36) then
--					update_of_rois <= '1';
--				else 
--					if (config_addr < 45 ) then
--						update_of_lessimportant <= '1';
--					end if;
--				end if;
				
				state_read_data <= RD_5;
				
			when EXECUTE =>
				update_of_rois <= '1';
				update_of_lessimportant <= '1';
				runnumber <= config_setting(45) & config_setting(46);
				
				state_read_data <= RD_5;

			when RD_END =>
			  state_sig <= X"3A";
				par_addr <= W5300_S0_CR;
                par_data <= X"0040"; -- RECV
                state_init <= WRITE_REG;
				next_state <= MAIN;
				
				
			when STATUS_OUT_START =>
				number_of_words_written_to_fifo <= (others => '0');
				state_read_data <= STATUS_OUT_CHECK_IF_FIFO_FREE_01;
			when STATUS_OUT_CHECK_IF_FIFO_FREE_01 =>
				par_addr <= W5300_S0_TX_FSR;
				state_init <= READ_REG;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_CHECK_IF_FIFO_FREE_02;
			when STATUS_OUT_CHECK_IF_FIFO_FREE_02 =>
				socket_tx_free (16) <= data_read(0);
				par_addr <= W5300_S0_TX_FSR + X"2";
				state_init <= READ_REG;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_CHECK_IF_FIFO_FREE_03;
			when STATUS_OUT_CHECK_IF_FIFO_FREE_03 =>
				socket_tx_free (15 downto 0) <= data_read;
				state_read_data <= STATUS_OUT_CHECK_IF_FIFO_FREE_04;
			when STATUS_OUT_CHECK_IF_FIFO_FREE_04 =>
				socket_tx_free_out <= socket_tx_free;
				if (socket_tx_free (16 downto 0) < W5300_TX_FIFO_SIZE_8B) then
					state_read_data <= STATUS_OUT_CHECK_IF_FIFO_FREE_01;
				else
					state_read_data <= STATUS_OUT_WRITE_HEAD;
				end if;
			when STATUS_OUT_WRITE_HEAD =>
				par_addr <= W5300_S0_TX_FIFOR;
				par_data <= X"fb02";
				state_init <= WRITE_REG;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_WRITE_CMD_COUNTER;	
			when STATUS_OUT_WRITE_CMD_COUNTER =>
				par_addr <= W5300_S0_TX_FIFOR;
				par_data <= cmd_counter;
				state_init <= WRITE_REG;
				cmd_counter <= cmd_counter +1;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_SET_MESSAGE_LENGTH_01;
			when STATUS_OUT_SET_MESSAGE_LENGTH_01 =>
				par_addr <= W5300_S0_TX_WRSR;
				par_data <= (others => '0');
				state_init <= WRITE_REG;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_SET_MESSAGE_LENGTH_02;
			when STATUS_OUT_SET_MESSAGE_LENGTH_02 =>
				par_addr <= W5300_S0_TX_WRSR + X"2";
				par_data <= conv_std_logic_vector(4,16);
				state_init <= WRITE_REG;
				next_state <= READ_DATA;
				state_read_data <= STATUS_OUT_ISSUE_SEND_COMMAND;
			when STATUS_OUT_ISSUE_SEND_COMMAND =>
				par_addr <= W5300_S0_CR;
				par_data <= X"0020"; -- Send
				state_init <= WRITE_REG;
				next_state <= READ_DATA;
				state_read_data <= RD_5;

			
				
      when others =>
        state_sig <= X"3F";
      
            end case; -- state_data_read
                
    

					when WRITE_DATA =>
						case state_write is
							
						  when WR_START =>
						    state_sig <= X"40";
						    if (local_write_header_flag = '1') then
								ram_addr <= local_ram_start_addr + 6; -- Address of HIGH word of Event ID
								state_write <= WR_GET_EVT_ID_WAIT1;
							else
					      		state_write <= WR_CHECK_FOR_FIFO_SPACE_01;
						    end if;
						      
						  when WR_GET_EVT_ID_WAIT1 =>
						    state_sig <= X"41";
						    state_write <= WR_GET_EVT_ID1;
						  when WR_GET_EVT_ID1 =>
						    state_sig <= X"42";
						  		event_number(31 downto 16) <= ram_data;
						  		ram_addr <= local_ram_start_addr + 9; -- Address of LOW word of Event ID
						  		state_write <= WR_GET_EVT_ID_WAIT2;
					  		when WR_GET_EVT_ID_WAIT2 =>
								state_write <= WR_GET_EVT_ID2;
						  when WR_GET_EVT_ID2 =>
						    state_sig <= X"43";
						  		event_number(15 downto 0) <= ram_data;
								mod7_start <= '1';
						  		if (mod7_valid = '0') then
							  		state_write <= WR_MOD7_STARTED;
						  		else
						  			state_write <= WR_GET_EVT_ID2;
					  			end if;
					  			
				  			when WR_MOD7_STARTED =>
				  			  state_sig <= X"44";
				  				if (mod7_started = '1') then
				  					mod7_start <= '0';
				  					state_write <= WR_WAIT_FOR_MOD7;
			  					end if;

			  				when WR_WAIT_FOR_MOD7 =>
			  				  state_sig <= X"45";
							  next_state_tmp <= next_state;
			  					if (mod7_valid = '1') then
			  						if (socket_send_mode = '1') then -- send via all sockets
												local_socket_nr <= mod7_result + 1;
									else -- only send via socket 0\
												local_socket_nr <= "000";
									end if;
									
									data_cnt <= 0;
									state_write <= WR_CHECK_FOR_FIFO_SPACE_01;  
								else 
				  					state_write <= WR_WAIT_FOR_MOD7;
			  					end if;
								
							-- Check FIFO Size
							when WR_CHECK_FOR_FIFO_SPACE_01 =>
							  state_sig <= X"46";
								par_addr <= W5300_S0_TX_FSR + local_socket_nr * W5300_S_INC;
								state_init <= READ_REG;
								next_state <= WRITE_DATA;
								state_write <= WR_CHECK_FOR_FIFO_SPACE_02;
							when WR_CHECK_FOR_FIFO_SPACE_02 =>
							  state_sig <= X"47";
								socket_tx_free (16) <= data_read(0);
								par_addr <= W5300_S0_TX_FSR + (local_socket_nr * W5300_S_INC) + X"2";
								state_init <= READ_REG;
								next_state <= WRITE_DATA;
								state_write <= WR_CHECK_FOR_FIFO_SPACE_03;
							when WR_CHECK_FOR_FIFO_SPACE_03 =>
							  state_sig <= X"48";
								socket_tx_free (15 downto 0) <= data_read;
								state_write <= WR_CHECK_FOR_FIFO_SPACE_04;
							when WR_CHECK_FOR_FIFO_SPACE_04 =>
							  state_sig <= X"49";
								socket_tx_free_out <= socket_tx_free;
--								if (socket_tx_free (16 downto 0) < write_length_bytes) then
								if (socket_tx_free (16 downto 0) < W5300_TX_FIFO_SIZE_8B) then
								
									state_write <= WR_CHECK_FOR_FIFO_SPACE_01;
								else
									if (local_write_header_flag = '1') then
										state_write <= WR_FIFO;
									else
										state_write <= WR_ADC;
									end if; 
								end if;
							
							-- Fill FIFO

							-- Write Header
							when WR_FIFO =>
							  state_sig <= X"4A";
								ram_addr <= local_ram_start_addr + local_ram_addr;
								state_write <= WR_FIFO1;
							when WR_FIFO1 =>
							  state_sig <= X"4B";
 								data_cnt <= data_cnt + 1;
								if (data_cnt < PACKAGE_HEADER_LENGTH) then --???
								  local_ram_addr <= local_ram_addr + 1;
--								  if (data_cnt = 2 or data_cnt = 5 or data_cnt = 8 ) then -- skip empty words
--								    local_ram_addr <= local_ram_addr + 2;
--								  end if;
--								  if (data_cnt = 9) then -- skip empty words
--								    local_ram_addr <= local_ram_addr + 4;
--								  end if;  
									par_addr <= W5300_S0_TX_FIFOR + local_socket_nr * W5300_S_INC;
									ram_access <= '1';
									state_init <= WRITE_REG;
									number_of_words_written_to_fifo <= number_of_words_written_to_fifo + 1;
									next_state <= WRITE_DATA;
									state_write <= WR_FIFO;
								else
									state_write <= WR_ADC;
								end if;
							-- End Write Header
							
							-- Write ADC-Data
							---- Start...
							when WR_ADC =>
							  state_sig <= X"4C";
								adc_data_addr <= local_ram_start_addr + local_ram_addr;
								drs_cnt <= 0;
								channel_cnt <= 1;
								data_cnt <= 0;
								roi_max <= (others => '0');
								data_end <= POSITION_OF_ROI_IN_CHANNEL_HEADER;
								state_write <= WR_ADC1;

							---- Write Channel
							when WR_ADC1 =>
							  state_sig <= X"4D";
								-- read ROI and set end of Channel-Data
								if (data_cnt = POSITION_OF_ROI_IN_CHANNEL_HEADER) then
									data_end <= conv_integer (ram_data) + CHANNEL_HEADER_SIZE;
									if (ram_data > roi_max) then
										roi_max <= ram_data (10 downto 0);
									end if;
								end if;
								ram_addr <= adc_data_addr + drs_cnt + (data_cnt * 4);
								state_write <= WR_ADC2;
							when WR_ADC2 =>
							
								if (data_cnt < data_end) then
									par_addr <= W5300_S0_TX_FIFOR + local_socket_nr * W5300_S_INC;
									ram_access <= '1';
									state_init <= WRITE_REG;
									number_of_words_written_to_fifo <= number_of_words_written_to_fifo + 1;
									next_state <= WRITE_DATA;
									data_cnt <= data_cnt + 1;
									state_write <= WR_ADC1;
								else
									-- Next DRS
									if (drs_cnt < 3) then
										drs_cnt <= drs_cnt + 1;
										data_cnt <= 0;
										data_end <= POSITION_OF_ROI_IN_CHANNEL_HEADER;
										state_write <= WR_ADC1;
									else
										-- Next Channel
										if (channel_cnt < local_fifo_channels) then
											channel_cnt <= channel_cnt + 1;
											roi_max <= (others => '0');
											drs_cnt <= 0;
											data_cnt <= 0;
											data_end <= POSITION_OF_ROI_IN_CHANNEL_HEADER;
											adc_data_addr <= adc_data_addr + ((conv_integer(roi_max) + CHANNEL_HEADER_SIZE) * 4);
											state_write <= WR_ADC1;
										else
											-- Ready
											if (local_write_end_flag = '1') then
												state_write <= WR_ENDFLAG;
											else
												state_write <= WR_05a;
											end if;
										end if;
									end if;    
								end if;
								-- End Write ADC-Data

              -- Write End Package Flag
              when WR_ENDFLAG =>
                state_sig <= X"4F";
                ram_addr <= adc_data_addr + ((conv_integer(roi_max) + CHANNEL_HEADER_SIZE) * 4);
                state_write <= WR_ENDFLAG1;
              when WR_ENDFLAG1 =>
                par_addr <= W5300_S0_TX_FIFOR + local_socket_nr * W5300_S_INC;
                ram_access <= '1';
                state_init <= WRITE_REG;
				number_of_words_written_to_fifo <= number_of_words_written_to_fifo + 1;
                next_state <= WRITE_DATA;
                state_write <= WR_ENDFLAG2;
              when WR_ENDFLAG2 =>
                ram_addr <= adc_data_addr + ((conv_integer(roi_max) + CHANNEL_HEADER_SIZE) * 4) + 1;
                state_write <= WR_ENDFLAG3;
              when WR_ENDFLAG3 =>
                state_init <= WRITE_REG;
                next_state <= WRITE_DATA;
				number_of_words_written_to_fifo <= number_of_words_written_to_fifo + 1;
                state_write <= WR_05a;
              
              -- End Write End Package Flag
              
              -- Wait????
              when WR_05a =>
				state_sig <= X"4E";
                if (wait_cntr < 10) then -- 3000 works???
                  wait_cntr <= wait_cntr + 1;
                else
                  wait_cntr <= 0;
                  state_write <= WR_05b;
                end if;
              when WR_05b =>
                state_write <= WR_05_PREPARE_LENGTH_INFO;

              --Send FIFO	
							when WR_05_PREPARE_LENGTH_INFO =>
								--number_of_words_written_to_fifo <= number_of_words_written_to_fifo - 1;
								state_init <= WRITE_DATA;
								state_write <= WR_05_POSTPREPARE_LENGTH_INFO;
								
							
							when WR_05_POSTPREPARE_LENGTH_INFO =>
								number_of_bytes_written_to_fifo <= number_of_words_written_to_fifo(15 downto 0) & '0';    
								state_init <= WRITE_DATA;
								state_write <= WR_05;							
							
							when WR_05 =>
							  ram_access <= '0';
								state_sig <= X"50";
								par_addr <= W5300_S0_TX_WRSR + local_socket_nr * W5300_S_INC;
								par_data <= (0 => write_length_bytes (16), others => '0');
								--par_data <= (0 => number_of_bytes_written_to_fifo(16), others => '0');
								state_init <= WRITE_REG;
								state_write <= WR_06;
							when WR_06 =>
								par_addr <= W5300_S0_TX_WRSR + (local_socket_nr * W5300_S_INC) + X"2";
								par_data <= write_length_bytes (15 downto 0);
								--par_data <= number_of_bytes_written_to_fifo(15 downto 0);
								
								-- prepare this value here, so I have it in the next state.
								wait_before_send_counter_goal <= FADid*50*MICROSEC_TO_WAIT_BEFORE_SEND;
								
								state_init <= WRITE_REG;
								state_write <= WR_07;
																
							when WR_07 =>
								number_of_words_written_to_fifo <= (others => '0');
								state_sig <= X"51";
								par_addr <= W5300_S0_CR + local_socket_nr * W5300_S_INC;
								par_data <= X"0020"; -- Send
								state_init <= WRITE_REG;
								state_write <= WR_ACK;
							when WR_ACK =>							-- handshake with MM
								data_valid_ack <= '1';
								state_write <= WR_WAIT_FOR_ACK;
							when WR_WAIT_FOR_ACK =>					-- handshake ACK with MM
								state_write <= WR_WAIT_FOR_ACK;
								if (data_valid_sr(1) = '0') then
									data_valid_ack <= '0';
									
									if (local_write_end_flag = '1') then
										-- the last package was just written, and we can go back to the main state
										state_init <= MAIN;
										state_write <= WR_START;
									else
										-- we just wrote, a part of an event and should not go back to main, in order to avoid 
										-- intermediate reconfiguration of the MM, in case an 'EXECUTE' command just arrived.
										-- but neither we should not go back to MAIN2, because data_valid is still low, as part of the MM-handshake.
										--	so we have to wait, until data_valid goes back high.
										--	if it never goes high, this can be a deadlock again, but it MUST go high, 
										-- because we did not send away the entire event, yet.
										state_init <= WRITE_DATA;
										state_write <= WAIT_FOR_DATA_VALID_HIGH_AGAIN;
									end if;
									
									
								end if;
							
							when WAIT_FOR_DATA_VALID_HIGH_AGAIN =>
								if (data_valid_sr(1) = '1') then
									state_init <= MAIN2;
									state_write <= WR_START;
								end if;
							
							when others =>
								state_sig <= X"4F";
						end case;
						-- End WRITE_DATA
						
					when READ_REG =>
					  --state_sig <= X"50";
						case count is
							when "000" =>
								cs <= '0';
								rd <= '0';
								wr <= '1';
								data <= (others => 'Z'); -- !!!!!!!!!!
								count <= "001";
								addr <= par_addr;
							when "001" =>
								count <= "010";
							when "010" =>
								count <= "100";
							when "100" =>
								data_read <= data;
								count <= "110";
							when "110" =>
								count <= "111";
							when "111" =>
								cs <= '1';
								rd <= '1';
								count <= "000";
								state_init <= next_state;
							when others =>
								null;
						end case;
					
					when WRITE_REG =>
					  --state_sig <= X"60";
						case count is
							when "000" =>
								cs <= '0';
								wr <= '0';
								rd <= '1';
								addr <= par_addr; 
								if (ram_access = '1') then
									data <= ram_data;
								else
									data <= par_data;
								end if;
								count <= "100";
							when "100" =>
								count <= "101";
							when "101" =>
								count <= "110";
							when "110" =>
								cs <= '1';
								wr <= '1';
								state_init <= next_state;
								count <= "000";
							when others =>
							  state_sig <= X"E0";
								null;
						end case;
					
					when others =>
					  state_sig <= X"F0";
						null;
				end case;
			end if; -- int_flag = '0'

		end if; -- rising_edge (clk)

	end process w5300_proc;
	
	
	
	--signal wait_for_sockets_closed_counter_overflow : std_logic := '0';
	--signal wait_for_sockets_closed_counter_enable : std_logic := '0';
	--signal wfscc_1 : integer range 0 to 50000 := 0;
	--signal wfscc_2 : integer range 0 to 2000 := 0;
	counter_before_reset_proc : process (clk)
	begin
		if rising_edge (clk) then
			if (wait_for_sockets_closed_counter_enable = '1') then
				wait_for_sockets_closed_counter_overflow <= '0';
				if (wfscc_1 = 50000) then
					if (wfscc_2 = 20000) then
						wait_for_sockets_closed_counter_overflow <= '1';
						wfscc_2 <= 20000;
						wfscc_1 <= 50000;
					else 
						wfscc_2 <= wfscc_2 + 1;
						wfscc_1 <= 0;
					end if;
				else
					wfscc_1 <= wfscc_1 + 1;
				end if;
			else
				wfscc_1 <= 0;
				wfscc_2 <= 0;
				wait_for_sockets_closed_counter_overflow <= '0';
			end if;
		
		end if;
	end process counter_before_reset_proc;
	
	single_trigger_gen : process (clk)
	begin
		if (rising_edge(clk)) then
		
			trigger_input_sr <= trigger_input_sr(0) & single_trigger_sig;
			
			if (trigger_input_sr = "01" and single_triggers_to_produce < 1023) then
				single_triggers_to_produce <= single_triggers_to_produce + 1;
			end if;
			
			
			case single_trigger_gen_state is 
				when IDLE =>
					if ( (data_generator_idle_sr(1) = '1') and (data_ram_not_full_sr(1) = '1') and (single_triggers_to_produce > 0) ) then
						--s_trigger <= '1';
						--	if just at the same moment a trigger is produces a new one comes in, the number of triggers to be produced is not decreased.
						if (trigger_input_sr = "01") then
							single_triggers_to_produce <= single_triggers_to_produce;
						else 
							single_triggers_to_produce <= single_triggers_to_produce - 1;
						end if;
						single_trigger_gen_state <= TRIGGERED;
					end if;

				when TRIGGERED =>
					if ( (data_generator_idle_sr(1) = '0') or (data_ram_not_full_sr(1) = '0' ) ) then
						--s_trigger <= '0';
						single_trigger_gen_state <= IDLE;
					end if;
			
				when others =>
					--s_trigger <= '0';
					
			end case; --single_trigger_gen_state
		
		end if; -- rising edge clk
		
	end process single_trigger_gen;
	
	

end Behavioral;