Reputation: 3457
I want to create a custom type in my generic
section of my entity
using VHDL-2008. However I get an error immediately in Modelsim with this code. The error is:
** Error: C:/Projects/source/My_Mux.vhd(35): near "is": expecting ';' or ')'
Note that Line 35 is the type t_Array
below:
entity My_Mux is
generic (
g_MUX_INPUTS : integer := 2;
type t_Array is array (0 to g_MUX_INPUTS-1) of std_logic_vector(7 downto 0)
);
port (
i_Select : in std_logic_vector(1 downto 0);
i_Mux_Data : in t_Array;
o_Data : out std_logic_vector(7 downto 0)
);
end entity My_Mux;
architecture RTL of My_Mux is
begin
o_Data <= i_Mux_Data(0) when i_Select = "00" else i_Mux_Data(1);
end architecture RTL;
I looked into creating a special function that I define in my generic portion of my code. But that requires that I overload the function in the instantiating module, which I really did not want to have to do, it seems needlessly complicated. If I could create a custom type in the generic it would solve my problem. Possible using VHDL-2008?
Upvotes: 1
Views: 2321
Reputation:
How would you expect to have type compatibility between the formal and actual if they declaration of a type were actually made in a generic declaration?
Each declaration in VHDL is unique, not by name but by declaration occurrence. What declaration the name references depends on scope and visibility. Both (all) places a name is used have to be able to reach the same declaration.
How a generic type is declared is found in IEEE Std 1076-2008 6.5.3 Interface type declarations:
An interface type declaration declares an interface type that appears as a generic of a design entity, a component, a block, a package, or a subprogram.
interface_type_declaration ::=
interface_incomplete_type_declarationinterface_incomplete_type_declaration ::= type identifier
An interface type provides a means for the environment to determine a type to be used for objects in a particular portion of a description. The set of values and applicable operations for an interface type may be determined by an associated subtype in the environment. The manner in which such associations are made is described in 6.5.7.
And the important thing to note is that is an incomplete type declaration, where the actual specifies a preexisting type with a subtype constraint (6.5.6.2):
The subtype denoted by a generic type is specified by the corresponding actual in a generic association list. It is an error if no such actual is specified for a given formal generic type (either because the formal generic is unassociated or because the actual is open).
Because that association is with a previously declared type there is little difference with doing the same thing the -1993 way:
library ieee;
use ieee.std_logic_1164.all;
package my_package is
type my_array is array (natural range <>) of std_logic_vector(7 downto 0);
end package;
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity My_Mux is
generic (
g_MUX_INPUTS: integer := 2
--type t_Array is array (0 to g_MUX_INPUTS-1) of
-- std_logic_vector(7 downto 0)
);
port (
i_Select: in std_logic_vector(1 downto 0);
-- i_Mux_Data: in t_Array;
i_Mux_Data: in my_array (0 to g_MUX_INPUTS - 1);
o_Data : out std_logic_vector(7 downto 0)
);
end entity My_Mux;
architecture RTL of My_Mux is
begin
o_Data <= i_Mux_Data(0) when i_Select = "00" else i_Mux_Data(1);
end architecture RTL;
There's an added package that has a type declaration my_array
which is an unbound (partially constrained) multidimensional array type.
This allows the use of the package my_package
to specify the type of the actual:
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity my_mux_tb is
end entity;
architecture foo of my_mux_tb is
constant MUX_INPUTS: natural := 2;
signal i_Select: std_logic_vector (1 downto 0);
signal i_Mux_Data: my_array (0 to MUX_INPUTS -1);
signal o_Data: std_logic_vector(7 downto 0);
begin
DUT:
entity work.My_mux
generic map (
g_MUX_INPUTS => MUX_INPUTS
)
port map (
i_Select => i_Select,
i_Mux_Data => i_Mux_Data,
o_Data => o_Data
);
end architecture;
The two examples above analyzed in order, elaborate and the testbench simulates (while doing nothing particular interesting besides telling us the subtype constraint is passed on the port actual).
The custom type would be required to be accessible to both the component or entity instantiation and the place the port actual is declared.
Using a generic type would allow you to remove the my_package
use clause from the my_mux
context clause, relying on the actual association instead.
You can also bind the type at elaboration time without switching the package (or relying on package instantiation in -2008 with it's own generics).
Upvotes: 5