-- 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 := '1'; 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 = 1) 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 = 1) 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 = 1 ) 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 <= '1'; 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"3C3C"; -- 60K TX par_addr <= W5300_TMS01R; state_init <=WRITE_REG; next_state <= STX1; when STX1 => par_data <= X"0000"; --- nothing par_addr <= W5300_TMS23R; state_init <=WRITE_REG; next_state <= STX2; when STX2 => par_data <= X"0000"; --- nothing par_addr <= W5300_TMS45R; state_init <=WRITE_REG; next_state <= STX3; when STX3 => par_data <= X"0000"; --- nothing par_addr <= W5300_TMS67R; state_init <=WRITE_REG; next_state <= SRX; -- Socket RX Memory Size when SRX => par_data <= X"0404"; -- 4K RX par_addr <= W5300_RMS01R; state_init <=WRITE_REG; next_state <= SRX1; when SRX1 => par_data <= X"0000"; --- nothing par_addr <= W5300_RMS23R; state_init <=WRITE_REG; next_state <= SRX2; when SRX2 => par_data <= X"0000"; --- nothing par_addr <= W5300_RMS45R; state_init <=WRITE_REG; next_state <= SRX3; when SRX3 => par_data <= X"0000"; --- nothing 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 = 1) 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 = 1) 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 = 1) 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 = 1) 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 = 1) 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 = 1) 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 = 1) 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 = 1) 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_FIX_OFF_TRUE => busy_enable <= '1'; state_read_data <= RD_5; when CMD_BUSY_FIX_OFF_FALSE => 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 <= "001"; 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;