----------------------------------------------------------------------------------
--									Implementace protokolu IPv4  			  	  		  		  --
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.my_constants.all;


entity ip_core is
	PORT(
		RX_CLK : 					in std_logic;
		TX_CLK: 						in std_logic;

		-- do transportni vrstvy
		RX_DATA : 					out std_logic_vector(7 downto 0);
		RX_DATA_VLD :				out std_logic;
		RX_DATA_BAD: 				out std_logic;
		RX_DATA_GOOD: 				out std_logic;

		-- z transportni vrsvy
		TX_DATA : 					in std_logic_vector(7 downto 0);
		TX_DATA_LEN: 				in std_logic_vector(UDP_ADDR_WIDTH - 1 downto 0);	
		TX_DATA_VLD: 				in std_logic;								
		TX_DATA_ACK : 				out std_logic;

		-- do mac_core 
		DATA_TO_MAC : 				out std_logic_vector(7 downto 0);
		DATA_TO_MAC_VLD : 		out std_logic;

		-- z mac_core 
		DATA_FROM_MAC : 			in std_logic_vector(7 downto 0);
		DATA_FROM_MAC_VLD : 		in std_logic;
		DATA_FROM_MAC_BAD: 		in std_logic;
		DATA_FROM_MAC_GOOD: 		in std_logic;
		DATA_TO_MAC_ACK : 		in std_logic;

		-- Info / smerovani
		SOURCE_IP:					out std_logic_vector(31 downto 0);
		SOURCE_PROTOCOL:			out std_logic_vector(7 downto 0);
		DESTINATION_IP: 			in std_logic_vector(31 downto 0);	
		DESTINATION_PROTOCOL:   in std_logic_vector(7 downto 0);	

		-- reset
		RESET : 						in std_logic 
	);
end ip_core;

architecture Behavioral of ip_core is

	COMPONENT ip_tx
	PORT(
		TX_CLK: 						in std_logic;
		RX_CLK: 						in std_logic;
		-- z transportni vrsvy
		TX_DATA : 					in std_logic_vector(7 downto 0);
		TX_DATA_LEN: 				in std_logic_vector(UDP_ADDR_WIDTH - 1 downto 0);
		TX_DATA_VLD: 				in std_logic;								 
		TX_DATA_ACK : 				out std_logic;

		-- do mac_core 
		DATA_TO_MAC : 				out std_logic_vector(7 downto 0);
		DATA_TO_MAC_VLD : 		out std_logic;
		DATA_TO_MAC_ACK : 		in std_logic;

		-- z rx_ip 
		ARP_IP_CACHE: 				in std_logic_vector(31 downto 0);
		ARP_MAC_CACHE: 			in std_logic_vector(47 downto 0);
		ARP_REPLY:					in std_logic;
		ARP_REQUEST:				in std_logic;
		
		-- smerovani
		DESTINATION_IP: 			in std_logic_vector(31 downto 0);
		DESTINATION_PROTOCOL:   in std_logic_vector(7 downto 0);

		-- reset
		RESET : 						in std_logic        
		);
	END COMPONENT;

	COMPONENT ip_rx
	PORT(
		RX_CLK : IN std_logic;
		DATA_FROM_MAC : IN std_logic_vector(7 downto 0);
		DATA_FROM_MAC_vld : IN std_logic;
		DATA_FROM_MAC_bad : IN std_logic;
		DATA_FROM_MAC_good : IN std_logic;
		RX_DATA : OUT std_logic_vector(7 downto 0);
		RX_DATA_VLD : OUT std_logic;
		RX_DATA_BAD : OUT std_logic;
		RX_DATA_GOOD : OUT std_logic;
		SOURCE_IP : OUT std_logic_vector(31 downto 0);
		SOURCE_PROTOCOL : OUT std_logic_vector(7 downto 0);
		ARP_MAC : OUT std_logic_vector(47 downto 0);
		ARP_REPLY : OUT std_logic;
		ARP_REQUEST : OUT std_logic;	
		RESET : IN std_logic          
		);
	END COMPONENT;

signal arp_request_i, arp_reply_i: std_logic		:= '0';
signal arp_mac_i: std_logic_vector(47 downto 0) := (others => '0');
signal arp_ip_i: std_logic_vector(31 downto 0)	:= (others => '0');

begin
	
	SOURCE_IP <= arp_ip_i;
	
	Inst_ip_tx: ip_tx PORT MAP(
		TX_CLK => TX_CLK,
		RX_CLK => RX_CLK,
 		
		TX_DATA => TX_DATA,
		TX_DATA_LEN => TX_DATA_LEN,
		TX_DATA_VLD => TX_DATA_VLD,
		TX_DATA_ACK => TX_DATA_ACK,
		
		DATA_TO_MAC => DATA_TO_MAC,
		DATA_TO_MAC_VLD => DATA_TO_MAC_VLD,
		DATA_TO_MAC_ACK => DATA_TO_MAC_ACK,

		ARP_IP_CACHE => arp_ip_i,
		ARP_MAC_CACHE => arp_mac_i,
		ARP_REPLY => arp_reply_i,
		ARP_REQUEST => arp_request_i,
	
		DESTINATION_IP => DESTINATION_IP,
		DESTINATION_PROTOCOL => DESTINATION_PROTOCOL,
		
		RESET => RESET
	);
		
	Inst_ip_rx: ip_rx PORT MAP(
		RX_CLK => RX_CLK,
		RX_DATA => RX_DATA,

		RX_DATA_VLD => RX_DATA_VLD,
		RX_DATA_BAD => RX_DATA_BAD,
		RX_DATA_GOOD => RX_DATA_GOOD,

		DATA_FROM_MAC => DATA_FROM_MAC,
		DATA_FROM_MAC_VLD => DATA_FROM_MAC_VLD,
		DATA_FROM_MAC_BAD => DATA_FROM_MAC_BAD,
		DATA_FROM_MAC_GOOD => DATA_FROM_MAC_GOOD,
		
		ARP_MAC => arp_mac_i,
		ARP_REPLY => arp_reply_i,
		ARP_REQUEST => arp_request_i,

		SOURCE_IP => arp_ip_i,
		SOURCE_PROTOCOL => SOURCE_PROTOCOL,

		RESET => RESET
	);

end Behavioral;

