From: Your Name Date: Mon, 22 Aug 2016 11:41:28 +0000 (+0200) Subject: update X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=6fb8aeb40b8128cf49bf462bfcf8d47d93838c19;p=trbnet.git update --- diff --git a/gbe_trb/protocols/trb_net16_gbe_response_constructor_KillPing.vhd b/gbe_trb/protocols/trb_net16_gbe_response_constructor_KillPing.vhd new file mode 100644 index 0000000..e37a477 --- /dev/null +++ b/gbe_trb/protocols/trb_net16_gbe_response_constructor_KillPing.vhd @@ -0,0 +1,344 @@ +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; + +use work.trb_net_gbe_components.all; +use work.trb_net_gbe_protocols.all; + +--******** +-- Response Constructor which responds to Ping messages +-- + +entity trb_net16_gbe_response_constructor_KillPing is +generic ( STAT_ADDRESS_BASE : integer := 0 +); +port ( + CLK : in std_logic; -- system clock + RESET : in std_logic; + +-- INTERFACE + MY_MAC_IN : in std_logic_vector(47 downto 0); + MY_IP_IN : in std_logic_vector(31 downto 0); + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); + + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_IDENT_OUT : out std_logic_vector(15 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); + + STAT_DATA_OUT : out std_logic_vector(31 downto 0); + STAT_ADDR_OUT : out std_logic_vector(7 downto 0); + STAT_DATA_RDY_OUT : out std_logic; + STAT_DATA_ACK_IN : in std_logic; + + RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0); + SENT_FRAMES_OUT : out std_logic_vector(15 downto 0); +-- END OF INTERFACE + + MY_TRBNET_ADDRESS_IN : in std_logic_vector(15 downto 0); + ISSUE_REBOOT_OUT : out std_logic; + +-- debug + DEBUG_OUT : out std_logic_vector(63 downto 0) +); +end trb_net16_gbe_response_constructor_KillPing; + + +architecture trb_net16_gbe_response_constructor_KillPing of trb_net16_gbe_response_constructor_KillPing is + +attribute syn_encoding : string; + +type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_LOAD, LOAD_FRAME, CLEANUP); +signal dissect_current_state, dissect_next_state : dissect_states; +attribute syn_encoding of dissect_current_state: signal is "onehot"; + +type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, CLEANUP); +signal stats_current_state, stats_next_state : stats_states; +attribute syn_encoding of stats_current_state : signal is "onehot"; + +signal sent_frames : std_logic_vector(15 downto 0); + +signal saved_data : std_logic_vector(447 downto 0); +signal saved_headers : std_logic_vector(63 downto 0); + +signal data_ctr : integer range 1 to 1500; +signal data_length : integer range 1 to 1500; +signal tc_data : std_logic_vector(8 downto 0); + +signal checksum : std_logic_vector(15 downto 0); + +signal checksum_l, checksum_r : std_logic_vector(19 downto 0); +signal checksum_ll, checksum_rr : std_logic_vector(15 downto 0); +signal checksum_lll, checksum_rrr : std_logic_vector(15 downto 0); + +signal issue_reboot : std_logic; + +begin + +DISSECT_MACHINE_PROC : process(RESET, CLK) +begin + if RESET = '1' then + dissect_current_state <= IDLE; + elsif rising_edge(CLK) then + dissect_current_state <= dissect_next_state; + end if; +end process DISSECT_MACHINE_PROC; + +DISSECT_MACHINE : process(dissect_current_state, PS_WR_EN_IN, PS_SELECTED_IN, PS_ACTIVATE_IN, PS_DATA_IN, data_ctr, data_length) +begin + case dissect_current_state is + + when IDLE => + if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + dissect_next_state <= READ_FRAME; + else + dissect_next_state <= IDLE; + end if; + + when READ_FRAME => + if (PS_DATA_IN(8) = '1') then + dissect_next_state <= WAIT_FOR_LOAD; + else + dissect_next_state <= READ_FRAME; + end if; + + when WAIT_FOR_LOAD => + if (PS_SELECTED_IN = '1') then + dissect_next_state <= LOAD_FRAME; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD_FRAME => + if (data_ctr = data_length + 1) then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD_FRAME; + end if; + + when CLEANUP => + dissect_next_state <= IDLE; + + end case; +end process DISSECT_MACHINE; + +DATA_CTR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) or (dissect_current_state = WAIT_FOR_LOAD) then + data_ctr <= 2; + elsif (dissect_current_state = READ_FRAME and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then -- in case of saving data from incoming frame + data_ctr <= data_ctr + 1; + elsif (dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1') then -- in case of constructing response + data_ctr <= data_ctr + 1; + end if; + end if; +end process DATA_CTR_PROC; + +DATA_LENGTH_PROC: process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + data_length <= 1; + elsif (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') then + data_length <= data_ctr; + end if; + end if; +end process DATA_LENGTH_PROC; + +SAVE_VALUES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) then + saved_headers <= (others => '0'); + saved_data <= (others => '0'); + elsif (dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then + saved_headers(7 downto 0) <= PS_DATA_IN(7 downto 0); + elsif (dissect_current_state = READ_FRAME) then + if (data_ctr < 9) then -- headers + saved_headers(data_ctr * 8 - 1 downto (data_ctr - 1) * 8) <= PS_DATA_IN(7 downto 0); + elsif (data_ctr > 8) then -- data + saved_data((data_ctr - 8) * 8 - 1 downto (data_ctr - 8 - 1) * 8) <= PS_DATA_IN(7 downto 0); + end if; + elsif (dissect_current_state = LOAD_FRAME) then + saved_headers(7 downto 0) <= x"00"; + saved_headers(23 downto 16) <= checksum(7 downto 0); + saved_headers(31 downto 24) <= checksum(15 downto 8); + end if; + end if; +end process SAVE_VALUES_PROC; + +CS_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') or (dissect_current_state = IDLE) then + checksum_l(19 downto 0) <= (others => '0'); + checksum_r(19 downto 0) <= (others => '0'); + checksum_ll(15 downto 0) <= (others => '0'); + checksum_rr(15 downto 0) <= (others => '0'); + checksum_lll(15 downto 0) <= (others => '0'); + checksum_rrr(15 downto 0) <= (others => '0'); + elsif (dissect_current_state = READ_FRAME and data_ctr > 4) then + if (std_logic_vector(to_unsigned(data_ctr, 1)) = "0") then + checksum_l <= checksum_l + PS_DATA_IN(7 downto 0); + else + checksum_r <= checksum_r + PS_DATA_IN(7 downto 0); + end if; + checksum_ll <= checksum_ll; + checksum_lll <= checksum_lll; + checksum_rr <= checksum_rr; + checksum_rrr <= checksum_rrr; + elsif (dissect_current_state = WAIT_FOR_LOAD) then + checksum_ll <= x"0000" + checksum_l(7 downto 0) + checksum_r(19 downto 8); + checksum_rr <= x"0000" + checksum_r(7 downto 0) + checksum_l(19 downto 8); + checksum_l <= checksum_l; + checksum_lll <= checksum_lll; + checksum_r <= checksum_r; + checksum_rrr <= checksum_rrr; + elsif (dissect_current_state = LOAD_FRAME and data_ctr = 2) then + checksum_lll <= x"0000" + checksum_ll(7 downto 0) + checksum_rr(15 downto 8); + checksum_rrr <= x"0000" + checksum_rr(7 downto 0) + checksum_ll(15 downto 8); + checksum_l <= checksum_l; + checksum_ll <= checksum_ll; + checksum_r <= checksum_r; + checksum_rr <= checksum_rr; + else + checksum_l <= checksum_l; + checksum_ll <= checksum_ll; + checksum_lll <= checksum_lll; + checksum_r <= checksum_r; + checksum_rr <= checksum_rr; + checksum_rrr <= checksum_rrr; + end if; + end if; +end process CS_PROC; +checksum(7 downto 0) <= not (checksum_rrr(7 downto 0) + checksum_lll(15 downto 8)); +checksum(15 downto 8) <= not (checksum_lll(7 downto 0) + checksum_rrr(15 downto 8)); + +TC_DATA_PROC : process(CLK) +begin + if rising_edge(CLK) then + tc_data(8) <= '0'; + + if (dissect_current_state = LOAD_FRAME) then + if (data_ctr < 10) then -- headers + for i in 0 to 7 loop + tc_data(i) <= saved_headers((data_ctr - 2) * 8 + i); + end loop; + else -- data + for i in 0 to 7 loop + tc_data(i) <= saved_data((data_ctr - 8 - 2) * 8 + i); + end loop; + + -- mark the last byte + if (data_ctr = data_length + 1) then + tc_data(8) <= '1'; + end if; + end if; + else + tc_data(7 downto 0) <= (others => '0'); + end if; + + TC_DATA_OUT <= tc_data; + + end if; +end process TC_DATA_PROC; + +PS_RESPONSE_SYNC : process(CLK) +begin + if rising_edge(CLK) then + if (dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP) then + PS_RESPONSE_READY_OUT <= '1'; + else + PS_RESPONSE_READY_OUT <= '0'; + end if; + + if (dissect_current_state = IDLE) then + PS_BUSY_OUT <= '0'; + else + PS_BUSY_OUT <= '1'; + end if; + end if; +end process PS_RESPONSE_SYNC; + +TC_FRAME_SIZE_OUT <= std_logic_vector(to_unsigned(data_length, 16)); +TC_FRAME_TYPE_OUT <= x"0008"; +TC_DEST_UDP_OUT <= x"0000"; -- not used +TC_SRC_MAC_OUT <= MY_MAC_IN; +TC_SRC_IP_OUT <= MY_IP_IN; +TC_SRC_UDP_OUT <= x"0000"; -- not used +TC_IP_PROTOCOL_OUT <= X"01"; -- ICMP +TC_IDENT_OUT <= x"2" & sent_frames(11 downto 0); + +ADDR_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (dissect_current_state = READ_FRAME) then + TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN; + TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN; + end if; + end if; +end process ADDR_PROC; + + +process(CLK) +begin + if rising_edge(CLK) then + + issue_reboot <= '0'; + + if (dissect_current_state = READ_FRAME and data_ctr = 28) then + if (saved_data(17 * 8 - 1 downto 16 * 8) = MY_TRBNET_ADDRESS_IN(15 downto 8) and saved_data(18 * 8 - 1 downto 17 * 8) = MY_TRBNET_ADDRESS_IN(7 downto 0)) then + issue_reboot <= '1'; + end if; + end if; + + ISSUE_REBOOT_OUT <= issue_reboot; + + end if; +end process; + +-- statistics + +-- +-- needed for identification +SENT_FRAMES_PROC : process(CLK) +begin + if rising_edge(CLK) then + if (RESET = '1') then + sent_frames <= (others => '0'); + elsif (dissect_current_state = CLEANUP) then + sent_frames <= sent_frames + x"1"; + end if; + end if; +end process SENT_FRAMES_PROC; + + +end trb_net16_gbe_response_constructor_KillPing; + +