Electronic – VHDL Unconstrained port in a entity

genericvhdl

I've a problem with the definition of an entity. I'm writing a wrapper that accepts several generic. Among these generic there are some boolean values that have the function to enable or disable the transmission of some input signal to the output of the entity. I'd like to have the width of the output signal related to the boolean values. This is what I want to do :

entity of DUT is 
   generic( 
     DATA_1_WIDTH : natural := 16;
     DATA_2_WIDTH : natural := 16;
     SWITCH_1 : boolean := FALSE;
     SWITCH_2 : boolean := FALSE;
     ....
     );
   port (
     clk : in std_logic;
     rst : in std_logic;
     DATA_1 : in std_logic_vector(DATA_1_WIDTH - 1 downto 0);
     DATA_2 : in std_logic_vector(DATA_2_WIDTH - 1 downto 0);
     ....
     DATA_OUT : out std_logic_vector);

Where the width of "DATA_OUT" change with the values of the switches :

  • When SWITCH_1 = TRUE and SWITCH_2 = TRUE => width of DATA_OUT = DATA_1_WIDTH + DATA_2_WIDTH + constant;
  • When SWITCH_1 = TRUE and SWITCH_2 = FALSE => width of DATA_OUT = DATA_1_WIDTH + constant;

And so on.

Can someone tell me a way to do this ?

Best Answer

Depending on how the rest of your entity works, you may be able to leave DATA_OUT as an unconstrained array. This means that you don't give it a width in the port map, and that it takes the width of the signal that you connect to it in the instantiating entity. This basically passes the problem up one level in the hierarchy.

You can also achieve this using a function. Create a package for your design, and within this create a function, something like this:

function GetDataOutWidth(Switch1, Switch2 : boolean; Data1Width, Data2Width : integer) return integer is
  constant WidthConstant : integer := 2; -- Or whatever
begin
  if (Switch2) then
    return Data1Width + Data2Width + WidthConstant;
  else
    return Data1Width + WidthConstant;
  end if;
end function;

Your code can then use this function in the port map, something like this:

DATA_OUT : out std_logic_vector(GetDataOutWidth(SWITCH_1, SWITCH_2, DATA_1_WIDTH, DATA_2_WIDTH)-1 downto 0)