-------------------------------------------------------------------------------
-- Title      : Wrapper for look-up table MIAUPhiPro1
-- Project    : 
-------------------------------------------------------------------------------
-- File       : miauphipro1lut.vhd
-- Author     : SAKULIN Hannes  <hsakulin@dsy-srv2.cern.ch>
-- Company    : 
-- Platform   : 
-------------------------------------------------------------------------------
-- Description: Wrapper for set of identical LUTs with different default values
--              as selected by instance
--
--              automatically generated by L1MuGMTLUTConverter.cc
-------------------------------------------------------------------------------
-- $Revision :$
-- $Date : $
-------------------------------------------------------------------------------
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

-------------------------------------------------------------------------------
-- Wrapper for all LUTs of this type
-------------------------------------------------------------------------------

entity miauphipro1lut is
  generic (
    instance_idx        : integer := 0;  -- type of LUT
    my_vme_base_address : integer := 0;  -- VME address of this instance
    edge                : std_logic := '1');  -- edge (for Block RAM LUTs)

  port (
    -- GMT data port
    phi_fine : in std_logic_vector(2 downto 0);
    eta : in std_logic_vector(3 downto 0);
    pt : in std_logic_vector(4 downto 0);
    charge : in std_logic_vector(0 downto 0);

    cphi_fine : out std_logic_vector(0 downto 0);
    cphi_ofs : out std_logic_vector(2 downto 0);

    -- clock and reset
    clk   : in std_logic;
    sinit : in std_logic;


    -- VME port
    vme_addr     : in    std_logic_vector;  -- leave unconstrained 
                                            -- may go downto 0 or downto 1
    vme_data     : in    std_logic_vector;  -- leave unconstrained
    vme_en       : in    std_logic;
    vme_wr       : in    std_logic;
    vme_data_out : out   std_logic_vector;                                    
    vme_en_out   : out   std_logic;        
    vme_clk      : in    std_logic);


end miauphipro1lut;


-------------------------------------------------------------------------------
-- Implementation
-------------------------------------------------------------------------------

architecture behavioral of miauphipro1lut is

    -- Synplicity black box declaration
  attribute syn_black_box : boolean;

  component miauphipro1_mip_dt
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_mip_dt: component is true;


  component miauphipro1_mip_brpc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_mip_brpc: component is true;


  component miauphipro1_iso_dt
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_iso_dt: component is true;


  component miauphipro1_iso_brpc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_iso_brpc: component is true;


  component miauphipro1_mip_csc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_mip_csc: component is true;


  component miauphipro1_mip_frpc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_mip_frpc: component is true;


  component miauphipro1_iso_csc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_iso_csc: component is true;


  component miauphipro1_iso_frpc
    port (
      addrb  : in  std_logic_vector(10 downto 0);
      addra  : in  std_logic_vector(12 downto 0);
      clkb   : in  std_logic;
      clka   : in  std_logic;
      dinb   : in  std_logic_vector(15 downto 0);
      doutb  : out std_logic_vector(15 downto 0);
      douta  : out std_logic_vector(3 downto 0);
      enb    : in  std_logic;
      sinita : in  std_logic;
      web    : in  std_logic);
  end component;
  attribute syn_black_box of miauphipro1_iso_frpc: component is true;



    
  signal gmt_addr_i : std_logic_vector(12 downto 0);
  signal gmt_data_i : std_logic_vector(3 downto 0);

  signal vme_addr_i : std_logic_vector(10 downto 0);
  signal vme_en_i   : std_logic;
  signal vme_din_i  : std_logic_vector(15 downto 0);
  signal vme_dout_i : std_logic_vector(15 downto 0);

  signal lutclk : std_logic;
  
begin  -- behavioral
  --------------------------------------------------------------------------------
  -- GMT data path
  --------------------------------------------------------------------------------

  gmt_addr_i <= (phi_fine & eta & pt & charge);

  cphi_ofs <=  gmt_data_i(2 downto 0);
  cphi_fine <=  gmt_data_i(3 downto 3);


    
  --------------------------------------------------------------------------------
  -- VME port
  --------------------------------------------------------------------------------
  assert vme_data'high <= 15 report "error: max VME data width is 16 bits" severity error;
  assert vme_addr'high >= 10 report "error: VME addr width has to be greater than 10" severity error;

  vme_addr_i <= vme_addr( vme_addr_i'high+1 downto 1 );  -- connect lower adress bits to LUT
  vme_din_i <= vme_data( vme_din_i'range );   -- VME data input is always connected to data bus

  -- purpose: decode VME address and generate internal enable signal 
  vme_addr_decode : process (vme_addr, vme_en) is
    variable my_addr_vec : std_logic_vector(vme_addr'high downto 0);
    variable selected    : boolean;
  begin  -- process vme_addr_decode
    my_addr_vec := std_logic_vector( TO_UNSIGNED ( my_vme_base_address, vme_addr'high+1 ) );
    selected    := my_addr_vec(vme_addr'high downto vme_addr_i'length+1) =
                   vme_addr(vme_addr'high downto vme_addr_i'length+1);
    vme_en_i <= '0' ;
    if selected then
      vme_en_i <= vme_en;
    end if;
  end process vme_addr_decode;

  -- register output enable
  reg_enout: process (vme_clk) is
  begin  
    if vme_clk'event and vme_clk = '1' then
      vme_en_out <= vme_en_i;    
    end if;
  end process reg_enout;

  -- output data is registered in LUT
  vme_data_out ( vme_dout_i'range ) <= vme_dout_i;
  vme_data_out ( 15 downto (vme_dout_i'high+1) ) <= (others => '0');

  -----------------------------------------------------------------------------
  -- Instantiation of the memory
  -----------------------------------------------------------------------------

  clkedge: if (edge ='1') generate
  begin  -- generate clkedge
    lutclk <= clk;
  end generate clkedge;

  invclkedge: if (edge ='0') generate
  begin  -- generate clkedge
    lutclk <= not clk;
  end generate invclkedge;


  G1 : if (instance_idx = 0) generate
    
    MIP_DT_LUT : miauphipro1_mip_dt
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G2 : if (instance_idx = 1) generate
    
    MIP_BRPC_LUT : miauphipro1_mip_brpc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G3 : if (instance_idx = 2) generate
    
    ISO_DT_LUT : miauphipro1_iso_dt
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G4 : if (instance_idx = 3) generate
    
    ISO_BRPC_LUT : miauphipro1_iso_brpc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G5 : if (instance_idx = 4) generate
    
    MIP_CSC_LUT : miauphipro1_mip_csc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G6 : if (instance_idx = 5) generate
    
    MIP_FRPC_LUT : miauphipro1_mip_frpc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G7 : if (instance_idx = 6) generate
    
    ISO_CSC_LUT : miauphipro1_iso_csc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  G8 : if (instance_idx = 7) generate
    
    ISO_FRPC_LUT : miauphipro1_iso_frpc
      port map (
        -- GMT data port
        addra => gmt_addr_i,
        douta  => gmt_data_i,

        -- VME port
        addrb => vme_addr_i,
        dinb  => vme_din_i,
        doutb => vme_dout_i,
        enb   => vme_en_i,
        web   => vme_wr,
        clkb  => vme_clk,

        -- clock and init
        clka    => lutclk,
        sinita  => sinit);
  end generate;

  

end behavioral;