neonriver123
neonriver123

Reputation: 11

Parameterizable VHDL subtypes

I know it's possible to create a subtype of a defined range, e.g:

subtype ADDRESS is UNSIGNED range (32 downto 0);

Is it possible to create a parameterizable type/subtype? Essentially leaving the value of '32' to be defined by the user upon making a variable of type ADDRESS. For example:

subtype ADDRESS is UNSIGNED range ( f(x) ) downto 0;

where f() is a function predefined in another package, and X is a natural integer supplied by the user upon creating an instance of ADDRESS.

Essentially I want to shorten...

y : UNSIGNED(f(X) downto 0);

to

y : ADDRESS(X);

where X is a natural.

Upvotes: 1

Views: 1014

Answers (2)

JHBonarius
JHBonarius

Reputation: 11261

Matthew Taylor's answer is already correct, but I would like to reply to your final question

y : ADDRESS(X);

In C you you use a macro, but in VHDL this is not possible. It would require the function ADDRESS to return a subtype-type. IEEE1076-2008 defines:

function_specification ::=
    [ pure | impure ] function designator
        subprogram_header
        [ [ parameter ] ( formal_parameter_list ) ] return type_mark

Where:

type_mark ::=
    type_name
  | subtype_name

I.e. the return type must be a type that is already defined. It cannot be a new [sub]type. You could do something with a subtype definition, like Matthew explains:

subtype ADDRESS_X is unsigned(f(X) downto 0);
signal new_signal : ADDRESS_X;

Upvotes: 1

Matthew
Matthew

Reputation: 13957

Well, yes. But you can't write:

subtype ADDRESS is UNSIGNED range ( f(x) ) downto 0;

because that is not correct VHDL. You must write:

subtype ADDRESS is UNSIGNED ( f(x) downto 0);

where x must be static. ie x must be a literal, constant or generic.

You can use functions in this way to define the value of constants and other static values. All the inputs to such a function must be static. Interestingly, such a function executes during elaboration, which can make it hard to debug. If you are having problems debugging such a function, you can temporarily change the target of the function's return value to something not static (eg a variable); then the function will execute after time 0, making it easier to debug. Here's a real example:

package P is
  function F(I : integer) return integer;
end package P;

package body P is
  function F(I : integer) return integer  is
  begin
    if I > 16 then 
      return I - 1;
    else
      return (I * 2) - 1;
    end if;
  end function F;

end package body P;

library IEEE;
use IEEE.numeric_std.all;
use work.P.all;

entity E is
  constant X : integer := 16;
end entity E;

architecture E of E is
  subtype ADDRESS is UNSIGNED ( f(x) downto 0);
begin

  process
  begin
    report "ADDRESS'left= " & integer'image(ADDRESS'left);
    wait;
  end process;

end architecture E;

And here it is on EDA Playground.

Upvotes: 1

Related Questions