----------------------------------------------------------------------------------
--									Test bench pro app_core	  			  	  		  		  	  --
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.my_constants.all;
 
ENTITY app_core_tb IS
END app_core_tb;
 
ARCHITECTURE behavior OF app_core_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT app_core
    PORT(
         GTX_CLK : IN  std_logic;
         TX_CLK : IN  std_logic;
         RX_CLK : IN  std_logic;
         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;
         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;
         DATA_TO_UDP : OUT  std_logic_vector(7 downto 0);
         DATA_TO_UDP_VLD : OUT  std_logic;
         DATA_TO_UDP_EN : IN  std_logic;
         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;
         CONNECT : IN  std_logic;
         CLOSE : IN  std_logic;
         CONNECTED : OUT  std_logic;
         RESET : IN  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal GTX_CLK : std_logic := '0';
   signal TX_CLK : std_logic := '0';
   signal RX_CLK : std_logic := '0';
   signal TX_DATA : std_logic_vector(7 downto 0) := (others => '0');
   signal TX_DATA_END : std_logic := '0';
   signal TX_DATA_VLD : std_logic := '0';
   signal DATA_TO_UDP_EN : std_logic := '0';
   signal DATA_FROM_UDP : std_logic_vector(7 downto 0) := (others => '0');
   signal DATA_FROM_UDP_VLD : std_logic := '0';
   signal DATA_FROM_UDP_GOOD : std_logic := '0';
   signal DATA_FROM_UDP_BAD : std_logic := '0';
   signal CONNECT : std_logic := '0';
   signal CLOSE : std_logic := '0';
   signal RESET : std_logic := '0';

 	--Outputs
   signal TX_DATA_ACK : std_logic;
   signal RX_DATA : std_logic_vector(7 downto 0);
   signal RX_DATA_VLD : std_logic;
   signal RX_DATA_GOOD : std_logic;
   signal RX_DATA_BAD : std_logic;
   signal DATA_TO_UDP : std_logic_vector(7 downto 0);
   signal DATA_TO_UDP_VLD : std_logic;
   signal CONNECTED : std_logic;

   -- Clock period definitions
   constant GTX_CLK_period : time := 8 ns;
   constant TX_CLK_period : time := 8 ns;
   constant RX_CLK_period : time := 8 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: app_core PORT MAP (
          GTX_CLK => GTX_CLK,
          TX_CLK => TX_CLK,
          RX_CLK => RX_CLK,
          TX_DATA => TX_DATA,
          TX_DATA_END => TX_DATA_END,
          TX_DATA_VLD => TX_DATA_VLD,
          TX_DATA_ACK => TX_DATA_ACK,
          RX_DATA => RX_DATA,
          RX_DATA_VLD => RX_DATA_VLD,
          RX_DATA_GOOD => RX_DATA_GOOD,
          RX_DATA_BAD => RX_DATA_BAD,
          DATA_TO_UDP => DATA_TO_UDP,
          DATA_TO_UDP_VLD => DATA_TO_UDP_VLD,
          DATA_TO_UDP_EN => DATA_TO_UDP_EN,
          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,
          CONNECT => CONNECT,
          CLOSE => CLOSE,
          CONNECTED => CONNECTED,
          RESET => RESET
        );

   -- Clock process definitions
   GTX_CLK_process :process
   begin
		GTX_CLK <= '0';
		wait for GTX_CLK_period/2;
		GTX_CLK <= '1';
		wait for GTX_CLK_period/2;
   end process;
 
   TX_CLK_process :process
   begin
		TX_CLK <= '0';
		wait for TX_CLK_period/2;
		TX_CLK <= '1';
		wait for TX_CLK_period/2;
   end process;
 
   RX_CLK_process :process
   begin
		RX_CLK <= '0';
		wait for RX_CLK_period/2;
		RX_CLK <= '1';
		wait for RX_CLK_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin		
      -- hold reset state for 100 ns.
      wait for 100 ns;	

      wait for GTX_CLK_period*10;
		wait for 320ns;
		
		DATA_TO_UDP_EN <= '1';
		---------------------------------
		-- SYNC -> navazani spojeni z PC
		---------------------------------		
		DATA_FROM_UDP_VLD <= '1';
		DATA_FROM_UDP <= x"AA";
		wait for 8ns;
		DATA_FROM_UDP <= x"00";
		wait for 24ns;
		DATA_FROM_UDP_VLD <= '0';
		wait for 16ns;
		DATA_FROM_UDP_GOOD <= '1';
		wait for 8ns;
		DATA_FROM_UDP_GOOD <= '0';
		wait for 64ns;
		
		---------------------------------
		-- DATA -> Odeslani xx paketu 
		---------------------------------		
		for i in 0 to 1 loop
			TX_DATA <= x"12";
			TX_DATA_VLD <= '1';
			wait until DATA_TO_UDP_VLD = '1';
			wait for 8ns;
			TX_DATA <= x"34";
			wait for 64ns;				-- jen kratka data
			TX_DATA_VLD <= '0';
			TX_DATA <= x"00";
			wait for 32ns;
		end loop;
		
			TX_DATA <= x"12";
			TX_DATA_VLD <= '1';
			wait for 24ns;
		
		---------------------------------
		-- ACK -> potvrzeni z PC
		---------------------------------		
		DATA_FROM_UDP_VLD <= '1';
		DATA_FROM_UDP <= x"BB";
		wait for 8ns;
		DATA_FROM_UDP <= x"00";
		wait for 16ns;
		DATA_FROM_UDP <= x"01";
		wait for 8ns;
		DATA_FROM_UDP_VLD <= '0';
		wait for 16ns;
		DATA_FROM_UDP_GOOD <= '1';
		wait for 8ns;
		DATA_FROM_UDP_GOOD <= '0';
		wait for 64ns;

	
	wait for 24ns;
		---------------------------------
		-- DATA -> Odeslani xx paketu 
		---------------------------------		
		for i in 0 to 1 loop
			TX_DATA <= x"12";
			TX_DATA_VLD <= '1';
			wait for 16ns;
			TX_DATA <= x"34";
			wait for 64ns;				-- jen kratka data
			TX_DATA_VLD <= '0';
			TX_DATA <= x"00";
			wait for 32ns;
		end loop;
		
		wait for 24ns;
		
		---------------------------------
		-- ERR -> error z PC
		---------------------------------		
		DATA_FROM_UDP_VLD <= '1';
		DATA_FROM_UDP <= x"EE";
		wait for 8ns;
		DATA_FROM_UDP <= x"00";
		wait for 16ns;
		DATA_FROM_UDP <= x"03";
		wait for 8ns;
		DATA_FROM_UDP_VLD <= '0';
		wait for 16ns;
		DATA_FROM_UDP_GOOD <= '1';
		wait for 8ns;
		DATA_FROM_UDP_GOOD <= '0';
		wait for 64ns;
		
		---------------------------------
		-- ESYN -> konec spojeni
		---------------------------------		
		DATA_FROM_UDP_VLD <= '1';
		DATA_FROM_UDP <= x"DD";
		wait for 8ns;
		DATA_FROM_UDP <= x"00";
		wait for 16ns;
		DATA_FROM_UDP <= x"00";
		wait for 8ns;
		DATA_FROM_UDP_VLD <= '0';
		wait for 16ns;
		DATA_FROM_UDP_GOOD <= '1';
		wait for 8ns;
		DATA_FROM_UDP_GOOD <= '0';
		wait for 64ns;

      wait;
   end process;

END;
