-------------------------------------------------------------------------------
-- Title      : Wrapper for look-up table LFMergeRankPtQ
-- Project    : 
-------------------------------------------------------------------------------
-- File       : lfmergerankptqlut.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 lfmergerankptqlut 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
    q : in std_logic_vector(2 downto 0);
    pt : in std_logic_vector(4 downto 0);

    rank_ptq : out std_logic_vector(1 downto 0);


    -- 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 lfmergerankptqlut;


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

architecture behavioral of lfmergerankptqlut is

    -- Synplicity black box declaration
  attribute syn_black_box : boolean;

  component lfmergerankptq_dt
    port (
      A    : IN  std_logic_VECTOR(7 downto 0);
      CLK  : IN  std_logic;
      D    : IN  std_logic_VECTOR(1 downto 0);
      WE   : IN  std_logic;
      I_CE : IN  std_logic;
      DPRA : IN  std_logic_VECTOR(7 downto 0);
      DPO  : OUT std_logic_VECTOR(1 downto 0);
      SPO  : OUT std_logic_VECTOR(1 downto 0));
  end component;
  attribute syn_black_box of lfmergerankptq_dt: component is true;


  component lfmergerankptq_brpc
    port (
      A    : IN  std_logic_VECTOR(7 downto 0);
      CLK  : IN  std_logic;
      D    : IN  std_logic_VECTOR(1 downto 0);
      WE   : IN  std_logic;
      I_CE : IN  std_logic;
      DPRA : IN  std_logic_VECTOR(7 downto 0);
      DPO  : OUT std_logic_VECTOR(1 downto 0);
      SPO  : OUT std_logic_VECTOR(1 downto 0));
  end component;
  attribute syn_black_box of lfmergerankptq_brpc: component is true;


  component lfmergerankptq_csc
    port (
      A    : IN  std_logic_VECTOR(7 downto 0);
      CLK  : IN  std_logic;
      D    : IN  std_logic_VECTOR(1 downto 0);
      WE   : IN  std_logic;
      I_CE : IN  std_logic;
      DPRA : IN  std_logic_VECTOR(7 downto 0);
      DPO  : OUT std_logic_VECTOR(1 downto 0);
      SPO  : OUT std_logic_VECTOR(1 downto 0));
  end component;
  attribute syn_black_box of lfmergerankptq_csc: component is true;


  component lfmergerankptq_frpc
    port (
      A    : IN  std_logic_VECTOR(7 downto 0);
      CLK  : IN  std_logic;
      D    : IN  std_logic_VECTOR(1 downto 0);
      WE   : IN  std_logic;
      I_CE : IN  std_logic;
      DPRA : IN  std_logic_VECTOR(7 downto 0);
      DPO  : OUT std_logic_VECTOR(1 downto 0);
      SPO  : OUT std_logic_VECTOR(1 downto 0));
  end component;
  attribute syn_black_box of lfmergerankptq_frpc: component is true;



    
  signal gmt_addr_i : std_logic_vector(7 downto 0);
  signal gmt_data_i : std_logic_vector(1 downto 0);

  signal vme_addr_i : std_logic_vector(7 downto 0);
  signal vme_en_i   : std_logic;
  signal vme_din_i  : std_logic_vector(1 downto 0);
  signal vme_dout_i : std_logic_vector(1 downto 0);

  
  
begin  -- behavioral
  --------------------------------------------------------------------------------
  -- GMT data path
  --------------------------------------------------------------------------------

  gmt_addr_i <= (q & pt);

  rank_ptq <=  gmt_data_i(1 downto 0);


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

  G1 : if (instance_idx = 0) generate
    
    DT_LUT : lfmergerankptq_dt
      port map (
        -- GMT data port
        DPRA => gmt_addr_i,
        DPO  => gmt_data_i,

        -- VME port
        A    => vme_addr_i,
        D    => vme_din_i,
        SPO  => vme_dout_i,
        I_CE => vme_en_i,
        WE   => vme_wr,

        -- clock
        CLK  => vme_clk);
  end generate;

  G2 : if (instance_idx = 1) generate
    
    BRPC_LUT : lfmergerankptq_brpc
      port map (
        -- GMT data port
        DPRA => gmt_addr_i,
        DPO  => gmt_data_i,

        -- VME port
        A    => vme_addr_i,
        D    => vme_din_i,
        SPO  => vme_dout_i,
        I_CE => vme_en_i,
        WE   => vme_wr,

        -- clock
        CLK  => vme_clk);
  end generate;

  G3 : if (instance_idx = 2) generate
    
    CSC_LUT : lfmergerankptq_csc
      port map (
        -- GMT data port
        DPRA => gmt_addr_i,
        DPO  => gmt_data_i,

        -- VME port
        A    => vme_addr_i,
        D    => vme_din_i,
        SPO  => vme_dout_i,
        I_CE => vme_en_i,
        WE   => vme_wr,

        -- clock
        CLK  => vme_clk);
  end generate;

  G4 : if (instance_idx = 3) generate
    
    FRPC_LUT : lfmergerankptq_frpc
      port map (
        -- GMT data port
        DPRA => gmt_addr_i,
        DPO  => gmt_data_i,

        -- VME port
        A    => vme_addr_i,
        D    => vme_din_i,
        SPO  => vme_dout_i,
        I_CE => vme_en_i,
        WE   => vme_wr,

        -- clock
        CLK  => vme_clk);
  end generate;

  

end behavioral;