VHDL mux in need of generics
There are 4 ways to a solve this:

Solution 1:

You can define a fixed width STD_LOGIC_VECTOR (SLV), which can be used to construct other vectors (let's call them STD_LOGIC_VECTOR_VECTORs (SLVV).

subtype T_SLV_8  is STD_LOGIC_VECTOR(7 downto 0);        -- define a Byte
type    T_SLVV_8 is array(NATURAL range &lt;&gt;) of T_SLV_8;  -- define a new unconstrained vector of Bytes.


Now you can define your entity as follows:

entity mux_slvv_8 is
  generic (
    PORTS  : POSITIVE  := 4
  );
  port (
    sel  : in  STD_LOGIC_VECTOR(log2ceilnz(PORTS) - 1 downto 0);
    X    : in  T_SLVV_8(PORTS - 1 downto 0);
    Y    : out T_SLV_8
  );
end;


The internal logic can be reduced to:

architecture rtl of mux_slvv_8 is
begin
  Y &lt;= X(to_integer(unsigned(sel)));
end;


This can be improved by extracting to_integer(unsigned(..)) into a function called to_index.

Solution 2:

The next step would be, to be also flexible in how many bits are multiplexed at once. So let's introduce a generic BITS to specify the data bits. VHDL has a problem to define array of unconstrained arrays (this is solved with VHDL-2008, but not all vendors support this feature).

So solution 2 uses a flat vector to pass all bits to the mux.

entity mux_flat is
  generic (
    PORTS  : POSITIVE  := 4;
    BITS   : POSITIVE  := 8
  );
  port (
    sel  : in  STD_LOGIC_VECTOR(log2ceilnz(PORTS) - 1 downto 0);
    X    : in  STD_LOGIC_VECTOR((BITS * PORTS) - 1 downto 0);
    Y    : out STD_LOGIC_VECTOR(BITS - 1 downto 0)
  );
end;

architecture rtl of mux_flat is
  type T_SLVV is array(NATURAL range &lt;&gt;) of STD_LOGIC_VECTOR(BITS - 1 downto 0);
  signal mux_in : T_SLVV(PORTS - 1 downto 0)
begin
  gen : for i in 0 to PORTS - 1 generate
    -- convert flat vector to slvv
    mux_in(i) &lt;= X(((i + 1) * BITS) - 1 downto (i * BITS));
  end generate;
  Y &lt;= mux_in(to_integer(unsigned(sel)));
end;


Solution 3:

Being flexible in PORTS and BITS can also be done by using a real 2-dimensional array -> STD_LOGIC_MATRIX (SLM).

type T_SLM is array(NATURAL range &lt;&gt;, NATURAL range &lt;&gt;) of STD_LOGIC;


This would be the entity declaration:

entity mux_slm is
  generic (
    PORTS  : POSITIVE  := 4;
    BITS   : POSITIVE  := 8
  );
  port (
    sel  : in  STD_LOGIC_VECTOR(log2ceilnz(PORTS) - 1 downto 0);
    X    : in  T_SLM(PORTS - 1 downto 0, BITS - 1 downto 0);
    Y    : out STD_LOGIC_VECTOR(BITS - 1 downto 0)
  );
end;


You could also write a generate loop to do some wiring or you can define some functions to do that.

-- get a matrix row
function get_row(slm : T_SLM; RowIndex : NATURAL) return STD_LOGIC_VECTOR is
  variable slv : STD_LOGIC_VECTOR(slm'high(2) downto slm'low(2)); -- Xilinx iSIM work-around, because 'range(2) = 'range(1); tested with ISE/iSIM 14.2
begin
  for i in slv'range loop
    slv(i) := slm(RowIndex, i);
  end loop;
  return slv;
end function;


And thats the corresponding architecture:

architecture rtl of mux_slm is
begin
  Y &lt;= get_Row(X, to_integer(unsigned(sel)));
end;


Solution 4:

If your tool supports VHDL-2008 and arrays of unconstrained vectors, then you can use this type:

type T_SLVV is array(NATURAL range &lt;&gt;) of STD_LOGIC_VECTOR;


Type Conversion:

The following images illustrates all possible type conversions regarding: SL, SLV, SLVV and SLM.



If you are interested in more, I could upload my complete collection of vector, vector-vector and matrix types, functions and procedures. Please give me a hint.

Edit:

Here is the package PoC.common.vectors. It's included in my PicoBlaze Library which is currently in beta state. The release of PoC is also planned, but not so progressed. So I included some necessary packages and modules into this library. The source code license is 'Apache License 2.0'.