--
-- wrapper-xp.vhd
--
-- Wrapper for HPC Common Interface

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;


library work;
use work.common_interface.all;
library UNISIM;
use UNISIM.vcomponents.all;


entity wrapper is
  port(
    lclk       : in    std_logic;
    clk200_p   : in    std_logic;
    clk200_n   : in    std_logic;
    mgtclk             : in  std_logic;
    mgtclkb            : in  std_logic;
    lreseto_l  : in    std_logic;
    lwrite     : in    std_logic;
    lads_l     : in    std_logic;
    lblast_l   : in    std_logic;
    lbterm_l   : out   std_logic;
    lad        : inout std_logic_vector(63 downto 0);
    lreadyi_l  : out   std_logic;
    lbe_l      : in    std_logic_vector(7 downto 0);
    fholda     : in    std_logic;
    finti_l    : out   std_logic;
    DDR0_RAS_N : out   std_logic;
    DDR0_CAS_N : out   std_logic;
    DDR0_WE_N  : out   std_logic;
    DDR0_ODT   : out   std_logic;
    DDR0_CKE   : out   std_logic;
    DDR0_CS_N  : out   std_logic;
    DDR0_DQ    : inout std_logic_vector(31 downto 0);
    DDR0_DQS   : inout std_logic_vector(3 downto 0);
    DDR0_DQS_N : inout std_logic_vector(3 downto 0);
    DDR0_DM    : out   std_logic_vector(3 downto 0);
    DDR0_CK    : out   std_logic_vector(1 downto 0);
    DDR0_CK_N  : out   std_logic_vector(1 downto 0);
    DDR0_BA    : out   std_logic_vector(2 downto 0);
    DDR0_A     : out   std_logic_vector(12 downto 0);
    DDR1_RAS_N : out   std_logic;
    DDR1_CAS_N : out   std_logic;
    DDR1_WE_N  : out   std_logic;
    DDR1_ODT   : out   std_logic;
    DDR1_CKE   : out   std_logic;
    DDR1_CS_N  : out   std_logic;
    DDR1_DQ    : inout std_logic_vector(31 downto 0);
    DDR1_DQS   : inout std_logic_vector(3 downto 0);
    DDR1_DQS_N : inout std_logic_vector(3 downto 0);
    DDR1_DM    : out   std_logic_vector(3 downto 0);
    DDR1_CK    : out   std_logic_vector(1 downto 0);
    DDR1_CK_N  : out   std_logic_vector(1 downto 0);
    DDR1_BA    : out   std_logic_vector(2 downto 0);
    DDR1_A     : out   std_logic_vector(12 downto 0);
    DDR2_RAS_N : out   std_logic;
    DDR2_CAS_N : out   std_logic;
    DDR2_WE_N  : out   std_logic;
    DDR2_ODT   : out   std_logic;
    DDR2_CKE   : out   std_logic;
    DDR2_CS_N  : out   std_logic;
    DDR2_DQ    : inout std_logic_vector(31 downto 0);
    DDR2_DQS   : inout std_logic_vector(3 downto 0);
    DDR2_DQS_N : inout std_logic_vector(3 downto 0);
    DDR2_DM    : out   std_logic_vector(3 downto 0);
    DDR2_CK    : out   std_logic_vector(1 downto 0);
    DDR2_CK_N  : out   std_logic_vector(1 downto 0);
    DDR2_BA    : out   std_logic_vector(2 downto 0);
    DDR2_A     : out   std_logic_vector(12 downto 0);
    DDR3_RAS_N : out   std_logic;
    DDR3_CAS_N : out   std_logic;
    DDR3_WE_N  : out   std_logic;
    DDR3_ODT   : out   std_logic;
    DDR3_CKE   : out   std_logic;
    DDR3_CS_N  : out   std_logic;
    DDR3_DQ    : inout std_logic_vector(31 downto 0);
    DDR3_DQS   : inout std_logic_vector(3 downto 0);
    DDR3_DQS_N : inout std_logic_vector(3 downto 0);
    DDR3_DM    : out   std_logic_vector(3 downto 0);
    DDR3_CK    : out   std_logic_vector(1 downto 0);
    DDR3_CK_N  : out   std_logic_vector(1 downto 0);
    DDR3_BA    : out   std_logic_vector(2 downto 0);
    DDR3_A     : out   std_logic_vector(12 downto 0);
    -- MGTs
    PCIE_RX_P  : in    std_logic_vector(7 downto 0);
    PCIE_RX_N  : in    std_logic_vector(7 downto 0);
    PCIE_TX_P  : out   std_logic_vector(7 downto 0);
    PCIE_TX_N  : out   std_logic_vector(7 downto 0);
    REAR_RX_P  : in    std_logic_vector(3 downto 0);
    REAR_RX_N  : in    std_logic_vector(3 downto 0);
    REAR_TX_P  : out   std_logic_vector(3 downto 0);
    REAR_TX_N  : out   std_logic_vector(3 downto 0);
    FRONT_RX_P : in    std_logic_vector(3 downto 0);
    FRONT_RX_N : in    std_logic_vector(3 downto 0);
    FRONT_TX_P : out   std_logic_vector(3 downto 0);
    FRONT_TX_N : out   std_logic_vector(3 downto 0));
end wrapper;

architecture mixed of wrapper is

   component user_top_level
    port (
      clk        : in  std_logic;
      rst        : in  std_logic;
      system_in  : in  std_logic_vector(system_width-1 downto 0);
      system_out : out std_logic_vector(system_width-1 downto 0);
      -- Timing Inputs
      tbus_bplane	:inout std_logic_vector(10 downto 1);
      tbus_header	:inout std_logic_vector(10 downto 1);  
      tbus_master	:in std_logic_vector(10 downto 1);
      ten_mhz_clk       : in std_logic;
      -- ADC Inputs
      adc_in_0_0 : in std_logic_vector(13 downto 0);
      adc_in_0_1 : in std_logic_vector(13 downto 0);
      adc_in_0_2 : in std_logic_vector(13 downto 0);
      adc_in_1_0 : in std_logic_vector(13 downto 0);
      adc_in_1_1 : in std_logic_vector(13 downto 0);
      adc_in_1_2 : in std_logic_vector(13 downto 0);
      adc_in_2_0 : in std_logic_vector(13 downto 0);
      adc_in_2_1 : in std_logic_vector(13 downto 0);
      adc_in_2_2 : in std_logic_vector(13 downto 0);
      adc_enb    : out std_logic_vector(2 downto 0);
      syn_rst    : out std_logic
      );
  end component;
  
 



-- XST black box declaration
--  attribute box_type                              : string;
--  attribute box_type of user_top_level : component is "black_box";

-- Synplicity black box declaration
--  attribute syn_black_box                              : boolean;
--  attribute syn_black_box of user_top_level : component is true;


  component commonif
    port(
      lclk       : in    std_logic;
      clk200_p   : in    std_logic;
      clk200_n   : in    std_logic;
      adcclk     : in  std_logic;
      lreseto_l  : in    std_logic;
      lwrite     : in    std_logic;
      lads_l     : in    std_logic;
      lblast_l   : in    std_logic;
      lbterm_o   : out   std_logic;
      lbterm_oe  : out   std_logic;
      lad_i      : in    std_logic_vector(63 downto 0);
      lad_o      : out   std_logic_vector(63 downto 0);
      lad_oe     : out   std_logic;
      lreadyi_o  : out   std_logic;
      lreadyi_oe : out   std_logic;
      lbe_l      : in    std_logic_vector(7 downto 0);
      fholda     : in    std_logic;
      finti_l    : out   std_logic;
      -- DDRII Memory Banks
      DDR0_RAS_N : out   std_logic;
      DDR0_CAS_N : out   std_logic;
      DDR0_WE_N  : out   std_logic;
      DDR0_ODT   : out   std_logic;
      DDR0_CKE   : out   std_logic;
      DDR0_CS_N  : out   std_logic;
      DDR0_DQ    : inout std_logic_vector(31 downto 0);
      DDR0_DQS   : inout std_logic_vector(3 downto 0);
      DDR0_DQS_N : inout std_logic_vector(3 downto 0);
      DDR0_DM    : out   std_logic_vector(3 downto 0);
      DDR0_CK    : out   std_logic_vector(1 downto 0);
      DDR0_CK_N  : out   std_logic_vector(1 downto 0);
      DDR0_BA    : out   std_logic_vector(2 downto 0);
      DDR0_A     : out   std_logic_vector(12 downto 0);
      DDR1_RAS_N : out   std_logic;
      DDR1_CAS_N : out   std_logic;
      DDR1_WE_N  : out   std_logic;
      DDR1_ODT   : out   std_logic;
      DDR1_CKE   : out   std_logic;
      DDR1_CS_N  : out   std_logic;
      DDR1_DQ    : inout std_logic_vector(31 downto 0);
      DDR1_DQS   : inout std_logic_vector(3 downto 0);
      DDR1_DQS_N : inout std_logic_vector(3 downto 0);
      DDR1_DM    : out   std_logic_vector(3 downto 0);
      DDR1_CK    : out   std_logic_vector(1 downto 0);
      DDR1_CK_N  : out   std_logic_vector(1 downto 0);
      DDR1_BA    : out   std_logic_vector(2 downto 0);
      DDR1_A     : out   std_logic_vector(12 downto 0);
      DDR2_RAS_N : out   std_logic;
      DDR2_CAS_N : out   std_logic;
      DDR2_WE_N  : out   std_logic;
      DDR2_ODT   : out   std_logic;
      DDR2_CKE   : out   std_logic;
      DDR2_CS_N  : out   std_logic;
      DDR2_DQ    : inout std_logic_vector(31 downto 0);
      DDR2_DQS   : inout std_logic_vector(3 downto 0);
      DDR2_DQS_N : inout std_logic_vector(3 downto 0);
      DDR2_DM    : out   std_logic_vector(3 downto 0);
      DDR2_CK    : out   std_logic_vector(1 downto 0);
      DDR2_CK_N  : out   std_logic_vector(1 downto 0);
      DDR2_BA    : out   std_logic_vector(2 downto 0);
      DDR2_A     : out   std_logic_vector(12 downto 0);
      DDR3_RAS_N : out   std_logic;
      DDR3_CAS_N : out   std_logic;
      DDR3_WE_N  : out   std_logic;
      DDR3_ODT   : out   std_logic;
      DDR3_CKE   : out   std_logic;
      DDR3_CS_N  : out   std_logic;
      DDR3_DQ    : inout std_logic_vector(31 downto 0);
      DDR3_DQS   : inout std_logic_vector(3 downto 0);
      DDR3_DQS_N : inout std_logic_vector(3 downto 0);
      DDR3_DM    : out   std_logic_vector(3 downto 0);
      DDR3_CK    : out   std_logic_vector(1 downto 0);
      DDR3_CK_N  : out   std_logic_vector(1 downto 0);
      DDR3_BA    : out   std_logic_vector(2 downto 0);
      DDR3_A     : out   std_logic_vector(12 downto 0);
      -- Interface to User Top Level
      clk        : out   std_logic;
      rst        : out   std_logic;
      system_in  : out   std_logic_vector(system_width-1 downto 0);
      system_out : in    std_logic_vector(system_width-1 downto 0));    
  end component;

  signal system_in, system_out : std_logic_vector(system_width-1 downto 0);

  signal clk, rst               : std_logic;
  attribute clock_signal        : string;
  attribute clock_signal of clk : signal is "yes";
  attribute clock_signal of rst : signal is "yes";


  component IOBUF is
    port (
      I  : in    std_logic;
      IO : inout std_logic;
      O  : out   std_logic;
      T  : in    std_logic
      );
  end component;


  signal lreadyi_o  : std_logic;
  signal lreadyi_oe : std_logic;
  signal lbterm_o   : std_logic;
  signal lbterm_oe  : std_logic;
  signal lad_o      : std_logic_vector(63 downto 0);
  signal lad_i      : std_logic_vector(63 downto 0);
  signal lad_oe     : std_logic;

  -------------------------------------------------------------------
  --
  --  NULL_PAIR core component declaration
  --
  -------------------------------------------------------------------
  component NULL_PAIR
    port (
      GREFCLK_IN : in  std_logic;
      RX1N_IN    : in  std_logic_vector(1 downto 0);
      RX1P_IN    : in  std_logic_vector(1 downto 0);
      TX1N_OUT   : out std_logic_vector(1 downto 0);
      TX1P_OUT   : out std_logic_vector(1 downto 0));   
  end component;

  attribute box_type              : string;
  attribute box_type of NULL_PAIR : component is "user_black_box";

  -- Timing and ADC I/0
  -- Temporarily Defined as signals
  -- To be defined as Ports when actual I/O pins defined

  -- Timing INputs
  signal cycle_start   : std_logic;
  signal cycle_stop    : std_logic;
  signal cal_start     : std_logic;
  signal cal_stop      : std_logic;
  signal injection     : std_logic;
  signal hchange       : std_logic;
  signal fref          : std_logic;
  signal ten_mhz_clk   : std_logic;
  -- Timing Outputs
  signal cycle_start_o : std_logic;
  signal cycle_stop_o  : std_logic;
  signal cal_start_o   : std_logic;
  signal cal_stop_o    : std_logic;
  signal injection_o   : std_logic;
  signal hchange_o     : std_logic;
  signal fref_o        : std_logic;
  signal ten_mhz_clk_o : std_logic;
  -- ADC Inputs
  signal adc_in_0_0    : std_logic_vector(13 downto 0);
  signal adc_in_0_1    : std_logic_vector(13 downto 0);
  signal adc_in_0_2    : std_logic_vector(13 downto 0);
  signal adc_in_1_0    : std_logic_vector(13 downto 0);
  signal adc_in_1_1    : std_logic_vector(13 downto 0);
  signal adc_in_1_2    : std_logic_vector(13 downto 0);
  signal adc_in_2_0    : std_logic_vector(13 downto 0);
  signal adc_in_2_1    : std_logic_vector(13 downto 0);
  signal adc_in_2_2    : std_logic_vector(13 downto 0);

   signal tbus_bplane,tbus_header,tbus_master : std_logic_vector(10 downto 1);
   signal adc_enb : std_logic_vector(2 downto 0);
   signal adcclk,sys_clk_i : std_logic;
begin

   user0 : user_top_level
    port map (
      clk        => clk,
      rst        => rst,
      system_in  => system_in,
      system_out => system_out,
      tbus_bplane     => tbus_bplane,
      tbus_header     => tbus_header,
      tbus_master     => tbus_master,    
      ten_mhz_clk =>  ten_mhz_clk,     
      adc_in_0_0 =>  adc_in_0_0,  
      adc_in_0_1 =>  adc_in_0_1,  
      adc_in_0_2 =>  adc_in_0_2,  
      adc_in_1_0 =>  adc_in_1_0,  
      adc_in_1_1 =>  adc_in_1_1,  
      adc_in_1_2 =>  adc_in_1_2,  
      adc_in_2_0 =>  adc_in_2_0,  
      adc_in_2_1 =>  adc_in_2_1,  
      adc_in_2_2 => adc_in_2_2,
      adc_enb => adc_enb,
      syn_rst => open
      );
  
   GT11CLK_MGT_0 : GT11CLK_MGT
	 port map (
		MGTCLKP		=> mgtclk,
		MGTCLKN		=> mgtclkb,
		SYNCLK1OUT	=> SYS_CLK_i,
		SYNCLK2OUT	=> open
	);


    sysclk0 : BUFG
        port map (
           O => adcclk,
           I => SYS_CLK_i
        );    
  

  commonif0 : commonif
    port map (
      lclk       => lclk,
      clk200_p   => clk200_p,
      clk200_n   => clk200_n,
      adcclk     => adcclk,
      lreseto_l  => lreseto_l,
      lwrite     => lwrite,
      lads_l     => lads_l,
      lblast_l   => lblast_l,
      lbterm_o   => lbterm_o,
      lbterm_oe  => lbterm_oe,
      lad_i      => lad_i,
      lad_o      => lad_o,
      lad_oe     => lad_oe,
      lreadyi_o  => lreadyi_o,
      lreadyi_oe => lreadyi_oe,
      lbe_l      => lbe_l,
      fholda     => fholda,
      finti_l    => finti_l,
      DDR0_RAS_N => DDR0_RAS_N,
      DDR0_CAS_N => DDR0_CAS_N,
      DDR0_WE_N  => DDR0_WE_N,
      DDR0_ODT   => DDR0_ODT,
      DDR0_CKE   => DDR0_CKE,
      DDR0_CS_N  => DDR0_CS_N,
      DDR0_DQ    => DDR0_DQ,
      DDR0_DQS   => DDR0_DQS,
      DDR0_DQS_N => DDR0_DQS_N,
      DDR0_DM    => DDR0_DM,
      DDR0_CK    => DDR0_CK,
      DDR0_CK_N  => DDR0_CK_N,
      DDR0_BA    => DDR0_BA,
      DDR0_A     => DDR0_A,
      DDR1_RAS_N => DDR1_RAS_N,
      DDR1_CAS_N => DDR1_CAS_N,
      DDR1_WE_N  => DDR1_WE_N,
      DDR1_ODT   => DDR1_ODT,
      DDR1_CKE   => DDR1_CKE,
      DDR1_CS_N  => DDR1_CS_N,
      DDR1_DQ    => DDR1_DQ,
      DDR1_DQS   => DDR1_DQS,
      DDR1_DQS_N => DDR1_DQS_N,
      DDR1_DM    => DDR1_DM,
      DDR1_CK    => DDR1_CK,
      DDR1_CK_N  => DDR1_CK_N,
      DDR1_BA    => DDR1_BA,
      DDR1_A     => DDR1_A,
      DDR2_RAS_N => DDR2_RAS_N,
      DDR2_CAS_N => DDR2_CAS_N,
      DDR2_WE_N  => DDR2_WE_N,
      DDR2_ODT   => DDR2_ODT,
      DDR2_CKE   => DDR2_CKE,
      DDR2_CS_N  => DDR2_CS_N,
      DDR2_DQ    => DDR2_DQ,
      DDR2_DQS   => DDR2_DQS,
      DDR2_DQS_N => DDR2_DQS_N,
      DDR2_DM    => DDR2_DM,
      DDR2_CK    => DDR2_CK,
      DDR2_CK_N  => DDR2_CK_N,
      DDR2_BA    => DDR2_BA,
      DDR2_A     => DDR2_A,
      DDR3_RAS_N => DDR3_RAS_N,
      DDR3_CAS_N => DDR3_CAS_N,
      DDR3_WE_N  => DDR3_WE_N,
      DDR3_ODT   => DDR3_ODT,
      DDR3_CKE   => DDR3_CKE,
      DDR3_CS_N  => DDR3_CS_N,
      DDR3_DQ    => DDR3_DQ,
      DDR3_DQS   => DDR3_DQS,
      DDR3_DQS_N => DDR3_DQS_N,
      DDR3_DM    => DDR3_DM,
      DDR3_CK    => DDR3_CK,
      DDR3_CK_N  => DDR3_CK_N,
      DDR3_BA    => DDR3_BA,
      DDR3_A     => DDR3_A,

      clk        => clk,
      rst        => rst,
      system_in  => system_in,
      system_out => system_out);


  -- BTERM should only be driven when the fpga is addressed otherwise
  -- float, because the control logic on the XRC might also drive it.
  --
  update_bterm : process(lbterm_o, lbterm_oe)
  begin
    if lbterm_oe = '1' then
      lbterm_l <= not lbterm_o;
    else
      lbterm_l <= 'Z';
    end if;
  end process update_bterm;

  --
  -- LREADYI# should only be driven when the fpga is addressed, otherwise
  -- float because the control logic on the XRC might also drive it.
  --
  update_ready : process(lreadyi_o, lreadyi_oe)
  begin
    if lreadyi_oe = '1' then
      lreadyi_l <= not lreadyi_o;
    else
      lreadyi_l <= 'Z';
    end if;
  end process update_ready;

  --
  -- Drive the local data bus on a read.
  --
  data_bus : process(lad_oe, lad_o)
  begin
    if lad_oe = '1' then
      lad <= lad_o;
    else
      lad <= (others => 'Z');
    end if;
  end process data_bus;

  lad_i <= lad;


  --
  -- PCIe lines on LHS of device
  --
  pcie_null_gen : for i in 0 to 3 generate
    pcie_null_pair_inst : NULL_PAIR
      port map
      (
        GREFCLK_IN => system_in(0),
        RX1N_IN    => PCIE_RX_N((2*i+1) downto 2*i),
        RX1P_IN    => PCIE_RX_P((2*i+1) downto 2*i),
        TX1N_OUT   => PCIE_TX_N((2*i+1) downto 2*i),
        TX1P_OUT   => PCIE_TX_P((2*i+1) downto 2*i)
        );
  end generate pcie_null_gen;


  --
  -- Rear MGT lines on RHS of device
  --
  rear_null_gen : for i in 0 to 1 generate
    rear_null_pair_inst : NULL_PAIR
      port map
      (
        GREFCLK_IN => system_in(0),
        RX1N_IN    => REAR_RX_N((2*i+1) downto 2*i),
        RX1P_IN    => REAR_RX_P((2*i+1) downto 2*i),
        TX1N_OUT   => REAR_TX_N((2*i+1) downto 2*i),
        TX1P_OUT   => REAR_TX_P((2*i+1) downto 2*i)
        );
  end generate rear_null_gen;


  --
  -- Front (XRM) MGT lines on RHS of device
  --
  front_null_gen : for i in 0 to 1 generate
    front_null_pair_inst : NULL_PAIR
      port map
      (
        GREFCLK_IN => system_in(0),
        RX1N_IN    => FRONT_RX_N((2*i+1) downto 2*i),
        RX1P_IN    => FRONT_RX_P((2*i+1) downto 2*i),
        TX1N_OUT   => FRONT_TX_N((2*i+1) downto 2*i),
        TX1P_OUT   => FRONT_TX_P((2*i+1) downto 2*i)
        );
  end generate front_null_gen;

  dummy_inputs: process (clk, rst)
  begin  -- process dummy_inputs
    if rst = '1' then                   
      adc_in_0_0 <= (others => '0');
      adc_in_0_1 <= (others => '0');
      adc_in_0_2 <= (others => '0');
      adc_in_1_0 <= (others => '0');
      adc_in_1_1 <= (others => '0');
      adc_in_1_2 <= (others => '0');
      adc_in_2_0 <= (others => '0');
      adc_in_2_1 <= (others => '0');
      adc_in_2_2 <= (others => '0');
      fref <= '0';
      ten_mhz_clk <= '0';
    elsif clk'event and clk = '1' then
      adc_in_0_0 <=  adc_in_0_0+1;
      adc_in_0_1 <=  adc_in_0_1+2;
      adc_in_0_2 <=  adc_in_0_2+3;
      adc_in_1_0 <=  adc_in_2_0+5;
      adc_in_1_1 <=  adc_in_2_1+6;
      adc_in_1_2 <=  adc_in_2_2+7;
      adc_in_2_0 <=  adc_in_1_0+8;
      adc_in_2_1 <=  adc_in_1_1+9;
      adc_in_2_2 <=  adc_in_1_2+10;
      fref <= adc_in_0_0(8);
      ten_mhz_clk <= adc_in_0_0(3);         
    end if;
  end process dummy_inputs;
  cycle_start <= '0';
  cycle_stop <= '0';
  cal_start <= '0';
  cal_stop <= '0';
  injection <= '0';
  hchange <= '0';
  
end mixed;
