--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   15:46:13 02/05/2016
-- Design Name:   
-- Module Name:   C:/Xilinx/Projects/nexys3_phy/nexys3_phy_tb.vhd
-- Project Name:  nexys3_phy
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: nexys3_phy
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

use std.textio.all;
use work.txt_util.all;

 
entity nexys3_phy_tb is
end nexys3_phy_tb;


architecture behavior of nexys3_phy_tb is 
 
    -- component declaration for the unit under test (uut)
 
	component nexys3_phy
	port (
		clk_in			: in    std_logic;
		board_id			: in    std_logic_vector(2 downto 0);
		PhyRstn			: out   std_logic;
		PhyRxClk			: in    std_logic;
		PhyRxDv			: in    std_logic;
		PhyRxd			: in    std_logic_vector(3 downto 0);
--		PhyRxEr			: in    std_logic;
		PhyTxClk			: in    std_logic;
		PhyTxEn			: out   std_logic;
		PhyTxd			: out   std_logic_vector(3 downto 0);
--		PhyTxEr			: out   std_logic;
		PhyMdc			: out   std_logic;
		PhyMdio			: inout std_logic;
		PhyCrs			: in    std_logic;
		PhyCol			: in    std_logic;
		GPIO_LEDs		: out   std_logic_vector(7 downto 0);
		GPIO_Switches	: in    std_logic_vector(7 downto 0);
		GPIO_Buttons	: in    std_logic_vector(4 downto 0);
		Disp_seg			: out   std_logic_vector(7 downto 0);
		Disp_an			: out   std_logic_vector(3 downto 0)
	);
	end component;
    

   --Inputs
   signal clk_in				: std_logic := '0';
	signal board_id			: std_logic_vector(2 downto 0) := (others => '0');
   signal PhyRxClk			: std_logic := '0';
   signal PhyRxDv				: std_logic := '0';
   signal PhyRxd				: std_logic_vector(3 downto 0) := (others => '0');
--   signal PhyRxEr				: std_logic := '0';
   signal PhyTxClk			: std_logic := '0';
   signal PhyCrs				: std_logic := '0';
   signal PhyCol				: std_logic := '0';
   signal GPIO_Switches		: std_logic_vector(7 downto 0) := "10000001";
   signal GPIO_Buttons		: std_logic_vector(4 downto 0) := (others => '0');

 	--Outputs
   signal PhyRstn				: std_logic;
   signal PhyTxEn				: std_logic;
   signal PhyTxd				: std_logic_vector(3 downto 0);
--   signal PhyTxEr				: std_logic;
   signal PhyMdc				: std_logic;
   signal GPIO_LEDs			: std_logic_vector(7 downto 0);
   signal Disp_seg			: std_logic_vector(7 downto 0);
   signal Disp_an				: std_logic_vector(3 downto 0);
	
	--InOut
   signal PhyMdio				: std_logic;
	
	signal tx_dump_data		: std_logic_vector(4 downto 0);

   -- Clock period definitions
   constant SysClk_period		: time := 10 ns;
   constant PhyRxClk_period	: time := 40 ns;
   constant PhyTxClk_period	: time := 40 ns;
 
begin
 
	-- Instantiate the Unit Under Test (UUT)
	uut: nexys3_phy
	port map (
		clk_in			=> clk_in,
		board_id			=> board_id,
		PhyRstn			=> PhyRstn,
		PhyRxClk			=> PhyRxClk,
		PhyRxDv			=> PhyRxDv,
		PhyRxd			=> PhyRxd,
--		PhyRxEr			=> PhyRxEr,
		PhyTxClk			=> PhyTxClk,
		PhyTxEn			=> PhyTxEn,
		PhyTxd			=> PhyTxd,
--		PhyTxEr			=> PhyTxEr,
		PhyMdc			=> PhyMdc,
		PhyMdio			=> PhyMdio,
		PhyCrs			=> PhyCrs,
		PhyCol			=> PhyCol,
		GPIO_LEDs		=> GPIO_LEDs,
		GPIO_Switches	=> GPIO_Switches,
		GPIO_Buttons	=> GPIO_Buttons,
		Disp_seg			=> Disp_seg,
		Disp_an			=> Disp_an
	);

   -- Clock process definitions
	SysClk_process :process
	begin
		clk_in <= '0';
		wait for SysClk_period/2;
		clk_in <= '1';
		wait for SysClk_period/2;
	end process;
	
	PhyRxClk_process :process
	begin
		PhyRxClk <= '0';
		wait for PhyRxClk_period/2;
		PhyRxClk <= '1';
		wait for PhyRxClk_period/2;
	end process;
 
	PhyTxClk_process :process
	begin
		PhyTxClk <= '0';
		wait for PhyTxClk_period/2;
		PhyTxClk <= '1';
		wait for PhyTxClk_period/2;
	end process;
 

	Enet_rx_proc: process
		file file_pointer : text;
		variable line_content : string(1 to 5);
		variable line_num : line;
		variable char : character :='0';
   begin
		
      wait for PhyRxClk_period*50;
		
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\arp.txt", READ_MODE);
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\ping.txt", READ_MODE);
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\udp.txt", READ_MODE);
		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\udp_readGPIOswitches.txt", READ_MODE);
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\udp_setLEDs.txt", READ_MODE);
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\large_packet.txt", READ_MODE);
--		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\chipscope\bad_packet_1_rxd.txt", READ_MODE);
		
		while not endfile(file_pointer) loop
			wait until rising_edge(PhyRxClk);
			
			readline (file_pointer, line_num);
			read (line_num, line_content);
			
			char := line_content(1);
			if (char = '0') then
				PhyRxDv <= '0';
			else
				PhyRxDv <= '1';
			end if;
			
			char := line_content(2);
			if (char = '0') then
				PhyRxd(3) <= '0';
			else
				PhyRxd(3) <= '1';
			end if;
			
			char := line_content(3);
			if (char = '0') then
				PhyRxd(2) <= '0';
			else
				PhyRxd(2) <= '1';
			end if;
			
			char := line_content(4);
			if (char = '0') then
				PhyRxd(1) <= '0';
			else
				PhyRxd(1) <= '1';
			end if;
			
			char := line_content(5);
			if (char = '0') then
				PhyRxd(0) <= '0';
			else
				PhyRxd(0) <= '1';
			end if;
		end loop;
		
		file_close(file_pointer);  --after reading all the lines close the file. 
		wait;
		
	end process;
	

	tx_dump_data <= PhyTxEn & PhyTxd;
      
	tx_dump_process: process
		file file_pointer : text;
		variable tx_string : string(1 to 5);
   begin
      wait for PhyTxClk_period*50;
		
		file_open(file_pointer, "C:\Xilinx\Projects\nexys3_phy\simdata\tx_data.txt", WRITE_MODE);
		
		while true loop
			wait until rising_edge(PhyTxClk);
			wait for 1 ns;
			tx_string := str(tx_dump_data);
			print(file_pointer, tx_string);
		end loop;
		
		file_close(file_pointer);
		
		report "Tx dump file closed"	severity NOTE;
		wait;
	end process;
 
 

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

      wait for PhyRxClk_period*10;

      -- insert stimulus here 

      wait;
   end process;

end;
