----------------------------------------------------------------------------------
--						Implementace protokolu APP (vlastni protokol) 			  	  	  --
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.my_constants.all;

entity app_core is
	port (
		GTX_CLK				: in std_logic;
		TX_CLK				: in std_logic;
		RX_CLK				: in std_logic;		
		-- uzivatelske rozhrani vstup
		TX_DATA				: in std_logic_vector(7 downto 0);
		TX_DATA_END			: in std_logic;
		TX_DATA_VLD			: in std_logic;		
		TX_DATA_ACK			: out std_logic;		
		-- uzivatelske rozhrani výstup
		RX_DATA				: out std_logic_vector(7 downto 0);
		RX_DATA_VLD			: out std_logic;
		RX_DATA_GOOD		: out std_logic;
		RX_DATA_BAD			: out std_logic;		
		-- do UDP vrstvy
		DATA_TO_UDP			: out std_logic_vector(7 downto 0);
		DATA_TO_UDP_VLD	: out std_logic;
		DATA_TO_UDP_EN		: in std_logic;	
		-- z UDP vrstvy
		DATA_FROM_UDP		: in std_logic_vector(7 downto 0);
		DATA_FROM_UDP_VLD	: in std_logic;
		DATA_FROM_UDP_GOOD: in std_logic;
		DATA_FROM_UDP_BAD	: in std_logic;
		------------------------------------------------
		-- Ovládací/informační signály pro připojení ke vzdálenému PC
		CONNECT				: in std_logic;
		CLOSE					: in std_logic;
		CONNECTED			: out std_logic;
		------------------------------------------------
		-- reset
		RESET					: in std_logic
	);

end app_core;

architecture Behavioral of app_core is

COMPONENT app_tx
PORT(
		GTX_CLK			: in std_logic;							-- clk pro odmereni casu
		TX_CLK			: in std_logic;							-- clk pro taktovani odesilani
		RX_CLK			: in std_logic;
		-- uzivatelske rozhrani vstup
		TX_DATA			: in std_logic_vector(7 downto 0);
		TX_DATA_VLD		: in std_logic;
		TX_DATA_ACK		: out std_logic;		
		TX_DATA_END		: in std_logic;
		-- do UDP vrstvy
		DATA_TO_UDP		: out std_logic_vector(7 downto 0);
		DATA_TO_UDP_VLD: out std_logic;
		DATA_TO_UDP_EN	: in std_logic;
		-- Control
		SEND_ACK			: in std_logic;
		SEND_SYNC		: in std_logic;
		SEND_ESYN		: in std_logic;
		SEND_ERR			: in std_logic;
		SEND_ADR			: in std_logic_vector(15 downto 0);
		-- Info o prijeti ACK, ERR paketu
		RECV_ACK			: in std_logic;
		RECV_ERR			: in std_logic;
		RECV_ADR			: in std_logic_vector(APP_ADDR_WIDTH-1 downto 0);	
		-- reset
		RESET				: in std_logic
	);
END COMPONENT;

COMPONENT app_rx
PORT(
		RX_CLK				: in std_logic;		
		-- uzivatelske rozhrani výstup
		RX_DATA				: out std_logic_vector(7 downto 0);
		RX_DATA_VLD			: out std_logic;
		RX_DATA_GOOD		: out std_logic;
		RX_DATA_BAD			: out std_logic;		
		-- z UDP vrstvy
		DATA_FROM_UDP		: in std_logic_vector(7 downto 0);
		DATA_FROM_UDP_VLD	: in std_logic;
		DATA_FROM_UDP_GOOD: in std_logic;
		DATA_FROM_UDP_BAD	: in std_logic;		
		--	ovladaci signaly pro komunikaci mezi RX a TX 
		RECV_ADR				: out std_logic_vector(APP_ADDR_WIDTH-1 downto 0);		-- potvrzeni prijeti dat do tohoto ID 
		RECV_ACK				: out std_logic;								-- zadost o odeslani potvrzení	
		RECV_ERR				: out std_logic;									
		SEND_ADR				: out std_logic_vector(15 downto 0);	-- potvrzeni prijeti dat do tohoto ID 
		SEND_ACK				: out std_logic;								-- zadost o odeslani potvrzení
		SEND_SYNC			: out std_logic;								-- potvrzeni zahajeni spojeni		
		SEND_ESYN			: out std_logic;								-- potvrzeni zahajeni spojeni		
		SEND_ERR				: out std_logic;								
		-- kontroluje zda je navazano spojeni
		CONNECTED			: out std_logic;								
		-- reset
		RESET					: in std_logic
	);
END COMPONENT;

signal send_ack_i, send_sync_i, send_esyn_i, send_err_i: std_logic	:= '0';
signal recv_ack_i, recv_err_i, recv_esyn_i, recv_sync_i: std_logic	:= '0';
signal send_adr_i: std_logic_vector(15 downto 0)							:= (others => '0');
signal recv_adr_i: std_logic_vector(APP_ADDR_WIDTH-1 downto 0) 		:= (others => '0');

begin

	-- Ukonceni spojeni (ze strany PC nebo signalem CLOSE)
	send_esyn_i <= recv_esyn_i or CLOSE; 
	send_sync_i <= recv_sync_i or CONNECT;

	Inst_App_tx: App_tx PORT MAP(
		GTX_CLK => GTX_CLK,
		RX_CLK => RX_CLK,
		TX_CLK => TX_CLK,
		TX_DATA => TX_DATA,
		TX_DATA_VLD => TX_DATA_VLD,
		TX_DATA_ACK => TX_DATA_ACK,
		TX_DATA_END => TX_DATA_END,
		DATA_TO_UDP => DATA_TO_UDP,
		DATA_TO_UDP_VLD => DATA_TO_UDP_VLD,
		DATA_TO_UDP_EN => DATA_TO_UDP_EN,
		
		SEND_ACK => send_ack_i,
		SEND_SYNC => send_sync_i,
		SEND_ESYN => send_esyn_i,
		SEND_ERR => send_err_i,
		SEND_ADR => send_adr_i,		
		RECV_ACK => recv_ack_i,
		RECV_ERR => recv_err_i,
		RECV_ADR => recv_adr_i,
		
		RESET => RESET 
	);
	
	Inst_App_rx: App_rx PORT MAP(
		RX_CLK => RX_CLK,
		RX_DATA => RX_DATA,
		RX_DATA_VLD => RX_DATA_VLD,
		RX_DATA_GOOD => RX_DATA_GOOD,
		RX_DATA_BAD => RX_DATA_BAD,
		DATA_FROM_UDP => DATA_FROM_UDP,
		DATA_FROM_UDP_VLD => DATA_FROM_UDP_VLD,
		DATA_FROM_UDP_GOOD => DATA_FROM_UDP_GOOD,
		DATA_FROM_UDP_BAD => DATA_FROM_UDP_BAD,
		
		SEND_ACK => send_ack_i,
		SEND_SYNC => recv_sync_i,
		SEND_ESYN => recv_esyn_i,
		SEND_ERR => send_err_i,
		SEND_ADR => send_adr_i,
		
		RECV_ACK => recv_ack_i,
		RECV_ERR => recv_err_i,
		RECV_ADR => recv_adr_i,

		CONNECTED => CONNECTED,

		RESET => RESET
	);


end Behavioral;

