--- /dev/null
+library IEEE;\r
+use IEEE.std_logic_1164.ALL;\r
+use IEEE.numeric_std.ALL;\r
+use IEEE.std_logic_UNSIGNED.ALL;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+use work.trb_net_components.all;\r
+\r
+entity gbe_frame_constr is\r
+ port( \r
+ -- ports for user logic\r
+ RESET : in std_logic;\r
+ CLK : in std_logic; -- 125MHz clock\r
+ LINK_OK_IN : in std_logic; \r
+ -- frame stuff\r
+ WR_EN_IN : in std_logic;\r
+ DATA_IN : in std_logic_vector(7 downto 0);\r
+ START_OF_DATA_IN : in std_logic;\r
+ END_OF_DATA_IN : in std_logic;\r
+ IP_F_SIZE_IN : in std_logic_vector(15 downto 0);\r
+ UDP_P_SIZE_IN : in std_logic_vector(15 downto 0); -- needed for fragmentation\r
+ HEADERS_READY_OUT : out std_logic;\r
+ READY_OUT : out std_logic;\r
+ DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);\r
+ DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);\r
+ DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0);\r
+ SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);\r
+ SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);\r
+ SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0);\r
+ FRAME_TYPE_IN : in std_logic_vector(15 downto 0);\r
+ IHL_VERSION_IN : in std_logic_vector(7 downto 0);\r
+ TOS_IN : in std_logic_vector(7 downto 0);\r
+ IDENTIFICATION_IN : in std_logic_vector(15 downto 0);\r
+ FLAGS_OFFSET_IN : in std_logic_vector(15 downto 0);\r
+ TTL_IN : in std_logic_vector(7 downto 0);\r
+ PROTOCOL_IN : in std_logic_vector(7 downto 0);\r
+ FRAME_DELAY_IN : in std_logic_vector(31 downto 0);\r
+ -- port for "RX ringbuffer"\r
+ FT_TX_DATA_OUT : out std_logic_vector(8 downto 0);\r
+ FT_TX_WR_OUT : out std_logic;\r
+ FT_TX_FIFOFULL_IN : in std_logic;\r
+ -- monitoring\r
+ MONITOR_TX_BYTES_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_TX_FRAMES_OUT : out std_logic_vector(31 downto 0)\r
+ );\r
+end entity gbe_frame_constr;\r
+\r
+architecture gbe_frame_constr_arch of gbe_frame_constr is\r
+\r
+attribute syn_encoding : string;\r
+\r
+type constructStates is (IDLE, DEST_MAC_ADDR, SRC_MAC_ADDR, FRAME_TYPE_S, VERSION,\r
+ TOS_S, IP_LENGTH, IDENT, FLAGS, TTL_S, PROTO, HEADER_CS,\r
+ SRC_IP_ADDR, DEST_IP_ADDR, SRC_PORT, DEST_PORT, UDP_LENGTH,\r
+ UDP_CS, SAVE_DATA, CLEANUP, DELAY);\r
+signal constructCurrentState, constructNextState : constructStates;\r
+attribute syn_encoding of constructCurrentState: signal is "onehot";\r
+\r
+signal headers_int_counter : integer range 0 to 6;\r
+signal fpf_data : std_logic_vector(7 downto 0);\r
+signal fpf_wr_en : std_logic;\r
+signal fpf_rd_en : std_logic;\r
+signal fpf_rd_en_q : std_logic;\r
+signal fpf_q : std_logic_vector(8 downto 0);\r
+signal ip_size : std_logic_vector(15 downto 0);\r
+signal ip_checksum : std_logic_vector(31 downto 0);\r
+signal udp_size : std_logic_vector(15 downto 0);\r
+signal udp_checksum : std_logic_vector(15 downto 0);\r
+signal put_udp_headers : std_logic;\r
+signal ready : std_logic;\r
+signal headers_ready : std_logic;\r
+\r
+signal cur_max : integer range 0 to 10;\r
+\r
+signal ip_cs_temp_right : std_logic_vector(15 downto 0);\r
+\r
+signal delay_ctr : std_logic_vector(31 downto 0);\r
+signal frame_delay_reg : std_logic_vector(31 downto 0);\r
+signal fpf_data_q : std_logic_vector(7 downto 0);\r
+signal fpf_wr_en_q : std_logic;\r
+signal fpf_eod_q : std_logic;\r
+\r
+signal mon_sent_frames : unsigned(31 downto 0);\r
+signal mon_sent_bytes : unsigned(31 downto 0);\r
+\r
+begin\r
+\r
+-- No checksum test needed\r
+udp_checksum <= x"0000";\r
+\r
+-- frame constructor ready\r
+THE_READY_PROC: process( CLK )\r
+begin\r
+if( rising_edge(CLK) )then\r
+ if( constructCurrentState = IDLE ) then\r
+ ready <= '1';\r
+ else\r
+ ready <= '0';\r
+ end if;\r
+\r
+ if( constructCurrentState = SAVE_DATA ) then\r
+ headers_ready <= '1';\r
+ else\r
+ headers_ready <= '0';\r
+ end if;\r
+end if;\r
+end process;\r
+\r
+-- Calculate UDP and IP sizes\r
+THE_SIZE_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( (put_udp_headers = '1') and (DEST_UDP_PORT_IN /= x"0000") ) then\r
+ ip_size <= IP_F_SIZE_IN + x"14" + x"8";\r
+ udp_size <= UDP_P_SIZE_IN + x"8";\r
+ else\r
+ ip_size <= IP_F_SIZE_IN + x"14";\r
+ udp_size <= UDP_P_SIZE_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SIZE_PROC;\r
+\r
+THE_IP_CS_PROC : process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( constructCurrentState = IDLE ) then\r
+ ip_checksum <= x"00000000";\r
+ else\r
+ case constructCurrentState is\r
+ when DEST_MAC_ADDR =>\r
+ case headers_int_counter is\r
+ when 0 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(7 downto 0);\r
+ when 1 =>\r
+ ip_checksum <= ip_checksum + SRC_IP_ADDRESS_IN(15 downto 8);\r
+ when 2 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(23 downto 16);\r
+ when 3 =>\r
+ ip_checksum <= ip_checksum + SRC_IP_ADDRESS_IN(31 downto 24);\r
+ when 4 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(7 downto 0);\r
+ when 5 =>\r
+ ip_checksum <= ip_checksum + DEST_IP_ADDRESS_IN(15 downto 8);\r
+ when others => null;\r
+ end case;\r
+ when SRC_MAC_ADDR =>\r
+ case headers_int_counter is\r
+ when 0 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(23 downto 16);\r
+ when 1 =>\r
+ ip_checksum <= ip_checksum + DEST_IP_ADDRESS_IN(31 downto 24);\r
+ when 2 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IHL_VERSION_IN;\r
+ when 3 =>\r
+ ip_checksum <= ip_checksum + TOS_IN;\r
+ when 4 =>\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + ip_size(15 downto 8);\r
+ when 5 =>\r
+ ip_checksum <= ip_checksum + ip_size(7 downto 0);\r
+ when others => null;\r
+ end case;\r
+ when VERSION =>\r
+ if( headers_int_counter = 0 ) then\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IDENTIFICATION_IN(7 downto 0);\r
+ end if;\r
+ when TOS_S =>\r
+ if( headers_int_counter = 0 ) then\r
+ ip_checksum <= ip_checksum + IDENTIFICATION_IN(15 downto 8);\r
+ end if;\r
+ when IP_LENGTH =>\r
+ if( headers_int_counter = 0 ) then\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + FLAGS_OFFSET_IN(15 downto 8);\r
+ elsif headers_int_counter = 1 then\r
+ ip_checksum <= ip_checksum + FLAGS_OFFSET_IN(7 downto 0);\r
+ end if;\r
+ when IDENT =>\r
+ if headers_int_counter = 0 then\r
+ ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + TTL_IN;\r
+ elsif headers_int_counter = 1 then\r
+ ip_checksum <= ip_checksum + PROTOCOL_IN;\r
+ end if;\r
+ -- gk 29.03.10 corrected the bug with bad checksums when sum larger than 16b\r
+ when FLAGS =>\r
+ if ( headers_int_counter = 0 ) then\r
+ ip_cs_temp_right <= ip_checksum(31 downto 16);\r
+ elsif( headers_int_counter = 1 ) then\r
+ ip_checksum(31 downto 16) <= (others => '0');\r
+ end if;\r
+ when TTL_S =>\r
+ if( headers_int_counter = 0 ) then\r
+ ip_checksum <= ip_checksum + ip_cs_temp_right;\r
+ end if;\r
+ when PROTO =>\r
+ if( headers_int_counter = 0 ) then\r
+ ip_checksum(15 downto 0) <= ip_checksum(15 downto 0) + ip_checksum(31 downto 16);\r
+ end if;\r
+ when others => null;\r
+ end case;\r
+ end if;\r
+ end if;\r
+end process THE_IP_CS_PROC;\r
+\r
+\r
+THE_CONSTRUCT_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( RESET = '1' ) then\r
+ constructCurrentState <= IDLE;\r
+ else\r
+ constructCurrentState <= constructNextState;\r
+ end if;\r
+ end if;\r
+end process THE_CONSTRUCT_PROC;\r
+\r
+--find next state of construct machine\r
+constructMachine: process( constructCurrentState, delay_ctr, FRAME_DELAY_IN, START_OF_DATA_IN, \r
+ END_OF_DATA_IN, headers_int_counter, put_udp_headers, CUR_MAX, \r
+ FRAME_TYPE_IN, DEST_UDP_PORT_IN)\r
+begin\r
+ constructNextState <= constructCurrentState;\r
+ if( headers_int_counter = cur_max ) then --can be checked everytime - if not in use, counter and cur_max are 0\r
+ case constructCurrentState is\r
+ when IDLE =>\r
+ if( START_OF_DATA_IN = '1' ) then\r
+ constructNextState <= DEST_MAC_ADDR;\r
+ end if;\r
+ when DEST_MAC_ADDR =>\r
+ constructNextState <= SRC_MAC_ADDR;\r
+ when SRC_MAC_ADDR =>\r
+ constructNextState <= FRAME_TYPE_S;\r
+ when FRAME_TYPE_S =>\r
+ if( FRAME_TYPE_IN = x"0008" ) then \r
+ constructNextState <= VERSION;\r
+ else -- otherwise transmit data as pure ethernet frame\r
+ constructNextState <= SAVE_DATA;\r
+ end if;\r
+ when VERSION =>\r
+ constructNextState <= TOS_S;\r
+ when TOS_S =>\r
+ constructNextState <= IP_LENGTH;\r
+ when IP_LENGTH =>\r
+ constructNextState <= IDENT;\r
+ when IDENT =>\r
+ constructNextState <= FLAGS;\r
+ when FLAGS =>\r
+ constructNextState <= TTL_S;\r
+ when TTL_S =>\r
+ constructNextState <= PROTO;\r
+ when PROTO =>\r
+ constructNextState <= HEADER_CS;\r
+ when HEADER_CS =>\r
+ constructNextState <= SRC_IP_ADDR;\r
+ when SRC_IP_ADDR =>\r
+ constructNextState <= DEST_IP_ADDR;\r
+ when DEST_IP_ADDR =>\r
+ if( (put_udp_headers = '1') and (DEST_UDP_PORT_IN /= x"0000") ) then\r
+ constructNextState <= SRC_PORT;\r
+ else\r
+ constructNextState <= SAVE_DATA;\r
+ end if;\r
+ when SRC_PORT =>\r
+ constructNextState <= DEST_PORT;\r
+ when DEST_PORT =>\r
+ constructNextState <= UDP_LENGTH;\r
+ when UDP_LENGTH =>\r
+ constructNextState <= UDP_CS;\r
+ when UDP_CS =>\r
+ constructNextState <= SAVE_DATA;\r
+ when SAVE_DATA =>\r
+ if( END_OF_DATA_IN = '1' ) then\r
+ constructNextState <= CLEANUP;\r
+ end if;\r
+ when CLEANUP =>\r
+ constructNextState <= DELAY;\r
+ when DELAY =>\r
+ if (delay_ctr = FRAME_DELAY_IN) then\r
+ constructNextState <= IDLE;\r
+ else\r
+ constructNextState <= DELAY;\r
+ end if;\r
+ \r
+ when others =>\r
+ constructNextState <= IDLE;\r
+ end case;\r
+ end if;\r
+end process constructMachine;\r
+\r
+THE_DELAY_CTR_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( (constructCurrentState = IDLE) or (constructCurrentState = CLEANUP) ) then\r
+ delay_ctr <= (others => '0');\r
+ elsif( constructCurrentState = DELAY ) then\r
+ delay_ctr <= delay_ctr + x"1";\r
+ end if;\r
+\r
+ frame_delay_reg <= FRAME_DELAY_IN;\r
+ end if;\r
+end process THE_DELAY_CTR_PROC;\r
+\r
+THE_BSM_CONSTR_PROC: process( constructCurrentState )\r
+begin\r
+--find maximum time in each state & set state bits\r
+ case constructCurrentState is\r
+ when IDLE => cur_max <= 0;\r
+ when DEST_MAC_ADDR => cur_max <= 5;\r
+ when SRC_MAC_ADDR => cur_max <= 5;\r
+ when FRAME_TYPE_S => cur_max <= 1;\r
+ when VERSION => cur_max <= 0;\r
+ when TOS_S => cur_max <= 0;\r
+ when IP_LENGTH => cur_max <= 1;\r
+ when IDENT => cur_max <= 1;\r
+ when FLAGS => cur_max <= 1;\r
+ when TTL_S => cur_max <= 0;\r
+ when PROTO => cur_max <= 0;\r
+ when HEADER_CS => cur_max <= 1;\r
+ when SRC_IP_ADDR => cur_max <= 3;\r
+ when DEST_IP_ADDR => cur_max <= 3;\r
+ when SRC_PORT => cur_max <= 1;\r
+ when DEST_PORT => cur_max <= 1;\r
+ when UDP_LENGTH => cur_max <= 1;\r
+ when UDP_CS => cur_max <= 1;\r
+ when SAVE_DATA => cur_max <= 0;\r
+ when CLEANUP => cur_max <= 0;\r
+ when DELAY => cur_max <= 0;\r
+ when others => cur_max <= 0;\r
+end case;\r
+end process THE_BSM_CONSTR_PROC;\r
+\r
+THE_HEADERS_INT_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( constructCurrentState = IDLE ) then\r
+ headers_int_counter <= 0;\r
+ else\r
+ if( headers_int_counter = cur_max ) then\r
+ headers_int_counter <= 0;\r
+ else\r
+ headers_int_counter <= headers_int_counter + 1;\r
+ end if;\r
+ end if;\r
+end if;\r
+end process THE_HEADERS_INT_PROC;\r
+\r
+THE_PUT_UDP_HEADERS_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( FLAGS_OFFSET_IN(12 downto 0) = "0000000000000" ) then\r
+ put_udp_headers <= '1';\r
+ else\r
+ put_udp_headers <= '0';\r
+ end if;\r
+ end if;\r
+end process THE_PUT_UDP_HEADERS_PROC;\r
+\r
+THE_FPF_WREN_PROC : process( constructCurrentState, WR_EN_IN, LINK_OK_IN )\r
+begin\r
+ if ( LINK_OK_IN = '0' ) then\r
+ fpf_wr_en <= '0';\r
+ elsif( (constructCurrentState /= IDLE) and (constructCurrentState /= CLEANUP) and (constructCurrentState /= SAVE_DATA) and (constructCurrentState /= DELAY) ) then\r
+ fpf_wr_en <= '1';\r
+ elsif( (constructCurrentState = SAVE_DATA) and (WR_EN_IN = '1') ) then\r
+ fpf_wr_en <= '1';\r
+ else\r
+ fpf_wr_en <= '0';\r
+ end if;\r
+end process THE_FPF_WREN_PROC;\r
+\r
+THE_FPF_DATA_PROC: process( constructCurrentState, DEST_MAC_ADDRESS_IN, SRC_MAC_ADDRESS_IN, FRAME_TYPE_IN, IHL_VERSION_IN,\r
+ TOS_IN, ip_size, IDENTIFICATION_IN, FLAGS_OFFSET_IN, TTL_IN, PROTOCOL_IN,\r
+ ip_checksum, SRC_IP_ADDRESS_IN, DEST_IP_ADDRESS_IN,\r
+ SRC_UDP_PORT_IN, DEST_UDP_PORT_IN, udp_size, udp_checksum, headers_int_counter, DATA_IN )\r
+begin\r
+ case constructCurrentState is\r
+ when IDLE => fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when DEST_MAC_ADDR => fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when SRC_MAC_ADDR => fpf_data <= SRC_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when FRAME_TYPE_S => fpf_data <= FRAME_TYPE_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when VERSION => fpf_data <= IHL_VERSION_IN;\r
+ when TOS_S => fpf_data <= TOS_IN;\r
+ when IP_LENGTH => fpf_data <= ip_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+ when IDENT => fpf_data <= IDENTIFICATION_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when FLAGS => fpf_data <= FLAGS_OFFSET_IN(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+ when TTL_S => fpf_data <= TTL_IN;\r
+ when PROTO => fpf_data <= PROTOCOL_IN;\r
+ when HEADER_CS => fpf_data <= x"ff" - ip_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+ when SRC_IP_ADDR => fpf_data <= SRC_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when DEST_IP_ADDR => fpf_data <= DEST_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when SRC_PORT => fpf_data <= SRC_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when DEST_PORT => fpf_data <= DEST_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+ when UDP_LENGTH => fpf_data <= udp_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+ when UDP_CS => fpf_data <= udp_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+ when SAVE_DATA => fpf_data <= DATA_IN;\r
+ when CLEANUP => fpf_data <= x"ab";\r
+ when DELAY => fpf_data <= x"ac";\r
+ when others => fpf_data <= x"00";\r
+ end case;\r
+end process THE_FPF_DATA_PROC;\r
+\r
+THE_SYNC_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ fpf_data_q <= fpf_data;\r
+ fpf_wr_en_q <= fpf_wr_en;\r
+ fpf_eod_q <= END_OF_DATA_IN;\r
+ end if;\r
+end process THE_SYNC_PROC;\r
+\r
+-- count bytes sent\r
+THE_MON_SENT_BYTES_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( LINK_OK_IN = '0' ) then\r
+ mon_sent_bytes <= (others => '0');\r
+ elsif( fpf_rd_en = '1' ) then\r
+ mon_sent_bytes <= mon_sent_bytes + 1;\r
+ else\r
+ mon_sent_bytes <= mon_sent_bytes;\r
+ end if;\r
+ end if;\r
+end process THE_MON_SENT_BYTES_PROC;\r
+\r
+-- count frames sent\r
+THE_MON_SENT_FRAMES_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) )then\r
+ if ( LINK_OK_IN = '0' ) then\r
+ mon_sent_frames <= (others => '0');\r
+ elsif( (fpf_wr_en_q = '1') and (fpf_eod_q = '1') ) then -- TO BE TESTED\r
+ mon_sent_frames <= mon_sent_frames + 1;\r
+ else\r
+ mon_sent_frames <= mon_sent_frames;\r
+ end if;\r
+ end if;\r
+end process THE_MON_SENT_FRAMES_PROC;\r
+\r
+-- Outputs\r
+\r
+FT_TX_DATA_OUT(7 downto 0) <= fpf_data_q;\r
+FT_TX_DATA_OUT(8) <= fpf_eod_q;\r
+FT_TX_WR_OUT <= fpf_wr_en_q;\r
+\r
+READY_OUT <= ready;\r
+HEADERS_READY_OUT <= headers_ready;\r
+\r
+MONITOR_TX_BYTES_OUT <= std_logic_vector(mon_sent_bytes);\r
+MONITOR_TX_FRAMES_OUT <= std_logic_vector(mon_sent_frames);\r
+\r
+end gbe_frame_constr_arch;\r
--- /dev/null
+LIBRARY IEEE;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.numeric_std.ALL;\r
+USE IEEE.std_logic_UNSIGNED.ALL;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+use work.trb_net_components.all;\r
+use work.gbe_protocols.all;\r
+\r
+--********\r
+-- here all frame checking has to be done, if the frame fits into protocol standards\r
+-- if so FR_FRAME_VALID_OUT is asserted after having received all bytes of a frame\r
+-- otherwise, after receiving all bytes, FR_FRAME_VALID_OUT keeps low and the fifo is cleared\r
+-- also a part of addresses assignment has to be done here\r
+\r
+-- This entity receives an Ethernet frame, disassembles it and checks if the frame has to be processed.\r
+-- In case, decoded information from header is stored in FIFOs and next stage is informed about available\r
+-- data by FR_FRAME_VALID_OUT.\r
+\r
+entity gbe_frame_receiver is\r
+port (\r
+ CLK : in std_logic; -- system clock\r
+ RESET : in std_logic;\r
+ LINK_OK_IN : in std_logic;\r
+ ALLOW_RX_IN : in std_logic;\r
+ MY_MAC_IN : in std_logic_vector(47 downto 0);\r
+-- killer ping\r
+ MY_TRBNET_ADDRESS_IN : in std_logic_vector(15 downto 0) := (others => '0');\r
+ ISSUE_REBOOT_OUT : out std_logic;\r
+-- input signals from TS_MAC\r
+ MAC_RX_EOF_IN : in std_logic; -- End Of Frame\r
+ MAC_RX_ER_IN : in std_logic; -- only for statistics\r
+ MAC_RXD_IN : in std_logic_vector(7 downto 0); -- RX data\r
+ MAC_RX_EN_IN : in std_logic; -- write signal\r
+-- output signal to control logic\r
+ FR_Q_OUT : out std_logic_vector(8 downto 0);\r
+ FR_RD_EN_IN : in std_logic;\r
+ FR_FRAME_VALID_OUT : out std_logic;\r
+ FR_GET_FRAME_IN : in std_logic;\r
+ FR_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0);\r
+ FR_FRAME_PROTO_OUT : out std_logic_vector(15 downto 0);\r
+ FR_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0);\r
+ FR_ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0);\r
+ FR_ALLOWED_IP_IN : in std_logic_vector(31 downto 0);\r
+ FR_ALLOWED_UDP_IN : in std_logic_vector(31 downto 0);\r
+ FR_VLAN_ID_IN : in std_logic_vector(31 downto 0);\r
+--\r
+ FR_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);\r
+ FR_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);\r
+ FR_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);\r
+ FR_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);\r
+ FR_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0);\r
+ FR_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0);\r
+--\r
+ OOB_REGISTER_0_OUT : out std_logic_vector(31 downto 0);\r
+ OOB_REGISTER_1_OUT : out std_logic_vector(31 downto 0);\r
+ OOB_REGISTER_2_OUT : out std_logic_vector(31 downto 0);\r
+ OOB_REGISTER_3_OUT : out std_logic_vector(31 downto 0);\r
+--\r
+ MONITOR_RX_BYTES_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_RX_FRAMES_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_DROPPED_OUT : out std_logic_vector(31 downto 0);\r
+ DEBUG_OUT : out std_logic_vector(15 downto 0)\r
+);\r
+end gbe_frame_receiver;\r
+\r
+architecture gbe_frame_receiver_arch of gbe_frame_receiver is\r
+\r
+attribute syn_encoding : string;\r
+type filter_states is (IDLE, REMOVE_DEST, REMOVE_SRC, REMOVE_TYPE, SAVE_FRAME, DROP_FRAME,\r
+ REMOVE_VID, REMOVE_VTYPE, REMOVE_IP, REMOVE_UDP, DECIDE, CLEANUP);\r
+signal filter_current_state, filter_next_state : filter_states;\r
+attribute syn_encoding of filter_current_state : signal is "onehot";\r
+\r
+signal fifo_wr_en : std_logic;\r
+signal rx_bytes_ctr : std_logic_vector(15 downto 0);\r
+signal frame_valid_q : std_logic;\r
+signal delayed_frame_valid : std_logic;\r
+signal delayed_frame_valid_q : std_logic;\r
+\r
+signal rec_fifo_empty : std_logic;\r
+signal rec_fifo_full : std_logic;\r
+signal sizes_fifo_full : std_logic;\r
+signal sizes_fifo_empty : std_logic;\r
+\r
+signal remove_ctr : unsigned(7 downto 0);\r
+signal new_frame : std_logic;\r
+signal new_frame_lock : std_logic := '0';\r
+signal saved_frame_type : std_logic_vector(15 downto 0);\r
+signal saved_vid : std_logic_vector(15 downto 0) := (others => '0');\r
+signal saved_src_mac : std_logic_vector(47 downto 0);\r
+signal saved_dest_mac : std_logic_vector(47 downto 0);\r
+signal frame_type_valid : std_logic;\r
+signal saved_proto : std_logic_vector(7 downto 0);\r
+signal saved_src_ip : std_logic_vector(31 downto 0);\r
+signal saved_dest_ip : std_logic_vector(31 downto 0);\r
+signal saved_src_udp : std_logic_vector(15 downto 0);\r
+signal saved_dest_udp : std_logic_vector(15 downto 0);\r
+\r
+signal error_frames_ctr : unsigned(15 downto 0);\r
+signal dbg_rec_frames : unsigned(31 downto 0);\r
+signal dbg_drp_frames : unsigned(31 downto 0);\r
+signal mon_rec_bytes : unsigned(31 downto 0);\r
+\r
+signal state : std_logic_vector(3 downto 0);\r
+\r
+signal rx_data : std_logic_vector(8 downto 0);\r
+signal fr_q : std_logic_vector(8 downto 0);\r
+\r
+signal fr_src_ip : std_logic_vector(31 downto 0);\r
+signal fr_dest_ip : std_logic_vector(31 downto 0);\r
+signal fr_dest_udp : std_logic_vector(15 downto 0);\r
+signal fr_src_udp : std_logic_vector(15 downto 0);\r
+signal fr_frame_size : std_logic_vector(15 downto 0);\r
+signal fr_frame_proto : std_logic_vector(15 downto 0);\r
+signal fr_dest_mac : std_logic_vector(47 downto 0);\r
+signal fr_src_mac : std_logic_vector(47 downto 0);\r
+signal fr_ip_proto : std_logic_vector(7 downto 0);\r
+\r
+signal xxx0 : std_logic_vector(7 downto 0);\r
+signal xxx1 : std_logic_vector(7 downto 0);\r
+\r
+signal oob_register_0_int : std_logic_vector(31 downto 0);\r
+signal oob_register_1_int : std_logic_vector(31 downto 0);\r
+signal oob_register_2_int : std_logic_vector(31 downto 0);\r
+signal oob_register_3_int : std_logic_vector(31 downto 0);\r
+signal oob_write : std_logic;\r
+\r
+attribute syn_preserve : boolean;\r
+attribute syn_keep : boolean;\r
+attribute syn_keep of rec_fifo_empty, rec_fifo_full, state, sizes_fifo_empty, sizes_fifo_full : signal is true;\r
+attribute syn_preserve of rec_fifo_empty, rec_fifo_full, state, sizes_fifo_empty, sizes_fifo_full : signal is true;\r
+\r
+begin\r
+\r
+-- new_frame is asserted when first byte of the frame arrives\r
+THE_NEW_FRAME_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) )then\r
+ if ( (LINK_OK_IN = '0') or (MAC_RX_EOF_IN = '1') ) then\r
+ new_frame <= '0';\r
+ new_frame_lock <= '0';\r
+ elsif( (new_frame_lock = '0') and (MAC_RX_EN_IN = '1') ) then\r
+ new_frame <= '1';\r
+ new_frame_lock <= '1';\r
+ else\r
+ new_frame <= '0';\r
+ end if;\r
+ end if;\r
+end process THE_NEW_FRAME_PROC;\r
+\r
+THE_FILTER_MACHINE_PROC: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ filter_current_state <= IDLE;\r
+ elsif( rising_edge(CLK) ) then\r
+ filter_current_state <= filter_next_state;\r
+ end if;\r
+end process THE_FILTER_MACHINE_PROC;\r
+\r
+THE_FILTER_MACHINE : process( filter_current_state, saved_frame_type, LINK_OK_IN, saved_proto, MY_MAC_IN,\r
+ saved_dest_mac, remove_ctr, new_frame, MAC_RX_EOF_IN, frame_type_valid, ALLOW_RX_IN)\r
+begin\r
+ case filter_current_state is\r
+\r
+ when IDLE =>\r
+ state <= x"1";\r
+ if( (new_frame = '1') and (ALLOW_RX_IN = '1') and (LINK_OK_IN = '1') ) then\r
+ filter_next_state <= REMOVE_DEST;\r
+ else\r
+ filter_next_state <= IDLE;\r
+ end if;\r
+\r
+ -- frames arrive without preamble!\r
+ when REMOVE_DEST =>\r
+ state <= x"3";\r
+ if( remove_ctr = x"03" ) then -- counter starts with a delay that's why only 3\r
+ -- destination MAC address filtering here\r
+ if( (saved_dest_mac = MY_MAC_IN) or (saved_dest_mac = x"ffffffffffff") ) then -- must accept broadcasts for ARP\r
+ filter_next_state <= REMOVE_SRC;\r
+ else\r
+ filter_next_state <= DECIDE;\r
+ end if;\r
+ else\r
+ filter_next_state <= REMOVE_DEST;\r
+ end if;\r
+\r
+ when REMOVE_SRC =>\r
+ state <= x"4";\r
+ if( remove_ctr = x"09" ) then\r
+ filter_next_state <= REMOVE_TYPE;\r
+ else\r
+ filter_next_state <= REMOVE_SRC;\r
+ end if;\r
+\r
+ when REMOVE_TYPE =>\r
+ state <= x"5";\r
+ if( remove_ctr = x"0b" ) then\r
+ if( saved_frame_type = x"8100" ) then -- VLAN tagged frame\r
+ filter_next_state <= REMOVE_VID;\r
+ else -- no VLAN tag\r
+ if( saved_frame_type = x"0800" ) then -- in case of IP continue removing headers\r
+ filter_next_state <= REMOVE_IP;\r
+ else\r
+ filter_next_state <= DECIDE;\r
+ end if;\r
+ end if;\r
+ else\r
+ filter_next_state <= REMOVE_TYPE;\r
+ end if;\r
+\r
+ when REMOVE_VID =>\r
+ state <= x"a";\r
+ if( remove_ctr = x"0d" ) then\r
+ filter_next_state <= REMOVE_VTYPE;\r
+ else\r
+ filter_next_state <= REMOVE_VID;\r
+ end if;\r
+\r
+ when REMOVE_VTYPE =>\r
+ state <= x"b";\r
+ if( remove_ctr = x"0f" ) then\r
+ if( saved_frame_type = x"0800" ) then -- in case of IP continue removing headers\r
+ filter_next_state <= REMOVE_IP;\r
+ else\r
+ filter_next_state <= DECIDE;\r
+ end if;\r
+ else\r
+ filter_next_state <= REMOVE_VTYPE;\r
+ end if;\r
+\r
+ when REMOVE_IP =>\r
+ state <= x"c";\r
+ if( remove_ctr = x"11" ) then\r
+ if( saved_proto = x"11" ) then -- forced to recognize udp only, TODO check all protocols\r
+ filter_next_state <= REMOVE_UDP;\r
+ else\r
+ filter_next_state <= DECIDE; -- changed from drop\r
+ end if;\r
+ else\r
+ filter_next_state <= REMOVE_IP;\r
+ end if;\r
+\r
+ when REMOVE_UDP =>\r
+ state <= x"d";\r
+ if( remove_ctr = x"19" ) then\r
+ filter_next_state <= DECIDE;\r
+ else\r
+ filter_next_state <= REMOVE_UDP;\r
+ end if;\r
+\r
+ when DECIDE =>\r
+ state <= x"6";\r
+ if ( frame_type_valid = '1' ) then\r
+ filter_next_state <= SAVE_FRAME;\r
+ elsif( saved_frame_type = x"0806" ) then\r
+ -- ARP?\r
+ filter_next_state <= SAVE_FRAME;\r
+ else\r
+ filter_next_state <= DROP_FRAME;\r
+ end if;\r
+\r
+ when SAVE_FRAME =>\r
+ state <= x"7";\r
+ if( MAC_RX_EOF_IN = '1' ) then\r
+ filter_next_state <= CLEANUP;\r
+ else\r
+ filter_next_state <= SAVE_FRAME;\r
+ end if;\r
+\r
+ when DROP_FRAME =>\r
+ state <= x"8";\r
+ if( MAC_RX_EOF_IN = '1' ) then\r
+ filter_next_state <= CLEANUP;\r
+ else\r
+ filter_next_state <= DROP_FRAME;\r
+ end if;\r
+\r
+ when CLEANUP =>\r
+ state <= x"9";\r
+ filter_next_state <= IDLE;\r
+\r
+ when others => null;\r
+\r
+ end case;\r
+end process THE_FILTER_MACHINE;\r
+\r
+-- counts the bytes to be removed from the ethernet headers fields\r
+REMOVE_CTR_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( (filter_current_state = IDLE) or\r
+ ((filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0f")) or\r
+ ((filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0b") and (saved_frame_type /= x"8100")) ) then\r
+ remove_ctr <= (others => '1');\r
+ elsif( (MAC_RX_EN_IN = '1') and (filter_current_state /= IDLE) ) then\r
+ remove_ctr <= remove_ctr + 1;\r
+ end if;\r
+ end if;\r
+end process REMOVE_CTR_PROC;\r
+\r
+THE_SAVED_PROTO_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_proto <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"07") ) then\r
+ saved_proto <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_PROTO_PROC;\r
+\r
+-- saves the destination mac address of the incoming frame\r
+THE_SAVED_DEST_MAC_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_dest_mac <= (others => '0');\r
+ elsif( (filter_current_state = IDLE) and (MAC_RX_EN_IN = '1') and (new_frame = '0') ) then\r
+ saved_dest_mac(7 downto 0) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = IDLE) and (new_frame = '1') and (ALLOW_RX_IN = '1') ) then\r
+ saved_dest_mac(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"FF") ) then\r
+ saved_dest_mac(23 downto 16) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"00") ) then\r
+ saved_dest_mac(31 downto 24) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"01") ) then\r
+ saved_dest_mac(39 downto 32) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"02") ) then\r
+ saved_dest_mac(47 downto 40) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_DEST_MAC_PROC;\r
+\r
+-- saves the source mac address of the incoming frame\r
+THE_SAVED_SRC_MAC_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_src_mac <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"03") )then\r
+ saved_src_mac(7 downto 0) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"04") ) then\r
+ saved_src_mac(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"05") ) then\r
+ saved_src_mac(23 downto 16) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"06") ) then\r
+ saved_src_mac(31 downto 24) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"07") ) then\r
+ saved_src_mac(39 downto 32) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"08") ) then\r
+ saved_src_mac(47 downto 40) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_SRC_MAC_PROC;\r
+\r
+-- saves the frame type of the incoming frame for futher check\r
+THE_SAVED_FRAME_TYPE_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_frame_type <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"09") ) then\r
+ saved_frame_type(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0a") ) then\r
+ saved_frame_type(7 downto 0) <= MAC_RXD_IN;\r
+ -- two more cases for VLAN tagged frame\r
+ elsif( (filter_current_state = REMOVE_VID) and (remove_ctr = x"0d") ) then\r
+ saved_frame_type(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0e") ) then\r
+ saved_frame_type(7 downto 0) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_FRAME_TYPE_PROC;\r
+\r
+THE_SAVED_SRC_IP_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_src_ip <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0a") ) then\r
+ saved_src_ip(7 downto 0) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0b") ) then\r
+ saved_src_ip(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0c") ) then\r
+ saved_src_ip(23 downto 16) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0d") ) then\r
+ saved_src_ip(31 downto 24) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_SRC_IP_PROC;\r
+\r
+THE_SAVED_DEST_IP_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_dest_ip <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0e") ) then\r
+ saved_dest_ip(7 downto 0) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0f") ) then\r
+ saved_dest_ip(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"10") ) then\r
+ saved_dest_ip(23 downto 16) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"11") ) then\r
+ saved_dest_ip(31 downto 24) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_DEST_IP_PROC;\r
+\r
+THE_SAVED_SRC_UDP_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_src_udp <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"12") ) then\r
+ saved_src_udp(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"13") ) then\r
+ saved_src_udp(7 downto 0) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_SRC_UDP_PROC;\r
+\r
+THE_SAVED_DEST_UDP_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_dest_udp <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"14") ) then\r
+ saved_dest_udp(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"15") ) then\r
+ saved_dest_udp(7 downto 0) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_DEST_UDP_PROC;\r
+\r
+-- saves VLAN id when tagged frame spotted\r
+THE_SAVED_VID_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( filter_current_state = CLEANUP ) then\r
+ saved_vid <= (others => '0');\r
+ elsif( (filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0b") and (saved_frame_type = x"8100") ) then\r
+ saved_vid(15 downto 8) <= MAC_RXD_IN;\r
+ elsif( (filter_current_state = REMOVE_VID) and (remove_ctr = x"0c") ) then\r
+ saved_vid(7 downto 0) <= MAC_RXD_IN;\r
+ end if;\r
+ end if;\r
+end process THE_SAVED_VID_PROC;\r
+\r
+THE_TYPE_VALIDATOR: entity gbe_type_validator\r
+port map(\r
+ CLK => CLK,\r
+ RESET => RESET,\r
+ FRAME_TYPE_IN => saved_frame_type,\r
+ ALLOWED_TYPES_IN => FR_ALLOWED_TYPES_IN,\r
+ SAVED_VLAN_ID_IN => saved_vid,\r
+ VLAN_ID_IN => FR_VLAN_ID_IN,\r
+ -- IP level\r
+ IP_PROTOCOLS_IN => saved_proto,\r
+ ALLOWED_IP_PROTOCOLS_IN => FR_ALLOWED_IP_IN,\r
+ -- UDP level\r
+ UDP_PROTOCOL_IN => saved_dest_udp,\r
+ ALLOWED_UDP_PROTOCOLS_IN => FR_ALLOWED_UDP_IN,\r
+ --\r
+ VALID_OUT => frame_type_valid\r
+);\r
+\r
+THE_RECEIVE_FIFO: entity fifo_4096x9\r
+port map(\r
+ Data => rx_data,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ WrEn => fifo_wr_en,\r
+ RdEn => FR_RD_EN_IN,\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ Q => fr_q,\r
+ Empty => rec_fifo_empty,\r
+ Full => rec_fifo_full\r
+);\r
+\r
+-- killer ping\r
+THE_KILLER_PING_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( (filter_current_state = SAVE_FRAME) and \r
+ (saved_proto = x"01") and \r
+ (saved_frame_type = x"0800") and\r
+ (rx_bytes_ctr = x"001A") and \r
+ (rx_data(7 downto 0) = MY_TRBNET_ADDRESS_IN(7 downto 0)) and\r
+ (MAC_RXD_IN = MY_TRBNET_ADDRESS_IN(15 downto 8)) ) then\r
+ ISSUE_REBOOT_OUT <= '1';\r
+ else\r
+ ISSUE_REBOOT_OUT <= '0';\r
+ end if;\r
+ end if;\r
+end process THE_KILLER_PING_PROC;\r
+\r
+THE_SECRET_FRAME_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( (filter_current_state = DECIDE) and \r
+ (saved_proto = x"11") and \r
+ (saved_frame_type = x"0800") and\r
+ (saved_dest_udp = x"d903") and \r
+ (saved_src_udp = x"2b67") ) then\r
+ oob_write <= '1';\r
+ else\r
+ oob_write <= '0';\r
+ end if;\r
+ end if;\r
+end process THE_SECRET_FRAME_PROC;\r
+\r
+THE_REGISTERS_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( oob_write = '1' ) then\r
+ case saved_src_ip(1 downto 0) is\r
+ when b"00" => oob_register_0_int <= saved_dest_ip;\r
+ when b"01" => oob_register_1_int <= saved_dest_ip;\r
+ when b"10" => oob_register_2_int <= saved_dest_ip;\r
+ when others => oob_register_3_int <= saved_dest_ip;\r
+ end case;\r
+ end if;\r
+ end if;\r
+end process THE_REGISTERS_PROC;\r
+\r
+OOB_REGISTER_0_OUT <= oob_register_0_int;\r
+OOB_REGISTER_1_OUT <= oob_register_1_int;\r
+OOB_REGISTER_2_OUT <= oob_register_2_int;\r
+OOB_REGISTER_3_OUT <= oob_register_3_int;\r
+\r
+THE_RX_FIFO_SYNC: process( CLK )\r
+begin\r
+ if rising_edge(CLK) then\r
+\r
+ rx_data(8) <= MAC_RX_EOF_IN;\r
+ rx_data(7 downto 0) <= MAC_RXD_IN;\r
+\r
+ if( MAC_RX_EN_IN = '1' ) then\r
+ if ( filter_current_state = SAVE_FRAME ) then\r
+ fifo_wr_en <= '1';\r
+-- elsif( (filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0f") ) then\r
+-- fifo_wr_en <= '1';\r
+ elsif( (filter_current_state = DECIDE) and (frame_type_valid = '1') ) then\r
+ fifo_wr_en <= '1';\r
+ else\r
+ fifo_wr_en <= '0';\r
+ end if;\r
+ else\r
+ fifo_wr_en <= '0';\r
+ end if;\r
+\r
+ end if;\r
+end process THE_RX_FIFO_SYNC;\r
+\r
+THE_SIZES_FIFO: entity fifo_512x32\r
+port map(\r
+ Data(15 downto 0) => rx_bytes_ctr,\r
+ Data(31 downto 16) => saved_frame_type,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ WrEn => frame_valid_q,\r
+ RdEn => FR_GET_FRAME_IN,\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ Q(15 downto 0) => fr_frame_size,\r
+ Q(31 downto 16) => fr_frame_proto,\r
+ Empty => sizes_fifo_empty,\r
+ Full => sizes_fifo_full\r
+);\r
+\r
+THE_MACS_FIFO: entity fifo_512x72\r
+port map(\r
+ Data(47 downto 0) => saved_src_mac,\r
+ Data(63 downto 48) => saved_src_udp,\r
+ Data(71 downto 64) => (others => '0'),\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ WrEn => frame_valid_q,\r
+ RdEn => FR_GET_FRAME_IN,\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ Q(47 downto 0) => fr_src_mac,\r
+ Q(63 downto 48) => fr_src_udp,\r
+ Q(71 downto 64) => xxx0, --open,\r
+ Empty => open,\r
+ Full => open\r
+);\r
+\r
+THE_MACD_FIFO: entity fifo_512x72\r
+port map(\r
+ Data(47 downto 0) => saved_dest_mac,\r
+ Data(63 downto 48) => saved_dest_udp,\r
+ Data(71 downto 64) => (others => '0'),\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ WrEn => frame_valid_q,\r
+ RdEn => FR_GET_FRAME_IN,\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ Q(47 downto 0) => fr_dest_mac,\r
+ Q(63 downto 48) => fr_dest_udp,\r
+ Q(71 downto 64) => xxx1, --open,\r
+ Empty => open,\r
+ Full => open\r
+);\r
+\r
+THE_IP_FIFO: entity fifo_512x72\r
+port map(\r
+ Data(31 downto 0) => saved_src_ip,\r
+ Data(63 downto 32) => saved_dest_ip,\r
+ Data(71 downto 64) => saved_proto,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ WrEn => frame_valid_q,\r
+ RdEn => FR_GET_FRAME_IN,\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ Q(31 downto 0) => fr_src_ip,\r
+ Q(63 downto 32) => fr_dest_ip,\r
+ Q(71 downto 64) => fr_ip_proto,\r
+ Empty => open,\r
+ Full => open\r
+);\r
+\r
+THE_SYNC_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ FR_SRC_IP_ADDRESS_OUT <= fr_src_ip;\r
+ FR_DEST_IP_ADDRESS_OUT <= fr_dest_ip;\r
+ FR_IP_PROTOCOL_OUT <= fr_ip_proto;\r
+ FR_DEST_UDP_PORT_OUT <= fr_dest_udp;\r
+ FR_DEST_MAC_ADDRESS_OUT <= fr_dest_mac;\r
+ FR_SRC_MAC_ADDRESS_OUT <= fr_src_mac;\r
+ FR_SRC_UDP_PORT_OUT <= fr_src_udp;\r
+ FR_FRAME_PROTO_OUT <= fr_frame_proto;\r
+ FR_FRAME_SIZE_OUT <= fr_frame_size;\r
+ FR_Q_OUT <= fr_q;\r
+ --\r
+ delayed_frame_valid <= MAC_RX_EOF_IN;\r
+ delayed_frame_valid_q <= delayed_frame_valid;\r
+ end if;\r
+end process THE_SYNC_PROC;\r
+\r
+THE_FRAME_VALID_PROC: process( CLK )\r
+begin\r
+ if( rising_edge(CLK) ) then\r
+ if( (MAC_RX_EOF_IN = '1') and (ALLOW_RX_IN = '1') and (frame_type_valid = '1') ) then\r
+ frame_valid_q <= '1';\r
+ else\r
+ frame_valid_q <= '0';\r
+ end if;\r
+ end if;\r
+end process THE_FRAME_VALID_PROC;\r
+\r
+THE_RX_BYTES_CTR_PROC: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ rx_bytes_ctr <= x"0001";\r
+ elsif( rising_edge(CLK) ) then\r
+ if( delayed_frame_valid_q = '1' ) then\r
+ rx_bytes_ctr <= x"0001";\r
+ elsif( fifo_wr_en = '1' ) then\r
+ rx_bytes_ctr <= rx_bytes_ctr + 1;\r
+ end if;\r
+ end if;\r
+end process THE_RX_BYTES_CTR_PROC;\r
+\r
+THE_ERROR_FRAMES_CTR_PROC: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ error_frames_ctr <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ error_frames_ctr <= error_frames_ctr + 1;\r
+ end if;\r
+end process THE_ERROR_FRAMES_CTR_PROC;\r
+\r
+FR_FRAME_VALID_OUT <= frame_valid_q when rising_edge(CLK);\r
+\r
+THE_RECEIVED_FRAMES_CTR: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ dbg_rec_frames <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ dbg_rec_frames <= dbg_rec_frames + 1;\r
+ end if;\r
+end process THE_RECEIVED_FRAMES_CTR;\r
+\r
+THE_DROPPED_FRAMES_CTR: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ dbg_drp_frames <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( (filter_current_state = DECIDE) and (frame_type_valid = '0') ) then\r
+ dbg_drp_frames <= dbg_drp_frames + 1;\r
+ end if;\r
+ end if;\r
+end process THE_DROPPED_FRAMES_CTR;\r
+\r
+MONITOR_DROPPED_OUT <= std_logic_vector(dbg_drp_frames);\r
+MONITOR_RX_FRAMES_OUT <= std_logic_vector(dbg_rec_frames);\r
+MONITOR_RX_BYTES_OUT <= std_logic_vector(mon_rec_bytes);\r
+\r
+THE_MON_REC_BYTES_PROC: process( CLK, RESET )\r
+begin\r
+ if ( RESET = '1' ) then\r
+ mon_rec_bytes <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( fifo_wr_en = '1' ) then\r
+ mon_rec_bytes <= mon_rec_bytes + x"1";\r
+ end if;\r
+ end if;\r
+end process;\r
+\r
+end gbe_frame_receiver_arch;\r
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.std_logic_ARITH.all;
-use IEEE.std_logic_UNSIGNED.all;
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-
---use work.trb_net_gbe_components.all;
-use work.gbe_protocols.all;
+ use work.gbe_protocols.all;
entity gbe_logic_wrapper is
generic(
);
end entity gbe_logic_wrapper;
-architecture RTL of gbe_logic_wrapper is
+architecture gbe_logic_wrapper_arch of gbe_logic_wrapper is
+
signal fr_q : std_logic_vector(8 downto 0);
signal fr_rd_en : std_logic;
signal fr_frame_valid : std_logic;
signal dbg_select_gen : std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
--- signal global_reset : std_logic;
--- signal rst_n : std_logic;
--- signal ff : std_logic;
signal link_ok : std_logic;
signal dhcp_done : std_logic;
DHCP_DONE_OUT <= dhcp_done;
- MAIN_CONTROL: entity work.trb_net16_gbe_main_control
+ THE_GBE_MAIN_CONTROL: entity work.gbe_main_control
generic map(
INCLUDE_SLOWCTRL => INCLUDE_SLOWCTRL,
INCLUDE_DHCP => INCLUDE_DHCP,
MAKE_RESET_OUT <= make_reset;
- TRANSMIT_CONTROLLER: entity trb_net16_gbe_transmit_control2
+ THE_TRANSMIT_CONTROL: entity work.gbe_transmit_control
port map(
CLK => CLK_125_IN,
RESET => RESET, --global_reset,
MONITOR_TX_PACKETS_OUT => monitor_tx_packets
);
- FRAME_CONSTRUCTOR: entity trb_net16_gbe_frame_constr
+ THE_FRAME_CONSTR: entity work.gbe_frame_constr
port map(
RESET => RESET, --global_reset,
CLK => CLK_125_IN,
-- frame_pause <= x"0000" & CFG_THROTTLE_PAUSE_IN; -- TAKE CARE!!!
frame_pause <= x"0000" & x"0000"; -- TAKE CARE!!!
- RECEIVE_CONTROLLER: entity trb_net16_gbe_receive_control
+ THE_RECEIVE_CONTROL: entity work.gbe_receive_control
port map(
CLK => CLK_125_IN,
RESET => RESET, --global_reset,
DEBUG_OUT => rc_debug
);
- FRAME_RECEIVER: entity trb_net16_gbe_frame_receiver
+ THE_FRAME_RECEIVER: entity work.gbe_frame_receiver
port map(
CLK => CLK_125_IN,
RESET => RESET, --global_reset,
MONITOR_GEN_DBG_OUT <= dbg_select_gen;
-end architecture RTL;
+end architecture gbe_logic_wrapper_arch;
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.trb_net_std.all;
+ use work.gbe_protocols.all;
+
+entity gbe_main_control is
+ generic(
+ INCLUDE_SLOWCTRL : std_logic := '0';
+ INCLUDE_DHCP : std_logic := '0';
+ INCLUDE_ARP : std_logic := '0';
+ INCLUDE_PING : std_logic := '0';
+ INCLUDE_FWD : std_logic := '0';
+ --
+ SLOWCTRL_BUFFER_SIZE : integer range 1 to 4
+ );
+ port(
+ CLK : in std_logic; -- system clock
+ CLK_125 : in std_logic;
+ RESET : in std_logic;
+ --
+ MC_LINK_OK_OUT : out std_logic; -- remark: set to '1' internally
+ MC_DHCP_DONE_OUT : out std_logic; -- remark: set if link_current_state = ACTIVE
+ MY_IP_OUT : out std_logic_vector(31 downto 0);
+ MC_MY_MAC_IN : in std_logic_vector(47 downto 0);
+ MY_TRBNET_ADDRESS_IN : in std_logic_vector(15 downto 0);
+ ISSUE_REBOOT_OUT : out std_logic;
+ -- signals to/from receive controller
+ RC_FRAME_WAITING_IN : in std_logic;
+ RC_LOADING_DONE_OUT : out std_logic;
+ RC_DATA_IN : in std_logic_vector(8 downto 0);
+ RC_RD_EN_OUT : out std_logic;
+ RC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0);
+ RC_FRAME_PROTO_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ --
+ RC_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);
+ RC_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);
+ RC_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);
+ RC_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);
+ RC_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0);
+ RC_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0);
+ -- signals to/from transmit controller
+ TC_TRANSMIT_CTRL_OUT : out std_logic;
+ TC_DATA_OUT : out std_logic_vector(8 downto 0);
+ TC_RD_EN_IN : in std_logic;
+ TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0);
+ TC_FRAME_TYPE_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);
+ TC_FLAGS_OFFSET_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_TRANSMIT_DONE_IN : in std_logic;
+ -- signals to/from sgmii/gbe pcs_an_complete
+ PCS_AN_COMPLETE_IN : in std_logic;
+ MAC_READY_CONF_IN : in std_logic;
+ -- signals to/from hub
+ GSC_CLK_IN : in std_logic;
+ GSC_INIT_DATAREADY_OUT : out std_logic;
+ GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0);
+ GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0);
+ GSC_INIT_READ_IN : in std_logic;
+ GSC_REPLY_DATAREADY_IN : in std_logic;
+ GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0);
+ GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0);
+ GSC_REPLY_READ_OUT : out std_logic;
+ GSC_BUSY_IN : in std_logic;
+ CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0);
+ --
+ RESET_TRBNET_IN : in std_logic;
+ RESET_SCTRL_IN : in std_logic;
+ MAKE_RESET_OUT : out std_logic;
+ -- Forwarder
+ FWD_DST_MAC_IN : in std_logic_vector(47 downto 0);
+ FWD_DST_IP_IN : in std_logic_vector(31 downto 0);
+ FWD_DST_UDP_IN : in std_logic_vector(15 downto 0);
+ FWD_DATA_IN : in std_logic_vector(7 downto 0);
+ FWD_DATA_VALID_IN : in std_logic;
+ FWD_SOP_IN : in std_logic;
+ FWD_EOP_IN : in std_logic;
+ FWD_READY_OUT : out std_logic;
+ FWD_FULL_OUT : out std_logic;
+ --
+ MONITOR_SELECT_REC_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_SENT_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_GEN_DBG_OUT : out std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ --
+ SCTRL_HIST_OUT : out hist_array;
+ --
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+ );
+end gbe_main_control;
+
+architecture gbe_main_control_arch of gbe_main_control is
+
+ attribute syn_encoding : string;
+
+ type link_states is (INACTIVE, ACTIVE, ENABLE_MAC, TIMEOUT, FINALIZE, WAIT_FOR_BOOT, GET_ADDRESS);
+ signal link_current_state, link_next_state : link_states;
+ attribute syn_encoding of link_current_state : signal is "onehot";
+
+ signal link_ok : std_logic;
+ signal link_ok_timeout_ctr : unsigned(15 downto 0);
+
+ type flow_states is (IDLE, TRANSMIT_CTRL, WAIT_FOR_FC, CLEANUP);
+ signal flow_current_state, flow_next_state : flow_states;
+ attribute syn_encoding of flow_current_state : signal is "onehot";
+
+ signal state : std_logic_vector(3 downto 0);
+ signal link_state : std_logic_vector(3 downto 0);
+ signal redirect_state : std_logic_vector(3 downto 0);
+
+ signal ps_wr_en : std_logic;
+ signal ps_response_ready : std_logic;
+ signal ps_busy : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal rc_rd_en : std_logic;
+ signal proto_select : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal loaded_bytes_ctr : unsigned(15 downto 0);
+
+ signal dhcp_start : std_logic;
+ signal dhcp_done : std_logic;
+ signal wait_ctr : unsigned(31 downto 0);
+
+ signal rc_data_local : std_logic_vector(8 downto 0);
+
+ type redirect_states is (IDLE, CHECK_TYPE, DROP, CHECK_BUSY, LOAD, BUSY, WAIT_ONE, FINISH, CLEANUP);
+ signal redirect_current_state, redirect_next_state : redirect_states;
+ attribute syn_encoding of redirect_current_state : signal is "onehot";
+
+ signal disable_redirect : std_logic;
+ signal ps_wr_en_q : std_logic;
+ signal ps_wr_en_qq : std_logic;
+
+ signal tc_data : std_logic_vector(8 downto 0);
+
+ attribute syn_preserve : boolean;
+ attribute syn_keep : boolean;
+ attribute syn_keep of link_state, state, redirect_state, dhcp_done : signal is true;
+ attribute syn_preserve of link_state, state, redirect_state, dhcp_done : signal is true;
+
+ signal mc_busy : std_logic;
+ signal incl_dhcp : std_logic;
+ signal flow_state : std_logic_vector(3 downto 0);
+ signal selector_debug : std_logic_vector(63 downto 0);
+
+begin
+ THE_PROTOCOL_SELECTOR: entity work.gbe_protocol_selector
+ generic map(
+ INCLUDE_SLOWCTRL => INCLUDE_SLOWCTRL,
+ INCLUDE_DHCP => INCLUDE_DHCP,
+ INCLUDE_ARP => INCLUDE_ARP,
+ INCLUDE_PING => INCLUDE_PING,
+ INCLUDE_FWD => INCLUDE_FWD,
+ SLOWCTRL_BUFFER_SIZE => SLOWCTRL_BUFFER_SIZE
+ )
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ PS_DATA_IN => rc_data_local,
+ PS_WR_EN_IN => ps_wr_en_qq,
+ PS_PROTO_SELECT_IN => proto_select,
+ PS_BUSY_OUT => ps_busy,
+ PS_FRAME_SIZE_IN => RC_FRAME_SIZE_IN,
+ PS_RESPONSE_READY_OUT => ps_response_ready,
+ PS_SRC_MAC_ADDRESS_IN => RC_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => RC_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => RC_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => RC_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => RC_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => RC_DEST_UDP_PORT_IN,
+ TC_DATA_OUT => tc_data,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_FRAME_SIZE_OUT => TC_FRAME_SIZE_OUT,
+ TC_FRAME_TYPE_OUT => TC_FRAME_TYPE_OUT,
+ TC_IP_PROTOCOL_OUT => TC_IP_PROTOCOL_OUT,
+ TC_IDENT_OUT => TC_IDENT_OUT,
+ TC_DEST_MAC_OUT => TC_DEST_MAC_OUT,
+ TC_DEST_IP_OUT => TC_DEST_IP_OUT,
+ TC_DEST_UDP_OUT => TC_DEST_UDP_OUT,
+ TC_SRC_MAC_OUT => TC_SRC_MAC_OUT,
+ TC_SRC_IP_OUT => TC_SRC_IP_OUT,
+ TC_SRC_UDP_OUT => TC_SRC_UDP_OUT,
+ MC_BUSY_IN => mc_busy,
+ MY_MAC_IN => MC_MY_MAC_IN,
+ MY_IP_OUT => MY_IP_OUT,
+ DHCP_START_IN => dhcp_start,
+ DHCP_DONE_OUT => dhcp_done,
+ GSC_CLK_IN => GSC_CLK_IN,
+ GSC_INIT_DATAREADY_OUT => GSC_INIT_DATAREADY_OUT,
+ GSC_INIT_DATA_OUT => GSC_INIT_DATA_OUT,
+ GSC_INIT_PACKET_NUM_OUT => GSC_INIT_PACKET_NUM_OUT,
+ GSC_INIT_READ_IN => GSC_INIT_READ_IN,
+ GSC_REPLY_DATAREADY_IN => GSC_REPLY_DATAREADY_IN,
+ GSC_REPLY_DATA_IN => GSC_REPLY_DATA_IN,
+ GSC_REPLY_PACKET_NUM_IN => GSC_REPLY_PACKET_NUM_IN,
+ GSC_REPLY_READ_OUT => GSC_REPLY_READ_OUT,
+ GSC_BUSY_IN => GSC_BUSY_IN,
+ MAKE_RESET_OUT => MAKE_RESET_OUT,
+
+ MY_TRBNET_ADDRESS_IN => MY_TRBNET_ADDRESS_IN,
+-- ISSUE_REBOOT_OUT => ISSUE_REBOOT_OUT,
+
+ CFG_MAX_REPLY_SIZE_IN => CFG_MAX_REPLY_SIZE_IN,
+
+ FWD_DST_MAC_IN => FWD_DST_MAC_IN,
+ FWD_DST_IP_IN => FWD_DST_IP_IN,
+ FWD_DST_UDP_IN => FWD_DST_UDP_IN,
+ FWD_DATA_IN => FWD_DATA_IN,
+ FWD_DATA_VALID_IN => FWD_DATA_VALID_IN,
+ FWD_SOP_IN => FWD_SOP_IN,
+ FWD_EOP_IN => FWD_EOP_IN,
+ FWD_READY_OUT => FWD_READY_OUT,
+ FWD_FULL_OUT => FWD_FULL_OUT,
+
+ -- input for statistics from outside
+ MONITOR_SELECT_REC_OUT => MONITOR_SELECT_REC_OUT,
+ MONITOR_SELECT_REC_BYTES_OUT => MONITOR_SELECT_REC_BYTES_OUT,
+ MONITOR_SELECT_SENT_BYTES_OUT => MONITOR_SELECT_SENT_BYTES_OUT,
+ MONITOR_SELECT_SENT_OUT => MONITOR_SELECT_SENT_OUT,
+ MONITOR_SELECT_GEN_DBG_OUT => MONITOR_SELECT_GEN_DBG_OUT,
+ SCTRL_HIST_OUT => SCTRL_HIST_OUT,
+ DEBUG_OUT => selector_debug
+ );
+
+ TC_DATA_OUT <= tc_data;
+
+ -- gk 07.11.11
+ -- do not select any response constructors when dropping a frame
+ proto_select <= RC_FRAME_PROTO_IN when disable_redirect = '0' else (others => '0');
+
+ -- gk 07.11.11
+ -- we do not answer at all, unless we are in either ACTIVE or GET_ADDRESS state.
+ -- in GET_ADDRESS state, we only answer on DHCP frames.
+ PROC_DISABLE_REDIRECT: process( CLK, RESET )
+ begin
+ if ( RESET = '1' ) then
+ disable_redirect <= '0';
+ elsif( rising_edge(CLK) ) then
+ if( redirect_current_state = CHECK_TYPE ) then
+ if ( (link_current_state /= ACTIVE) and (link_current_state /= GET_ADDRESS) ) then
+ disable_redirect <= '1';
+ elsif( (link_current_state = GET_ADDRESS) and (RC_FRAME_PROTO_IN /= "10") ) then -- (UDP, DHCP)
+ disable_redirect <= '1';
+ else
+ disable_redirect <= '0';
+ end if;
+ end if;
+ end if;
+ end process PROC_DISABLE_REDIRECT;
+
+ -- warning
+ PROC_SYNC: process( CLK )
+ begin
+ if( rising_edge(CLK) ) then
+ rc_data_local <= RC_DATA_IN;
+ end if;
+ end process PROC_SYNC;
+
+ PROC_REDIRECT_FSM: process( CLK, RESET )
+ begin
+ if ( RESET = '1' ) then
+ redirect_current_state <= IDLE;
+ elsif( rising_edge(CLK) ) then
+ redirect_current_state <= redirect_next_state;
+ end if;
+ end process PROC_REDIRECT_FSM;
+
+ PROC_REDIRECT_TRANSITIONS: process( redirect_current_state, link_current_state, RC_FRAME_WAITING_IN,
+ ps_busy, RC_FRAME_PROTO_IN, loaded_bytes_ctr, RC_FRAME_SIZE_IN )
+ begin
+ redirect_state <= x"0";
+
+ case redirect_current_state is
+ when IDLE =>
+ redirect_state <= x"1";
+ if( RC_FRAME_WAITING_IN = '1' ) then
+ redirect_next_state <= CHECK_TYPE;
+ else
+ redirect_next_state <= IDLE;
+ end if;
+
+ when CHECK_TYPE =>
+ redirect_state <= x"2";
+ if ( link_current_state = ACTIVE ) then
+ redirect_next_state <= CHECK_BUSY;
+ elsif( (link_current_state = GET_ADDRESS) and (RC_FRAME_PROTO_IN = "10") ) then
+ redirect_next_state <= CHECK_BUSY;
+ else
+ redirect_next_state <= DROP;
+ end if;
+
+ when DROP =>
+ redirect_state <= x"3";
+ if( loaded_bytes_ctr = unsigned(RC_FRAME_SIZE_IN) - 1 ) then
+ redirect_next_state <= WAIT_ONE;
+ else
+ redirect_next_state <= DROP;
+ end if;
+
+ when CHECK_BUSY =>
+ redirect_state <= x"4";
+ if( or_all(ps_busy and RC_FRAME_PROTO_IN) = '0' ) then
+ redirect_next_state <= LOAD;
+ else
+ redirect_next_state <= BUSY;
+ end if;
+
+ when LOAD =>
+ redirect_state <= x"5";
+ if( loaded_bytes_ctr = unsigned(RC_FRAME_SIZE_IN) - 1 ) then
+ redirect_next_state <= WAIT_ONE;
+ else
+ redirect_next_state <= LOAD;
+ end if;
+
+ when BUSY =>
+ redirect_state <= x"6";
+ if( or_all(ps_busy and RC_FRAME_PROTO_IN) = '0' ) then
+ redirect_next_state <= LOAD;
+ else
+ redirect_next_state <= BUSY;
+ end if;
+
+ when WAIT_ONE =>
+ redirect_state <= x"7";
+ redirect_next_state <= FINISH;
+
+ when FINISH =>
+ redirect_state <= x"8";
+ redirect_next_state <= CLEANUP;
+
+ when CLEANUP =>
+ redirect_state <= x"9";
+ redirect_next_state <= IDLE;
+
+ when others => redirect_next_state <= IDLE;
+
+ end case;
+ end process PROC_REDIRECT_TRANSITIONS;
+
+ rc_rd_en <= '1' when redirect_current_state = LOAD or redirect_current_state = DROP else '0';
+ RC_RD_EN_OUT <= rc_rd_en;
+
+ PROC_LOADING_DONE: process( CLK )
+ begin
+ if rising_edge(CLK) then
+ if (RC_DATA_IN(8) = '1' and ps_wr_en_q = '1') then
+ RC_LOADING_DONE_OUT <= '1';
+ else
+ RC_LOADING_DONE_OUT <= '0';
+ end if;
+ end if;
+ end process PROC_LOADING_DONE;
+
+ PROC_PS_WR_EN: process( CLK )
+ begin
+ if rising_edge(CLK) then
+ ps_wr_en <= rc_rd_en;
+ ps_wr_en_q <= ps_wr_en;
+ ps_wr_en_qq <= ps_wr_en_q;
+ end if;
+ end process PROC_PS_WR_EN;
+
+ PROC_LOADED_BYTES_CTR: process( CLK )
+ begin
+ if rising_edge(CLK) then
+ if ( redirect_current_state = IDLE) then
+ loaded_bytes_ctr <= (others => '0');
+ elsif( ((redirect_current_state = LOAD) or (redirect_current_state = DROP)) and (rc_rd_en = '1') )then
+ loaded_bytes_ctr <= loaded_bytes_ctr + x"1";
+ end if;
+ end if;
+ end process PROC_LOADED_BYTES_CTR;
+
+ --*********************
+ -- DATA FLOW CONTROL
+
+ PROC_FLOW_FSM: process( CLK, RESET )
+ begin
+ if ( RESET = '1' ) then
+ flow_current_state <= IDLE;
+ elsif( rising_edge(CLK) ) then
+ flow_current_state <= flow_next_state;
+ end if;
+ end process PROC_FLOW_FSM;
+
+ PROC_FLOW_TRANSITIONS: process(flow_current_state, TC_TRANSMIT_DONE_IN, ps_response_ready, tc_data)
+ begin
+ flow_state <= x"0";
+
+ case flow_current_state is
+ when IDLE =>
+ flow_state <= x"1";
+ if (ps_response_ready = '1') then
+ flow_next_state <= TRANSMIT_CTRL;
+ else
+ flow_next_state <= IDLE;
+ end if;
+
+ when TRANSMIT_CTRL =>
+ flow_state <= x"2";
+ if (tc_data(8) = '1') then
+ flow_next_state <= WAIT_FOR_FC;
+ else
+ flow_next_state <= TRANSMIT_CTRL;
+ end if;
+
+ when WAIT_FOR_FC =>
+ flow_state <= x"3";
+ if (TC_TRANSMIT_DONE_IN = '1') then
+ flow_next_state <= CLEANUP;
+ else
+ flow_next_state <= WAIT_FOR_FC;
+ end if;
+
+ when CLEANUP =>
+ flow_state <= x"4";
+ flow_next_state <= IDLE;
+
+ when others => flow_next_state <= IDLE;
+
+ end case;
+ end process PROC_FLOW_TRANSITIONS;
+
+ PROC_BUSY: process( CLK )
+ begin
+ if rising_edge(CLK) then
+ if (flow_current_state = IDLE and ps_response_ready = '1') then
+ TC_TRANSMIT_CTRL_OUT <= '1';
+ else
+ TC_TRANSMIT_CTRL_OUT <= '0';
+ end if;
+
+ if (flow_current_state = TRANSMIT_CTRL or flow_current_state = WAIT_FOR_FC) then
+ mc_busy <= '1';
+ else
+ mc_busy <= '0';
+ end if;
+ end if;
+ end process PROC_BUSY;
+
+ --***********************
+ -- LINK STATE CONTROL
+
+ PROC_LINK_FSM: process( RESET, CLK )
+ begin
+ if ( RESET = '1' ) then
+ link_current_state <= INACTIVE;
+ elsif( rising_edge(CLK) ) then
+ link_current_state <= link_next_state;
+ end if;
+ end process PROC_LINK_FSM;
+
+ INCL_DHCP_GEN: if (INCLUDE_DHCP = '1') generate
+ incl_dhcp <= '1';
+ end generate INCL_DHCP_GEN;
+ NOINCL_DHCP_GEN: if (INCLUDE_DHCP = '0') generate
+ incl_dhcp <= '0';
+ end generate NOINCL_DHCP_GEN;
+
+ -- to be reworked. link_ok_timer is not needed anymore!
+ PROC_LINK_TRANSITIONS: process( link_current_state, dhcp_done, wait_ctr, PCS_AN_COMPLETE_IN, incl_dhcp, MAC_READY_CONF_IN, link_ok_timeout_ctr )
+ begin
+ link_state <= x"0";
+
+ case link_current_state is
+ when INACTIVE =>
+ link_state <= x"1";
+ if (PCS_AN_COMPLETE_IN = '1') then
+ link_next_state <= TIMEOUT;
+ else
+ link_next_state <= INACTIVE;
+ end if;
+
+ when TIMEOUT =>
+ link_state <= x"2";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ else
+ if (link_ok_timeout_ctr = x"ffff") then
+ link_next_state <= ENABLE_MAC;
+ else
+ link_next_state <= TIMEOUT;
+ end if;
+ end if;
+
+ when ENABLE_MAC =>
+ link_state <= x"3";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ elsif (MAC_READY_CONF_IN = '1') then
+ link_next_state <= FINALIZE;
+ else
+ link_next_state <= ENABLE_MAC;
+ end if;
+
+ when FINALIZE =>
+ link_state <= x"4";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ else
+ link_next_state <= WAIT_FOR_BOOT;
+ end if;
+
+ when WAIT_FOR_BOOT =>
+ link_state <= x"5";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ else
+ if (wait_ctr = x"0000_1000") then
+ if (incl_dhcp = '1') then
+ link_next_state <= GET_ADDRESS;
+ else
+ link_next_state <= ACTIVE;
+ end if;
+ else
+ link_next_state <= WAIT_FOR_BOOT;
+ end if;
+ end if;
+
+ when GET_ADDRESS =>
+ link_state <= x"6";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ else
+ if (dhcp_done = '1') then
+ link_next_state <= ACTIVE;
+ else
+ link_next_state <= GET_ADDRESS;
+ end if;
+ end if;
+
+ when ACTIVE =>
+ link_state <= x"7";
+ if (PCS_AN_COMPLETE_IN = '0') then
+ link_next_state <= INACTIVE;
+ else
+ link_next_state <= ACTIVE;
+ end if;
+
+ when others =>
+ link_next_state <= INACTIVE;
+
+ end case;
+ end process PROC_LINK_TRANSITIONS;
+
+ MC_DHCP_DONE_OUT <= '1' when link_current_state = ACTIVE else '0';
+
+ PROC_LINK_OK_CTR: process( CLK )
+ begin
+ if( rising_edge(CLK) ) then
+ if ( link_current_state /= TIMEOUT ) then
+ link_ok_timeout_ctr <= (others => '0');
+ elsif( link_current_state = TIMEOUT ) then
+ link_ok_timeout_ctr <= link_ok_timeout_ctr + 1;
+ end if;
+
+ if( link_current_state = GET_ADDRESS ) then
+ dhcp_start <= '1';
+ else
+ dhcp_start <= '0';
+ end if;
+ end if;
+ end process PROC_LINK_OK_CTR;
+
+ link_ok <= '1'; -- BUG - what the fuck?
+
+ PROC_WAIT_CTR: process( CLK )
+ begin
+ if( rising_edge(CLK) ) then
+ if( link_current_state = WAIT_FOR_BOOT ) then
+ wait_ctr <= wait_ctr + 1;
+ else
+ wait_ctr <= (others => '0');
+ end if;
+ end if;
+ end process PROC_WAIT_CTR;
+
+ MC_LINK_OK_OUT <= link_ok;
+
+ -- END OF LINK STATE CONTROL
+ --*************
+
+ DEBUG_OUT <= selector_debug;
+
+end gbe_main_control_arch;
--- /dev/null
+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.gbe_protocols.all;
+
+--********
+-- maps the frame type and protocol code into internal value which sets the priority
+
+entity gbe_protocol_prioritizer is
+port(
+ CLK : in std_logic;
+ RESET : in std_logic;
+ FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type
+ PROTOCOL_CODE_IN : in std_logic_vector(7 downto 0); -- ip protocol
+ UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0);
+ CODE_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0)
+);
+end gbe_protocol_prioritizer;
+
+architecture gbe_protocol_prioritizer_arch of gbe_protocol_prioritizer is
+
+begin
+
+PRIORITIZE: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ CODE_OUT <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+
+ CODE_OUT <= (others => '0');
+
+ --**** HERE ADD YOU PROTOCOL RECOGNITION AT WANTED PRIORITY LEVEL
+ -- priority level is the bit position in the CODE_OUT vector
+ -- less significant bit has the higher priority
+ case FRAME_TYPE_IN is
+
+ -- IPv4
+ when x"0800" =>
+ if ( PROTOCOL_CODE_IN = x"11" ) then -- UDP
+ -- No. 2 = DHCP
+ if ( UDP_PROTOCOL_IN = x"0044" ) then -- DHCP Client
+ CODE_OUT(1) <= '1';
+ -- No. 4 = SCTRL
+ elsif( UDP_PROTOCOL_IN = x"6590" ) then -- SCTRL module
+ CODE_OUT(2) <= '1';
+ else
+ -- branch for pure IPv4
+ CODE_OUT <= (others => '0');
+ end if;
+ -- No. 3 = ICMP
+ elsif( PROTOCOL_CODE_IN = x"01") then -- ICMP
+ CODE_OUT(4) <= '1';
+ else
+ CODE_OUT <= (others => '0');
+ end if;
+
+ -- No. 1 = ARP
+ when x"0806" =>
+ CODE_OUT(0) <= '1';
+
+ -- last slot is reserved for Trash
+ when others =>
+ CODE_OUT <= (others => '0');
+
+ end case;
+
+ end if;
+
+end process PRIORITIZE;
+
+end gbe_protocol_prioritizer_arch;
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+--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.gbe_protocols.all;
+
+entity gbe_protocol_selector is
+ generic(
+ INCLUDE_SLOWCTRL : std_logic := '0';
+ INCLUDE_DHCP : std_logic := '0';
+ INCLUDE_ARP : std_logic := '0';
+ INCLUDE_PING : std_logic := '0';
+ INCLUDE_FWD : std_logic := '0';
+ SLOWCTRL_BUFFER_SIZE : integer range 1 to 4
+ );
+ port(
+ CLK : in std_logic; -- system clock
+ RESET : in std_logic;
+ -- signals to/from main controller
+ PS_DATA_IN : in std_logic_vector(8 downto 0);
+ PS_WR_EN_IN : in std_logic;
+ PS_PROTO_SELECT_IN : in std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ PS_BUSY_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ PS_FRAME_SIZE_IN : in std_logic_vector(15 downto 0);
+ PS_RESPONSE_READY_OUT : out 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);
+ -- signals to/from transmit controller with constructed response
+ TC_DATA_OUT : out std_logic_vector(8 downto 0);
+ TC_RD_EN_IN : in std_logic;
+ 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);
+ MC_BUSY_IN : in std_logic;
+ -- misc signals for response constructors
+ MY_MAC_IN : in std_logic_vector(47 downto 0);
+ MY_IP_OUT : out std_logic_vector(31 downto 0);
+ DHCP_START_IN : in std_logic;
+ DHCP_DONE_OUT : out std_logic;
+ GSC_CLK_IN : in std_logic;
+ GSC_INIT_DATAREADY_OUT : out std_logic;
+ GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0);
+ GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0);
+ GSC_INIT_READ_IN : in std_logic;
+ GSC_REPLY_DATAREADY_IN : in std_logic;
+ GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0);
+ GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0);
+ GSC_REPLY_READ_OUT : out std_logic;
+ GSC_BUSY_IN : in std_logic;
+ CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0); -- USED IN SCTRL
+ MAKE_RESET_OUT : out std_logic;
+ MY_TRBNET_ADDRESS_IN : in std_logic_vector(15 downto 0);
+ ISSUE_REBOOT_OUT : out std_logic;
+ -- Forwarder
+ FWD_DST_MAC_IN : in std_logic_vector(47 downto 0);
+ FWD_DST_IP_IN : in std_logic_vector(31 downto 0);
+ FWD_DST_UDP_IN : in std_logic_vector(15 downto 0);
+ FWD_DATA_IN : in std_logic_vector(7 downto 0);
+ FWD_DATA_VALID_IN : in std_logic;
+ FWD_SOP_IN : in std_logic;
+ FWD_EOP_IN : in std_logic;
+ FWD_READY_OUT : out std_logic;
+ FWD_FULL_OUT : out std_logic;
+ -- input for statistics from outside
+ MONITOR_SELECT_REC_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_SENT_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ MONITOR_SELECT_GEN_DBG_OUT : out std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ SCTRL_HIST_OUT : out hist_array;
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+ );
+end gbe_protocol_selector;
+
+architecture gbe_protocol_selector_arch of gbe_protocol_selector is
+
+ attribute syn_encoding : string;
+
+ signal rd_en : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal resp_ready : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal tc_wr : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal tc_data : std_logic_vector(c_MAX_PROTOCOLS * 9 - 1 downto 0);
+ signal tc_size : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+ signal tc_type : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+ signal busy : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal selected : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ signal tc_mac : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0);
+ signal tc_ip : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ signal tc_udp : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+ signal tc_src_mac : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0);
+ signal tc_src_ip : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+ signal tc_src_udp : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+ signal tc_ip_proto : std_logic_vector(c_MAX_PROTOCOLS * 8 - 1 downto 0);
+
+ type select_states is (IDLE, LOOP_OVER, SELECT_ONE, PROCESS_REQUEST, CLEANUP);
+ signal select_current_state, select_next_state : select_states;
+ attribute syn_encoding of select_current_state : signal is "onehot";
+
+ signal state : std_logic_vector(3 downto 0);
+ signal index : integer range 0 to c_MAX_PROTOCOLS - 1;
+
+ signal mult : std_logic;
+
+ signal tc_ident : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+ signal zeros : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+
+ attribute syn_preserve : boolean;
+ attribute syn_keep : boolean;
+ attribute syn_keep of state, mult : signal is true;
+ attribute syn_preserve of state, mult : signal is true;
+
+ signal my_ip : std_logic_vector(31 downto 0);
+ signal select_state : std_logic_vector(3 downto 0);
+
+begin
+ zeros <= (others => '0');
+ MY_IP_OUT <= my_ip;
+
+ ARP_GEN: if( INCLUDE_ARP = '1' ) generate
+ -- protocol Nr. 1 ARP
+ THE_ARP: entity work.gbe_response_constructor_ARP
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ -- INTERFACE
+ MY_MAC_IN => MY_MAC_IN,
+ MY_IP_IN => my_ip,
+ PS_DATA_IN => PS_DATA_IN,
+ PS_WR_EN_IN => PS_WR_EN_IN,
+ PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(0),
+ PS_RESPONSE_READY_OUT => resp_ready(0),
+ PS_BUSY_OUT => busy(0),
+ PS_SELECTED_IN => selected(0),
+ PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_DATA_OUT => tc_data(1 * 9 - 1 downto 0 * 9),
+ TC_FRAME_SIZE_OUT => tc_size(1 * 16 - 1 downto 0 * 16),
+ TC_FRAME_TYPE_OUT => tc_type(1 * 16 - 1 downto 0 * 16),
+ TC_IP_PROTOCOL_OUT => tc_ip_proto(1 * 8 - 1 downto 0 * 8),
+ TC_IDENT_OUT => tc_ident(1 * 16 - 1 downto 0 * 16),
+ TC_DEST_MAC_OUT => tc_mac(1 * 48 - 1 downto 0 * 48),
+ TC_DEST_IP_OUT => tc_ip(1 * 32 - 1 downto 0 * 32),
+ TC_DEST_UDP_OUT => tc_udp(1 * 16 - 1 downto 0 * 16),
+ TC_SRC_MAC_OUT => tc_src_mac(1 * 48 - 1 downto 0 * 48),
+ TC_SRC_IP_OUT => tc_src_ip(1 * 32 - 1 downto 0 * 32),
+ TC_SRC_UDP_OUT => tc_src_udp(1 * 16 - 1 downto 0 * 16),
+ DEBUG_OUT => MONITOR_SELECT_GEN_DBG_OUT(1 * 64 - 1 downto 0 * 64)
+ -- END OF INTERFACE
+ );
+ end generate ARP_GEN;
+
+ NO_ARP_GEN: if( INCLUDE_ARP = '0' ) generate
+ resp_ready(0) <= '0';
+ busy(0) <= '0';
+ end generate NO_ARP_GEN;
+
+ DHCP_GEN: if( INCLUDE_DHCP = '1' ) generate
+ -- protocol No. 2 DHCP
+ THE_DHCP: entity work.gbe_response_constructor_DHCP
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ -- INTERFACE
+ MY_MAC_IN => MY_MAC_IN,
+ MY_IP_IN => my_ip,
+ PS_DATA_IN => PS_DATA_IN,
+ PS_WR_EN_IN => PS_WR_EN_IN,
+ PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(1),
+ PS_RESPONSE_READY_OUT => resp_ready(1),
+ PS_BUSY_OUT => busy(1),
+ PS_SELECTED_IN => selected(1),
+ PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_DATA_OUT => tc_data(2 * 9 - 1 downto 1 * 9),
+ TC_FRAME_SIZE_OUT => tc_size(2 * 16 - 1 downto 1 * 16),
+ TC_FRAME_TYPE_OUT => tc_type(2 * 16 - 1 downto 1 * 16),
+ TC_IP_PROTOCOL_OUT => tc_ip_proto(2 * 8 - 1 downto 1 * 8),
+ TC_IDENT_OUT => tc_ident(2 * 16 - 1 downto 1 * 16),
+ TC_DEST_MAC_OUT => tc_mac(2 * 48 - 1 downto 1 * 48),
+ TC_DEST_IP_OUT => tc_ip(2 * 32 - 1 downto 1 * 32),
+ TC_DEST_UDP_OUT => tc_udp(2 * 16 - 1 downto 1 * 16),
+ TC_SRC_MAC_OUT => tc_src_mac(2 * 48 - 1 downto 1 * 48),
+ TC_SRC_IP_OUT => tc_src_ip(2 * 32 - 1 downto 1 * 32),
+ TC_SRC_UDP_OUT => tc_src_udp(2 * 16 - 1 downto 1 * 16),
+ -- END OF INTERFACE
+ MY_IP_OUT => my_ip,
+ DHCP_START_IN => DHCP_START_IN,
+ DHCP_DONE_OUT => DHCP_DONE_OUT,
+ DEBUG_OUT => MONITOR_SELECT_GEN_DBG_OUT(2 * 64 - 1 downto 1 * 64)
+ );
+ end generate DHCP_GEN;
+
+ NO_DHCP_GEN: if( INCLUDE_DHCP = '0' ) generate
+ resp_ready(1) <= '0';
+ busy(1) <= '0';
+ end generate NO_DHCP_GEN;
+
+ PING_GEN: if( INCLUDE_PING = '1' ) generate
+ --protocol No. 3 Ping
+ THE_PING: entity work.gbe_response_constructor_Ping
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ ---- INTERFACE
+ MY_MAC_IN => MY_MAC_IN,
+ MY_IP_IN => my_ip,
+ PS_DATA_IN => PS_DATA_IN,
+ PS_WR_EN_IN => PS_WR_EN_IN,
+ PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(4),
+ PS_RESPONSE_READY_OUT => resp_ready(4),
+ PS_BUSY_OUT => busy(4),
+ PS_SELECTED_IN => selected(4),
+ PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_DATA_OUT => tc_data(5 * 9 - 1 downto 4 * 9),
+ TC_FRAME_SIZE_OUT => tc_size(5 * 16 - 1 downto 4 * 16),
+ TC_FRAME_TYPE_OUT => tc_type(5 * 16 - 1 downto 4 * 16),
+ TC_IP_PROTOCOL_OUT => tc_ip_proto(5 * 8 - 1 downto 4 * 8),
+ TC_IDENT_OUT => tc_ident(5 * 16 - 1 downto 4 * 16),
+ TC_DEST_MAC_OUT => tc_mac(5 * 48 - 1 downto 4 * 48),
+ TC_DEST_IP_OUT => tc_ip(5 * 32 - 1 downto 4 * 32),
+ TC_DEST_UDP_OUT => tc_udp(5 * 16 - 1 downto 4 * 16),
+ TC_SRC_MAC_OUT => tc_src_mac(5 * 48 - 1 downto 4 * 48),
+ TC_SRC_IP_OUT => tc_src_ip(5 * 32 - 1 downto 4 * 32),
+ TC_SRC_UDP_OUT => tc_src_udp(5 * 16 - 1 downto 4 * 16),
+ DEBUG_OUT => MONITOR_SELECT_GEN_DBG_OUT(5 * 64 - 1 downto 4 * 64)
+ -- END OF INTERFACE
+ );
+ end generate PING_GEN;
+
+ NO_PING_GEN: if( INCLUDE_PING = '0' ) generate
+ resp_ready(4) <= '0';
+ busy(4) <= '0';
+ end generate NO_PING_GEN;
+
+ SCTRL_GEN: if( INCLUDE_SLOWCTRL = '1' ) generate
+ THE_SCTRL: entity work.gbe_response_constructor_SCTRL
+ generic map(
+ SLOWCTRL_BUFFER_SIZE => SLOWCTRL_BUFFER_SIZE
+ )
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ -- INTERFACE
+ MY_MAC_IN => MY_MAC_IN,
+ MY_IP_IN => my_ip,
+ PS_DATA_IN => PS_DATA_IN,
+ PS_WR_EN_IN => PS_WR_EN_IN,
+ PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(2),
+ PS_RESPONSE_READY_OUT => resp_ready(2),
+ PS_BUSY_OUT => busy(2),
+ PS_SELECTED_IN => selected(2),
+ PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_DATA_OUT => tc_data(3 * 9 - 1 downto 2 * 9),
+ TC_FRAME_SIZE_OUT => tc_size(3 * 16 - 1 downto 2 * 16),
+ TC_FRAME_TYPE_OUT => tc_type(3 * 16 - 1 downto 2 * 16),
+ TC_IP_PROTOCOL_OUT => tc_ip_proto(3 * 8 - 1 downto 2 * 8),
+ TC_IDENT_OUT => tc_ident(3 * 16 - 1 downto 2 * 16),
+ TC_DEST_MAC_OUT => tc_mac(3 * 48 - 1 downto 2 * 48),
+ TC_DEST_IP_OUT => tc_ip(3 * 32 - 1 downto 2 * 32),
+ TC_DEST_UDP_OUT => tc_udp(3 * 16 - 1 downto 2 * 16),
+ TC_SRC_MAC_OUT => tc_src_mac(3 * 48 - 1 downto 2 * 48),
+ TC_SRC_IP_OUT => tc_src_ip(3 * 32 - 1 downto 2 * 32),
+ TC_SRC_UDP_OUT => tc_src_udp(3 * 16 - 1 downto 2 * 16),
+ DEBUG_OUT => MONITOR_SELECT_GEN_DBG_OUT(3 * 64 - 1 downto 2 * 64),
+ -- END OF INTERFACE
+ GSC_CLK_IN => GSC_CLK_IN,
+ GSC_INIT_DATAREADY_OUT => GSC_INIT_DATAREADY_OUT,
+ GSC_INIT_DATA_OUT => GSC_INIT_DATA_OUT,
+ GSC_INIT_PACKET_NUM_OUT => GSC_INIT_PACKET_NUM_OUT,
+ GSC_INIT_READ_IN => GSC_INIT_READ_IN,
+ GSC_REPLY_DATAREADY_IN => GSC_REPLY_DATAREADY_IN,
+ GSC_REPLY_DATA_IN => GSC_REPLY_DATA_IN,
+ GSC_REPLY_PACKET_NUM_IN => GSC_REPLY_PACKET_NUM_IN,
+ GSC_REPLY_READ_OUT => GSC_REPLY_READ_OUT,
+ GSC_BUSY_IN => GSC_BUSY_IN,
+ CFG_MAX_REPLY_SIZE_IN => CFG_MAX_REPLY_SIZE_IN,
+ MAKE_RESET_OUT => MAKE_RESET_OUT,
+ MONITOR_SELECT_REC_OUT => MONITOR_SELECT_REC_OUT(3 * 32 - 1 downto 2 * 32),
+ MONITOR_SELECT_REC_BYTES_OUT => MONITOR_SELECT_REC_BYTES_OUT(3 * 32 - 1 downto 2 * 32),
+ MONITOR_SELECT_SENT_BYTES_OUT => MONITOR_SELECT_SENT_BYTES_OUT(3 * 32 - 1 downto 2 * 32),
+ MONITOR_SELECT_SENT_OUT => MONITOR_SELECT_SENT_OUT(3 * 32 - 1 downto 2 * 32),
+ DATA_HIST_OUT => SCTRL_HIST_OUT
+ );
+ end generate SCTRL_GEN;
+
+ NO_SCTRL_GEN: if( INCLUDE_SLOWCTRL = '0' ) generate
+ resp_ready(2) <= '0';
+ busy(2) <= '0';
+ MAKE_RESET_OUT <= '0';
+
+ GSC_INIT_DATAREADY_OUT <= '0';
+ GSC_INIT_DATA_OUT <= (others => '0');
+ GSC_INIT_PACKET_NUM_OUT <= (others => '0');
+ GSC_REPLY_READ_OUT <= '1';
+ end generate NO_SCTRL_GEN;
+
+ ---------------------------------------------------------------------------------------
+ -- once upon a time, this was "READOUT"
+ resp_ready(3) <= '0';
+ busy(3) <= '0';
+ ---------------------------------------------------------------------------------------
+
+ FWD_GEN: if( INCLUDE_FWD = '1' ) generate
+
+ THE_FORWARD: entity work.gbe_response_constructor_Forward
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ ---- INTERFACE
+ MY_MAC_IN => MY_MAC_IN,
+ MY_IP_IN => my_ip,
+ PS_DATA_IN => PS_DATA_IN,
+ PS_WR_EN_IN => PS_WR_EN_IN,
+ PS_ACTIVATE_IN => PS_PROTO_SELECT_IN(5),
+ PS_RESPONSE_READY_OUT => resp_ready(5),
+ PS_BUSY_OUT => busy(5),
+ PS_SELECTED_IN => selected(5),
+ PS_SRC_MAC_ADDRESS_IN => PS_SRC_MAC_ADDRESS_IN,
+ PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+ PS_SRC_IP_ADDRESS_IN => PS_SRC_IP_ADDRESS_IN,
+ PS_DEST_IP_ADDRESS_IN => PS_DEST_IP_ADDRESS_IN,
+ PS_SRC_UDP_PORT_IN => PS_SRC_UDP_PORT_IN,
+ PS_DEST_UDP_PORT_IN => PS_DEST_UDP_PORT_IN,
+ TC_RD_EN_IN => TC_RD_EN_IN,
+ TC_DATA_OUT => tc_data(6 * 9 - 1 downto 5 * 9),
+ TC_FRAME_SIZE_OUT => tc_size(6 * 16 - 1 downto 5 * 16),
+ TC_FRAME_TYPE_OUT => tc_type(6 * 16 - 1 downto 5 * 16),
+ TC_IP_PROTOCOL_OUT => tc_ip_proto(6 * 8 - 1 downto 5 * 8),
+ TC_IDENT_OUT => tc_ident(6 * 16 - 1 downto 5 * 16),
+ TC_DEST_MAC_OUT => tc_mac(6 * 48 - 1 downto 5 * 48),
+ TC_DEST_IP_OUT => tc_ip(6 * 32 - 1 downto 5 * 32),
+ TC_DEST_UDP_OUT => tc_udp(6 * 16 - 1 downto 5 * 16),
+ TC_SRC_MAC_OUT => tc_src_mac(6 * 48 - 1 downto 5 * 48),
+ TC_SRC_IP_OUT => tc_src_ip(6 * 32 - 1 downto 5 * 32),
+ TC_SRC_UDP_OUT => tc_src_udp(6 * 16 - 1 downto 5 * 16),
+ RECEIVED_FRAMES_OUT => open,
+ SENT_FRAMES_OUT => open,
+ FWD_DST_MAC_IN => FWD_DST_MAC_IN,
+ FWD_DST_IP_IN => FWD_DST_IP_IN,
+ FWD_DST_UDP_IN => FWD_DST_UDP_IN,
+ FWD_DATA_IN => FWD_DATA_IN,
+ FWD_DATA_VALID_IN => FWD_DATA_VALID_IN,
+ FWD_SOP_IN => FWD_SOP_IN,
+ FWD_EOP_IN => FWD_EOP_IN,
+ FWD_READY_OUT => FWD_READY_OUT,
+ FWD_FULL_OUT => FWD_FULL_OUT,
+ DEBUG_OUT => DEBUG_OUT(31 downto 0) --open
+ -- END OF INTERFACE
+ );
+
+ end generate FWD_GEN;
+
+ DEBUG_OUT(63 downto 32) <= (others => '0');
+
+ NO_FWD_GEN: if( INCLUDE_FWD = '0' ) generate
+ resp_ready(5) <= '0';
+ busy(5) <= '0';
+ DEBUG_OUT(31 downto 0) <= (others => '0');
+ end generate NO_FWD_GEN;
+
+ PS_BUSY_OUT <= busy;
+
+ PROC_SELECT_MACHINE: process( CLK, RESET )
+ begin
+ if ( RESET = '1' ) then
+ select_current_state <= IDLE;
+ elsif( rising_edge(CLK) ) then
+ select_current_state <= select_next_state;
+ end if;
+ end process PROC_SELECT_MACHINE;
+
+ PROC_SELECT_TRANSITIONS: process(select_current_state, MC_BUSY_IN, resp_ready, index, zeros, busy)
+ begin
+ select_state <= x"0";
+
+ case (select_current_state) is
+ when IDLE =>
+ select_state <= x"1";
+ if (MC_BUSY_IN = '0') then
+ select_next_state <= LOOP_OVER;
+ else
+ select_next_state <= IDLE;
+ end if;
+
+ when LOOP_OVER =>
+ select_state <= x"2";
+ if (resp_ready /= zeros) then
+ if (resp_ready(index) = '1') then
+ select_next_state <= SELECT_ONE;
+ elsif (index = c_MAX_PROTOCOLS) then
+ select_next_state <= CLEANUP;
+ else
+ select_next_state <= LOOP_OVER;
+ end if;
+ else
+ select_next_state <= CLEANUP;
+ end if;
+
+ when SELECT_ONE =>
+ select_state <= x"3";
+ if (MC_BUSY_IN = '1') then
+ select_next_state <= PROCESS_REQUEST;
+ else
+ select_next_state <= SELECT_ONE;
+ end if;
+
+ when PROCESS_REQUEST =>
+ select_state <= x"4";
+ if (busy(index) = '0') then
+ select_next_state <= CLEANUP;
+ else
+ select_next_state <= PROCESS_REQUEST;
+ end if;
+
+ when CLEANUP =>
+ select_state <= x"5";
+ select_next_state <= IDLE;
+
+ when others => select_next_state <= IDLE;
+
+ end case;
+ end process PROC_SELECT_TRANSITIONS;
+
+ PROC_INDEX: process( CLK )
+ begin
+ if( rising_edge(CLK) ) then
+ if ( select_current_state = IDLE ) then
+ index <= 0;
+ elsif( select_current_state = LOOP_OVER and resp_ready(index) = '0' ) then
+ index <= index + 1;
+ end if;
+ end if;
+ end process PROC_INDEX;
+
+ PROC_SELECTOR: process( CLK )
+ begin
+ if( rising_edge(CLK) ) then
+ if( select_current_state = SELECT_ONE or select_current_state = PROCESS_REQUEST ) then
+ TC_DATA_OUT <= tc_data((index + 1) * 9 - 1 downto index * 9);
+ TC_FRAME_SIZE_OUT <= tc_size((index + 1) * 16 - 1 downto index * 16);
+ TC_FRAME_TYPE_OUT <= tc_type((index + 1) * 16 - 1 downto index * 16);
+ TC_DEST_MAC_OUT <= tc_mac((index + 1) * 48 - 1 downto index * 48);
+ TC_DEST_IP_OUT <= tc_ip((index + 1) * 32 - 1 downto index * 32);
+ TC_DEST_UDP_OUT <= tc_udp((index + 1) * 16 - 1 downto index * 16);
+ TC_SRC_MAC_OUT <= tc_src_mac((index + 1) * 48 - 1 downto index * 48);
+ TC_SRC_IP_OUT <= tc_src_ip((index + 1) * 32 - 1 downto index * 32);
+ TC_SRC_UDP_OUT <= tc_src_udp((index + 1) * 16 - 1 downto index * 16);
+ TC_IP_PROTOCOL_OUT <= tc_ip_proto((index + 1) * 8 - 1 downto index * 8);
+ TC_IDENT_OUT <= tc_ident((index + 1) * 16 - 1 downto index * 16);
+ if( select_current_state = SELECT_ONE ) then
+ PS_RESPONSE_READY_OUT <= '1';
+ selected(index) <= '0';
+ else
+ PS_RESPONSE_READY_OUT <= '0';
+ selected(index) <= '1';
+ end if;
+ else
+ TC_DATA_OUT <= (others => '0');
+ TC_FRAME_SIZE_OUT <= (others => '0');
+ TC_FRAME_TYPE_OUT <= (others => '0');
+ TC_DEST_MAC_OUT <= (others => '0');
+ TC_DEST_IP_OUT <= (others => '0');
+ TC_DEST_UDP_OUT <= (others => '0');
+ TC_SRC_MAC_OUT <= (others => '0');
+ TC_SRC_IP_OUT <= (others => '0');
+ TC_SRC_UDP_OUT <= (others => '0');
+ TC_IP_PROTOCOL_OUT <= (others => '0');
+ TC_IDENT_OUT <= (others => '0');
+ PS_RESPONSE_READY_OUT <= '0';
+ selected <= (others => '0');
+ end if;
+ end if;
+ end process PROC_SELECTOR;
+
+end gbe_protocol_selector_arch;
--- /dev/null
+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.gbe_protocols.all;
+
+entity gbe_receive_control is
+port (
+ CLK : in std_logic; -- system clock
+ RESET : in std_logic;
+-- signals to/from frame_receiver
+ RC_DATA_IN : in std_logic_vector(8 downto 0);
+ FR_RD_EN_OUT : out std_logic;
+ FR_FRAME_VALID_IN : in std_logic;
+ FR_GET_FRAME_OUT : out std_logic;
+ FR_FRAME_SIZE_IN : in std_logic_vector(15 downto 0);
+ FR_FRAME_PROTO_IN : in std_logic_vector(15 downto 0);
+ FR_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0);
+
+ FR_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);
+ FR_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);
+ FR_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);
+ FR_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);
+ FR_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0);
+ FR_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0);
+ -- signals to/from main controller
+ RC_RD_EN_IN : in std_logic;
+ RC_Q_OUT : out std_logic_vector(8 downto 0);
+ RC_FRAME_WAITING_OUT : out std_logic;
+ RC_LOADING_DONE_IN : in std_logic;
+ RC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0);
+ RC_FRAME_PROTO_OUT : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+ RC_SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);
+ RC_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);
+ RC_SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);
+ RC_DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);
+ RC_SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0);
+ RC_DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0);
+ -- statistics
+ FRAMES_RECEIVED_OUT : out std_logic_vector(31 downto 0);
+ BYTES_RECEIVED_OUT : out std_logic_vector(31 downto 0);
+ --
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+);
+end gbe_receive_control;
+
+architecture gbe_receive_control_arch of gbe_receive_control is
+
+attribute syn_encoding : string;
+
+type load_states is (IDLE, PREPARE, WAIT_ONE, READY);
+signal load_current_state, load_next_state : load_states;
+attribute syn_encoding of load_current_state : signal is "onehot";
+
+signal frames_received_ctr : unsigned(31 downto 0);
+signal frames_readout_ctr : unsigned(31 downto 0);
+signal bytes_rec_ctr : unsigned(31 downto 0);
+
+signal state : std_logic_vector(3 downto 0);
+signal proto_code : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+signal reset_prioritizer : std_logic;
+signal frame_waiting : std_logic;
+
+-- debug only
+signal saved_proto : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+
+begin
+
+FR_RD_EN_OUT <= RC_RD_EN_IN;
+RC_Q_OUT <= RC_DATA_IN;
+RC_FRAME_SIZE_OUT <= FR_FRAME_SIZE_IN;
+RC_SRC_MAC_ADDRESS_OUT <= FR_SRC_MAC_ADDRESS_IN;
+RC_DEST_MAC_ADDRESS_OUT <= FR_DEST_MAC_ADDRESS_IN;
+RC_SRC_IP_ADDRESS_OUT <= FR_SRC_IP_ADDRESS_IN;
+RC_DEST_IP_ADDRESS_OUT <= FR_DEST_IP_ADDRESS_IN;
+RC_SRC_UDP_PORT_OUT <= FR_SRC_UDP_PORT_IN;
+RC_DEST_UDP_PORT_OUT <= FR_DEST_UDP_PORT_IN;
+
+protocol_prioritizer: entity gbe_protocol_prioritizer
+port map(
+ CLK => CLK,
+ RESET => reset_prioritizer,
+ --
+ FRAME_TYPE_IN => FR_FRAME_PROTO_IN,
+ PROTOCOL_CODE_IN => FR_IP_PROTOCOL_IN,
+ UDP_PROTOCOL_IN => FR_DEST_UDP_PORT_IN,
+ --
+ CODE_OUT => proto_code
+);
+
+reset_prioritizer <= '1' when load_current_state = IDLE else '0';
+
+RC_FRAME_PROTO_OUT <= proto_code; -- no more ones as the incorrect value, last slot for Trash
+
+LOAD_MACHINE_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ load_current_state <= IDLE;
+ elsif( rising_edge(CLK) ) then
+ load_current_state <= load_next_state;
+ end if;
+end process LOAD_MACHINE_PROC;
+
+LOAD_MACHINE: process( load_current_state, frames_readout_ctr, frames_received_ctr, RC_LOADING_DONE_IN )
+begin
+ case load_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ if( frames_readout_ctr /= frames_received_ctr ) then -- frame is still waiting in frame_receiver
+ load_next_state <= PREPARE;
+ else
+ load_next_state <= IDLE;
+ end if;
+
+ when PREPARE => -- prepare frame size
+ state <= x"2";
+ load_next_state <= WAIT_ONE;
+
+ when WAIT_ONE =>
+ load_next_state <= READY;
+
+ when READY => -- wait for reading out the whole frame
+ state <= x"3";
+ if( RC_LOADING_DONE_IN = '1' ) then
+ load_next_state <= IDLE;
+ else
+ load_next_state <= READY;
+ end if;
+
+ end case;
+end process LOAD_MACHINE;
+
+process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( load_current_state = PREPARE ) then
+ FR_GET_FRAME_OUT <= '1';
+ else
+ FR_GET_FRAME_OUT <= '0';
+ end if;
+
+ if( (load_current_state = READY) and (RC_LOADING_DONE_IN = '0') ) then
+ RC_FRAME_WAITING_OUT <= '1';
+ else
+ RC_FRAME_WAITING_OUT <= '0';
+ end if;
+ end if;
+end process;
+
+FRAMES_REC_CTR_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ frames_received_ctr <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( FR_FRAME_VALID_IN = '1' ) then
+ frames_received_ctr <= frames_received_ctr + 1;
+ end if;
+ end if;
+end process FRAMES_REC_CTR_PROC;
+
+FRAMES_READOUT_CTR_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ frames_readout_ctr <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( RC_LOADING_DONE_IN = '1' ) then
+ frames_readout_ctr <= frames_readout_ctr + 1;
+ end if;
+ end if;
+end process FRAMES_READOUT_CTR_PROC;
+
+-- debug only
+BYTES_REC_CTR_PROC : process( CLK )
+begin
+ if ( RESET = '1' ) then
+ bytes_rec_ctr <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( FR_FRAME_VALID_IN = '1' ) then
+ bytes_rec_ctr <= bytes_rec_ctr + unsigned(FR_FRAME_SIZE_IN);
+ end if;
+ end if;
+end process BYTES_REC_CTR_PROC;
+
+SAVED_PROTO_PROC : process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( load_current_state = READY ) then
+ if( and_all(proto_code) = '0' ) then
+ saved_proto <= proto_code;
+ else
+ saved_proto <= (others => '0');
+ end if;
+ else
+ saved_proto <= saved_proto;
+ end if;
+ end if;
+end process SAVED_PROTO_PROC;
+
+end gbe_receive_control_arch;
--- /dev/null
+library ieee;\r
+ use ieee.std_logic_1164.all;\r
+ use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity gbe_rx_rb is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ -- MAC interface (RX)\r
+ MAC_RX_DATA_IN : in std_logic_vector(7 downto 0); -- RX data from TSMAC\r
+ MAC_RX_WR_IN : in std_logic; -- RX data write from TSMAC\r
+ MAC_RX_EOF_IN : in std_logic; -- RX EndOfFrame from TSMAC\r
+ MAC_RX_ERROR_IN : in std_logic; -- RX Error from TSMAC\r
+ MAC_RX_FIFOFULL_OUT : out std_logic;\r
+ -- FIFO interface (TX)\r
+ FIFO_FULL_IN : in std_logic; -- TX fifo full, delay read from ring buffer\r
+ FIFO_WR_OUT : out std_logic; -- TX fifo write\r
+ FIFO_Q_OUT : out std_logic_vector(8 downto 0); -- TX data\r
+ FRAME_REQ_IN : in std_logic; -- one pulse starts readout of frame stored in ring buffer\r
+ FRAME_ACK_OUT : out std_logic; -- one pulse for "end of frame"\r
+ FRAME_AVAIL_OUT : out std_logic; -- number of frames stored in ring buffer\r
+ FRAME_START_OUT : out std_logic -- StartOfFrame signal\r
+ );\r
+end entity gbe_rx_rb;\r
+\r
+-- This entity acts as receive buffer for the new GbE media interface. It connects to the MAC RX ports,\r
+-- and is storing incoming Ethernet frames. \r
+-- Broken frames (indicated by MAC_RX_ERROR_IN) are dropped, and in addition, frames which can't be stored\r
+-- completely (due to potential ring buffer overflow) are also dropped.\r
+-- This entity can forward frames on request by doing "DMA":\r
+-- If a frame is requested by FRAME_REQ_IN, the entity decides if a full frame is available (as shown by\r
+-- FRAME_AVAIL_OUT), in case no data is present, a FRAME_ACK_OUT is generated to avoid deadlocks, but\r
+-- no data is transfered.\r
+-- If a frame can be transfered, FRAME_START_OUT is set for one cycle, and data is written out \r
+-- (handshaking with FIFO_FULL_IN) on FIFO_Q_OUT, with data validated by FIFO_WR_OUT.\r
+-- With the EOF signal (FIFO_Q_OUT(8)) set FRAME_ACK_OUT is also set and the transfer ends.\r
+\r
+architecture gbe_rx_rb_arch of gbe_rx_rb is\r
+\r
+-- state machine signals\r
+ type state_t is (RX_DENY,RX_READY,RX_FRAME,FRAME_OK,FRAME_BAD,FORWARD,SKIP);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal rd_ptr : unsigned(11 downto 0);\r
+ signal wr_ptr : unsigned(11 downto 0);\r
+ signal last_wr_ptr : std_logic_vector(11 downto 0);\r
+ signal rb_used_x : unsigned(11 downto 0);\r
+ signal rb_full_x : std_logic;\r
+ signal rb_empty_x : std_logic;\r
+ signal ce_wr_ptr_x : std_logic;\r
+ signal ld_wr_ptr_x : std_logic;\r
+ signal ce_rd_ptr_x : std_logic;\r
+ signal wr_ram_x : std_logic;\r
+ signal rd_ram_x : std_logic;\r
+ signal ram_q : std_logic_vector(8 downto 0);\r
+ signal frame_requested : std_logic;\r
+ signal frame_acknowledged : std_logic;\r
+ signal fifo_wr_int : std_logic;\r
+ signal empty_read_ack : std_logic;\r
+ signal normal_read_ack_x : std_logic;\r
+ signal sof_int : std_logic;\r
+ signal frames_avail : unsigned(7 downto 0);\r
+ signal frame_active : std_logic;\r
+ signal frame_error : std_logic;\r
+ \r
+begin\r
+\r
+ -- FrameActive: we must not change to "receive" in the middle of a frame\r
+ -- when "buffer full" condition is deasserted.\r
+ -- Needs to be extra process, not inside the state machine!\r
+ PROC_FRAME_ACTIVE: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ frame_active <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( (MAC_RX_WR_IN = '1') and (frame_active = '0') ) then\r
+ frame_active <= '1';\r
+ elsif( (MAC_RX_EOF_IN = '1') and (frame_active = '1') ) then\r
+ frame_active <= '0';\r
+ end if;\r
+ end if;\r
+ end process PROC_FRAME_ACTIVE;\r
+\r
+ -- Read pointer for ring buffer\r
+ PROC_RD_PTR: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ rd_ptr <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( ce_rd_ptr_x = '1' ) then\r
+ rd_ptr <= rd_ptr + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_RD_PTR;\r
+\r
+ -- Write pointer for ring buffer\r
+ PROC_WR_PTR: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ wr_ptr <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( ld_wr_ptr_x = '1' ) then\r
+ wr_ptr <= unsigned(last_wr_ptr);\r
+ elsif( ce_wr_ptr_x = '1' ) then\r
+ wr_ptr <= wr_ptr + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_WR_PTR;\r
+\r
+ -- last write pointer: used to drop a broken frame, in case\r
+ PROC_LAST_WR_PTR: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ last_wr_ptr <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( (STATE = RX_READY) and (MAC_RX_WR_IN = '1') ) then\r
+ last_wr_ptr <= std_logic_vector(wr_ptr);\r
+ end if;\r
+ end if;\r
+ end process PROC_LAST_WR_PTR;\r
+\r
+ -- ring buffer fill level\r
+ rb_used_x <= wr_ptr - rd_ptr;\r
+ \r
+ -- ring buffer full \r
+ -- TAKE CARE: the last byte of a frame is taken into account\r
+ -- by "one less" for the full condition\r
+ rb_full_x <= '1' when (rb_used_x(11 downto 1) = b"1111_1111_111") else '0';\r
+\r
+ -- ring buffer empty\r
+ rb_empty_x <= '1' when (rb_used_x(11 downto 0) = b"0000_0000_0000") else '0';\r
+\r
+ MAC_RX_FIFOFULL_OUT <= rb_full_x;\r
+ \r
+ -- DPRAM as ring buffer\r
+ THE_DP_RAM: entity work.rb_4k_9\r
+ port map(\r
+ WRADDRESS => std_logic_vector(wr_ptr),\r
+ RDADDRESS => std_logic_vector(rd_ptr),\r
+ DATA(8) => MAC_RX_EOF_IN,\r
+ DATA(7 downto 0) => MAC_RX_DATA_IN,\r
+ WE => wr_ram_x,\r
+ RDCLOCK => CLK,\r
+ RDCLOCKEN => '1',\r
+ RESET => RESET,\r
+ WRCLOCK => CLK,\r
+ WRCLOCKEN => '1',\r
+ Q => ram_q\r
+ );\r
+\r
+ -- write signal \r
+ wr_ram_x <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or -- first byte of frame\r
+ ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) -- all other bytes of frame\r
+ else '0';\r
+ ce_wr_ptr_x <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or\r
+ ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) \r
+ else '0';\r
+\r
+ -- FrameError: catches problem with FIFOFULL during a frame write.\r
+ PROC_FRAME_ERROR: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ frame_error <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( (frame_active = '1') and (rb_full_x = '1') and (MAC_RX_WR_IN = '1') ) then\r
+ frame_error <= '1';\r
+ elsif( (frame_active = '0') ) then -- could be better!\r
+ frame_error <= '0';\r
+ end if;\r
+ end if;\r
+ end process PROC_FRAME_ERROR;\r
+ \r
+ -- FrameReq signal, one pulse only\r
+ PROC_FRAME_REQ: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ frame_requested <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( (FRAME_REQ_IN = '1') and (frame_requested = '0') ) then\r
+ frame_requested <= '1';\r
+ elsif( ((ram_q(8) = '1') and (frame_requested = '1')) or (empty_read_ack = '1') ) then\r
+ frame_requested <= '0';\r
+ end if;\r
+ end if;\r
+ end process PROC_FRAME_REQ;\r
+ \r
+ -- NormalReadAck signal: ends a normal data transfer by EOF\r
+ normal_read_ack_x <= ram_q(8) and fifo_wr_int;\r
+ \r
+ -- read signal\r
+ rd_ram_x <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0';\r
+ ce_rd_ptr_x <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0';\r
+\r
+ empty_read_ack <= FRAME_REQ_IN and rb_empty_x when rising_edge(CLK);\r
+ sof_int <= FRAME_REQ_IN and not frame_requested when rising_edge(CLK); \r
+ FRAME_START_OUT <= sof_int when rising_edge(CLK);\r
+ fifo_wr_int <= rd_ram_x when rising_edge(CLK);\r
+ FIFO_WR_OUT <= fifo_wr_int when rising_edge(CLK);\r
+ FRAME_ACK_OUT <= normal_read_ack_x or empty_read_ack when rising_edge(CLK); \r
+ FIFO_Q_OUT <= ram_q when rising_edge(CLK);\r
+ \r
+ -- FramesAvailable counter\r
+ PROC_FRAMES_AVAIL: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ frames_avail <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( (STATE = FRAME_OK) and (normal_read_ack_x = '0') ) then\r
+ -- one frame written successfully\r
+ frames_avail <= frames_avail + 1;\r
+ elsif( (STATE /= FRAME_OK) and (normal_read_ack_x = '1') ) then\r
+ -- one frame read successfully\r
+ frames_avail <= frames_avail - 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_FRAMES_AVAIL;\r
+ \r
+ FRAME_AVAIL_OUT <= '1' when (frames_avail /= x"00") else '0';\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ PROC_FSM: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ STATE <= RX_DENY;\r
+ elsif( rising_edge(CLK) ) then\r
+ STATE <= NEXT_STATE;\r
+ end if;\r
+ end process PROC_FSM;\r
+\r
+ PROC_STATE_TRANSITIONS: process( STATE, MAC_RX_WR_IN, MAC_RX_EOF_IN, MAC_RX_ERROR_IN, frame_active, rb_full_x )\r
+ begin\r
+ ld_wr_ptr_x <= '0';\r
+ \r
+ case STATE is\r
+\r
+ when RX_DENY =>\r
+ if( (frame_active = '0') and (rb_full_x = '0') ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+ \r
+ when RX_READY =>\r
+ if( MAC_RX_WR_IN = '1' ) then\r
+ NEXT_STATE <= RX_FRAME;\r
+ else\r
+ NEXT_STATE <= RX_READY;\r
+ end if;\r
+ \r
+ when RX_FRAME =>\r
+ if ( (MAC_RX_EOF_IN = '1') and (MAC_RX_ERROR_IN = '0') and (rb_full_x = '0') ) then\r
+ NEXT_STATE <= FRAME_OK;\r
+ elsif( (MAC_RX_EOF_IN = '1') and ((MAC_RX_ERROR_IN = '1') or (rb_full_x = '1')) ) then\r
+ NEXT_STATE <= FRAME_BAD;\r
+ ld_wr_ptr_x <= '1';\r
+ else\r
+ NEXT_STATE <= RX_FRAME;\r
+ end if;\r
+ \r
+ when FRAME_OK =>\r
+ NEXT_STATE <= FORWARD;\r
+ \r
+ when FORWARD =>\r
+ if( rb_full_x = '0' ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+\r
+ when FRAME_BAD =>\r
+ NEXT_STATE <= SKIP;\r
+ \r
+ when SKIP =>\r
+ if( rb_full_x = '0' ) then\r
+ NEXT_STATE <= RX_READY;\r
+ else\r
+ NEXT_STATE <= RX_DENY;\r
+ end if;\r
+\r
+ when others =>\r
+ NEXT_STATE <= RX_DENY;\r
+ end case;\r
+ end process PROC_STATE_TRANSITIONS;\r
+\r
+end architecture gbe_rx_rb_arch;\r
--- /dev/null
+library ieee;\r
+ use ieee.std_logic_1164.all;\r
+ use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity gbe_sgl_ctrl is\r
+ port(\r
+ CLK : in std_logic;\r
+ RESET : in std_logic;\r
+ -- UL port\r
+ UL_FIFOFULL_IN : in std_logic := '0'; -- UL TX FIFO is full\r
+ UL_FRAME_AVAIL_IN : in std_logic := '0'; -- UL RX has frames available for scattering\r
+ UL_FRAME_REQ_OUT : out std_logic; -- UL RX request to send\r
+ UL_FRAME_ACK_IN : in std_logic := '0'; -- UL RX sent acknowledge\r
+ -- DL ports (includes SCTRL)\r
+ DL_FIFOFULL_IN : in std_logic_vector(15 downto 0) := (others => '0'); -- DL TXn FIFO is full\r
+ DL_FRAME_AVAIL_IN : in std_logic_vector(15 downto 0) := (others => '0'); -- DL RXn has frames available for scattering\r
+ DL_FRAME_REQ_OUT : out std_logic_vector(15 downto 0); -- DL RXn request to send\r
+ DL_FRAME_ACK_IN : in std_logic_vector(15 downto 0) := (others => '0'); -- DL RXn sent acknowledge\r
+ -- LOCAL port\r
+ LOCAL_FIFOFULL_IN : in std_logic := '0'; -- LOCAL TX FIFO is full\r
+ LOCAL_FRAME_AVAIL_IN : in std_logic := '0'; -- LOCAL RX has frames available\r
+ LOCAL_FRAME_REQ_OUT : out std_logic; -- LOCAL RX request to send\r
+ LOCAL_FRAME_ACK_IN : in std_logic := '0'; -- LOCAL RX sent acknowledge\r
+ --\r
+ DL_RX_PORT_SEL_OUT : out std_logic_vector(15 downto 0);\r
+ DL_RX_PORT_MUX_OUT : out std_logic_vector(3 downto 0);\r
+ DL_TX_PORT_SEL_OUT : out std_logic; -- '0' => LOCAL, '1' UL\r
+ LOCAL_TX_PORT_SEL_OUT : out std_logic;\r
+ UL_TX_PORT_SEL_OUT : out std_logic;\r
+ --\r
+ DEBUG : out std_logic_vector(15 downto 0)\r
+ );\r
+end entity gbe_sgl_ctrl;\r
+\r
+architecture gbe_sgl_ctrl_arch of gbe_sgl_ctrl is\r
+\r
+-- Components\r
+\r
+-- state machine signals\r
+ type state_t is (IDLE,SC_START,SC_PORT,SC_DELAY,SC_CLEANUP,\r
+ GA_START,GA_STORE,GA_PORT,GA_DELAY,GA_CLEANUP,\r
+ LC_START,LC_PORT,LC_DELAY,LC_CLEANUP);\r
+ signal STATE, NEXT_STATE : state_t;\r
+\r
+-- Signals\r
+ signal scatter_fifofull_x : std_logic;\r
+ signal gather_fifofull_x : std_logic;\r
+ signal local_fifofull_x : std_logic;\r
+ signal gather_needed_x : std_logic;\r
+ signal store_ports_x : std_logic;\r
+ signal stored_ports : std_logic_vector(15 downto 0);\r
+ signal all_ports_done_x : std_logic;\r
+ signal select_ports : std_logic_vector(15 downto 0);\r
+ signal req_ports : std_logic_vector(15 downto 0);\r
+ signal next_mux_x : std_logic_vector(3 downto 0);\r
+ signal mux_ports : std_logic_vector(3 downto 0);\r
+ signal next_port_x : std_logic_vector(15 downto 0);\r
+\r
+ signal ul_frame_req_x : std_logic;\r
+ signal ul_frame_req : std_logic;\r
+ signal local_frame_req_x : std_logic;\r
+ signal local_frame_req : std_logic;\r
+\r
+ signal dl_tx_port_sel_x : std_logic;\r
+ signal local_tx_port_sel_x : std_logic;\r
+ signal ul_tx_port_sel_x : std_logic;\r
+\r
+ signal bsm : std_logic_vector(3 downto 0);\r
+ \r
+begin\r
+\r
+ -- Debug signals for hardware\r
+ DEBUG(15 downto 4) <= (others => '0');\r
+ DEBUG(3 downto 0) <= bsm;\r
+\r
+ -- SCATTER: fifofull is created from DL and LOCAL ports (not SCTRL)\r
+ scatter_fifofull_x <= '1' when ((DL_FIFOFULL_IN(15 downto 1) /= b"0000_0000_0000_000") or (LOCAL_FIFOFULL_IN = '1'))\r
+ else '0';\r
+\r
+ -- GATHER: fifofull is created from UL and LOCAL\r
+ gather_fifofull_x <= '1' when ((UL_FIFOFULL_IN = '1') or (LOCAL_FIFOFULL_IN = '1'))\r
+ else '0';\r
+\r
+ -- LOCAL: fifofull is created from UL and DL ()\r
+ local_fifofull_x <= '1' when ((DL_FIFOFULL_IN(15 downto 1) /= b"0000_0000_0000_000") or (UL_FIFOFULL_IN = '1'))\r
+ else '0';\r
+\r
+ -- GATHER:\r
+ gather_needed_x <= '1' when (DL_FRAME_AVAIL_IN /= x"0000")\r
+ else '0';\r
+\r
+ -- store the src port status\r
+ GEN_REGS: for I in 0 to 15 generate\r
+ THE_SRC_STORE_PROC: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ stored_ports(I) <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ if ( store_ports_x = '1' ) then\r
+ stored_ports(I) <= DL_FRAME_AVAIL_IN(I);\r
+ elsif( DL_FRAME_ACK_IN(I) = '1' ) then\r
+ stored_ports(I) <= '0';\r
+ end if;\r
+ end if;\r
+ end process THE_SRC_STORE_PROC;\r
+ end generate;\r
+\r
+ all_ports_done_x <= '1' when stored_ports = x"0000" else '0';\r
+\r
+ -- select the port data\r
+ THE_SELECT_PORT_PROC: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ select_ports <= (others => '0');\r
+ mux_ports <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ select_ports <= next_port_x;\r
+ mux_ports <= next_mux_x;\r
+ end if;\r
+ end process THE_SELECT_PORT_PROC;\r
+\r
+ DL_RX_PORT_SEL_OUT <= select_ports;\r
+ DL_RX_PORT_MUX_OUT <= mux_ports;\r
+\r
+ -- port frame request, one clock cycle pulse\r
+ req_ports <= not select_ports and next_port_x when rising_edge(CLK);\r
+\r
+ DL_FRAME_REQ_OUT <= req_ports;\r
+\r
+ -- priority decoced "next port to serve" signals\r
+ THE_NEXT_PORT_PROC: process( stored_ports )\r
+ begin\r
+ if ( stored_ports(0) = '1' ) then\r
+ next_port_x <= x"0001";\r
+ next_mux_x <= x"0";\r
+ elsif( stored_ports(1) = '1' ) then\r
+ next_port_x <= x"0002";\r
+ next_mux_x <= x"1";\r
+ elsif( stored_ports(2) = '1' ) then\r
+ next_port_x <= x"0004";\r
+ next_mux_x <= x"2";\r
+ elsif( stored_ports(3) = '1' ) then\r
+ next_port_x <= x"0008";\r
+ next_mux_x <= x"3";\r
+ elsif( stored_ports(4) = '1' ) then\r
+ next_port_x <= x"0010";\r
+ next_mux_x <= x"4";\r
+ elsif( stored_ports(5) = '1' ) then\r
+ next_port_x <= x"0020";\r
+ next_mux_x <= x"5";\r
+ elsif( stored_ports(6) = '1' ) then\r
+ next_port_x <= x"0040";\r
+ next_mux_x <= x"6";\r
+ elsif( stored_ports(7) = '1' ) then\r
+ next_port_x <= x"0080";\r
+ next_mux_x <= x"7";\r
+ elsif( stored_ports(8) = '1' ) then\r
+ next_port_x <= x"0100";\r
+ next_mux_x <= x"8";\r
+ elsif( stored_ports(9) = '1' ) then\r
+ next_port_x <= x"0200";\r
+ next_mux_x <= x"9";\r
+ elsif( stored_ports(10) = '1' ) then\r
+ next_port_x <= x"0400";\r
+ next_mux_x <= x"a";\r
+ elsif( stored_ports(11) = '1' ) then\r
+ next_port_x <= x"0800";\r
+ next_mux_x <= x"b";\r
+ elsif( stored_ports(12) = '1' ) then\r
+ next_port_x <= x"1000";\r
+ next_mux_x <= x"c";\r
+ elsif( stored_ports(13) = '1' ) then\r
+ next_port_x <= x"2000";\r
+ next_mux_x <= x"d";\r
+ elsif( stored_ports(14) = '1' ) then\r
+ next_port_x <= x"4000";\r
+ next_mux_x <= x"e";\r
+ elsif( stored_ports(15) = '1' ) then\r
+ next_port_x <= x"8000";\r
+ next_mux_x <= x"f";\r
+ else\r
+ next_port_x <= x"0000";\r
+ next_mux_x <= x"0";\r
+ end if;\r
+ end process THE_NEXT_PORT_PROC;\r
+\r
+ -----------------------------------------------------------\r
+ -- Outputs\r
+ -----------------------------------------------------------\r
+ UL_FRAME_REQ_OUT <= ul_frame_req;\r
+ LOCAL_FRAME_REQ_OUT <= local_frame_req;\r
+ DL_TX_PORT_SEL_OUT <= dl_tx_port_sel_x;\r
+ LOCAL_TX_PORT_SEL_OUT <= local_tx_port_sel_x;\r
+ UL_TX_PORT_SEL_OUT <= ul_tx_port_sel_x;\r
+\r
+ -----------------------------------------------------------\r
+ -- statemachine: clocked process\r
+ -----------------------------------------------------------\r
+ THE_FSM: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ STATE <= IDLE;\r
+ ul_frame_req <= '0';\r
+ local_frame_req <= '0';\r
+ elsif( rising_edge(CLK) ) then\r
+ STATE <= NEXT_STATE;\r
+ ul_frame_req <= ul_frame_req_x;\r
+ local_frame_req <= local_frame_req_x;\r
+ end if;\r
+ end process THE_FSM;\r
+\r
+ -----------------------------------------------------------\r
+ --\r
+ -----------------------------------------------------------\r
+ THE_STATE_TRANSITIONS: process( STATE, UL_FRAME_AVAIL_IN, LOCAL_FRAME_AVAIL_IN, UL_FRAME_ACK_IN,\r
+ LOCAL_FRAME_ACK_IN, scatter_fifofull_x, gather_fifofull_x,\r
+ local_fifofull_x, all_ports_done_x )\r
+ begin\r
+ ul_frame_req_x <= '0';\r
+ local_frame_req_x <= '0';\r
+ store_ports_x <= '0';\r
+ dl_tx_port_sel_x <= '0';\r
+ local_tx_port_sel_x <= '0';\r
+ ul_tx_port_sel_x <= '0';\r
+\r
+ case STATE is\r
+ when IDLE =>\r
+ bsm <= x"0";\r
+ if ( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+ NEXT_STATE <= SC_START;\r
+ elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+ NEXT_STATE <= GA_START;\r
+ elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+ NEXT_STATE <= LC_START;\r
+ else \r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when SC_START =>\r
+ bsm <= x"1";\r
+ NEXT_STATE <= SC_PORT;\r
+ ul_frame_req_x <= '1';\r
+ dl_tx_port_sel_x <= '1';\r
+ local_tx_port_sel_x <= '1';\r
+\r
+ when SC_PORT =>\r
+ bsm <= x"2";\r
+ if( UL_FRAME_ACK_IN = '1' ) then\r
+ NEXT_STATE <= SC_DELAY;\r
+ else\r
+ NEXT_STATE <= SC_PORT;\r
+ end if;\r
+ dl_tx_port_sel_x <= '1';\r
+ local_tx_port_sel_x <= '1';\r
+\r
+ when SC_DELAY =>\r
+ bsm <= x"3";\r
+ NEXT_STATE <= SC_CLEANUP;\r
+ dl_tx_port_sel_x <= '1';\r
+ local_tx_port_sel_x <= '1';\r
+\r
+ when SC_CLEANUP =>\r
+ bsm <= x"4";\r
+ if ( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+ NEXT_STATE <= GA_START;\r
+ elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+ NEXT_STATE <= LC_START;\r
+ elsif( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+ NEXT_STATE <= SC_START;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+ dl_tx_port_sel_x <= '1'; -- maybe not needed\r
+ local_tx_port_sel_x <= '1'; -- maybe not needed\r
+\r
+ when GA_START =>\r
+ bsm <= x"5";\r
+ NEXT_STATE <= GA_STORE;\r
+ store_ports_x <= '1';\r
+ ul_tx_port_sel_x <= '1';\r
+\r
+ when GA_STORE =>\r
+ bsm <= x"6";\r
+ NEXT_STATE <= GA_PORT;\r
+ ul_tx_port_sel_x <= '1';\r
+\r
+ when GA_PORT =>\r
+ bsm <= x"7";\r
+ if( all_ports_done_x = '1' ) then\r
+ NEXT_STATE <= GA_DELAY;\r
+ else\r
+ NEXT_STATE <= GA_PORT;\r
+ end if;\r
+ ul_tx_port_sel_x <= '1';\r
+\r
+ when GA_DELAY =>\r
+ bsm <= x"8";\r
+ NEXT_STATE <= GA_CLEANUP;\r
+ ul_tx_port_sel_x <= '1';\r
+\r
+ when GA_CLEANUP =>\r
+ bsm <= x"9";\r
+ if ( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+ NEXT_STATE <= LC_START;\r
+ elsif( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+ NEXT_STATE <= SC_START;\r
+ elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+ NEXT_STATE <= GA_START;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+ ul_tx_port_sel_x <= '1'; -- maybe not needed\r
+\r
+ when LC_START =>\r
+ bsm <= x"a";\r
+ NEXT_STATE <= LC_PORT;\r
+ local_frame_req_x <= '1';\r
+\r
+ when LC_PORT =>\r
+ bsm <= x"b";\r
+ if( LOCAL_FRAME_ACK_IN = '1' ) then\r
+ NEXT_STATE <= LC_DELAY;\r
+ else\r
+ NEXT_STATE <= LC_PORT;\r
+ end if;\r
+\r
+ when LC_DELAY =>\r
+ bsm <= x"c";\r
+ NEXT_STATE <= LC_CLEANUP;\r
+\r
+ when LC_CLEANUP =>\r
+ bsm <= x"d";\r
+ if ( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+ NEXT_STATE <= SC_START;\r
+ elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+ NEXT_STATE <= GA_START;\r
+ elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+ NEXT_STATE <= LC_START;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when others =>\r
+ bsm <= x"f";\r
+ NEXT_STATE <= IDLE;\r
+ end case;\r
+ end process THE_STATE_TRANSITIONS;\r
+\r
+end architecture gbe_sgl_ctrl_arch;\r
--- /dev/null
+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.gbe_protocols.all;
+
+entity gbe_transmit_control is
+port (
+ CLK : in std_logic;
+ RESET : in std_logic;
+-- signal to/from main controller
+ TC_DATAREADY_IN : in std_logic;
+ TC_RD_EN_OUT : out std_logic;
+ TC_DATA_IN : in std_logic_vector(7 downto 0);
+ TC_FRAME_SIZE_IN : in std_logic_vector(15 downto 0);
+ TC_FRAME_TYPE_IN : in std_logic_vector(15 downto 0);
+ TC_IP_PROTOCOL_IN : in std_logic_vector(7 downto 0);
+ TC_DEST_MAC_IN : in std_logic_vector(47 downto 0);
+ TC_DEST_IP_IN : in std_logic_vector(31 downto 0);
+ TC_DEST_UDP_IN : in std_logic_vector(15 downto 0);
+ TC_SRC_MAC_IN : in std_logic_vector(47 downto 0);
+ TC_SRC_IP_IN : in std_logic_vector(31 downto 0);
+ TC_SRC_UDP_IN : in std_logic_vector(15 downto 0);
+ TC_TRANSMISSION_DONE_OUT : out std_logic;
+ TC_IDENT_IN : in std_logic_vector(15 downto 0);
+ TC_MAX_FRAME_IN : in std_logic_vector(15 downto 0);
+-- signal to/from frame constructor
+ FC_DATA_OUT : out std_logic_vector(7 downto 0);
+ FC_WR_EN_OUT : out std_logic;
+ FC_READY_IN : in std_logic;
+ FC_H_READY_IN : in std_logic;
+ FC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0);
+ FC_IP_SIZE_OUT : out std_logic_vector(15 downto 0);
+ FC_UDP_SIZE_OUT : out std_logic_vector(15 downto 0);
+ FC_IDENT_OUT : out std_logic_vector(15 downto 0); -- internal packet counter
+ FC_FLAGS_OFFSET_OUT : out std_logic_vector(15 downto 0);
+ FC_SOD_OUT : out std_logic;
+ FC_EOD_OUT : out std_logic;
+ FC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0);
+--
+ DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);
+ DEST_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);
+ DEST_UDP_PORT_OUT : out std_logic_vector(15 downto 0);
+ SRC_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);
+ SRC_IP_ADDRESS_OUT : out std_logic_vector(31 downto 0);
+ SRC_UDP_PORT_OUT : out std_logic_vector(15 downto 0);
+--
+ MONITOR_TX_PACKETS_OUT : out std_logic_vector(31 downto 0);
+--
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+);
+end gbe_transmit_control;
+
+architecture gbe_transmit_control_arch of gbe_transmit_control is
+
+attribute syn_encoding : string;
+
+type transmit_states is (IDLE, PREPARE_HEADERS, WAIT_FOR_H, TRANSMIT, SEND_ONE, SEND_TWO, CLOSE, WAIT_FOR_TRANS, DIVIDE, CLEANUP);
+signal transmit_current_state, transmit_next_state : transmit_states;
+attribute syn_encoding of transmit_current_state : signal is "onehot";
+
+signal tc_rd, tc_rd_q, tc_rd_qq : std_logic;
+signal local_end : std_logic_vector(15 downto 0);
+
+signal actual_frame_bytes, full_packet_size, ip_size, packet_loaded_bytes : std_logic_vector(15 downto 0);
+signal go_to_divide, more_fragments : std_logic;
+signal first_frame : std_logic;
+signal mon_packets_sent_ctr : std_logic_vector(31 downto 0);
+signal state : std_logic_vector(3 downto 0);
+
+begin
+
+TRANSMIT_MACHINE_PROC : process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ transmit_current_state <= IDLE;
+ elsif( rising_edge(CLK) ) then
+ transmit_current_state <= transmit_next_state;
+ end if;
+end process TRANSMIT_MACHINE_PROC;
+
+TRANSMIT_MACHINE : process(transmit_current_state, FC_H_READY_IN, TC_DATAREADY_IN, FC_READY_IN, local_end, TC_MAX_FRAME_IN, actual_frame_bytes, go_to_divide)
+begin
+ state <= x"0";
+ case transmit_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ if (TC_DATAREADY_IN = '1') then
+ transmit_next_state <= PREPARE_HEADERS;
+ else
+ transmit_next_state <= IDLE;
+ end if;
+
+ when PREPARE_HEADERS =>
+ state <= x"2";
+ transmit_next_state<= WAIT_FOR_H;
+
+ when WAIT_FOR_H =>
+ state <= x"3";
+ if (FC_H_READY_IN = '1') then
+ transmit_next_state <= TRANSMIT;
+ else
+ transmit_next_state <= WAIT_FOR_H;
+ end if;
+
+ when TRANSMIT =>
+ state <= x"4";
+ if (local_end = x"0000") then
+ transmit_next_state <= SEND_ONE;
+ else
+ if (actual_frame_bytes = TC_MAX_FRAME_IN - x"1") then
+ transmit_next_state <= SEND_ONE;
+ else
+ transmit_next_state <= TRANSMIT;
+ end if;
+ end if;
+
+ when SEND_ONE =>
+ state <= x"5";
+ transmit_next_state <= SEND_TWO;
+
+ when SEND_TWO =>
+ state <= x"6";
+ transmit_next_state <= CLOSE;
+
+ when CLOSE =>
+ state <= x"7";
+ transmit_next_state <= WAIT_FOR_TRANS;
+
+ when WAIT_FOR_TRANS =>
+ state <= x"8";
+ if (FC_READY_IN = '1') then
+ if (go_to_divide = '1') then
+ transmit_next_state <= DIVIDE;
+ else
+ transmit_next_state <= CLEANUP;
+ end if;
+ else
+ transmit_next_state <= WAIT_FOR_TRANS;
+ end if;
+
+ when DIVIDE =>
+ state <= x"9";
+ transmit_next_state <= PREPARE_HEADERS;
+
+ when CLEANUP =>
+ state <= x"a";
+ transmit_next_state <= IDLE;
+
+ end case;
+end process TRANSMIT_MACHINE;
+
+tc_rd <= '1' when transmit_current_state = TRANSMIT else '0';
+
+TC_RD_EN_OUT <= tc_rd;
+
+SYNC_PROC : process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ tc_rd_q <= tc_rd;
+ tc_rd_qq <= tc_rd_q;
+ FC_WR_EN_OUT <= tc_rd_qq;
+ end if;
+end process SYNC_PROC;
+
+ACTUAL_FRAME_BYTES_PROC : process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( transmit_current_state = IDLE or transmit_current_state = DIVIDE ) then
+ actual_frame_bytes <= (others => '0');
+ elsif( transmit_current_state = TRANSMIT ) then
+ actual_frame_bytes <= actual_frame_bytes + x"1";
+ end if;
+ end if;
+end process ACTUAL_FRAME_BYTES_PROC;
+
+GO_TO_DIVIDE_PROC : process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( transmit_current_state = IDLE or transmit_current_state = DIVIDE ) then
+ go_to_divide <= '0';
+ elsif( transmit_current_state = TRANSMIT and actual_frame_bytes = TC_MAX_FRAME_IN - x"1" ) then
+ go_to_divide <= '1';
+ elsif( transmit_current_state = SEND_ONE and full_packet_size = packet_loaded_bytes ) then
+ go_to_divide <= '0';
+ end if;
+ end if;
+end process GO_TO_DIVIDE_PROC;
+
+LOCAL_END_PROC : process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( transmit_current_state = IDLE and TC_DATAREADY_IN = '1' ) then
+ local_end <= TC_FRAME_SIZE_IN - x"1";
+ full_packet_size <= TC_FRAME_SIZE_IN;
+ elsif( transmit_current_state = TRANSMIT ) then
+ local_end <= local_end - x"1";
+ full_packet_size <= full_packet_size;
+ end if;
+ end if;
+end process LOCAL_END_PROC;
+
+FC_DATA_OUT <= TC_DATA_IN;
+FC_SOD_OUT <= '1' when transmit_current_state = WAIT_FOR_H else '0';
+FC_EOD_OUT <= '1' when transmit_current_state = CLOSE else '0';
+
+process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( transmit_current_state = PREPARE_HEADERS ) then
+ if( local_end >= TC_MAX_FRAME_IN ) then
+ ip_size <= TC_MAX_FRAME_IN;
+ else
+ ip_size <= local_end + x"1";
+ end if;
+ else
+ ip_size <= ip_size;
+ end if;
+ end if;
+end process;
+FC_IP_SIZE_OUT <= ip_size;
+FC_UDP_SIZE_OUT <= full_packet_size;
+
+FC_FLAGS_OFFSET_OUT(15 downto 14) <= "00";
+FC_FLAGS_OFFSET_OUT(13) <= more_fragments;
+
+MORE_FRAGMENTS_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( transmit_current_state = PREPARE_HEADERS ) then
+ if( local_end >= TC_MAX_FRAME_IN ) then
+ more_fragments <= '1';
+ else
+ more_fragments <= '0';
+ end if;
+ end if;
+ end if;
+end process MORE_FRAGMENTS_PROC;
+
+FC_FLAGS_OFFSET_OUT(12 downto 0) <= ('0' & x"000") when first_frame = '1' else (packet_loaded_bytes(15 downto 3) + x"1");
+
+PACKET_LOADED_BYTES_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( transmit_current_state = IDLE ) then
+ packet_loaded_bytes <= x"0000";
+ elsif( transmit_current_state = TRANSMIT ) then
+ packet_loaded_bytes <= packet_loaded_bytes + x"1";
+ end if;
+ end if;
+end process PACKET_LOADED_BYTES_PROC;
+
+FIRST_FRAME_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( transmit_current_state = IDLE ) then
+ first_frame <= '1';
+ elsif( transmit_current_state = DIVIDE ) then
+ first_frame <= '0';
+ end if;
+ end if;
+end process FIRST_FRAME_PROC;
+
+
+TC_TRANSMISSION_DONE_OUT <= '1' when transmit_current_state = CLEANUP else '0';
+
+FC_FRAME_TYPE_OUT <= TC_FRAME_TYPE_IN;
+FC_IP_PROTOCOL_OUT <= TC_IP_PROTOCOL_IN;
+DEST_MAC_ADDRESS_OUT <= TC_DEST_MAC_IN;
+DEST_IP_ADDRESS_OUT <= TC_DEST_IP_IN;
+DEST_UDP_PORT_OUT <= TC_DEST_UDP_IN;
+SRC_MAC_ADDRESS_OUT <= TC_SRC_MAC_IN;
+SRC_IP_ADDRESS_OUT <= TC_SRC_IP_IN;
+SRC_UDP_PORT_OUT <= TC_SRC_UDP_IN;
+FC_IDENT_OUT <= TC_IDENT_IN;
+
+-- monitoring
+
+process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ mon_packets_sent_ctr <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( transmit_current_state = CLEANUP ) then
+ mon_packets_sent_ctr <= mon_packets_sent_ctr + x"1";
+ end if;
+ end if;
+end process;
+
+MONITOR_TX_PACKETS_OUT <= mon_packets_sent_ctr;
+
+DEBUG_OUT(3 downto 0) <= state;
+DEBUG_OUT(4) <= FC_READY_IN;
+
+end gbe_transmit_control_arch;
+
+
--- /dev/null
+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.gbe_protocols.all;
+
+--********
+-- contains valid frame types codes and performs checking of type and vlan id
+-- by default there is place for 32 frame type which is hardcoded value
+-- due to allow register which is set by slow control
+
+entity gbe_type_validator is
+port (
+ CLK : in std_logic; -- 125MHz clock input
+ RESET : in std_logic;
+ -- ethernet level
+ FRAME_TYPE_IN : in std_logic_vector(15 downto 0); -- recovered frame type
+ SAVED_VLAN_ID_IN : in std_logic_vector(15 downto 0); -- recovered vlan id
+ ALLOWED_TYPES_IN : in std_logic_vector(31 downto 0); -- signal from gbe_setup
+ VLAN_ID_IN : in std_logic_vector(31 downto 0); -- two values from gbe setup
+ -- IP level
+ IP_PROTOCOLS_IN : in std_logic_vector(7 downto 0);
+ ALLOWED_IP_PROTOCOLS_IN : in std_logic_vector(31 downto 0);
+ -- UDP level
+ UDP_PROTOCOL_IN : in std_logic_vector(15 downto 0);
+ ALLOWED_UDP_PROTOCOLS_IN : in std_logic_vector(31 downto 0);
+ -- result
+ VALID_OUT : out std_logic
+);
+end gbe_type_validator;
+
+architecture gbe_type_validator_arch of gbe_type_validator is
+
+signal result : std_logic_vector(c_MAX_FRAME_TYPES - 1 downto 0);
+signal ip_result : std_logic_vector(c_MAX_IP_PROTOCOLS - 1 downto 0);
+signal udp_result : std_logic_vector(c_MAX_UDP_PROTOCOLS - 1 downto 0);
+signal partially_valid : std_logic; -- only protocols, vlan to be checked
+signal zeros : std_logic_vector(c_MAX_FRAME_TYPES - 1 downto 0);
+
+begin
+
+ zeros <= (others => '0');
+
+-- checks for allowed IP protocols (UDP, ICMP)
+IP_RESULTS_GEN: for i in 0 to c_MAX_IP_PROTOCOLS - 1 generate
+process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( (IP_PROTOCOLS(i) = IP_PROTOCOLS_IN) and (ALLOWED_IP_PROTOCOLS_IN(i) = '1') )then
+ ip_result(i) <= '1';
+ else
+ ip_result(i) <= '0';
+ end if;
+ end if;
+end process;
+end generate IP_RESULTS_GEN;
+
+-- checks for allowed UDP destination ports (DHCP, SCTRL)
+UDP_RESULTS_GEN: for i in 0 to c_MAX_UDP_PROTOCOLS - 1 generate
+process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( (UDP_PROTOCOLS(i) = UDP_PROTOCOL_IN) and (ALLOWED_UDP_PROTOCOLS_IN(i) = '1') ) then
+ udp_result(i) <= '1';
+ else
+ udp_result(i) <= '0';
+ end if;
+ end if;
+end process;
+end generate UDP_RESULTS_GEN;
+
+-- checks for allowed frame type (IPv4, ARP)
+FRAME_RESULTS_GEN: for i in 0 to c_MAX_FRAME_TYPES - 1 generate
+process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( (FRAME_TYPES(i) = FRAME_TYPE_IN) and (ALLOWED_TYPES_IN(i) = '1') ) then
+ result(i) <= '1';
+ else
+ result(i) <= '0';
+ end if;
+ end if;
+end process;
+end generate FRAME_RESULTS_GEN;
+
+PARTIALLY_VALID_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( RESET = '1' ) then
+ partially_valid <= '0';
+ elsif( FRAME_TYPE_IN = x"0800" ) then -- ip frame
+ if ( IP_PROTOCOLS_IN = x"11" ) then -- in case of udp inside ip
+ partially_valid <= or_all(udp_result);
+ elsif( (IP_PROTOCOLS_IN = x"01") or (IP_PROTOCOLS_IN = x"dd") or (IP_PROTOCOLS_IN = x"ee") ) then -- in case of ICMP
+ partially_valid <= '1';
+ else -- do not accept other protocols than udp and icmp inside ip
+ partially_valid <= '0';
+ end if;
+ elsif( result /= zeros ) then-- other frame
+ partially_valid <= '1';
+ else
+ partially_valid <= '0';
+ end if;
+ end if;
+end process PARTIALLY_VALID_PROC;
+
+VALID_OUT_PROC: process( CLK )
+begin
+ if rising_edge(CLK) then
+ if( partially_valid = '1' ) then
+ if ( SAVED_VLAN_ID_IN = x"0000" ) then
+ VALID_OUT <= '1';
+ elsif( VLAN_ID_IN = x"0000_0000" ) then
+ VALID_OUT <= '0';
+ elsif( (SAVED_VLAN_ID_IN = VLAN_ID_IN(15 downto 0)) or (SAVED_VLAN_ID_IN = VLAN_ID_IN(31 downto 16)) ) then
+ VALID_OUT <= '1';
+ else
+ VALID_OUT <= '0';
+ end if;
+ else
+ VALID_OUT <= '0';
+ end if;
+ end if;
+end process VALID_OUT_PROC;
+
+end gbe_type_validator_arch;
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.std_logic_ARITH.all;
-use IEEE.std_logic_UNSIGNED.all;
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-
---use work.trb_net_gbe_components.all;
-use work.gbe_protocols.all;
+ use work.gbe_protocols.all;
entity gbe_wrapper_fifo is
generic(
);
end entity gbe_wrapper_fifo;
-architecture RTL of gbe_wrapper_fifo is
+architecture gbe_wrapper_fifo_arch of gbe_wrapper_fifo is
signal mac : std_logic_vector(47 downto 0);
-------------------------------------------------------------------------------------------------
-- HACK: replace the borken internal FIFO by a ring buffer
- THE_FRAME_TX: entity rx_rb
+ THE_FRAME_TX: entity work.gbe_rx_rb
port map(
CLK => CLK_125_IN,
RESET => RESET,
);
-------------------------------------------------------------------------------------------------
- -- debug(127 downto 64) are local
- -- debug(63 downto 0) are media interface
+-- debug(127 downto 64) are local
+-- debug(63 downto 0) are media interface
-- DEBUG_OUT <= monitor_gen_dbg(95 downto 64);
mac <= MC_UNIQUE_ID_IN(15 downto 8) & MC_UNIQUE_ID_IN(23 downto 16) & MC_UNIQUE_ID_IN(31 downto 24) & x"0" & MC_UNIQUE_ID_IN(35 downto 32) & x"7ada";
- MAKE_RESET_OUT <= '1' when make_reset = '1' else '0';
-
- ISSUE_REBOOT_OUT <= '0' when issue_reboot = '0' else '1';
+ MAKE_RESET_OUT <= '1' when make_reset = '1' else '0';
+ ISSUE_REBOOT_OUT <= '1' when issue_reboot = '1' else '0';
- STATUS_OUT(7 downto 1) <= (others => '0');
- STATUS_OUT(0) <= dhcp_done; -- DHCP has completed
-
- gbe_inst : entity work.gbe_logic_wrapper
+ STATUS_OUT(7 downto 1) <= (others => '0');
+ STATUS_OUT(0) <= dhcp_done;
+
+ THE_GBE_LOGIC_WRAPPER : entity work.gbe_logic_wrapper
generic map(
INCLUDE_SLOWCTRL => LINK_HAS_SLOWCTRL,
INCLUDE_DHCP => LINK_HAS_DHCP,
DEBUG_OUT => DEBUG_OUT --open
);
- -- sum_rx_* ???
- -- sum_tx_* ???
-
- NOSCTRL_MAP_GEN : if (LINK_HAS_SLOWCTRL = '0') generate
+ NOSCTRL_MAP_GEN : if( LINK_HAS_SLOWCTRL = '0' ) generate
mlt_gsc_clk <= '0';
GSC_INIT_DATAREADY_OUT <= '0';
GSC_INIT_DATA_OUT <= (others => '0');
mlt_gsc_busy <= '0';
end generate NOSCTRL_MAP_GEN;
- SCTRL_MAP_GEN : if (LINK_HAS_SLOWCTRL = '1') generate
+ SCTRL_MAP_GEN : if( LINK_HAS_SLOWCTRL = '1' ) generate
mlt_gsc_clk <= GSC_CLK_IN;
GSC_INIT_DATAREADY_OUT <= mlt_gsc_init_dataready;
GSC_INIT_DATA_OUT <= mlt_gsc_init_data;
mlt_gsc_busy <= GSC_BUSY_IN;
end generate SCTRL_MAP_GEN;
-end architecture RTL;
+end architecture gbe_wrapper_fifo_arch;
library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.numeric_std.all;\r
+ use ieee.std_logic_1164.all;\r
+ use ieee.numeric_std.all;\r
\r
library work;\r
\r
-entity sgl_ctrl is\r
+entity gbe_sgl_ctrl is\r
port(\r
CLK : in std_logic;\r
RESET : in std_logic;\r
--\r
DEBUG : out std_logic_vector(15 downto 0)\r
);\r
-end entity sgl_ctrl;\r
+end entity gbe_sgl_ctrl;\r
\r
-architecture sgl_ctrl_arch of sgl_ctrl is\r
+architecture gbe_sgl_ctrl_arch of gbe_sgl_ctrl is\r
\r
-- Components\r
\r
end process THE_NEXT_PORT_PROC;\r
\r
-----------------------------------------------------------\r
+ -- Outputs\r
-----------------------------------------------------------\r
UL_FRAME_REQ_OUT <= ul_frame_req;\r
LOCAL_FRAME_REQ_OUT <= local_frame_req;\r
end case;\r
end process THE_STATE_TRANSITIONS;\r
\r
-end architecture;\r
+end architecture gbe_sgl_ctrl_arch;\r
--- /dev/null
+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.gbe_protocols.all;
+
+entity gbe_response_constructor_ARP is
+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);
+-- END OF INTERFACE
+-- debug
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_ARP;
+
+architecture gbe_response_constructor_ARP_arch of gbe_response_constructor_ARP is
+
+attribute syn_encoding : string;
+
+type dissect_states is (IDLE, READ_FRAME, DECIDE, LOAD_FRAME, WAIT_FOR_LOAD, 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 saved_opcode : std_logic_vector(15 downto 0);
+signal saved_sender_ip : std_logic_vector(31 downto 0);
+signal saved_target_ip : std_logic_vector(31 downto 0);
+signal data_ctr : integer range 0 to 30;
+signal values : std_logic_vector(223 downto 0);
+signal tc_data : std_logic_vector(8 downto 0);
+
+signal state : std_logic_vector(3 downto 0);
+signal rec_frames : std_logic_vector(15 downto 0);
+signal sent_frames : std_logic_vector(15 downto 0);
+signal stat_data_temp : std_logic_vector(31 downto 0);
+
+signal tc_wr : std_logic;
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of state : signal is true;
+attribute syn_preserve of state : signal is true;
+
+begin
+
+values(15 downto 0) <= x"0100"; -- hardware type
+values(31 downto 16) <= x"0008"; -- protocol type
+values(39 downto 32) <= x"06"; -- hardware size
+values(47 downto 40) <= x"04"; -- protocol size
+values(63 downto 48) <= x"0200"; --opcode (reply)
+values(111 downto 64) <= MY_MAC_IN; -- sender (my) mac
+values(143 downto 112) <= MY_IP_IN;
+values(191 downto 144) <= PS_SRC_MAC_ADDRESS_IN; -- target mac
+values(223 downto 192) <= saved_sender_ip; -- target ip
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+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, MY_IP_IN, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, data_ctr, PS_SELECTED_IN, saved_target_ip)
+begin
+ case dissect_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ 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 =>
+ state <= x"2";
+ if (PS_DATA_IN(8) = '1') then
+ dissect_next_state <= DECIDE;
+ else
+ dissect_next_state <= READ_FRAME;
+ end if;
+
+ when DECIDE =>
+ state <= x"3";
+ if (saved_target_ip = MY_IP_IN) then
+ dissect_next_state <= WAIT_FOR_LOAD;
+ -- in case the request is not for me, drop it
+ else
+ dissect_next_state <= IDLE;
+ end if;
+
+ when WAIT_FOR_LOAD =>
+ state <= x"4";
+ if (PS_SELECTED_IN = '1') then
+ dissect_next_state <= LOAD_FRAME;
+ else
+ dissect_next_state <= WAIT_FOR_LOAD;
+ end if;
+
+ when LOAD_FRAME =>
+ state <= x"5";
+ if (data_ctr = 28) then
+ dissect_next_state <= CLEANUP;
+ else
+ dissect_next_state <= LOAD_FRAME;
+ end if;
+
+ when CLEANUP =>
+ state <= x"e";
+ dissect_next_state <= IDLE;
+
+ end case;
+end process DISSECT_MACHINE;
+
+DATA_CTR_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ data_ctr <= 1;
+ elsif( rising_edge(CLK) ) then
+ if ( (dissect_current_state = IDLE) and (PS_WR_EN_IN = '0') ) then
+ data_ctr <= 1;
+ elsif( dissect_current_state = WAIT_FOR_LOAD ) then
+ data_ctr <= 1;
+ elsif( dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+ data_ctr <= data_ctr + 1;
+ 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;
+
+SAVE_VALUES_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ saved_opcode <= (others => '0');
+ saved_sender_ip <= (others => '0');
+ saved_target_ip <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if (dissect_current_state = READ_FRAME) then
+ case (data_ctr) is
+
+ when 6 =>
+ saved_opcode(7 downto 0) <= PS_DATA_IN(7 downto 0);
+ when 7 =>
+ saved_opcode(15 downto 8) <= PS_DATA_IN(7 downto 0);
+ when 13 =>
+ saved_sender_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+ when 14 =>
+ saved_sender_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+ when 15 =>
+ saved_sender_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+ when 16 =>
+ saved_sender_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+ when 23 =>
+ saved_target_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+ when 24 =>
+ saved_target_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+ when 25 =>
+ saved_target_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+ when 26 =>
+ saved_target_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+
+ when others => null;
+ end case;
+ end if;
+ end if;
+end process SAVE_VALUES_PROC;
+
+TC_DATA_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ tc_data(8) <= '0';
+
+ if (dissect_current_state = LOAD_FRAME) then
+ for i in 0 to 7 loop
+ tc_data(i) <= values((data_ctr - 1) * 8 + i);
+ end loop;
+ -- mark the last byte
+ if (data_ctr = 28) then
+ tc_data(8) <= '1';
+ 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 <= x"001c"; -- fixed frame size
+
+TC_FRAME_TYPE_OUT <= x"0608";
+TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN;
+TC_DEST_IP_OUT <= x"00000000"; -- doesnt matter
+TC_DEST_UDP_OUT <= x"0000"; -- doesnt matter
+TC_SRC_MAC_OUT <= MY_MAC_IN;
+TC_SRC_IP_OUT <= x"00000000"; -- doesnt matter
+TC_SRC_UDP_OUT <= x"0000"; -- doesnt matter
+TC_IP_PROTOCOL_OUT <= x"00"; -- doesnt matter
+TC_IDENT_OUT <= (others => '0'); -- doesn't matter
+
+end gbe_response_constructor_ARP_arch;
+
+
--- /dev/null
+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_net_gbe_protocols.all;
+
+entity gbe_response_constructor_DHCP is
+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);
+-- END OF INTERFACE
+ MY_IP_OUT : out std_logic_vector(31 downto 0);
+ DHCP_START_IN : in std_logic;
+ DHCP_DONE_OUT : out std_logic;
+-- debug
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_DHCP;
+
+
+architecture gbe_response_constructor_DHCP_arch of gbe_response_constructor_DHCP is
+
+attribute syn_encoding : string;
+
+type main_states is (BOOTING, DELAY, SENDING_DISCOVER, WAITING_FOR_OFFER, SENDING_REQUEST, WAITING_FOR_ACK, ESTABLISHED);
+signal main_current_state, main_next_state : main_states;
+attribute syn_encoding of main_current_state: signal is "onehot";
+
+type receive_states is (IDLE, DISCARD, CLEANUP, SAVE_VALUES);
+signal receive_current_state, receive_next_state : receive_states;
+attribute syn_encoding of receive_current_state: signal is "onehot";
+
+type discover_states is (IDLE, WAIT_FOR_LOAD, BOOTP_HEADERS, CLIENT_IP, YOUR_IP, ZEROS1, MY_MAC, ZEROS2, VENDOR_VALS, VENDOR_VALS2, TERMINATION, CLEANUP);
+signal construct_current_state, construct_next_state : discover_states;
+attribute syn_encoding of construct_current_state: signal is "onehot";
+
+type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, LOAD_DISCARDED, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal state : std_logic_vector(3 downto 0);
+signal rec_frames : std_logic_vector(15 downto 0);
+signal sent_frames : std_logic_vector(15 downto 0);
+
+signal wait_ctr : std_logic_vector(31 downto 0); -- wait for 5 sec before sending request
+signal load_ctr : integer range 0 to 600 := 0;
+
+signal bootp_hdr : std_logic_vector(95 downto 0);
+
+signal tc_data : std_logic_vector(8 downto 0);
+signal vendor_values : std_logic_vector(175 downto 0);
+signal save_ctr : integer range 0 to 600 := 0;
+signal saved_transaction_id : std_logic_vector(31 downto 0);
+signal saved_proposed_ip : std_logic_vector(31 downto 0);
+signal saved_dhcp_type : std_logic_vector(23 downto 0);
+signal saved_true_ip : std_logic_vector(31 downto 0);
+signal transaction_id : std_logic_vector(31 downto 0);
+signal client_ip_reg : std_logic_vector(31 downto 0);
+signal your_ip_reg : std_logic_vector(31 downto 0);
+signal saved_server_mac : std_logic_vector(47 downto 0);
+signal saved_server_ip : std_logic_vector(31 downto 0);
+signal state2 : std_logic_vector(3 downto 0);
+signal state3 : std_logic_vector(3 downto 0);
+signal vendor_values2 : std_logic_vector(47 downto 0);
+
+signal discarded_ctr : std_logic_vector(15 downto 0);
+
+signal stat_data_temp : std_logic_vector(31 downto 0);
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of state, state2 : signal is true;
+attribute syn_preserve of state, state2 : signal is true;
+
+signal wait_value : std_logic_vector(31 downto 0);
+
+signal my_ip : std_logic_vector(31 downto 0);
+
+begin
+
+-- ****
+-- fixing the constant values for DHCP request headers
+TC_DEST_MAC_OUT <= x"ffffffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_mac;
+TC_DEST_IP_OUT <= x"ffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_ip;
+TC_DEST_UDP_OUT <= x"4300";
+TC_SRC_MAC_OUT <= MY_MAC_IN;
+TC_SRC_IP_OUT <= x"00000000" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_proposed_ip;
+TC_SRC_UDP_OUT <= x"4400";
+TC_IP_PROTOCOL_OUT <= x"11"; -- udp
+bootp_hdr(7 downto 0) <= x"01"; -- message type(request)
+bootp_hdr(15 downto 8) <= x"01"; -- hardware type (eth)
+bootp_hdr(23 downto 16) <= x"06"; -- hardware address length
+bootp_hdr(31 downto 24) <= x"00"; -- hops
+bootp_hdr(63 downto 32) <= transaction_id; -- transaction id;
+bootp_hdr(95 downto 64) <= x"0000_0000"; -- seconds elapsed/flags
+transaction_id <= x"cefa" & MY_MAC_IN(47 downto 40) & MY_MAC_IN(23 downto 16);
+vendor_values(31 downto 0) <= x"63538263"; -- magic cookie (dhcp message)
+vendor_values(55 downto 32) <= x"010135" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else x"030135"; -- dhcp discover, then dhcp request
+vendor_values(79 downto 56) <= x"01073d"; -- client identifier
+vendor_values(127 downto 80) <= MY_MAC_IN; -- client identifier
+vendor_values(143 downto 128) <= x"040c"; -- client name
+--vendor_values(175 downto 144) <= x"33425254"; -- client name (TRB3)
+vendor_values(175 downto 144) <= x"6f72694b"; -- client name (Kiro)
+vendor_values2(15 downto 0) <= x"0436"; -- server identifier
+vendor_values2(47 downto 16) <= saved_server_ip;
+
+--*****************
+-- setting of global variable for IP address
+my_ip <= saved_true_ip when main_current_state = ESTABLISHED else (others => '0');
+MY_IP_OUT <= my_ip;
+--
+--*****************
+
+SAVE_SERVER_ADDR_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( main_current_state = BOOTING ) then
+ saved_server_mac <= (others => '0');
+ saved_server_ip <= (others => '0');
+ elsif( (main_current_state = WAITING_FOR_OFFER) and (receive_current_state = SAVE_VALUES and save_ctr = 1) ) then
+ saved_server_mac <= PS_SRC_MAC_ADDRESS_IN;
+ saved_server_ip <= PS_SRC_IP_ADDRESS_IN;
+ end if;
+ end if;
+end process SAVE_SERVER_ADDR_PROC;
+
+
+-- **** MAIN MACHINE PART
+
+MAIN_MACHINE_PROC: process( CLK, RESET)
+begin
+ if ( RESET = '1' ) then
+ main_current_state <= BOOTING;
+ elsif( rising_edge(CLK) ) then
+ main_current_state <= main_next_state;
+ end if;
+end process MAIN_MACHINE_PROC;
+
+wait_value <= x"2000_0000";
+
+MAIN_MACHINE : process(main_current_state, DHCP_START_IN, construct_current_state, wait_ctr, receive_current_state, PS_DATA_IN, wait_value)
+begin
+ state2 <= x"0";
+
+ case (main_current_state) is
+
+ when BOOTING =>
+ state2 <= x"1";
+ if (DHCP_START_IN = '1') then
+ main_next_state <= DELAY;
+ else
+ main_next_state <= BOOTING;
+ end if;
+
+ when DELAY =>
+ state2 <= x"2";
+ if (wait_ctr = wait_value) then
+ main_next_state <= SENDING_DISCOVER;
+ else
+ main_next_state <= DELAY;
+ end if;
+
+ when SENDING_DISCOVER =>
+ state2 <= x"3";
+ if (construct_current_state = CLEANUP) then
+ main_next_state <= WAITING_FOR_OFFER;
+ else
+ main_next_state <= SENDING_DISCOVER;
+ end if;
+
+ when WAITING_FOR_OFFER =>
+ state2 <= x"4";
+ if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then
+ main_next_state <= SENDING_REQUEST;
+ elsif (wait_ctr = x"2000_0000") then
+ main_next_state <= BOOTING;
+ else
+ main_next_state <= WAITING_FOR_OFFER;
+ end if;
+
+ when SENDING_REQUEST =>
+ state2 <= x"5";
+ if (construct_current_state = CLEANUP) then
+ main_next_state <= WAITING_FOR_ACK;
+ else
+ main_next_state <= SENDING_REQUEST;
+ end if;
+
+ when WAITING_FOR_ACK =>
+ state2 <= x"6";
+ if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then
+ main_next_state <= ESTABLISHED;
+ elsif (wait_ctr = x"2000_0000") then
+ main_next_state <= BOOTING;
+ else
+ main_next_state <= WAITING_FOR_ACK;
+ end if;
+
+ when ESTABLISHED =>
+ state2 <= x"7";
+ main_next_state <= ESTABLISHED;
+
+ when others => main_next_state <= BOOTING;
+
+ end case;
+
+end process MAIN_MACHINE;
+
+WAIT_CTR_PROC : process(CLK)
+begin
+ if rising_edge(CLK) then
+ if (main_current_state = SENDING_DISCOVER or main_current_state = SENDING_REQUEST or main_current_state = BOOTING) then
+ wait_ctr <= (others => '0');
+ elsif (main_current_state = WAITING_FOR_ACK and receive_current_state = SAVE_VALUES and PS_DATA_IN(8) = '1') then
+ wait_ctr <= (others => '0');
+ elsif (main_current_state = WAITING_FOR_ACK or main_current_state = WAITING_FOR_OFFER or main_current_state = DELAY or main_current_state = ESTABLISHED) then
+ wait_ctr <= wait_ctr + x"1";
+ else
+ wait_ctr <= wait_ctr;
+ end if;
+ end if;
+end process WAIT_CTR_PROC;
+
+DHCP_DONE_OUT <= '1' when main_current_state = ESTABLISHED else '0';
+
+
+-- **** MESSAGES RECEIVING PART
+
+RECEIVE_MACHINE_PROC : process(RESET, CLK)
+begin
+ if RESET = '1' then
+ receive_current_state <= IDLE;
+ elsif rising_edge(CLK) then
+ receive_current_state <= receive_next_state;
+ end if;
+end process RECEIVE_MACHINE_PROC;
+
+RECEIVE_MACHINE : process(receive_current_state, main_current_state, bootp_hdr, saved_dhcp_type, saved_transaction_id, PS_DATA_IN, PS_DEST_MAC_ADDRESS_IN, MY_MAC_IN, PS_ACTIVATE_IN, PS_WR_EN_IN, save_ctr)
+begin
+ state3 <= x"0";
+
+ case receive_current_state is
+
+ when IDLE =>
+ state3 <= x"1";
+ if (PS_ACTIVATE_IN = '1' and PS_WR_EN_IN = '1') then
+ if (main_current_state = WAITING_FOR_OFFER or main_current_state = WAITING_FOR_ACK) then -- ready to receive dhcp frame
+ if (PS_DEST_MAC_ADDRESS_IN = MY_MAC_IN) then -- check if i'm the addressee (discards broadcasts also)
+ receive_next_state <= SAVE_VALUES;
+ else
+ receive_next_state <= DISCARD; -- discard if the frame is not for me
+ end if;
+ else
+ receive_next_state <= DISCARD; -- discard if the frame arrived at wrong time
+ end if;
+ else
+ receive_next_state <= IDLE;
+ end if;
+
+ when SAVE_VALUES =>
+ state3 <= x"2";
+ if (PS_DATA_IN(8) = '1') then
+ receive_next_state <= CLEANUP;
+ -- check if the same transaction
+ elsif (save_ctr = 9) and (saved_transaction_id /= bootp_hdr(63 downto 32)) then
+ receive_next_state <= DISCARD;
+ -- if the wrong message at the wrong time
+ elsif (main_current_state = WAITING_FOR_OFFER) and (save_ctr = 242) and (saved_dhcp_type /= x"020135") then
+ receive_next_state <= DISCARD;
+ -- if the wrong message at the wrong time
+ elsif (main_current_state = WAITING_FOR_ACK) and (save_ctr = 242) and (saved_dhcp_type /= x"050135") then
+ receive_next_state <= DISCARD;
+ else
+ receive_next_state <= SAVE_VALUES;
+ end if;
+
+ when DISCARD =>
+ state3 <= x"3";
+ if (PS_DATA_IN(8) = '1') then
+ receive_next_state <= CLEANUP;
+ else
+ receive_next_state <= DISCARD;
+ end if;
+
+ when CLEANUP =>
+ state3 <= x"4";
+ receive_next_state <= IDLE;
+
+ when others => receive_next_state <= IDLE;
+
+ end case;
+
+end process RECEIVE_MACHINE;
+
+SAVE_CTR_PROC : process(CLK)
+begin
+ if rising_edge(CLK) then
+ if (receive_current_state = IDLE) then
+ save_ctr <= 0;
+ elsif (receive_current_state = SAVE_VALUES and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then
+ save_ctr <= save_ctr + 1;
+ else
+ save_ctr <= save_ctr;
+ end if;
+ end if;
+end process SAVE_CTR_PROC;
+
+SAVE_VALUES_PROC : process(CLK)
+begin
+ if rising_edge(CLK) then
+ if (main_current_state = BOOTING) then
+ saved_transaction_id <= (others => '0');
+ saved_proposed_ip <= (others => '0');
+ saved_true_ip <= (others => '0');
+ saved_dhcp_type <= (others => '0');
+ -- dissection of DHCP Offer message
+ elsif (main_current_state = WAITING_FOR_OFFER and receive_current_state = SAVE_VALUES) then
+
+ saved_true_ip <= saved_true_ip;
+
+ case save_ctr is
+
+ when 3 =>
+ saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 4 =>
+ saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 5 =>
+ saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when 6 =>
+ saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0);
+
+
+ when 15 =>
+ saved_proposed_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 16 =>
+ saved_proposed_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 17 =>
+ saved_proposed_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when 18 =>
+ saved_proposed_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+
+
+ when 239 =>
+ saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 240 =>
+ saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 241 =>
+ saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when others => null;
+
+ end case;
+ -- dissection on DHCP Ack message
+ elsif (main_current_state = WAITING_FOR_ACK and receive_current_state = SAVE_VALUES) then
+
+ saved_proposed_ip <= saved_proposed_ip;
+
+ case save_ctr is
+
+ when 3 =>
+ saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 4 =>
+ saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 5 =>
+ saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when 6 =>
+ saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0);
+
+
+ when 15 =>
+ saved_true_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 16 =>
+ saved_true_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 17 =>
+ saved_true_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when 18 =>
+ saved_true_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+
+
+ when 239 =>
+ saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0);
+
+ when 240 =>
+ saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0);
+
+ when 241 =>
+ saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0);
+
+ when others => null;
+
+ end case;
+ else
+ saved_transaction_id <= saved_transaction_id;
+ saved_proposed_ip <= saved_proposed_ip;
+ saved_true_ip <= saved_true_ip;
+ saved_dhcp_type <= saved_dhcp_type;
+ end if;
+ end if;
+end process SAVE_VALUES_PROC;
+
+
+-- **** MESSAGES CONSTRUCTING PART
+
+CONSTRUCT_MACHINE_PROC : process(RESET, CLK)
+begin
+ if RESET = '1' then
+ construct_current_state <= IDLE;
+ elsif rising_edge(CLK) then
+ if (main_current_state = BOOTING) then
+ construct_current_state <= IDLE;
+ else
+ construct_current_state <= construct_next_state;
+ end if;
+ end if;
+end process CONSTRUCT_MACHINE_PROC;
+
+CONSTRUCT_MACHINE : process(construct_current_state, main_current_state, load_ctr, PS_SELECTED_IN)
+begin
+ state <= x"0";
+
+ case construct_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ if (main_current_state = SENDING_DISCOVER) or (main_current_state = SENDING_REQUEST) then
+ construct_next_state <= WAIT_FOR_LOAD;
+ else
+ construct_next_state <= IDLE;
+ end if;
+
+ when WAIT_FOR_LOAD =>
+ state <= x"2";
+ if (PS_SELECTED_IN = '1') then
+ construct_next_state <= BOOTP_HEADERS;
+ else
+ construct_next_state <= WAIT_FOR_LOAD;
+ end if;
+
+
+ when BOOTP_HEADERS =>
+ state <= x"3";
+ if (load_ctr = 11) then
+ construct_next_state <= CLIENT_IP;
+ else
+ construct_next_state <= BOOTP_HEADERS;
+ end if;
+
+ when CLIENT_IP =>
+ state <= x"4";
+ if (load_ctr = 15) then
+ construct_next_state <= YOUR_IP;
+ else
+ construct_next_state <= CLIENT_IP;
+ end if;
+
+ when YOUR_IP =>
+ state <= x"5";
+ if (load_ctr = 19) then
+ construct_next_state <= ZEROS1;
+ else
+ construct_next_state <= YOUR_IP;
+ end if;
+
+ when ZEROS1 =>
+ state <= x"6";
+ if (load_ctr = 27) then
+ construct_next_state <= MY_MAC;
+ else
+ construct_next_state <= ZEROS1;
+ end if;
+
+ when MY_MAC =>
+ state <= x"7";
+ if (load_ctr = 33) then
+ construct_next_state <= ZEROS2;
+ else
+ construct_next_state <= MY_MAC;
+ end if;
+
+ when ZEROS2 =>
+ state <= x"8";
+ if (load_ctr = 235) then
+ construct_next_state <= VENDOR_VALS;
+ else
+ construct_next_state <= ZEROS2;
+ end if;
+
+ when VENDOR_VALS =>
+ state <= x"9";
+ if (load_ctr = 257) then
+ -- for discover it's enough of values
+ if (main_current_state = SENDING_DISCOVER) then
+ construct_next_state <= TERMINATION;
+ -- for request there is some more values needed
+ else
+ construct_next_state <= VENDOR_VALS2;
+ end if;
+ else
+ construct_next_state <= VENDOR_VALS;
+ end if;
+
+ when VENDOR_VALS2 =>
+ state <= x"a";
+ if (load_ctr = 263) then
+ construct_next_state <= TERMINATION;
+ else
+ construct_next_state <= VENDOR_VALS2;
+ end if;
+
+ when TERMINATION =>
+ state <= x"b";
+ construct_next_state <= CLEANUP;
+
+ when CLEANUP =>
+ state <= x"c";
+ construct_next_state <= IDLE;
+
+ when others => construct_next_state <= IDLE;
+
+ end case;
+end process CONSTRUCT_MACHINE;
+
+LOAD_CTR_PROC : process(CLK)
+begin
+ if rising_edge(CLK) then
+ if (construct_current_state = IDLE) then
+ load_ctr <= 0;
+ elsif (TC_RD_EN_IN = '1') and (PS_SELECTED_IN = '1') then
+ load_ctr <= load_ctr + 1;
+ else
+ load_ctr <= load_ctr;
+ end if;
+ end if;
+end process LOAD_CTR_PROC;
+
+TC_DATA_PROC : process(CLK)
+begin
+ if rising_edge(CLK) then
+ case (construct_current_state) is
+
+ when BOOTP_HEADERS =>
+ for i in 0 to 7 loop
+ tc_data(i) <= bootp_hdr(load_ctr * 8 + i);
+ end loop;
+ tc_data(8) <= '0';
+
+ when CLIENT_IP =>
+ if (main_current_state = SENDING_DISCOVER) then
+ tc_data(7 downto 0) <= x"00";
+ elsif (main_current_state = SENDING_REQUEST) then
+ for i in 0 to 7 loop
+ tc_data(i) <= saved_proposed_ip((load_ctr - 12) * 8 + i);
+ end loop;
+ end if;
+ tc_data(8) <= '0';
+
+ when YOUR_IP =>
+ tc_data(7 downto 0) <= x"00";
+ tc_data(8) <= '0';
+
+ when ZEROS1 =>
+ tc_data(7 downto 0) <= x"00";
+ tc_data(8) <= '0';
+
+ when MY_MAC =>
+ for i in 0 to 7 loop
+ tc_data(i) <= MY_MAC_IN((load_ctr - 28) * 8 + i);
+ end loop;
+ tc_data(8) <= '0';
+
+ when ZEROS2 =>
+ tc_data(7 downto 0) <= x"00";
+ tc_data(8) <= '0';
+
+ when VENDOR_VALS =>
+ for i in 0 to 7 loop
+ tc_data(i) <= vendor_values((load_ctr - 236) * 8 + i);
+ end loop;
+ tc_data(8) <= '0';
+
+ -- needed only for DHCP Request message
+ when VENDOR_VALS2 =>
+ for i in 0 to 7 loop
+ tc_data(i) <= vendor_values2((load_ctr - 258) * 8 + i);
+ end loop;
+ tc_data(8) <= '0';
+
+ when TERMINATION =>
+ tc_data(7 downto 0) <= x"ff";
+ tc_data(8) <= '1';
+
+ when others =>
+ tc_data(7 downto 0) <= x"00";
+ tc_data(8) <= '0';
+
+ end case;
+
+ TC_DATA_OUT <= tc_data;
+
+ end if;
+end process;
+
+PS_RESPONSE_SYNC : process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (construct_current_state = IDLE or construct_current_state = CLEANUP) then
+ PS_RESPONSE_READY_OUT <= '0';
+ else
+ PS_RESPONSE_READY_OUT <= '1';
+ end if;
+
+ if (construct_current_state = IDLE) then
+ PS_BUSY_OUT <= '0';
+ else
+ PS_BUSY_OUT <= '1';
+ end if;
+ end if;
+end process PS_RESPONSE_SYNC;
+
+-- fixed sizes for discover and request messages
+TC_FRAME_SIZE_OUT <= x"0103" when (main_current_state = SENDING_DISCOVER) else x"0109";
+
+TC_FRAME_TYPE_OUT <= x"0008"; -- frame type: ip
+
+TC_IDENT_OUT <= x"1" & sent_frames(11 downto 0);
+
+SENT_FRAMES_PROC : process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ sent_frames <= (others => '0');
+ elsif (construct_current_state = CLEANUP) then
+ sent_frames <= sent_frames + x"1";
+ end if;
+ end if;
+end process SENT_FRAMES_PROC;
+
+-- **** debug
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ DEBUG_OUT(3 downto 0) <= state;
+ DEBUG_OUT(7 downto 4) <= state2;
+ DEBUG_OUT(11 downto 8) <= state3;
+ end if;
+end process;
+
+-- ****
+
+end gbe_response_constructor_DHCP_arch;
+
+
--- /dev/null
+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;
+
+-- WARNING: data latency was wrong by one cycle (first byte not sent, last byte duplicated), and
+-- size was calculated wrong (one off). Works now FOR ME. To be tested carefully!
+
+-- BUG: If a frame written triggers FIFOFULL, it must be discarded. Maximum frame payload is 4096bytes.
+
+entity gbe_response_constructor_Forward is
+ 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);
+ --
+ RECEIVED_FRAMES_OUT : out std_logic_vector(15 downto 0);
+ SENT_FRAMES_OUT : out std_logic_vector(15 downto 0);
+ -- END OF INTERFACE
+ FWD_DST_MAC_IN : in std_logic_vector(47 downto 0);
+ FWD_DST_IP_IN : in std_logic_vector(31 downto 0);
+ FWD_DST_UDP_IN : in std_logic_vector(15 downto 0);
+ FWD_DATA_IN : in std_logic_vector(7 downto 0);
+ FWD_DATA_VALID_IN : in std_logic;
+ FWD_SOP_IN : in std_logic;
+ FWD_EOP_IN : in std_logic;
+ FWD_READY_OUT : out std_logic;
+ FWD_FULL_OUT : out std_logic;
+ -- debug
+ DEBUG_OUT : out std_logic_vector(31 downto 0)
+ );
+end gbe_response_constructor_Forward;
+
+architecture gbe_response_constructor_Forward_arch of gbe_response_constructor_Forward is
+
+attribute syn_encoding : string;
+
+type dissect_states is (IDLE, SAVE, WAIT_FOR_LOAD, LOAD, CLEANUP);
+signal dissect_current_state, dissect_next_state : dissect_states;
+attribute syn_encoding of dissect_current_state: signal is "safe,gray";
+
+signal ff_wr_en : std_logic;
+signal ff_rd_en : std_logic;
+signal resp_bytes_ctr : std_logic_vector(15 downto 0);
+signal ff_empty : std_logic;
+signal ff_full : std_logic;
+signal ff_q : std_logic_vector(8 downto 0);
+signal ff_rd_lock : std_logic;
+
+signal state : std_logic_vector(3 downto 0);
+signal rec_frames : std_logic_vector(15 downto 0);
+signal sent_frames : std_logic_vector(15 downto 0);
+
+signal local_eop : std_logic;
+
+begin
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+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, FWD_SOP_IN, FWD_EOP_IN, ff_q, ff_rd_lock, PS_SELECTED_IN)
+begin
+ case dissect_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ if (FWD_SOP_IN = '1') then
+ dissect_next_state <= SAVE;
+ else
+ dissect_next_state <= IDLE;
+ end if;
+
+ when SAVE =>
+ state <= x"2";
+ if (FWD_EOP_IN = '1') then
+ dissect_next_state <= WAIT_FOR_LOAD;
+ else
+ dissect_next_state <= SAVE;
+ end if;
+
+ when WAIT_FOR_LOAD =>
+ state <= x"3";
+ if (PS_SELECTED_IN = '0') then
+ dissect_next_state <= LOAD;
+ else
+ dissect_next_state <= WAIT_FOR_LOAD;
+ end if;
+
+ when LOAD =>
+ state <= x"4";
+ if (ff_q(8) = '1') and (ff_rd_lock = '0') then
+ dissect_next_state <= CLEANUP;
+ else
+ dissect_next_state <= LOAD;
+ end if;
+
+ when CLEANUP =>
+ state <= x"5";
+ dissect_next_state <= IDLE;
+
+ end case;
+end process DISSECT_MACHINE;
+
+PS_BUSY_OUT <= '0' when dissect_current_state = IDLE else '1';
+
+ff_wr_en <= '1' when (FWD_DATA_VALID_IN = '1') else '0';
+
+local_eop <= '1' when (dissect_current_state = SAVE and FWD_EOP_IN = '1' and FWD_DATA_VALID_IN = '1') else '0';
+
+FF_RD_LOCK_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ ff_rd_lock <= '1';
+ elsif( rising_edge(CLK) ) then
+ if( dissect_current_state = LOAD and ff_rd_en = '1' ) then
+ ff_rd_lock <= '0';
+ else
+ ff_rd_lock <= '1';
+ end if;
+ end if;
+end process FF_RD_LOCK_PROC;
+
+FRAME_FIFO: entity fifo_4096x9
+port map(
+ Data(7 downto 0) => FWD_DATA_IN,
+ Data(8) => local_eop,
+ WrClock => CLK,
+ RdClock => CLK,
+ WrEn => ff_wr_en,
+ RdEn => ff_rd_en,
+ Reset => RESET,
+ RPReset => RESET,
+ Q => ff_q,
+ Empty => ff_empty,
+ Full => ff_full
+);
+
+ff_rd_en <= '1' when (TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') else '0';
+
+--TC_DATA_OUT <= ff_q; -- BUG?!?
+TC_DATA_OUT <= ff_q when rising_edge(CLK);
+
+PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = LOAD) else '0';
+
+--TC_FRAME_SIZE_OUT <= resp_bytes_ctr + x"1"; -- BUG?!?
+TC_FRAME_SIZE_OUT <= resp_bytes_ctr;
+
+TC_FRAME_TYPE_OUT <= x"0008";
+TC_DEST_MAC_OUT <= FWD_DST_MAC_IN;
+TC_DEST_IP_OUT <= FWD_DST_IP_IN;
+TC_DEST_UDP_OUT <= FWD_DST_UDP_IN;
+TC_SRC_MAC_OUT <= MY_MAC_IN;
+TC_SRC_IP_OUT <= MY_IP_IN;
+TC_SRC_UDP_OUT <= FWD_DST_UDP_IN;
+TC_IP_PROTOCOL_OUT <= x"11";
+TC_IDENT_OUT <= x"6" & sent_frames(11 downto 0);
+
+RESP_BYTES_CTR_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ resp_bytes_ctr <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if ( dissect_current_state = IDLE ) then
+ resp_bytes_ctr <= (others => '0');
+ elsif( dissect_current_state = SAVE and FWD_DATA_VALID_IN = '1' ) then
+ resp_bytes_ctr <= resp_bytes_ctr + x"1";
+ end if;
+
+ FWD_FULL_OUT <= ff_full;
+
+ if( dissect_current_state = IDLE ) then
+ FWD_READY_OUT <= '1';
+ else
+ FWD_READY_OUT <= '0';
+ end if;
+
+ end if;
+end process RESP_BYTES_CTR_PROC;
+
+REC_FRAMES_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ rec_frames <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+ rec_frames <= rec_frames + x"1";
+ end if;
+ end if;
+end process REC_FRAMES_PROC;
+
+SENT_FRAMES_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ sent_frames <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( dissect_current_state = WAIT_FOR_LOAD and PS_SELECTED_IN = '0' ) then
+ sent_frames <= sent_frames + x"1";
+ end if;
+ end if;
+end process SENT_FRAMES_PROC;
+
+RECEIVED_FRAMES_OUT <= rec_frames;
+SENT_FRAMES_OUT <= sent_frames;
+
+-- **** debug
+DEBUG_OUT(3 downto 0) <= state;
+DEBUG_OUT(4) <= ff_empty;
+DEBUG_OUT(5) <= ff_full;
+DEBUG_OUT(6) <= ff_wr_en;
+DEBUG_OUT(7) <= ff_rd_en;
+DEBUG_OUT(15 downto 8) <= ff_q(7 downto 0);
+DEBUG_OUT(16) <= ff_q(8);
+DEBUG_OUT(17) <= local_eop;
+DEBUG_OUT(31 downto 18) <= (others => '0');
+-- ****
+
+end gbe_response_constructor_Forward_arch;
--- /dev/null
+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.gbe_protocols.all;
+
+entity gbe_response_constructor_Ping is
+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);
+-- END OF INTERFACE
+-- debug
+ DEBUG_OUT : out std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_Ping;
+
+architecture gbe_response_constructor_Ping_arch of gbe_response_constructor_Ping 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 : std_logic_vector(19 downto 0);
+signal checksum_r : std_logic_vector(19 downto 0);
+signal checksum_ll : std_logic_vector(15 downto 0);
+signal checksum_rr : std_logic_vector(15 downto 0);
+signal checksum_lll : std_logic_vector(15 downto 0);
+signal checksum_rrr : std_logic_vector(15 downto 0);
+
+begin
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+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, RESET )
+begin
+ if ( RESET = '1' ) then
+ data_ctr <= 2;
+ elsif( rising_edge(CLK) ) then
+ if ( (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, RESET )
+begin
+ if ( RESET = '1' ) then
+ data_length <= 1;
+ elsif( rising_edge(CLK) ) then
+ if (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, RESET )
+begin
+ if ( RESET = '1' ) then
+ saved_headers <= (others => '0');
+ saved_data <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if ( 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, RESET )
+begin
+ if ( RESET = '1' ) 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( rising_edge(CLK) ) then
+ if( 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;
+ 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;
+
+SENT_FRAMES_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ sent_frames <= (others => '0');
+ elsif( rising_edge(CLK) ) then
+ if( dissect_current_state = CLEANUP ) then
+ sent_frames <= sent_frames + x"1";
+ end if;
+ end if;
+end process SENT_FRAMES_PROC;
+
+end gbe_response_constructor_Ping_arch;
+
+
--- /dev/null
+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.gbe_protocols.all;
+
+
+entity gbe_response_constructor_SCTRL is
+ generic(
+ SLOWCTRL_BUFFER_SIZE : integer range 1 to 4 := 1
+ );
+ 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);
+--
+ DEBUG_OUT : out std_logic_vector(63 downto 0);
+ -- END OF INTERFACE
+ -- protocol specific ports
+ GSC_CLK_IN : in std_logic;
+ GSC_INIT_DATAREADY_OUT : out std_logic;
+ GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0);
+ GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0);
+ GSC_INIT_READ_IN : in std_logic;
+ GSC_REPLY_DATAREADY_IN : in std_logic;
+ GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0);
+ GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0);
+ GSC_REPLY_READ_OUT : out std_logic;
+ GSC_BUSY_IN : in std_logic;
+ MAKE_RESET_OUT : out std_logic;
+ CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0);
+ -- end of protocol specific ports
+ MONITOR_SELECT_REC_OUT : out std_logic_vector(31 downto 0);
+ MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(31 downto 0);
+ MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(31 downto 0);
+ MONITOR_SELECT_SENT_OUT : out std_logic_vector(31 downto 0);
+ DATA_HIST_OUT : out hist_array
+ );
+end entity gbe_response_constructor_SCTRL;
+
+architecture gbe_response_constructor_SCTRL_arch of gbe_response_constructor_SCTRL is
+
+attribute syn_encoding : string;
+
+type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_HUB, LOAD_TO_HUB, WAIT_FOR_RESPONSE, SAVE_RESPONSE, LOAD_FRAME, WAIT_FOR_LOAD, 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_RECEIVED, LOAD_REPLY, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal saved_target_ip : std_logic_vector(31 downto 0);
+signal data_ctr : integer range 0 to 30;
+
+signal rec_frames : std_logic_vector(15 downto 0);
+
+signal rx_fifo_q : std_logic_vector(17 downto 0);
+signal rx_fifo_qq : std_logic_vector(17 downto 0);
+signal rx_fifo_wr, rx_fifo_rd : std_logic;
+signal tx_eod, rx_eod : std_logic;
+
+signal tx_fifo_q : std_logic_vector(8 downto 0);
+signal tx_fifo_wr, tx_fifo_rd : std_logic;
+signal tx_fifo_reset : std_logic;
+signal gsc_reply_read : std_logic;
+signal gsc_init_dataready : std_logic;
+signal gsc_init_dataready_q : std_logic;
+
+signal tx_data_ctr : std_logic_vector(15 downto 0);
+signal tx_loaded_ctr : std_logic_vector(15 downto 0);
+signal tx_frame_loaded : std_logic_vector(15 downto 0);
+
+signal packet_num : std_logic_vector(2 downto 0);
+
+signal init_ctr, reply_ctr : std_logic_vector(15 downto 0);
+signal rx_empty, tx_empty : std_logic;
+
+signal rx_full, tx_full : std_logic;
+
+signal size_left : std_logic_vector(15 downto 0);
+
+signal reset_detected : std_logic := '0';
+signal make_reset : std_logic := '0';
+
+signal fifo_rd_q : std_logic;
+
+signal too_much_data : std_logic;
+
+signal rx_fifo_data : std_logic_vector(8 downto 0);
+signal tx_fifo_data : std_logic_vector(17 downto 0);
+
+signal tc_wr : std_logic;
+signal state : std_logic_vector(3 downto 0);
+signal saved_hdr_1 : std_logic_vector(7 downto 0) := x"ab";
+signal saved_hdr_2 : std_logic_vector(7 downto 0) := x"cd";
+signal saved_hdr_ctr : std_logic_vector(3 downto 0);
+
+signal mon_rec_frames, mon_rec_bytes, mon_sent_frames, mon_sent_bytes : std_logic_vector(31 downto 0);
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true;
+attribute syn_preserve of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true;
+
+signal hist_inst : hist_array;
+signal reset_all_hist : std_logic_vector(31 downto 0);
+
+signal rx_cnt, tx_cnt : std_logic_vector(15 downto 0);
+
+begin
+
+MAKE_RESET_OUT <= make_reset;
+
+receive_fifo: entity work.fifo_2kx9x18_wcnt
+ PORT map(
+ Reset => RESET,
+ RPReset => RESET,
+ WrClock => CLK,
+ RdClock => CLK,
+ Data => rx_fifo_data,
+ WrEn => rx_fifo_wr,
+ RdEn => rx_fifo_rd,
+ Q => rx_fifo_q,
+ Full => rx_full,
+ Empty => rx_empty,
+ WCNT => rx_cnt(11 downto 0)
+ );
+
+--TODO: change to synchronous
+rx_fifo_rd <= '1' when (gsc_init_dataready = '1' and dissect_current_state = LOAD_TO_HUB) or
+ (gsc_init_dataready = '1' and dissect_current_state = WAIT_FOR_HUB and GSC_INIT_READ_IN = '1') or
+ (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1')
+ else '0'; -- preload first word
+
+RX_FIFO_WR_SYNC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+
+ if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and (saved_hdr_ctr = "0100" or saved_hdr_ctr = "1000") ) then
+ rx_fifo_wr <= '1';
+ else
+ rx_fifo_wr <= '0';
+ end if;
+
+ rx_fifo_data <= PS_DATA_IN;
+ end if;
+end process RX_FIFO_WR_SYNC;
+
+SAVED_HDR_CTR_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( dissect_current_state = IDLE and PS_WR_EN_IN = '0' and PS_ACTIVATE_IN = '0' ) then
+ saved_hdr_ctr <= "0001";
+ elsif( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr /= "1000" ) then
+ saved_hdr_ctr(3 downto 0) <= saved_hdr_ctr(2 downto 0) & '0';
+ end if;
+ end if;
+end process SAVED_HDR_CTR_PROC;
+
+SAVED_HDR_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+ if( saved_hdr_ctr = "0001" ) then
+ saved_hdr_1 <= PS_DATA_IN(7 downto 0);
+ saved_hdr_2 <= saved_hdr_2;
+ elsif( saved_hdr_ctr = "0010" ) then
+ saved_hdr_2 <= PS_DATA_IN(7 downto 0);
+ saved_hdr_1 <= saved_hdr_1;
+ end if;
+ end if;
+ end if;
+end process SAVED_HDR_PROC;
+
+----TODO: add a register
+GSC_INIT_DATA_OUT(7 downto 0) <= rx_fifo_q(16 downto 9);
+GSC_INIT_DATA_OUT(15 downto 8) <= rx_fifo_q(7 downto 0);
+
+------ TODO: change it to synchronous
+GSC_INIT_PACKET_NUM_OUT <= packet_num;
+GSC_INIT_DATAREADY_OUT <= gsc_init_dataready;
+gsc_init_dataready <= '1' when (GSC_INIT_READ_IN = '1' and dissect_current_state = LOAD_TO_HUB) or --TODO Ob das so richtig ist, ohne auf fifo_rd zu schauen?
+ (dissect_current_state = WAIT_FOR_HUB)
+ else '0';
+
+PACKET_NUM_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( dissect_current_state = IDLE ) then
+ packet_num <= "100";
+ elsif( GSC_INIT_READ_IN = '1' and rx_fifo_rd = '1' and packet_num = "100" and dissect_current_state /= READ_FRAME ) then --BUG zählt schon hoch beim fifo_rd weil read schon 1 ist. read geht aber nur auf 1 wenn dataready auf 1 ist
+ packet_num <= "000";
+ elsif( rx_fifo_rd = '1' and packet_num /= "100" ) then
+ packet_num <= packet_num + "1";
+ end if;
+ end if;
+end process PACKET_NUM_PROC;
+
+tf_4k_gen: if SLOWCTRL_BUFFER_SIZE = 1 generate
+ transmit_fifo: entity work.fifo_4kx18x9_wcnt
+ port map(
+ Reset => tx_fifo_reset,
+ RPReset => tx_fifo_reset,
+ WrClock => CLK,
+ RdClock => CLK,
+ Data => tx_fifo_data,
+ WrEn => tx_fifo_wr,
+ RdEn => tx_fifo_rd,
+ Q => tx_fifo_q,
+ Full => tx_full,
+ Empty => tx_empty,
+ WCNT => tx_cnt(11 downto 0)
+ );
+end generate tf_4k_gen;
+
+tf_65k_gen: if SLOWCTRL_BUFFER_SIZE = 2 generate
+ transmit_fifo: entity work.fifo_64kx18x9_wcnt
+ port map(
+ Reset => tx_fifo_reset,
+ RPReset => tx_fifo_reset,
+ WrClock => CLK,
+ RdClock => CLK,
+ Data => tx_fifo_data,
+ WrEn => tx_fifo_wr,
+ RdEn => tx_fifo_rd,
+ Q => tx_fifo_q,
+ Full => tx_full,
+ Empty => tx_empty,
+ WCNT => tx_cnt
+ );
+end generate tf_65k_gen;
+
+TX_FIFO_WR_SYNC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( GSC_REPLY_DATAREADY_IN = '1' and gsc_reply_read = '1' ) then
+ tx_fifo_wr <= '1';
+ elsif( saved_hdr_ctr = "0010" ) then
+ tx_fifo_wr <= '1';
+ else
+ tx_fifo_wr <= '0';
+ end if;
+
+ if( saved_hdr_ctr = "010" ) then
+ tx_fifo_data <= '0' & PS_DATA_IN(7 downto 0) & '0' & x"02";
+ else
+ tx_fifo_data(7 downto 0) <= GSC_REPLY_DATA_IN(15 downto 8);
+ tx_fifo_data(8) <= '0';
+ tx_fifo_data(16 downto 9) <= GSC_REPLY_DATA_IN(7 downto 0);
+ tx_fifo_data(17) <= '0';
+ end if;
+ end if;
+end process TX_FIFO_WR_SYNC;
+
+tx_fifo_rd <= '1' when TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1' else '0';
+
+TX_FIFO_SYNC_PROC: process( CLK, RESET )
+begin
+ if ( RESET = '1' ) then
+ tx_fifo_reset <= '1';
+ elsif( rising_edge(CLK) ) then
+ if( too_much_data = '1' and dissect_current_state = CLEANUP ) then
+ tx_fifo_reset <= '1';
+ else
+ tx_fifo_reset <= '0';
+ end if;
+ end if;
+end process TX_FIFO_SYNC_PROC;
+
+TC_DATA_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+
+ TC_DATA_OUT(7 downto 0) <= tx_fifo_q(7 downto 0);
+
+ if( tx_loaded_ctr = tx_data_ctr ) then
+ TC_DATA_OUT(8) <= '1';
+ else
+ TC_DATA_OUT(8) <= '0';
+ end if;
+ end if;
+end process TC_DATA_PROC;
+
+GSC_REPLY_READ_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( dissect_current_state = WAIT_FOR_RESPONSE or dissect_current_state = SAVE_RESPONSE ) then
+ gsc_reply_read <= '1';
+ else
+ gsc_reply_read <= '0';
+ end if;
+ end if;
+end process GSC_REPLY_READ_PROC;
+GSC_REPLY_READ_OUT <= gsc_reply_read;
+
+-- counter of data received from TRBNet hub
+TX_DATA_CTR_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if (dissect_current_state = IDLE) then
+ tx_data_ctr <= (others => '0');
+ elsif( tx_fifo_wr = '1' ) then
+ tx_data_ctr <= tx_data_ctr + x"2";
+ end if;
+ end if;
+end process TX_DATA_CTR_PROC;
+
+TOO_MUCH_DATA_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( dissect_current_state = IDLE ) then
+ too_much_data <= '0';
+ elsif( (dissect_current_state = SAVE_RESPONSE) and (tx_data_ctr = CFG_MAX_REPLY_SIZE_IN(15 downto 0)) ) then
+ too_much_data <= '1';
+ end if;
+ end if;
+end process TOO_MUCH_DATA_PROC;
+
+-- total counter of data transported to frame constructor
+TX_LOADED_CTR_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( dissect_current_state = IDLE ) then
+ tx_loaded_ctr <= x"0000";
+ elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then
+ tx_loaded_ctr <= tx_loaded_ctr + x"1";
+ end if;
+ end if;
+end process TX_LOADED_CTR_PROC;
+
+PS_RESPONSE_SYNC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if( too_much_data = '0' ) 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;
+ end if;
+
+ if( dissect_current_state = IDLE or dissect_current_state = WAIT_FOR_RESPONSE ) then
+ PS_BUSY_OUT <= '0';
+ else
+ PS_BUSY_OUT <= '1';
+ end if;
+ end if;
+end process PS_RESPONSE_SYNC;
+
+TC_FRAME_TYPE_OUT <= x"0008";
+TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN;
+TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN;
+TC_DEST_UDP_OUT(7 downto 0) <= PS_SRC_UDP_PORT_IN(15 downto 8);
+TC_DEST_UDP_OUT(15 downto 8) <= PS_SRC_UDP_PORT_IN(7 downto 0);
+TC_SRC_MAC_OUT <= MY_MAC_IN;
+TC_SRC_IP_OUT <= MY_IP_IN;
+TC_SRC_UDP_OUT <= x"9065"; --x"a861";
+TC_IP_PROTOCOL_OUT <= x"11";
+TC_IDENT_OUT <= x"3" & reply_ctr(11 downto 0);
+
+TC_FRAME_SIZE_OUT <= tx_data_ctr;
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+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, reset_detected, too_much_data, PS_WR_EN_IN, PS_ACTIVATE_IN,
+ PS_DATA_IN, PS_SELECTED_IN, GSC_INIT_READ_IN, GSC_REPLY_DATAREADY_IN, tx_loaded_ctr,
+ tx_data_ctr, rx_fifo_q, GSC_BUSY_IN)
+begin
+ state <= x"0";
+
+ case dissect_current_state is
+
+ when IDLE =>
+ state <= x"1";
+ 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 =>
+ state <= x"2";
+ if (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '0')) then
+ dissect_next_state <= WAIT_FOR_HUB;
+ elsif (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '1')) then
+ dissect_next_state <= LOAD_TO_HUB;
+ else
+ dissect_next_state <= READ_FRAME;
+ end if;
+
+ when WAIT_FOR_HUB =>
+ state <= x"3";
+ if (GSC_INIT_READ_IN = '1') then
+ dissect_next_state <= LOAD_TO_HUB;
+ else
+ dissect_next_state <= WAIT_FOR_HUB;
+ end if;
+
+ when LOAD_TO_HUB =>
+ state <= x"4";
+ if ((rx_fifo_q(17) = '1') and (GSC_INIT_READ_IN = '1')) then
+ if (reset_detected = '1') then
+ dissect_next_state <= CLEANUP;
+ else
+ dissect_next_state <= WAIT_FOR_RESPONSE;
+ end if;
+ else
+ dissect_next_state <= LOAD_TO_HUB;
+ end if;
+
+ when WAIT_FOR_RESPONSE =>
+ state <= x"5";
+ if (GSC_REPLY_DATAREADY_IN = '1') then
+ dissect_next_state <= SAVE_RESPONSE;
+ else
+ dissect_next_state <= WAIT_FOR_RESPONSE;
+ end if;
+
+ when SAVE_RESPONSE =>
+ state <= x"6";
+ if (GSC_REPLY_DATAREADY_IN = '0' and GSC_BUSY_IN = '0') then
+ if (too_much_data = '0') then
+ dissect_next_state <= WAIT_FOR_LOAD;
+ else
+ dissect_next_state <= CLEANUP;
+ end if;
+ else
+ dissect_next_state <= SAVE_RESPONSE;
+ end if;
+
+ when WAIT_FOR_LOAD =>
+ state <= x"7";
+ if (PS_SELECTED_IN = '1') then
+ dissect_next_state <= LOAD_FRAME;
+ else
+ dissect_next_state <= WAIT_FOR_LOAD;
+ end if;
+
+ when LOAD_FRAME =>
+ state <= x"8";
+ if (tx_loaded_ctr = tx_data_ctr) then
+ dissect_next_state <= CLEANUP;
+ else
+ dissect_next_state <= LOAD_FRAME;
+ end if;
+
+ when CLEANUP =>
+ state <= x"9";
+ dissect_next_state <= IDLE;
+
+ when others => dissect_next_state <= IDLE;
+
+ end case;
+end process DISSECT_MACHINE;
+
+-- reset request packet detection
+RESET_DETECTED_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( dissect_current_state = IDLE ) then
+ reset_detected <= '0';
+ elsif( PS_DATA_IN(7 downto 0) = x"80" and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr = "0100" ) then
+ reset_detected <= '1';
+ end if;
+ end if;
+end process RESET_DETECTED_PROC;
+
+MAKE_RESET_PROC: process( CLK )
+begin
+ if( rising_edge(CLK) ) then
+ if ( dissect_current_state = IDLE ) then
+ make_reset <= '0';
+ elsif( dissect_current_state = CLEANUP and reset_detected = '1' ) then
+ make_reset <= '1';
+ end if;
+ end if;
+end process MAKE_RESET_PROC;
+
+
+-- monitoring
+
+hist_ctrs_gen : for i in 0 to 31 generate
+
+ process( CLK )
+ begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ reset_all_hist(i) <= '1';
+ elsif (hist_inst(i) = x"ffff_ffff") then
+ reset_all_hist(i) <= '1';
+ else
+ reset_all_hist(i) <= '0';
+ end if;
+ end if;
+ end process;
+
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if (reset_all_hist /= x"0000_0000") then
+ hist_inst(i) <= (others => '0');
+ elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr and i = to_integer(unsigned(tx_data_ctr(15 downto 11)))) then
+ hist_inst(i) <= hist_inst(i) + x"1";
+ else
+ hist_inst(i) <= hist_inst(i);
+ end if;
+ end if;
+ end process;
+
+end generate hist_ctrs_gen;
+
+DATA_HIST_OUT <= hist_inst;
+
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ DEBUG_OUT(0) <= rx_full;
+ DEBUG_OUT(1) <= rx_empty;
+ DEBUG_OUT(2) <= tx_full;
+ DEBUG_OUT(3) <= tx_empty;
+ DEBUG_OUT(7 downto 4) <= state;
+ DEBUG_OUT(23 downto 8) <= rx_cnt;
+ DEBUG_OUT(39 downto 24) <= tx_cnt;
+ DEBUG_OUT(63 downto 40) <= (others => '0');
+ end if;
+end process;
+
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ mon_rec_frames <= (others => '0');
+ elsif (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') then
+ mon_rec_frames <= mon_rec_frames + x"1";
+ else
+ mon_rec_frames <= mon_rec_frames;
+ end if;
+ end if;
+end process;
+MONITOR_SELECT_REC_OUT <= mon_rec_frames;
+
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ mon_rec_bytes <= (others => '0');
+ elsif (rx_fifo_wr = '1') then
+ mon_rec_bytes <= mon_rec_bytes + x"1";
+ else
+ mon_rec_bytes <= mon_rec_bytes;
+ end if;
+ end if;
+end process;
+MONITOR_SELECT_REC_BYTES_OUT <= mon_rec_bytes;
+
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ mon_sent_frames <= (others => '0');
+ elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr) then
+ mon_sent_frames <= mon_sent_frames + x"1";
+ else
+ mon_sent_frames <= mon_sent_frames;
+ end if;
+ end if;
+end process;
+MONITOR_SELECT_SENT_OUT <= mon_sent_frames;
+
+process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ mon_sent_bytes <= (others => '0');
+ elsif (tx_fifo_rd = '1') then
+ mon_sent_bytes <= mon_sent_bytes + x"1";
+ else
+ mon_sent_bytes <= mon_sent_bytes;
+ end if;
+ end if;
+end process;
+MONITOR_SELECT_SENT_BYTES_OUT <= mon_sent_bytes;
+
+-- needed for identification
+REPLY_CTR_PROC : process( CLK )
+begin
+ if rising_edge(CLK) then
+ if (RESET = '1') then
+ reply_ctr <= (others => '0');
+ elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr) then
+ reply_ctr <= reply_ctr + x"1";
+ end if;
+ end if;
+end process REPLY_CTR_PROC;
+
+end architecture gbe_response_constructor_SCTRL_arch;
-LIBRARY IEEE;
-USE IEEE.std_logic_1164.ALL;
-USE IEEE.std_logic_ARITH.ALL;
-USE IEEE.std_logic_UNSIGNED.ALL;
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-use work.trb_net_gbe_components.all;
-use work.med_sync_define_RS.all;
+ use work.trb_net_std.all;
+ use work.med_sync_define_RS.all;
-- short documentation:
-- LINK_MODE: set to c_IS_SLAVE for uplink port, c_IS_MASTER for downlink port,
);
-- RX ringbuffer
- THE_FW_RB: entity rx_rb
+ THE_FW_RB: entity work.gbe_rx_rb
port map(
CLK => MASTER_CLK_IN,
RESET => CLEAR, --RESET, -- CHECKIFWORKS
--- /dev/null
+--Media interface TX state machine\r
+\r
+LIBRARY IEEE;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.numeric_std.all;\r
+\r
+entity gbe_tx_reset is\r
+ port(\r
+ CLEAR : in std_logic; -- async reset, active high, should not be used!\r
+ CLK_REF : in std_logic; -- usually local oscillator sourced \r
+ TX_PLL_LOL_IN : in std_logic; -- externally or'ed\r
+ TX_CLOCK_AVAIL_IN : in std_logic; -- suitable TX clock available \r
+ TX_PCS_RST_CH_C_OUT : out std_logic; -- PCS reset\r
+ SYNC_TX_QUAD_OUT : out std_logic; -- sync all QUADs to TX bit 0\r
+ LINK_TX_READY_OUT : out std_logic; -- TX lane can use used now\r
+ STATE_OUT : out std_logic_vector(3 downto 0)\r
+ );\r
+end entity gbe_tx_reset;\r
+\r
+architecture gbe_tx_reset_arch of gbe_tx_reset is\r
+\r
+ constant count_index : integer := 18; -- end of timer\r
+\r
+ type statetype is ( IDLE, WAIT_FOR_TIMER, SYNC_ALL, SYNC_DONE, NORMAL );\r
+\r
+ signal CURRENT_STATE : statetype; -- current state of lsm\r
+ signal NEXT_STATE : statetype; -- next state of lsm\r
+ \r
+ signal tx_pcs_rst_ch_c_int : std_logic;\r
+ signal sync_tx_quad_int : std_logic;\r
+ signal link_tx_ready_int : std_logic;\r
+ signal sync_tx_quad_trans : std_logic;\r
+ \r
+ signal tx_pll_lol_all_q : std_logic; -- synced\r
+ signal tx_clock_avail_q : std_logic; -- synced\r
+ \r
+ signal counter : unsigned(count_index downto 0);\r
+ signal timer : std_logic;\r
+ signal reset_timer : std_logic;\r
+\r
+begin\r
+\r
+-- This reset handler takes care of enabling all TX SerDes blocks in parallel,\r
+-- independently of RX SerDes blocks. The only difference between master and slave\r
+-- ports is the TX_CLOCK_AVAIL_IN input signal.\r
+-- This will delay the TX SerDes startup until the slave RX port is fully active.\r
+\r
+-- synchronize, just to be on the safe side\r
+ SYNC_SFP_SIGS : entity work.signal_sync\r
+ generic map(\r
+ WIDTH => 2,\r
+ DEPTH => 3\r
+ )\r
+ port map(\r
+ RESET => '0',\r
+ CLK0 => CLK_REF, \r
+ CLK1 => CLK_REF,\r
+ D_IN(0) => TX_PLL_LOL_IN, \r
+ D_IN(1) => TX_CLOCK_AVAIL_IN,\r
+ D_OUT(0) => tx_pll_lol_all_q,\r
+ D_OUT(1) => tx_clock_avail_q\r
+ );\r
+\r
+-- Timer\r
+ THE_TIMER_PROC: process( CLK_REF )\r
+ begin\r
+ if( rising_edge(CLK_REF) ) then\r
+ if( reset_timer = '1' ) then\r
+ counter <= (others => '0');\r
+ else\r
+ if( counter(count_index) = '0' ) then\r
+ counter <= counter + 1 ;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process THE_TIMER_PROC;\r
+\r
+ timer <= counter(count_index);\r
+\r
+-- State machine clocked process\r
+ THE_FSM_PROC: process( CLK_REF, CLEAR )\r
+ begin\r
+ if( CLEAR = '1' ) then\r
+ CURRENT_STATE <= IDLE;\r
+ TX_PCS_RST_CH_C_OUT <= '1';\r
+ LINK_TX_READY_OUT <= '0';\r
+ else \r
+ if( rising_edge(CLK_REF) ) then\r
+ CURRENT_STATE <= NEXT_STATE;\r
+ TX_PCS_RST_CH_C_OUT <= tx_pcs_rst_ch_c_int;\r
+ LINK_TX_READY_OUT <= link_tx_ready_int;\r
+ end if;\r
+ end if;\r
+ end process THE_FSM_PROC;\r
+\r
+ THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer, tx_pll_lol_all_q, tx_clock_avail_q )\r
+ begin\r
+ reset_timer <= '0';\r
+ tx_pcs_rst_ch_c_int <= '0';\r
+ sync_tx_quad_int <= '0';\r
+ link_tx_ready_int <= '0';\r
+ STATE_OUT <= x"F";\r
+\r
+ case CURRENT_STATE is\r
+\r
+ when IDLE =>\r
+ STATE_OUT <= x"1";\r
+ tx_pcs_rst_ch_c_int <= '1';\r
+ reset_timer <= '1';\r
+ if( tx_clock_avail_q = '1' ) then\r
+ NEXT_STATE <= WAIT_FOR_TIMER;\r
+ else\r
+ NEXT_STATE <= IDLE;\r
+ end if;\r
+\r
+ when WAIT_FOR_TIMER =>\r
+ STATE_OUT <= x"2";\r
+ tx_pcs_rst_ch_c_int <= '1';\r
+ if( timer = '1' ) then\r
+ if( tx_pll_lol_all_q = '0' ) then\r
+ NEXT_STATE <= SYNC_ALL;\r
+ else\r
+ NEXT_STATE <= IDLE; -- restart timer\r
+ end if;\r
+ else\r
+ NEXT_STATE <= WAIT_FOR_TIMER;\r
+ end if;\r
+\r
+ when SYNC_ALL =>\r
+ STATE_OUT <= x"3";\r
+ tx_pcs_rst_ch_c_int <= '1';\r
+ reset_timer <= '1';\r
+ sync_tx_quad_int <= '1';\r
+ NEXT_STATE <= SYNC_DONE;\r
+\r
+ when SYNC_DONE =>\r
+ STATE_OUT <= x"4";\r
+ if( timer = '1' ) then\r
+ NEXT_STATE <= NORMAL;\r
+ else\r
+ NEXT_STATE <= SYNC_DONE;\r
+ end if;\r
+\r
+ when NORMAL =>\r
+ STATE_OUT <= x"5";\r
+ tx_pcs_rst_ch_c_int <= '0';\r
+ link_tx_ready_int <= '1';\r
+ reset_timer <= '1';\r
+ if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then\r
+ NEXT_STATE <= IDLE;\r
+ else\r
+ NEXT_STATE <= NORMAL;\r
+ end if;\r
+\r
+ when others =>\r
+ STATE_OUT <= x"f";\r
+ NEXT_STATE <= IDLE;\r
+\r
+ end case;\r
+\r
+ end process THE_FSM_DECODE_PROC;\r
+\r
+ -- TX serializer is operational "at level" of this signal, \r
+ -- and gets reset by a transition (according to SerDes Usage Guide).\r
+ -- Timer1 is used to delay the TX link ready signal by some cycles.\r
+ THE_QUAD_SYNC_PROC: process( CLK_REF, CLEAR )\r
+ begin\r
+ if( CLEAR = '1' ) then\r
+ sync_tx_quad_trans <= '0';\r
+ else \r
+ if( rising_edge(CLK_REF) ) then\r
+ if( sync_tx_quad_int = '1' ) then\r
+ sync_tx_quad_trans <= not sync_tx_quad_trans;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process THE_QUAD_SYNC_PROC;\r
+\r
+ SYNC_TX_QUAD_OUT <= sync_tx_quad_trans;\r
+\r
+end architecture gbe_tx_reset_arch;\r
\r
signal sda_drv : std_logic;\r
signal scl_drv : std_logic;\r
- \r
- -- Components\r
- component i2c_slim is\r
- port(\r
- CLOCK : in std_logic;\r
- RESET : in std_logic;\r
- -- I2C command / setup\r
- I2C_GO_IN : in std_logic; -- startbit to trigger I2C actions\r
- ACTION_IN : in std_logic; -- '0' -> write, '1' -> read\r
- WORD_IN : in std_logic; -- '0' -> byte, '1' -> word\r
- I2C_SPEED_IN : in std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
- I2C_ADDR_IN : in std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
- I2C_CMD_IN : in std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
- I2C_DW_IN : in std_logic_vector(15 downto 0); -- data word for write command\r
- I2C_DR_OUT : out std_logic_vector(15 downto 0); -- data word from read command\r
- STATUS_OUT : out std_logic_vector(7 downto 0); -- status and error bits\r
- VALID_OUT : out std_logic;\r
- I2C_BUSY_OUT : out std_logic;\r
- I2C_DONE_OUT : out std_logic;\r
- -- I2C connections\r
- SDA_IN : in std_logic;\r
- SDA_OUT : out std_logic;\r
- SCL_IN : in std_logic;\r
- SCL_OUT : out std_logic;\r
- -- Debug\r
- BSM_OUT : out std_logic_vector(4 downto 0)\r
- );\r
- end component i2c_slim;\r
-\r
-\r
\r
begin\r
\r
end if;\r
end process THE_TIME_COUNTER_PROC;\r
\r
-THE_I2C_SLIM: i2c_slim \r
+THE_I2C_SLIM: entity i2c_slim \r
port map(\r
CLOCK => CLK,\r
RESET => RESET,\r
\r
signal sda_drv : std_logic;\r
signal scl_drv : std_logic;\r
- \r
- -- Components\r
- component i2c_slim2 is\r
- port(\r
- CLOCK : in std_logic;\r
- RESET : in std_logic;\r
- -- I2C command / setup\r
- I2C_GO_IN : in std_logic; -- startbit to trigger I2C actions\r
- ACTION_IN : in std_logic; -- '0' -> write, '1' -> read\r
- WORD_IN : in std_logic; -- '0' -> byte, '1' -> word\r
- DIRECT_IN : in std_logic; -- '0' -> normal access, '1' -> direct read\r
- I2C_SPEED_IN : in std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
- I2C_ADDR_IN : in std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
- I2C_CMD_IN : in std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
- I2C_DW_IN : in std_logic_vector(15 downto 0); -- data word for write command\r
- I2C_DR_OUT : out std_logic_vector(15 downto 0); -- data word from read command\r
- STATUS_OUT : out std_logic_vector(7 downto 0); -- status and error bits\r
- VALID_OUT : out std_logic;\r
- I2C_BUSY_OUT : out std_logic;\r
- I2C_DONE_OUT : out std_logic;\r
- -- I2C connections\r
- SDA_IN : in std_logic;\r
- SDA_OUT : out std_logic;\r
- SCL_IN : in std_logic;\r
- SCL_OUT : out std_logic;\r
- -- Debug\r
- BSM_OUT : out std_logic_vector(3 downto 0)\r
- );\r
- end component i2c_slim2;\r
\r
begin\r
\r
end if;\r
end process THE_TIME_COUNTER_PROC;\r
\r
-THE_I2C_SLIM: i2c_slim2 \r
+THE_I2C_SLIM: entity i2c_slim2 \r
port map(\r
CLOCK => CLK,\r
RESET => RESET,\r
---------------------------------------
-- a sbuf (to_int direction)
---------------------------------------
--- gen_int_sbuf : if SECURE_MODE_TO_INT = 1 generate
- SBUF: trb_net16_sbuf
- generic map (
- VERSION => SBUF_VERSION)
- port map (
- CLK => CLK,
- RESET => RESET,
- CLK_EN => CLK_EN,
- COMB_DATAREADY_IN => next_INT_MASTER_DATAREADY_OUT,
- COMB_next_READ_OUT => sbuf_next_READ,
- COMB_READ_IN => '1',
- COMB_DATA_IN => next_INT_MASTER_DATA_OUT,
- COMB_PACKET_NUM_IN => next_INT_MASTER_PACKET_NUM_OUT,
- SYN_DATAREADY_OUT => buf_INT_MASTER_DATAREADY_OUT,
- SYN_DATA_OUT => INT_MASTER_DATA_OUT,
- SYN_PACKET_NUM_OUT => buf_INT_MASTER_PACKET_NUM_OUT,
- SYN_READ_IN => INT_MASTER_READ_IN,
- STAT_BUFFER => sbuf_status(0)
- );
+ SBUF: trb_net16_sbuf
+ generic map (
+ VERSION => SBUF_VERSION)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ COMB_DATAREADY_IN => next_INT_MASTER_DATAREADY_OUT,
+ COMB_next_READ_OUT => sbuf_next_READ,
+ COMB_READ_IN => '1',
+ COMB_DATA_IN => next_INT_MASTER_DATA_OUT,
+ COMB_PACKET_NUM_IN => next_INT_MASTER_PACKET_NUM_OUT,
+ SYN_DATAREADY_OUT => buf_INT_MASTER_DATAREADY_OUT,
+ SYN_DATA_OUT => INT_MASTER_DATA_OUT,
+ SYN_PACKET_NUM_OUT => buf_INT_MASTER_PACKET_NUM_OUT,
+ SYN_READ_IN => INT_MASTER_READ_IN,
+ STAT_BUFFER => sbuf_status(0)
+ );
- process(CLK)
- begin
- if rising_edge(CLK) then
- if RESET = '1' then
- sbuf_free <= '0';
- elsif CLK_EN = '1' then
- sbuf_free <= sbuf_next_READ or INT_MASTER_READ_IN;
- end if;
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ sbuf_free <= '0';
+ elsif CLK_EN = '1' then
+ sbuf_free <= sbuf_next_READ or INT_MASTER_READ_IN;
end if;
- end process;
--- end generate;
-
--- gen_int_nonsbuf : if SECURE_MODE_TO_INT = 0 generate
--- buf_INT_MASTER_DATAREADY_OUT <= next_INT_MASTER_DATAREADY_OUT;
--- INT_MASTER_DATA_OUT <= next_INT_MASTER_DATA_OUT;
--- buf_INT_MASTER_PACKET_NUM_OUT <= next_INT_MASTER_PACKET_NUM_OUT;
--- sbuf_free <= INT_MASTER_READ_IN;
--- end generate;
+ end if;
+ end process;
INT_MASTER_PACKET_NUM_OUT <= buf_INT_MASTER_PACKET_NUM_OUT;
INT_MASTER_DATAREADY_OUT <= buf_INT_MASTER_DATAREADY_OUT;
-
---------------------------------------
-- a sbuf (to_apl direction)
---------------------------------------
--- gen_apl_sbuf : if SECURE_MODE_TO_APL = 1 generate
- SBUF_TO_APL: trb_net16_sbuf
- generic map (
- VERSION => SBUF_VERSION)
- port map (
- CLK => CLK,
- RESET => RESET,
- CLK_EN => CLK_EN,
- COMB_DATAREADY_IN => next_APL_DATAREADY_OUT,
- COMB_next_READ_OUT => sbuf_to_apl_next_READ,
- COMB_READ_IN => '1',
- COMB_DATA_IN => next_APL_DATA_OUT,
- COMB_PACKET_NUM_IN => next_APL_PACKET_NUM_OUT,
- SYN_DATAREADY_OUT => reg_APL_DATAREADY_OUT,
- SYN_DATA_OUT => reg_APL_DATA_OUT,
- SYN_PACKET_NUM_OUT => reg_APL_PACKET_NUM_OUT,
- SYN_READ_IN => APL_READ_IN,
- STAT_BUFFER => sbuf_status(1)
- );
-
+ SBUF_TO_APL: trb_net16_sbuf
+ generic map (
+ VERSION => SBUF_VERSION)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ COMB_DATAREADY_IN => next_APL_DATAREADY_OUT,
+ COMB_next_READ_OUT => sbuf_to_apl_next_READ,
+ COMB_READ_IN => '1',
+ COMB_DATA_IN => next_APL_DATA_OUT,
+ COMB_PACKET_NUM_IN => next_APL_PACKET_NUM_OUT,
+ SYN_DATAREADY_OUT => reg_APL_DATAREADY_OUT,
+ SYN_DATA_OUT => reg_APL_DATA_OUT,
+ SYN_PACKET_NUM_OUT => reg_APL_PACKET_NUM_OUT,
+ SYN_READ_IN => APL_READ_IN,
+ STAT_BUFFER => sbuf_status(1)
+ );
- SBUF_TO_APL2: trb_net_sbuf
- generic map (
- VERSION => SBUF_VERSION,
- DATA_WIDTH => 3)
- port map (
- CLK => CLK,
- RESET => RESET,
- CLK_EN => CLK_EN,
- COMB_DATAREADY_IN => next_APL_DATAREADY_OUT,
- COMB_next_READ_OUT => open,
- COMB_READ_IN => '1',
- COMB_DATA_IN => next_APL_TYP_OUT,
- SYN_DATAREADY_OUT => sbuf_apl_type_dataready,
- SYN_DATA_OUT => buf_APL_TYP_OUT,
- SYN_READ_IN => APL_READ_IN,
- STAT_BUFFER => sbuf_status(2)
- );
+ SBUF_TO_APL2: trb_net_sbuf
+ generic map (
+ VERSION => SBUF_VERSION,
+ DATA_WIDTH => 3)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ COMB_DATAREADY_IN => next_APL_DATAREADY_OUT,
+ COMB_next_READ_OUT => open,
+ COMB_READ_IN => '1',
+ COMB_DATA_IN => next_APL_TYP_OUT,
+ SYN_DATAREADY_OUT => sbuf_apl_type_dataready,
+ SYN_DATA_OUT => buf_APL_TYP_OUT,
+ SYN_READ_IN => APL_READ_IN,
+ STAT_BUFFER => sbuf_status(2)
+ );
- reg_APL_TYP_OUT <= TYPE_ILLEGAL when reg_APL_DATAREADY_OUT = '0' else buf_APL_TYP_OUT;
- process(CLK)
- begin
- if rising_edge(CLK) then
- if RESET = '1' then
- sbuf_to_apl_free <= '0';
- elsif CLK_EN = '1' then
- sbuf_to_apl_free <= sbuf_to_apl_next_READ;
- end if;
+ reg_APL_TYP_OUT <= TYPE_ILLEGAL when reg_APL_DATAREADY_OUT = '0' else buf_APL_TYP_OUT;
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ sbuf_to_apl_free <= '0';
+ elsif CLK_EN = '1' then
+ sbuf_to_apl_free <= sbuf_to_apl_next_READ;
end if;
- end process;
--- end generate;
-
--- gen_apl_nonsbuf : if SECURE_MODE_TO_APL = 0 generate
--- reg_APL_DATAREADY_OUT <= next_APL_DATAREADY_OUT;
--- reg_APL_DATA_OUT <= next_APL_DATA_OUT;
--- reg_APL_PACKET_NUM_OUT <= next_APL_PACKET_NUM_OUT;
--- reg_APL_TYP_OUT <= next_APL_TYP_OUT;
--- sbuf_to_apl_free <= APL_READ_IN;
--- end generate;
+ end if;
+ end process;
next_APL_DATA_OUT <= fifo_to_apl_data_out;
next_APL_PACKET_NUM_OUT <= fifo_to_apl_long_packet_num_out;
-- save packet type
---------------------------------------
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
-- select data for int direction
---------------------------------------
-
- process(current_combined_header, current_registered_trailer, current_data, out_select)
+ process( current_combined_header, current_registered_trailer, current_data, out_select )
begin
case out_select is
when HDR => next_INT_MASTER_DATA_OUT <= current_combined_header;
end case;
end process;
-
-
process(master_counter, fifo_to_int_data_out, registered_trailer_F1,
registered_trailer_F2, registered_trailer_F3, registered_trailer_F0,
registered_header_F0, registered_header_F1, registered_header_F2,
-- fifo to apl
---------------------------------------
--- GEN_FIFO_TO_APL: if FIFO_TO_APL_DEPTH >0 generate
- FIFO_TO_APL: trb_net16_fifo
- generic map (
- DEPTH => FIFO_TO_APL_DEPTH,
- USE_VENDOR_CORES => USE_VENDOR_CORES)
- port map (
- CLK => CLK,
- RESET => RESET,
- CLK_EN => CLK_EN,
- DATA_IN => fifo_to_apl_data_in,
- PACKET_NUM_IN => fifo_to_apl_packet_num_in,
- WRITE_ENABLE_IN => fifo_to_apl_write,
- DATA_OUT => next_fifo_to_apl_data_out,
- PACKET_NUM_OUT => next_fifo_to_apl_packet_num_out,
- READ_ENABLE_IN => fifo_to_apl_read,
- DATA_COUNT_OUT => fifo_to_apl_data_count,
- FULL_OUT => fifo_to_apl_full,
- EMPTY_OUT => next_fifo_to_apl_empty
- );
--- end generate;
-
--- GEN_DUMMY_FIFO_TO_APL: if FIFO_TO_APL_DEPTH = 0 generate
--- FIFO_TO_APL: trb_net16_dummy_fifo
--- port map (
--- CLK => CLK,
--- RESET => RESET,
--- CLK_EN => CLK_EN,
--- DATA_IN => fifo_to_apl_data_in,
--- PACKET_NUM_IN => fifo_to_apl_packet_num_in,
--- WRITE_ENABLE_IN => fifo_to_apl_write,
--- DATA_OUT => next_fifo_to_apl_data_out,
--- PACKET_NUM_OUT => next_fifo_to_apl_packet_num_out,
--- READ_ENABLE_IN => fifo_to_apl_read,
--- FULL_OUT => fifo_to_apl_full,
--- EMPTY_OUT => next_fifo_to_apl_empty
--- );
--- end generate;
+ FIFO_TO_APL: trb_net16_fifo
+ generic map (
+ DEPTH => FIFO_TO_APL_DEPTH,
+ USE_VENDOR_CORES => USE_VENDOR_CORES)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ DATA_IN => fifo_to_apl_data_in,
+ PACKET_NUM_IN => fifo_to_apl_packet_num_in,
+ WRITE_ENABLE_IN => fifo_to_apl_write,
+ DATA_OUT => next_fifo_to_apl_data_out,
+ PACKET_NUM_OUT => next_fifo_to_apl_packet_num_out,
+ READ_ENABLE_IN => fifo_to_apl_read,
+ DATA_COUNT_OUT => fifo_to_apl_data_count,
+ FULL_OUT => fifo_to_apl_full,
+ EMPTY_OUT => next_fifo_to_apl_empty
+ );
---------------------------------------
-- keep track of fifo to apl read operations
---------------------------------------
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
-- keep track of fifo to int read operations
---------------------------------------
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
end if;
end process;
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if APL_SEND_IN = '1' then
fifo_to_int_long_packet_num_out(0) <= fifo_to_int_packet_num_out(0);
fifo_to_int_long_packet_num_out(1) <= not saved_fifo_to_int_long_packet_num_out(1) when last_fifo_to_int_read = '1' and not saved_fifo_to_int_long_packet_num_out(2) = '1' and saved_fifo_to_int_long_packet_num_out(0) = '1' else saved_fifo_to_int_long_packet_num_out(1);
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
fifo_to_apl_long_packet_num_out(0) <= fifo_to_apl_packet_num_out(0);
fifo_to_apl_long_packet_num_out(1) <= not saved_fifo_to_apl_long_packet_num_out(1) when last_fifo_to_apl_read = '1' and not saved_fifo_to_apl_long_packet_num_out(2) = '1' and saved_fifo_to_apl_long_packet_num_out(0) = '1' else saved_fifo_to_apl_long_packet_num_out(1);
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
end if;
end process;
-
-
---------------------------------------
--state machine for direction to APL
---------------------------------------
end process;
- PROC_FSM_REG : process(CLK)
+ PROC_FSM_REG: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
end if;
end process;
- PROC_SEQ_CNT : process(CLK)
+ PROC_SEQ_CNT: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' or CTRL_SEQNR_RESET = '1' then
end if;
end process;
-
-
PROC_ENDP_REACHED : process(CLK)
begin
if rising_edge(CLK) then
end if;
end process;
-
-
-
---------------------------------------------------------------------
--Connection to FIFOs
---------------------------------------------------------------------
-
-- connect Transmitter port
fifo_to_int_data_in <= APL_DATA_IN;
fifo_to_int_packet_num_in <= APL_PACKET_NUM_IN(2) & APL_PACKET_NUM_IN(0);
--Running Signals
---------------------------------------------------------------------
- RUN_OUT_gen : process(CLK)
+ RUN_OUT_gen: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
end process;
APL_RUN_OUT <= buf_APL_RUN_OUT;
- RUNNING_gen : process(CLK)
+ RUNNING_gen: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
--Header & Trailer Words
---------------------------------------------------------------------
-
--get target address from active APL
gentarget1: if API_TYPE = 1 generate
combined_header_F1 <= APL_TARGET_ADDRESS_IN;
--save target address for passive api
gentarget0: if API_TYPE = 0 generate
- reg_hdr_f1: process(CLK)
+ reg_hdr_f1: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
combined_trailer_F3(11 downto 4) <= sequence_counter; -- SEQNR
combined_trailer_F3(3 downto 0) <= APL_DTYPE_IN;
- PROC_REG3 : process(CLK)
+ PROC_REG3: process( CLK )
begin
if rising_edge(CLK) then
if update_registered_trailer = '1' then
end if;
end process;
- PROC_REG_HDR : process(CLK)
+ PROC_REG_HDR: process( CLK )
begin
if rising_edge(CLK) then
if update_registered_header = '1' then
--Decode FSM states
---------------------------------------------------------------------
- process(state_to_apl)
+ process( state_to_apl )
begin
case state_to_apl is
when sa_IDLE => state_bits_to_apl <= "000";
end case;
end process;
- process(state_to_int)
+ process( state_to_int )
begin
case state_to_int is
when IDLE => state_bits_to_int <= "000";
use work.trb_net_components.all;
use work.config.all;
-
entity trb_net16_endpoint_standalone_sctrl is
generic (
FIFO_TO_INT_DEPTH : integer := 6;
use work.version.all;
use work.config.all;
-
-
-
entity trb_net16_regIO is
generic (
NUM_STAT_REGS : integer range 0 to 6 := 3; --log2 of number of status registers
---------------------------------------------------------------------
--5bit address decoder for registers
---------------------------------------------------------------------
- pattern_gen_inst : trb_net_pattern_gen
+ pattern_gen_inst: trb_net_pattern_gen
generic map(
WIDTH => 5
)
-- trbnet addresses
---------------------------------------------------------------------
- the_addresses : trb_net16_addresses
+ the_addresses: trb_net16_addresses
generic map(
INIT_ADDRESS => INIT_ADDRESS,
INIT_UNIQUE_ID => INIT_UNIQUE_ID,
STAT_DEBUG => buf_STAT_ADDR_DEBUG
);
-
---------------------------------------------------------------------
-- Main State Machine
---------------------------------------------------------------------
- fsm : process(API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN,
+ fsm: process(API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN,
address, saved_Reg_high, saved_Reg_low, saved_operation, current_state,
buf_API_SEND_OUT, next_packet_counter, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT,
REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern, DAT_NO_MORE_DATA_IN,
end process;
- reg_fsm : process(CLK)
+ reg_fsm: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
---------------------------------------------------------------------
-- Packet Numbers
---------------------------------------------------------------------
- reg_packet_counter : process(CLK)
+ reg_packet_counter: process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
end if;
end process;
- next_packet_counter_proc : process(API_READ_IN, buf_API_DATAREADY_OUT, packet_counter)
+ next_packet_counter_proc: process( API_READ_IN, buf_API_DATAREADY_OUT, packet_counter )
begin
if buf_API_DATAREADY_OUT = '1' and API_READ_IN = '1' then
if packet_counter = "011" then
---------------------------------------------------------------------
-- Generate output to API
---------------------------------------------------------------------
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' then
-- Read from DAT port
---------------------------------------------------------------------
--save Dataready_in in case API can not read immediately
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if RESET = '1' or current_state = IDLE then
end if;
end process;
- process(CLK)
+ process( CLK )
begin
if rising_edge(CLK) then
if DAT_DATAREADY_IN = '1' then
COMMON_CTRL_REG_OUT <= buf_COMMON_CTRL_REG_OUT;
- PROC_STROBES : process(CLK)
+ PROC_STROBES: process( CLK )
begin
if rising_edge(CLK) then
COMMON_STAT_REG_STROBE <= next_COMMON_STAT_REG_STROBE;
STAT(30) <= API_READ_IN;
STAT(31) <= '0';
- process(current_state)
+ process( current_state )
begin
case current_state is
when IDLE => state_bits <= "0000";
end case;
end process;
-
STAT_ADDR_DEBUG(2 downto 0) <= state_bits(2 downto 0);
STAT_ADDR_DEBUG(3) <= ADR_DONT_UNDERSTAND;
STAT_ADDR_DEBUG(4) <= API_DATAREADY_IN;
STAT_ADDR_DEBUG(14) <= ADR_SEND_OUT;
STAT_ADDR_DEBUG(15) <= ADR_DATAREADY_OUT;
-
-
end architecture;
-