----------------------------------------------------------------------------------
--									Test bench pro udp_core	  			  	  		  		  	  --
----------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use work.my_constants.all;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY udp_core_tb IS
END udp_core_tb;
 
ARCHITECTURE behavior OF udp_core_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT udp_core
    PORT(
         TX_CLK : IN  std_logic;
         RX_CLK : IN  std_logic;
         DATA_FROM_IP : IN  std_logic_vector(7 downto 0);
         DATA_FROM_IP_VLD : IN  std_logic;
         DATA_FROM_IP_GOOD : IN  std_logic;
         DATA_FROM_IP_BAD : IN  std_logic;
         SOURCE_IP : IN  std_logic_vector(31 downto 0);
         DATA_TO_IP : OUT  std_logic_vector(7 downto 0);
         DATA_TO_IP_VLD : OUT  std_logic;
			DATA_TO_IP_LEN: out std_logic_vector(UDP_ADDR_WIDTH - 1 downto 0);
         DATA_TO_IP_ACK : IN  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;
         TX_DATA : IN  std_logic_vector(7 downto 0);
         TX_DATA_VLD : IN  std_logic;
         TX_DATA_EN : OUT  std_logic;
         DESTINATION_PORT : IN  std_logic_vector(15 downto 0);
         DESTINATION_IP : IN  std_logic_vector(31 downto 0);
         RESET : IN  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal TX_CLK : std_logic := '0';
   signal RX_CLK : std_logic := '0';
   signal DATA_FROM_IP : std_logic_vector(7 downto 0) := (others => '0');
   signal DATA_FROM_IP_VLD : std_logic := '0';
   signal DATA_FROM_IP_GOOD : std_logic := '0';
   signal DATA_FROM_IP_BAD : std_logic := '0';
   signal SOURCE_IP : std_logic_vector(31 downto 0) := (others => '0');
   signal DATA_TO_IP_ACK : std_logic := '0';
   signal TX_DATA : std_logic_vector(7 downto 0) := (others => '0');
   signal TX_DATA_VLD : std_logic := '0';
   signal DESTINATION_PORT : std_logic_vector(15 downto 0) := (others => '0');
   signal DESTINATION_IP : std_logic_vector(31 downto 0) := (others => '0');
   signal RESET : std_logic := '0';

 	--Outputs
   signal DATA_TO_IP : std_logic_vector(7 downto 0);
   signal DATA_TO_IP_VLD : std_logic;
	signal DATA_TO_IP_LEN: std_logic_vector(UDP_ADDR_WIDTH - 1 downto 0);
   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 TX_DATA_EN : std_logic;

   -- Clock period definitions
   constant TX_CLK_period : time := 8 ns;
   constant RX_CLK_period : time := 8 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: udp_core PORT MAP (
          TX_CLK => TX_CLK,
          RX_CLK => RX_CLK,
          DATA_FROM_IP => DATA_FROM_IP,
          DATA_FROM_IP_VLD => DATA_FROM_IP_VLD,
          DATA_FROM_IP_GOOD => DATA_FROM_IP_GOOD,
          DATA_FROM_IP_BAD => DATA_FROM_IP_BAD,
          SOURCE_IP => SOURCE_IP,
          DATA_TO_IP => DATA_TO_IP,
          DATA_TO_IP_VLD => DATA_TO_IP_VLD,
          DATA_TO_IP_LEN => DATA_TO_IP_LEN,
          DATA_TO_IP_ACK => DATA_TO_IP_ACK,
          RX_DATA => RX_DATA,
          RX_DATA_VLD => RX_DATA_VLD,
          RX_DATA_GOOD => RX_DATA_GOOD,
          RX_DATA_BAD => RX_DATA_BAD,
          TX_DATA => TX_DATA,
          TX_DATA_VLD => TX_DATA_VLD,
          TX_DATA_EN => TX_DATA_EN,
          DESTINATION_PORT => DESTINATION_PORT,
          DESTINATION_IP => DESTINATION_IP,
          RESET => RESET
        );

   -- Clock process definitions
   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 TX_CLK_period*10;

		wait for 100 ns;	
		-- Zdrojova IP
		SOURCE_IP <= x"0A1402BA";
		DATA_FROM_IP_VLD <= '1';
     
	  ----------------------------
		-- Prijem dat --------------
      ----------------------------
	
		-- HLAVICKA ---
		-- Porty
		DATA_FROM_IP <= x"7D";
		wait for 8ns;	
		DATA_FROM_IP <= x"DE";
		wait for 8ns;	
		DATA_FROM_IP <= x"7D";
		wait for 8ns;	
		DATA_FROM_IP <= x"DE";
		--- Délka
		wait for 8ns;	
		DATA_FROM_IP <= x"00";
		wait for 8ns;	
		DATA_FROM_IP <= x"0C";
		-- checksum
		wait for 8ns;	
		DATA_FROM_IP <= x"19";
		wait for 8ns;	
		DATA_FROM_IP <= x"90";
      ----------------------------
		-- DATA -----------
		
		wait for 8ns;	
		DATA_FROM_IP <= x"61";
		wait for 8ns;	
		DATA_FROM_IP <= x"68";
		wait for 8ns;	
		DATA_FROM_IP <= x"6F";
		wait for 8ns;	
		DATA_FROM_IP <= x"6A";
		-- Konec
		wait for 8ns;	
		DATA_FROM_IP_VLD <= '0';
		DATA_FROM_IP <= x"00";
		
		wait for 8ns;
		-- Potvrzeni
		DATA_FROM_IP_GOOD <= '1';
    		wait for 8ns;
 		DATA_FROM_IP_GOOD <= '0';
		wait for 80ns;
	 
	 ----------------------------
		-- Odesilani dat ----------
      ----------------------------
		TX_DATA_VLD <= '1';
		DESTINATION_PORT <= x"7DDE";
		DESTINATION_IP <= x"0A1402BB";
		for i in 0 to 3 loop
			TX_DATA <= conv_std_logic_vector(i+200,8);
			wait for 8ns;
		end loop;
		TX_DATA_VLD <= '0';
		TX_DATA <=x"00";
		DESTINATION_PORT <= x"0000";
		DESTINATION_IP <= x"00000000";
		wait for 194ns;
		DATA_TO_IP_ACK <= '1';
		wait for 8ns;
		DATA_TO_IP_ACK <= '0';

		-- konec
      wait;
   end process;

END;
