--=============================================================================
--! @file fmc-tlu_v0-1_test-bench.vhd
--=============================================================================

--! @brief Test-bench for FMC format mini-TLU for AIDA
--
--! @details 
--
--! @author David Cussans, 31/07/12
--! @date 11:49:20 02/21/2014
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY fmctlu_v0_1_testbench IS
END fmctlu_v0_1_testbench;
 
ARCHITECTURE behavior OF fmctlu_v0_1_testbench IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT top_extphy
    PORT(
         busy_n_i : IN  std_logic_vector(2 downto 0);
         busy_p_i : IN  std_logic_vector(2 downto 0);
         cfd_discr_n_i : IN  std_logic_vector(3 downto 0);
         cfd_discr_p_i : IN  std_logic_vector(3 downto 0);
         dip_switch_i : IN  std_logic_vector(3 downto 0);
         dut_clk_n_i : IN  std_logic_vector(2 downto 0);
         dut_clk_p_i : IN  std_logic_vector(2 downto 0);
         gmii_rx_clk_i : IN  std_logic;
         gmii_rx_dv_i : IN  std_logic;
         gmii_rx_er_i : IN  std_logic;
         gmii_rxd_i : IN  std_logic_vector(7 downto 0);
         sysclk_n_i : IN  std_logic;
         sysclk_p_i : IN  std_logic;
         threshold_discr_n_i : IN  std_logic_vector(3 downto 0);
         threshold_discr_p_i : IN  std_logic_vector(3 downto 0);
         gmii_gtx_clk_o : OUT  std_logic;
         gmii_tx_en_o : OUT  std_logic;
         gmii_tx_er_o : OUT  std_logic;
         gmii_txd_o : OUT  std_logic_vector(7 downto 0);
         gpio_hdr : OUT  std_logic_vector(7 downto 0);
         leds_o : OUT  std_logic_vector(3 downto 0);
         phy_rstb_o : OUT  std_logic;
         reset_or_clk_n_o : OUT  std_logic_vector(2 downto 0);
         reset_or_clk_p_o : OUT  std_logic_vector(2 downto 0);
         triggers_n_o : OUT  std_logic_vector(2 downto 0);
         triggers_p_o : OUT  std_logic_vector(2 downto 0);
         extclk_n_b : INOUT  std_logic;
         extclk_p_b : INOUT  std_logic;
         i2c_scl_b : INOUT  std_logic;
         i2c_sda_b : INOUT  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal busy_n_i : std_logic_vector(2 downto 0) := (others => '0');
   signal busy_p_i : std_logic_vector(2 downto 0) := (others => '0');
   signal cfd_discr_n_i : std_logic_vector(3 downto 0) := (others => '0');
   signal cfd_discr_p_i : std_logic_vector(3 downto 0) := (others => '0');
   signal dip_switch_i : std_logic_vector(3 downto 0) := (others => '0');
   signal dut_clk_n_i : std_logic_vector(2 downto 0) := (others => '0');
   signal dut_clk_p_i : std_logic_vector(2 downto 0) := (others => '0');
   signal gmii_rx_clk_i : std_logic := '0';
   signal gmii_rx_dv_i : std_logic := '0';
   signal gmii_rx_er_i : std_logic := '0';
   signal gmii_rxd_i : std_logic_vector(7 downto 0) := (others => '0');
   signal sysclk_n_i : std_logic := '0';
   signal sysclk_p_i : std_logic := '0';
   signal threshold_discr_n_i : std_logic_vector(3 downto 0) := (others => '0');
   signal threshold_discr_p_i : std_logic_vector(3 downto 0) := (others => '0');
    signal s_threshold_discr : std_logic_vector(3 downto 0) := (others => '0');

	--BiDirs
   signal extclk_n_b : std_logic;
   signal extclk_p_b : std_logic;
   signal i2c_scl_b : std_logic;
   signal i2c_sda_b : std_logic;

 	--Outputs
   signal gmii_gtx_clk_o : std_logic;
   signal gmii_tx_en_o : std_logic;
   signal gmii_tx_er_o : std_logic;
   signal gmii_txd_o : std_logic_vector(7 downto 0);
   signal gpio_hdr : std_logic_vector(7 downto 0);
   signal leds_o : std_logic_vector(3 downto 0);
   signal phy_rstb_o : std_logic;
   signal reset_or_clk_n_o : std_logic_vector(2 downto 0);
   signal reset_or_clk_p_o : std_logic_vector(2 downto 0);
   signal triggers_n_o : std_logic_vector(2 downto 0);
   signal triggers_p_o : std_logic_vector(2 downto 0);
 
   signal sysclock : std_logic := '0';
   constant sysclock_period : time := 5 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: top_extphy PORT MAP (
          busy_n_i => busy_n_i,
          busy_p_i => busy_p_i,
          cfd_discr_n_i => cfd_discr_n_i,
          cfd_discr_p_i => cfd_discr_p_i,
          dip_switch_i => dip_switch_i,
          dut_clk_n_i => dut_clk_n_i,
          dut_clk_p_i => dut_clk_p_i,
          gmii_rx_clk_i => gmii_rx_clk_i,
          gmii_rx_dv_i => gmii_rx_dv_i,
          gmii_rx_er_i => gmii_rx_er_i,
          gmii_rxd_i => gmii_rxd_i,
          sysclk_n_i => sysclk_n_i,
          sysclk_p_i => sysclk_p_i,
          threshold_discr_n_i => threshold_discr_n_i,
          threshold_discr_p_i => threshold_discr_p_i,
          gmii_gtx_clk_o => gmii_gtx_clk_o,
          gmii_tx_en_o => gmii_tx_en_o,
          gmii_tx_er_o => gmii_tx_er_o,
          gmii_txd_o => gmii_txd_o,
          gpio_hdr => gpio_hdr,
          leds_o => leds_o,
          phy_rstb_o => phy_rstb_o,
          reset_or_clk_n_o => reset_or_clk_n_o,
          reset_or_clk_p_o => reset_or_clk_p_o,
          triggers_n_o => triggers_n_o,
          triggers_p_o => triggers_p_o,
          extclk_n_b => extclk_n_b,
          extclk_p_b => extclk_p_b,
          i2c_scl_b => i2c_scl_b,
          i2c_sda_b => i2c_sda_b
        );

   -- Clock process definitions
   sysclock_process :process
   begin
		sysclock <= '0';
		wait for sysclock_period/2;
		sysclock <= '1';
		wait for sysclock_period/2;
   end process;
   sysclk_n_i <= not sysclock;
   sysclk_p_i <= sysclock;
 

   -- Generate pulses
   cmp_pulseGen: entity work.pmtPulseGenerator
     generic map (
       g_NUM_CHANNELS => 4)
     port map (
       pulses_o               => s_threshold_discr,
       numPulses_i            => 50,
       averagePulseInterval_i => 10 us,
       averagePulseWidth_i      => 10 ns,
       pulseJitter_i          => 2 ns,
       sysclock_i             => sysclock,
       simulationDone_o       => open);

   threshold_discr_p_i <= s_threshold_discr;
   threshold_discr_n_i <= not s_threshold_discr;
   
   
   -- Stimulus process
   stim_proc: process
   begin		
      -- hold reset state for 100 ns.
      wait for 100 ns;	

      wait for sysclock_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;
