-- -- Network RX Packet Formatter -- -- removes mac headers and sorts out data width problems -- -- presumes to have a ll_fifo downstream with no dst_rdy flow control coming in -- -- Originally by Matt, then updated to 16 by Erdem, then Matt messed more library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; --use ieee.std_logic_unsigned.all; library utils; use utils.pkg_types.all; library hsio; use hsio.pkg_core_globals.all; entity net_rx_pktfmt16 is generic( BYTESWAP : integer := 1 ); port( -- net side input interface net_data_i : in slv16; -- Erdem slv8; net_sof_i : in std_logic; net_eof_i : in std_logic; net_dst_rdy_o : out std_logic; net_src_rdy_i : in std_logic; -- hsio side side (output) interface hsio_data_o : out slv16 := x"0000"; hsio_sof_o : out std_logic; hsio_eof_o : out std_logic; hsio_dst_rdy_i : in std_logic; hsio_src_rdy_o : out std_logic; rx_src_mac_o : out slv48; clk : in std_logic; rst : in std_logic ); -- Declarations end net_rx_pktfmt16 ; architecture rtl of net_rx_pktfmt16 is signal bcount : integer range 0 to 15; signal bcount_clr : std_logic; signal bcount_inc : std_logic; signal rx_net_hdr : slv16_array (0 to 7) := (others => x"0000"); signal srcdst_rdy : std_logic; signal in_header : std_logic; signal type_check : std_logic; signal net_data : slv16; type states is ( NetHeader, HSIO_SrcRdy, HSIO_SOF, Wait_EOF, Idle, Reset ); signal state, nstate : states; begin gen_byteswap1 : if (BYTESWAP = 1) generate net_data <= net_data_i (7 downto 0) & net_data_i (15 downto 8); end generate; gen_byteswap0 : if (BYTESWAP = 0) generate net_data <= net_data_i; end generate; hsio_data_o <= net_data; -- State Machine -------------------------------------------------------- prc_rxformat_sm_clocked : process (clk) begin if rising_edge(clk) then if (rst = '1') then state <= Reset; else state <= nstate; end if; end if; end process; prc_rx_format_sm_async : process (net_src_rdy_i, net_sof_i, net_eof_i, hsio_dst_rdy_i, bcount, state ) begin --defaults nstate <= Idle; in_header <= '0'; hsio_src_rdy_o <= '0'; hsio_sof_o <= '0'; hsio_eof_o <= '0'; bcount_clr <= '0'; bcount_inc <= '0'; net_dst_rdy_o <= '0'; type_check <= '0'; case state is when Reset => net_dst_rdy_o <= '0'; bcount_clr <= '1'; nstate <= Idle; when Idle => nstate <= Idle; net_dst_rdy_o <= '1'; in_header <= '1'; if (net_src_rdy_i = '1') and (net_sof_i = '1') then bcount_inc <= '1'; nstate <= NetHeader; end if; when NetHeader => -- dst mac, src mac nstate <= NetHeader; net_dst_rdy_o <= '1'; in_header <= '1'; bcount_inc <= '1'; -- we presume no src flow control if (bcount = 4) then -- one less because it inc's (and net_dst_rdy's) 1 more time nstate <= HSIO_SrcRdy; end if; when HSIO_SrcRdy => nstate <= HSIO_SrcRdy; in_header <= '1'; -- otherwise we miss the last word hsio_src_rdy_o <= '1'; if (hsio_dst_rdy_i = '1') then net_dst_rdy_o <= '1'; nstate <= HSIO_SOF; end if; when HSIO_SOF => nstate <= HSIO_SOF; hsio_src_rdy_o <= '1'; hsio_sof_o <= '1'; type_check <= '1'; -- SOF = convenient place marker if (hsio_dst_rdy_i = '1') then net_dst_rdy_o <= '1'; nstate <= Wait_EOF; end if; when Wait_EOF => nstate <= Wait_EOF; hsio_src_rdy_o <= '1'; if (net_eof_i = '1') then hsio_eof_o <= '1'; end if; if (hsio_dst_rdy_i = '1') then net_dst_rdy_o <= '1'; if (net_eof_i = '1') then nstate <= Reset; end if; end if; end case; end process; prc_byte_counter : process (clk) begin if rising_edge(clk) then if (rst = '1') or (bcount_clr = '1') then bcount <= 0; else if (bcount_inc = '1') and (bcount < 7) then bcount <= bcount + 1; end if; end if; end if; end process; prc_src_mac_store : process (clk) begin if rising_edge(clk) then if (in_header = '1') then rx_net_hdr(bcount) <= net_data; end if; -- check if packet us of right type if (type_check = '1') and (net_data(15 downto 4) = x"876") then rx_src_mac_o <= rx_net_hdr(3) & rx_net_hdr(4) & rx_net_hdr(5); end if; end if; end process; end architecture;