Reputation: 11
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
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
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