--******************************************************************************
--* @short   VME bus multiplexer for the internal VME busses
--******************************************************************************
--* @author  SAKULIN Hannes  <hsakulin@dsy-srv2.cern.ch>
--* @version $Revision: 1.2 $
--* @date    $Date: 2004/12/17 09:30:38 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;


package VMEMux is

  subtype TVMEData is std_logic_vector (15 downto 0);
  type TVMEData_vec is array (integer range <>) of TVMEData;
  type TVMEEnable_vec is array (integer range <>) of std_logic;

  procedure mux_vme (
    constant data_vec : in TVMEData_vec;
    constant en_vec : in TVMEEnable_vec;
    signal data : out TVMEData;
    signal en : out std_logic);

end package VMEMux;

package body VMEMux is

  procedure mux_vme (
    constant data_vec : in TVMEData_vec;
    constant en_vec : in TVMEEnable_vec;
    signal data : out TVMEData;
    signal en : out std_logic) is

    variable data_vec_and : TVMEData_vec(data_vec'range);
    
    variable data_muxed : TVMEData;
    variable en_ored    : std_logic;
  begin
    assert data_vec'high = en_vec'high report  "error in VMEMux: mismatch of data and enable dimensions" severity error;
    assert data_vec'low  = en_vec'low  report "error in VMEMux: mismatch of data and enable dimensions" severity error;
    
    -- AND
    for i in data_vec'range loop
      data_vec_and(i) := (others => '0');
      if en_vec(i) = '1' then
        data_vec_and(i) := data_vec(i);
      end if;
    end loop;  -- i

    -- OR
    data_muxed := (others => '0');
    en_ored := '0';
    for i in data_vec'range loop
      data_muxed := data_muxed or data_vec_and(i);
      en_ored := en_ored or en_vec(i);
    end loop;  -- i

    data <= data_muxed;
    en   <= en_ored;    
  end;
  

end package body VMEMux;