-------------------------------------------------------------
-- MSS copyright 2014
--	Filename:  tbCOM5401loopback2.vhd
-- Author: Alain Zarembowitch / MSS
--	Version: 1
--	Date last modified: 1/30/14
-- Inheritance: 	N/A
-- 
-- description:  this testbench sends multiple frames with various lengths to the COM5401 Ethernet MAC 
-- where it is looped back. The objective is to visualize the PHY interface signals, the CRC insertion
-- by the MAC layer and the frame verification upon reception.
-- Configure MII_SEL = '0' for RGMII PHY emulation, '1' for GMII
-- 1st tx packet at 4us
--
-- Use tbcom5401loopback2.wcfg to visualize the key traces in the isim simulator.
-------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
 
ENTITY tbCOM5401loopback2 IS
END tbCOM5401loopback2;
 
ARCHITECTURE behavior OF tbCOM5401loopback2 IS 
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
	COMPONENT COM5401
	GENERIC (
		MII_SEL: std_logic;  
		PHY_ADDR: std_logic_vector(4 downto 0);
		CLK_FREQUENCY: integer;
		PLATFORM: integer;
		INTERNAL_PHY_CLKS_DELAYS: std_logic;
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		MAC_TX_CONFIG : IN std_logic_vector(15 downto 0);
		MAC_RX_CONFIG : IN std_logic_vector(15 downto 0);
		MAC_ADDR : IN std_logic_vector(47 downto 0);
		PHY_CONFIG_CHANGE : IN std_logic;
		PHY_RESET : IN std_logic;
		SPEED : IN std_logic_vector(1 downto 0);
		DUPLEX : IN std_logic;
		TEST_MODE : IN std_logic_vector(1 downto 0);
		POWER_DOWN : IN std_logic;
		CLK_SKEW : IN std_logic_vector(9 downto 0);
		MAC_TX_DATA : IN std_logic_vector(7 downto 0);
		MAC_TX_DATA_VALID : IN std_logic;
		MAC_TX_EOF : IN std_logic;
		MAC_RX_CTS : IN std_logic;
		RXC : IN std_logic;
		RXD : IN std_logic_vector(3 downto 0);
		RX_CTL : IN std_logic;
		MII_TX_CLK : IN std_logic;
		GMII_MII_CRS : IN std_logic;
		GMII_MII_COL : IN std_logic;
		GMII_MII_RX_CLK : IN std_logic;
		GMII_MII_RXD : IN std_logic_vector(7 downto 0);
		GMII_MII_RX_DV : IN std_logic;
		GMII_MII_RX_ER : IN std_logic;    
		MDIO : INOUT std_logic;      
		MAC_TX_CTS : OUT std_logic;
		MAC_RX_DATA : OUT std_logic_vector(7 downto 0);
		MAC_RX_DATA_VALID : OUT std_logic;
		MAC_RX_SOF : OUT std_logic;
		MAC_RX_EOF : OUT std_logic;
		TXC : OUT std_logic;
		TXD : OUT std_logic_vector(3 downto 0);
		TX_CTL : OUT std_logic;
		RESET_N : OUT std_logic;
		MCLK : OUT std_logic;
		GMII_TX_CLK : OUT std_logic;
		GMII_MII_TXD : OUT std_logic_vector(7 downto 0);
		GMII_MII_TX_EN : OUT std_logic;
		GMII_MII_TX_ER : OUT std_logic;
		LINK_STATUS : OUT std_logic;
		SPEED_STATUS : OUT std_logic_vector(1 downto 0);
		DUPLEX_STATUS : OUT std_logic;
		PHY_ID : OUT std_logic_vector(15 downto 0);
		N_RX_FRAMES: out  std_logic_vector(15 downto 0);
		N_RX_BAD_CRCS: out  std_logic_vector(15 downto 0);
		N_RX_FRAMES_TOO_SHORT: out  std_logic_vector(15 downto 0);
		N_RX_FRAMES_TOO_LONG: out  std_logic_vector(15 downto 0);
		N_RX_WRONG_ADDR: out  std_logic_vector(15 downto 0);
		N_RX_LENGTH_ERRORS: out  std_logic_vector(15 downto 0);
		CS1 : OUT std_logic_vector(7 downto 0);
		CS1_CLK : OUT std_logic;
		CS2 : OUT std_logic_vector(7 downto 0);
		CS2_CLK : OUT std_logic;
		CS_CLKG : OUT std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;
    
	COMPONENT PHYSIM_RGMII
	PORT(
		TXC : IN std_logic;
		TXD : IN std_logic_vector(3 downto 0);
		TX_CTL : IN std_logic;
		RESET_N : IN std_logic;
		MCLK : IN std_logic;    
		MDIO : INOUT std_logic;      
		RXC : OUT std_logic;
		RXD : OUT std_logic_vector(3 downto 0);
		RX_CTL : OUT std_logic;
		CLK125_NDO : OUT std_logic
		);
	END COMPONENT;

	COMPONENT PHYSIM_GMII_MII
	PORT(
		GTX_CLK : IN std_logic;
		TXD : IN std_logic_vector(7 downto 0);
		TX_EN : IN std_logic;
		TX_ER : IN std_logic;
		RESET_N : IN std_logic;
		SPEED : IN std_logic_vector(1 downto 0);
		MCLK : IN std_logic;    
		MDIO : INOUT std_logic;      
		TX_CLK : OUT std_logic;
		RX_CLK : OUT std_logic;
		RXD : OUT std_logic_vector(7 downto 0);
		RX_DV : OUT std_logic;
		RX_ER : OUT std_logic;
		CRS : OUT std_logic;
		COL : OUT std_logic;
		CLK125_NDO : OUT std_logic
		);
	END COMPONENT;

--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
-- Suffix _D indicates a one CLK delayed version of the net with the same name
-- Suffix _X indicates an extended precision version of the net with the same name
-- Suffix _N indicates an inverted version of the net with the same name

	signal TX_FRAME_LENGTH: integer := 0;
	signal TX_FRAME_COUNTER: integer := 0;

   signal CLK : std_logic := '0';
   signal CLK125G : std_logic := '0';
	signal SYNC_RESET : std_logic := '0';
	signal SYNC_RESET_CNTR: std_logic_vector(3 downto 0) := (others => '0');
	signal MAC_TX_CONFIG : std_logic_vector(15 downto 0) := (others => '0');
	signal MAC_RX_CONFIG: std_logic_vector(15 downto 0) := (others => '0');
	signal MAC_ADDR: std_logic_vector(47 downto 0);
   signal MAC_TX_DATA : std_logic_vector(7 downto 0) := (others => '0');
	signal TX_COUNTER: std_logic_vector(10 downto 0) := "00000000000";			
	signal TX_BYTE_INDEX: std_logic_vector(10 downto 0) := "00000000000";	
   signal MAC_TX_DATA_VALID : std_logic := '0';
   signal MAC_TX_EOF : std_logic := '0';
   signal MAC_RX_CTS : std_logic := '0';
   signal RXC : std_logic := '0';
   signal RXD : std_logic_vector(3 downto 0) := (others => '0');
   signal RXD1 : std_logic_vector(3 downto 0) := (others => '0');
	signal BIT_ERROR: std_logic := '0';
   signal RX_CTL : std_logic := '0';
   signal CLK125_NDO : std_logic := '0';
	signal MII_TX_CLK: std_logic;
	signal GMII_MII_RX_CLK: std_logic;
	signal GMII_MII_RXD : std_logic_vector(7 downto 0);
	signal GMII_MII_RX_DV : std_logic;
	signal GMII_MII_RX_ER : std_logic;    

	--BiDirs
   signal MDIO : std_logic;

 	--Outputs
   signal MAC_TX_CTS : std_logic;
   signal MAC_RX_DATA : std_logic_vector(7 downto 0);
   signal MAC_RX_DATA_VALID : std_logic;
   signal MAC_RX_SOF : std_logic;
   signal MAC_RX_EOF : std_logic;
   signal TXC : std_logic;
   signal TXD : std_logic_vector(3 downto 0);
   signal TX_CTL : std_logic;
   signal RESET_N : std_logic;
   signal MCLK : std_logic;
   signal LINK_STATUS : std_logic;
   signal SPEED_STATUS : std_logic_vector(1 downto 0);
   signal DUPLEX_STATUS : std_logic;
	signal GMII_TX_CLK: std_logic;
	signal GMII_MII_TXD: std_logic_vector(7 downto 0);
	signal GMII_MII_TX_EN: std_logic;
	signal GMII_MII_TX_ER: std_logic;
	signal GMII_MII_CRS: std_logic;
	signal GMII_MII_COL: std_logic;
	signal N_RX_FRAMES: std_logic_vector(15 downto 0) := (others => '0');
	signal N_RX_BAD_CRCS: std_logic_vector(15 downto 0) := (others => '0');
	signal N_RX_FRAMES_TOO_SHORT: std_logic_vector(15 downto 0) := (others => '0');
	signal N_RX_FRAMES_TOO_LONG: std_logic_vector(15 downto 0) := (others => '0');
	signal N_RX_LENGTH_ERRORS: std_logic_vector(15 downto 0) := (others => '0');
	signal N_RX_WRONG_ADDR: std_logic_vector(15 downto 0) := (others => '0');
	signal TP: std_logic_vector(10 downto 1);
	
	-- test bench
	signal TX_EN: std_logic := '0';

   -- User-side clock. Independent of the 2.5/25/125 MHz PHY clock.
--   constant CLK_period : time := 10 ns;  -- 100 MHz user clock
   constant CLK_period : time := 8 ns;  -- 125 MHz user clock
	constant CLK_FREQUENCY: integer := 125;	-- in MHz, must be consistent with CLK_period
	
	
--// CONFIGURATION ------------------------------------------------
constant MII_SEL: std_logic := '0';   -- select which MII interface: 0 = RGMII, 1 = GMII/MII
	
 
--------------------------------------------------------
--     IMPLEMENTATION
--------------------------------------------------------
BEGIN

--// USER CONFIGURATIONS -----------------------------------------------------

-- Clock process definitions
CLK_process :process
begin
	CLK <= '0';
	wait for CLK_period/2;
	CLK <= '1';
	wait for CLK_period/2;
end process;

-- sync reset
process(CLK)
begin
	if rising_edge(CLK) then
		if(SYNC_RESET_CNTR(3) = '0') then
			SYNC_RESET_CNTR <= SYNC_RESET_CNTR + 1;
		end if;
		if(SYNC_RESET_CNTR = "0111") then
			SYNC_RESET <= '1';
		else
			SYNC_RESET <= '0';
		end if;
	end if;
end process;

-- User commands
CLK125G <= CLK125_NDO;
MAC_TX_CONFIG <= x"0003"; -- enable padding, crc32
--MAC_TX_CONFIG <= x"0000"; -- user is responsible for padding and crc32
--MAC_RX_CONFIG <= x"0001"; -- promiscuous mode
MAC_RX_CONFIG <= x"0006"; -- check address, allow broadcast and multicast rx packets
--MAC_RX_CONFIG <= x"0008"; -- check address, no broadcast nor multicast rx packets, filter out crc field
MAC_ADDR <= x"D0D1D2D3D4D5";
--MAC_ADDR <= x"A0A1A2A3A4A5";
--MAC_ADDR <= x"01000CCCCCCC";  -- Cisco Delivery Protocol, Ethernet multicast address example.
	
--// USER TX DATA -----------------------------------------------------
-- send byte count

-- delay 1st frame transmission
tx_en_001: process
begin	
	TX_EN <= '0';
	wait for 4000ns;
	TX_EN <= '1';
	wait for 12800ns;
	TX_EN <= '0';
	wait for 4000ns;
	TX_EN <= '1';
	wait;
end process;

--BYTE_CNTR_001: process(ASYNC_RESET, CLK)
--begin
--	if(ASYNC_RESET = '1') then
--		MAC_TX_DATA <= (others => '0');
--		MAC_TX_EOF <= '0';
--		MAC_TX_DATA_VALID <= '0';
--	elsif rising_edge(CLK) then
--		if(START_TX = '1') then
--			-- start transmitting
--			MAC_TX_DATA <= x"00";
--			MAC_TX_EOF <= '0';
--			MAC_TX_DATA_VALID <= '1';
--		elsif(MAC_TX_DATA = 10) then
--			MAC_TX_EOF <= '1';  -- last byte in packet
--			MAC_TX_DATA <= MAC_TX_DATA + 1;
--		elsif(MAC_TX_DATA = 11) then
--			MAC_TX_EOF <= '0';
--			MAC_TX_DATA_VALID <= '0';
--		elsif(MAC_TX_DATA_VALID = '1') then
--			MAC_TX_DATA <= MAC_TX_DATA + 1;
--		end if;
--	end if;
--end process;

TX_PACKET_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(SYNC_RESET = '1') then
			TX_COUNTER <= (others => '0');
			TX_FRAME_COUNTER <= 0;
			MAC_TX_EOF <= '0';
			MAC_TX_DATA_VALID <= '0';
		elsif(TX_EN = '1') and (TX_COUNTER = 0) and (MAC_TX_CTS = '1') and (TX_FRAME_COUNTER < 5) then	-- 5 FRAMES MAX IN THIS SIMULATION
			-- start transmitting after a delayed start and when MAC shows Clear-To-Send
			TX_COUNTER <= TX_COUNTER + 1;
			MAC_TX_DATA_VALID <= '1';
			MAC_TX_EOF <= '0';
		elsif(TX_COUNTER = TX_FRAME_LENGTH) and (MAC_TX_CTS = '1') then	
			TX_COUNTER <= (others => '0');	-- rewind counter... immediately start transmitting the next frame
			TX_FRAME_COUNTER <= TX_FRAME_COUNTER + 1;
			MAC_TX_EOF <= '1';  -- last byte in packet 
		elsif(TX_COUNTER > 0) and (TX_COUNTER < TX_FRAME_LENGTH) and (MAC_TX_CTS = '1') then 
			TX_COUNTER <= TX_COUNTER + 1;
			MAC_TX_DATA_VALID <= '1';
		else
			MAC_TX_DATA_VALID <= '0';
			MAC_TX_EOF <= '0';
		end if;
	end if;
end process;

-- change frame length. Multi-frame simulation
-- Minimum frame size is 63 when no padding is enabled
TX_FRAME_LENGTH <= 1499 when (TX_FRAME_COUNTER = 0) else 	
						 41 when (TX_FRAME_COUNTER = 1) else	
						 63 when (TX_FRAME_COUNTER = 2) else 
						 1499 when (TX_FRAME_COUNTER = 3) else 
						 256;

TX_BYTE_INDEX <= TX_COUNTER - 1;

MAC_TX_DATA_GEN: process(TX_BYTE_INDEX)
begin
	case TX_BYTE_INDEX(6 downto 0) is
			 when "0000000" => MAC_TX_DATA <= x"FF";
			 when "0000001" => MAC_TX_DATA <= x"FF";
			 when "0000010" => MAC_TX_DATA <= x"FF";
			 when "0000011" => MAC_TX_DATA <= x"FF";
			 when "0000100" => MAC_TX_DATA <= x"FF";
			 when "0000101" => MAC_TX_DATA <= x"FF";
			 when "0000110" => MAC_TX_DATA <= x"00";
			 when "0000111" => MAC_TX_DATA <= x"0E";
			 when "0001000" => MAC_TX_DATA <= x"08";
			 when "0001001" => MAC_TX_DATA <= x"CA";
			 when "0001010" => MAC_TX_DATA <= x"BB";
			 when "0001011" => MAC_TX_DATA <= x"A3";
			 when "0001100" => MAC_TX_DATA <= x"08";
			 when "0001101" => MAC_TX_DATA <= x"06";
			 when "0001110" => MAC_TX_DATA <= x"00";
			 when "0001111" => MAC_TX_DATA <= x"01";
			 when "0010000" => MAC_TX_DATA <= x"08";
			 when "0010001" => MAC_TX_DATA <= x"00";
			 when "0010010" => MAC_TX_DATA <= x"06";
			 when "0010011" => MAC_TX_DATA <= x"04";
			 when "0010100" => MAC_TX_DATA <= x"00";
			 when "0010101" => MAC_TX_DATA <= x"01";
			 when "0010110" => MAC_TX_DATA <= x"00";
			 when "0010111" => MAC_TX_DATA <= x"0E";
			 when "0011000" => MAC_TX_DATA <= x"08";
			 when "0011001" => MAC_TX_DATA <= x"CA";
			 when "0011010" => MAC_TX_DATA <= x"BB";
			 when "0011011" => MAC_TX_DATA <= x"A3";
			 when "0011100" => MAC_TX_DATA <= x"AC";
			 when "0011101" => MAC_TX_DATA <= x"10";
			 when "0011110" => MAC_TX_DATA <= x"01";
			 when "0011111" => MAC_TX_DATA <= x"7E";
			 when "0100000" => MAC_TX_DATA <= x"00";
			 when "0100001" => MAC_TX_DATA <= x"00";
			 when "0100010" => MAC_TX_DATA <= x"00";
			 when "0100011" => MAC_TX_DATA <= x"00";
			 when "0100100" => MAC_TX_DATA <= x"00";
			 when "0100101" => MAC_TX_DATA <= x"00";
			 when "0100110" => MAC_TX_DATA <= x"AC";
			 when "0100111" => MAC_TX_DATA <= x"10";
			 when "0101000" => MAC_TX_DATA <= x"01";
			 when "0101001" => MAC_TX_DATA <= x"1F";
			 when "0101010" => MAC_TX_DATA <= x"00";
			 when "0101011" => MAC_TX_DATA <= x"00";
			 when "0101100" => MAC_TX_DATA <= x"00";
			 when "0101101" => MAC_TX_DATA <= x"00";
			 when "0101110" => MAC_TX_DATA <= x"00";
			 when "0101111" => MAC_TX_DATA <= x"00";
			 when "0110000" => MAC_TX_DATA <= x"00";
			 when "0110001" => MAC_TX_DATA <= x"00";
			 when "0110010" => MAC_TX_DATA <= x"00";
-- test test test
--			 when "0110011" => MAC_TX_DATA <= x"00";
			 when "0110011" => MAC_TX_DATA <= x"D5";
			 when "0110100" => MAC_TX_DATA <= x"00";
			 when "0110101" => MAC_TX_DATA <= x"00";
			 when "0110110" => MAC_TX_DATA <= x"00";
			 when "0110111" => MAC_TX_DATA <= x"00";
			 when "0111000" => MAC_TX_DATA <= x"00";
			 when "0111001" => MAC_TX_DATA <= x"00";
			 when "0111010" => MAC_TX_DATA <= x"00";
			 when "0111011" => MAC_TX_DATA <= x"00";
			 when "0111100" => MAC_TX_DATA <= x"13";	-- checksum for a 64-byte frame when 
			 when "0111101" => MAC_TX_DATA <= x"1B";
			 when "0111110" => MAC_TX_DATA <= x"C4";
			 when "0111111" => MAC_TX_DATA <= x"D3";
			 when others => MAC_TX_DATA <= x"00";


--		when "00000" => MAC_TX_DATA <= x"D0";  -- destination address
--		when "00001" => MAC_TX_DATA <= x"D1";
--		when "00010" => MAC_TX_DATA <= x"D2";
--		when "00011" => MAC_TX_DATA <= x"D3";
--		when "00100" => MAC_TX_DATA <= x"D4";
--		when "00101" => MAC_TX_DATA <= x"D5";
--		when "00110" => MAC_TX_DATA <= x"A0";  -- source address
--		when "00111" => MAC_TX_DATA <= x"A1";
--		when "01000" => MAC_TX_DATA <= x"A2";
--		when "01001" => MAC_TX_DATA <= x"A3";
--		when "01010" => MAC_TX_DATA <= x"A4";
--		when "01011" => MAC_TX_DATA <= x"A5";
--		when "01100" => MAC_TX_DATA <= x"00";  -- length/type MSB first
--		when "01101" => MAC_TX_DATA <= x"12";
--		when "01110" => MAC_TX_DATA <= x"00";  -- payload data
--		when "01111" => MAC_TX_DATA <= x"01";
--		when "10000" => MAC_TX_DATA <= x"02";
--		when "10001" => MAC_TX_DATA <= x"03";
--		when "10010" => MAC_TX_DATA <= x"04";
--		when "10011" => MAC_TX_DATA <= x"05";
--		when "10100" => MAC_TX_DATA <= x"06";
--		when "10101" => MAC_TX_DATA <= x"07";
--		when "10110" => MAC_TX_DATA <= x"08";
--		when "10111" => MAC_TX_DATA <= x"09";
--		when "11000" => MAC_TX_DATA <= x"0A";
--		when "11001" => MAC_TX_DATA <= x"0B";
--		when "11010" => MAC_TX_DATA <= x"0C";
--		when "11011" => MAC_TX_DATA <= x"0D";
--		when "11100" => MAC_TX_DATA <= x"0E";
--		when "11101" => MAC_TX_DATA <= x"0F";
--		when "11110" => MAC_TX_DATA <= x"10";
--		when others => MAC_TX_DATA <= x"11";
	end case;
end process;

	

		

--// Instantiate the Unit Under Test (UUT) -----------------------------------------------------
MAC_RX_CTS <= '1'; -- read rx data as fast as possible.

	LAN_001: COM5401 
	GENERIC MAP(
		MII_SEL => MII_SEL,
		PHY_ADDR => "00100",	-- PHY_AD0/1 pulled-down by 1KOhm, PHY_AD2 pulled-up in .ucf file.
		CLK_FREQUENCY => CLK_FREQUENCY,
		PLATFORM => 6,	-- Xilinx spartan-6
		INTERNAL_PHY_CLKS_DELAYS => '1',
		SIMULATION => '1'
	)
	PORT MAP(
		 CLK => CLK,
		 SYNC_RESET => SYNC_RESET,
		 MAC_TX_CONFIG => MAC_TX_CONFIG,
		 MAC_RX_CONFIG => MAC_RX_CONFIG,
		 MAC_ADDR => MAC_ADDR, 
		 PHY_CONFIG_CHANGE => '0',
		 PHY_RESET => '0',
		 SPEED => "11",	-- unused here. Use defaults within.
		 DUPLEX => '1',	-- unused here. Use defaults within.
		 TEST_MODE => "00",	-- unused here. Use defaults within.
		 CLK_SKEW => "1111111111",	-- unused here. Use defaults within
		 POWER_DOWN => '0', -- unused here. Use defaults within.
		 MAC_TX_DATA => MAC_TX_DATA,
		 MAC_TX_DATA_VALID => MAC_TX_DATA_VALID,
		 MAC_TX_EOF => MAC_TX_EOF,
		 MAC_TX_CTS => MAC_TX_CTS,
		 MAC_RX_DATA => MAC_RX_DATA,
		 MAC_RX_DATA_VALID => MAC_RX_DATA_VALID,
		 MAC_RX_SOF => MAC_RX_SOF,
		 MAC_RX_EOF => MAC_RX_EOF,
		 MAC_RX_CTS => MAC_RX_CTS,
		 TXC => TXC,	-- RGMII interface ----------------
		 TXD => TXD,
		 TX_CTL => TX_CTL,
		 RXC => RXC,
		 RXD => RXD1,
		 RX_CTL => RX_CTL,
		 RESET_N => RESET_N,
		 MCLK => MCLK,
		 MDIO => MDIO,
		 MII_TX_CLK => MII_TX_CLK, -- MII interface  -----
		 GMII_TX_CLK => GMII_TX_CLK,
		 GMII_MII_TXD => GMII_MII_TXD,
		 GMII_MII_TX_EN => GMII_MII_TX_EN,
		 GMII_MII_TX_ER => GMII_MII_TX_ER,
		 GMII_MII_CRS => GMII_MII_CRS,
		 GMII_MII_COL => GMII_MII_COL,
		 GMII_MII_RX_CLK => GMII_MII_RX_CLK,
		 GMII_MII_RXD => GMII_MII_RXD,
		 GMII_MII_RX_DV => GMII_MII_RX_DV,
		 GMII_MII_RX_ER => GMII_MII_RX_ER, -- end of MII interface ------
		 LINK_STATUS => LINK_STATUS,
		 SPEED_STATUS => SPEED_STATUS,
		 DUPLEX_STATUS => DUPLEX_STATUS,
		 PHY_ID => open,
		 N_RX_FRAMES => N_RX_FRAMES,
		 N_RX_BAD_CRCS => N_RX_BAD_CRCS,
		 N_RX_FRAMES_TOO_SHORT => N_RX_FRAMES_TOO_SHORT,
		 N_RX_FRAMES_TOO_LONG => N_RX_FRAMES_TOO_LONG,
		 N_RX_WRONG_ADDR => N_RX_WRONG_ADDR,
		 N_RX_LENGTH_ERRORS => N_RX_LENGTH_ERRORS,
		 CS_CLKG => open,
		 CS1 => open,
		 CS1_CLK => open,
		 CS2 => open,
		 CS2_CLK => open,
		 TP => TP
		 
	  );

-- add bit errors
RXD1 <= RXD when BIT_ERROR = '0' else RXD(3 downto 1) & not RXD(0); 
process
begin
	BIT_ERROR <= '0';
	wait for 20000 ns;
	BIT_ERROR <= '1';
	wait for 8 ns;
	BIT_ERROR <= '0';
	wait;
end process;
	

--// PHY EMULATION ----------------------------------------------
IF_SEL_000: if(MII_SEL = '0') generate
	PHYSIM_RGMII_001: PHYSIM_RGMII PORT MAP(
		 TXC => TXC,
		 TXD => TXD,
		 TX_CTL => TX_CTL,
		 RXC => RXC,
		 RXD => RXD,
		 RX_CTL => RX_CTL,
		 RESET_N => RESET_N,
		 MCLK => MCLK,
		 MDIO => MDIO,
		 CLK125_NDO => CLK125_NDO
	);
end generate;	

IF_SEL_001: if(MII_SEL = '1') generate
	Inst_PHYSIM_GMII_MII: PHYSIM_GMII_MII PORT MAP(
		TX_CLK => MII_TX_CLK,
		GTX_CLK => GMII_TX_CLK,
		TXD => GMII_MII_TXD,
		TX_EN => GMII_MII_TX_EN,
		TX_ER =>GMII_MII_TX_ER,
		RX_CLK => GMII_MII_RX_CLK,
		RXD => GMII_MII_RXD,
		RX_DV => GMII_MII_RX_DV,
		RX_ER => GMII_MII_RX_ER,
		CRS => GMII_MII_CRS,
		COL => GMII_MII_COL,
		 RESET_N => RESET_N,
-- User to change the speed below to mimic the PHY autonegotiation
--       SPEED => "00",  -- PHY-negotiated speed 10Mbps/2.5 MHz(as if after autonegotiation)
--       SPEED => "01",  -- PHY-negotiated speed 100Mbps/25 MHz(as if after autonegotiation)
       SPEED => "10",  -- PHY-negotiated speed 1Gbps/125 MHz(as if after autonegotiation)
		 MCLK => MCLK,
		 MDIO => MDIO,
		 CLK125_NDO => CLK125_NDO
	);
end generate;	

END;
