]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
update
authorYour Name <you@example.com>
Mon, 22 Aug 2016 11:41:28 +0000 (13:41 +0200)
committerYour Name <you@example.com>
Mon, 22 Aug 2016 11:41:28 +0000 (13:41 +0200)
gbe_trb/protocols/trb_net16_gbe_response_constructor_KillPing.vhd [new file with mode: 0644]

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 (file)
index 0000000..e37a477
--- /dev/null
@@ -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;
+
+