I am trying to create a bus/dataflow multiplexer with variable width and number of inputs, and use it as an IP Module in block design with Vivado. So far I have successfully managed to create a 2to1 mux with variable width:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux is
Generic ( NUM_BITS : integer);
Port (
SEL : in STD_LOGIC;
A : in STD_LOGIC_VECTOR(NUM_BITS-1 downto 0);
B : in STD_LOGIC_VECTOR(NUM_BITS-1 downto 0);
X : out STD_LOGIC_VECTOR(NUM_BITS-1 downto 0));
end mux;
architecture Behavioral of mux is
begin
X <= A when (SEL = '0') else B;
end Behavioral;
This works. I am able to drop this into the Block Design tool in Vivado, and I am able to customize the block and change the value of "NUM_BITS".
Customizable IP Mux in Block Design
I have almost successfully created a variable input mux with fixed width:
use IEEE.STD_LOGIC_1164.ALL;
package my_pkg is
-- Generic ( NUM_BITS : integer);
type inputs is array(natural range<>) of STD_LOGIC_VECTOR(8 downto 0);
end my_pkg;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;
use work.my_pkg.all;
entity mux is
Generic ( SEL_WIDTH : integer);
Port (
SEL : in STD_LOGIC_VECTOR(SEL_WIDTH-1 downto 0);
INPUT : in inputs(0 downto 2**SEL_WIDTH-1);
OUTPUT : out STD_LOGIC_VECTOR(8 downto 0));
end mux;
architecture Behavioral of mux is
begin
OUTPUT <= INPUT(to_integer(unsigned(SEL)));
end Behavioral;
However, I am not able to drop this into the block design tool because port type needs to be std_logic_vector in order to be recognized by the block design tool.
I have seen some other posts addressing similar issues:
Using array of std_logic_vector as a port type, with both ranges using a generic - unable to use the provided examples in block design tool
Use generic parameter as port array length - used this to create the code in second portion
But neither of these helped me achieve what I would like. I would like to combine these two into one multiplexer with BOTH variable inputs and width. I am using Xilinx Vivado 2020.1