Bundles in VHDL
Introduction
This page discusses issues around defining the concept of a bundle in VHDL. We use the term
bundle here instead of
interface to distinguish this concept from the use of interface objects in VHDL; a bundle (or more precisely a view of a bundle) will itself be an interface object. We take into consideration the requirements that have been formulated in several contributions, the VHDL language definintion, the VHDL-AMS language definition to the extent of not preventing the concept to be extended for use in VHDL-AMS, and the definition of
interfaces in SystemVerilog.
Collected Requirements Interpreted within the VHDL Language Definition
The detailed requirements currently exist in a number of places; they have to be consolidated and formalized. Here we take the ideas expressed by the requirements and explore how they could be expressed in the current VHDL framework without introducing new concepts. Examples are given with the intent of illustrating the issues; the syntax is tentative, and no consideration is given to use clauses etc. needed to make declarations visible. It should be noted that there are many inconsistencies and open questions at this time.
The Bundle Concept
A bundle intends to separate the definition of (a part of) the interface of a design unit from its implementation. From a language perspective, a bundle is a concept that has two parts: a declaration that specifies the properties of the bundle, e.g. its members (the generalized type), and an actual or formal object that has these properties (the generalized port or signal). The bundle declaration has a declarative region in which the elements of the bundle are declared. Such elements may be:
- A collection of objects. For a bundle that describes communication between instances of design entities, such objects may be signals and shared variables. In VHDL-AMS, quantities and terminals may also be part of a bundle. If extended to uses other than ports of a design unit and related uses, the objects may also include constants, variables, and files.
- Definitions of subprograms useful to manipulate objects of a bundle
- Other declarations: subprogram declaration, subprogram instantiation declaration, package declaration, package instantiation declaration, type declaration, subtype declaration, alias declaration, attribute declaration, attribute specification, use clause, group template declaration, group declaration.
Jointly, these elements are the
permanent elements of the bundle. A bundle may be parameterized in the following ways:
- A generic constant, for example to define the bounds of an array object declared in the bundle
- A generic type to specify the type of an object declared in the bundle. This would make it possible to keep the structure of a bundle but replace the implementation of one of its elements.
- A generic subprobram defining a method of the bundle. It should be noted that only subprograms that have been declared as part of the bundle can be redefined, i.e. this is not a mechanism for extending the methods of the interface.
- A generic package. The possibilities offered by generic packages of bundles have to be explored.
A bundle may also include objects that logically may be part of more than one bundle. The most prominent such object is a clock; other examples would be supply and ground. Such objects are declared as formal ports of a bundle; the corresponding actual objects are specified when a bundle object is created (declared or instantiated), either as part of the declaration/instantiation or as a separate step. Each bundle object creation may associate the bundle with different objects. We may want to call these objects the
per instance elements of the bundle.
Example of a bundle declaration:
bundle b is
generic (ub: integer := 7); -- A simple parameterization defining a generic constant
port (signal clk: in std_logic); -- A per instance object of the bundle; its name in the bundle is clk
signal s1: std_logic := '0'; -- Permanent objects of the bundle
signal s2: std_logic_vector(ub downto 0) := (others => '0');
shared variable sv : my_protected_type;
end bundle b;
Bundles may be declared in the following declarative parts: block declarative part, entity declarative part, package declarative part. Whether it should be possible to declare bundles in other places where declarations can be made (package body declarative part, process declarative part, protected type declarative part, protected type body declarative part, subprogram declarative part) has to be looked at. However, the rules for bundles declared in these places could be quite restrictive because of the possible ways to refer to the declaration.
Objects with Bundle Properties
We have to be able to create an object with bundle properties to hold values during simulation. The common way to create such objects is by means of an object declaration. For a simple bundle
bs
without generics and ports:
bundle object o : bs;
There are a number of issues to consider to make this possible. First, if a bundle has neither generics nor ports the bundle object declaration is straightforward, as just shown. Next, if the bundle has ports, there must be a way to associate an actual with a formal port of the bundle. There is no precedent for this to be done in a declaration in VHDL today. Finally, if the bundle has generics, their impact has to be reflected somehow before using the result in a declaration. VHDL 2008 solved this problem for generic packages and generic subprograms by introducing corresponding instantiation declarations: A generic package (i.e. a package with a generic clause) has to be instantiated in a package instantiation declaration, and the name of the corresponding instantiated package is then used where the package and its content is referred to. For a generic subprogram the approach is equivalent.
An alternative approach could be to consider a bundle to be something like a design entity, in which case the bundle object could be created by a bundle instantiation statement with a syntax similar to a component instantiation statement. This approach could handle both generics and ports of a bundle, but referring to the elements of a bundle may not be as straightforward as we would like. This aspect will be discussed below.
Questions
- Should there be restrictions on what objects may be made per instance objects of a bundle objects? For example, are there any issues (from usage or from the language perspective) with making an element of one bundle a per instance element of another bundle?
- Is there a need to declare bundle objects that are composites? The question is whether we need to have array bundles and record bundles, or whether it is sufficient to define the composite aspects for the elements of a bundle. SystemVerilog interfaces are always scalars.
Brent Hayhoe: - My initial thoughts regarding composite bundles are that they will lead to unnecessary complexity. We are defining bundles as groups of interconnect objects (signals, variables, etc.) and it's these that can be hierarchically declared as composite types. If we start to type bundles we may get circular declaration problems?
/Brent Hayhoe\
Views of a Bundle
This is what in SystemVerilog is called a
modport. Views are used to declare formal ports of kind bundle. A bundle may have many views, each defining the elements of the bundle that are part of this view, and the corresponding modes. These elements may be a subset of the objects declared for the bundle, as well as slices or elements of these objects. It remains to be seen whether it is necessary or desirable to also make non-object members of a bundle part of the view. There will be interesting issues to be considered about how a view makes selected declarations of the bundle visible at the place where only the view is visible. Views of a bundle may appear as interface objects for entities, components, blocks, and subprograms.
Example:
bundle view v of b is
signal s1: in std_logic;
signal s2: out std_logic_vector(1 downto 0); -- Is this the appropriate way to define a subset of an object?
end bundle view v;
A bundle view may then be used in an entity declaration or a subprogram declaration:
entity e is
port (bundle object x: v); -- The view is specified at the place of the subtype indication
end entity e;
procedure p(bundle object x: v) is
...
end procedure p;
Note that the view is on the bundle, not on a bundle object or an instance of a bundle. The reason is that using bundle views in port clauses would not be possible for a view referring to a bundle object or instance without severe implications on usage. OTOH, this limits the kind of properties that can be controlled by the view. The implications have yet to be analyzed.
As mentioned in the comment, the view appears at the place of the subtype indication of the port element. In a way the relationship of a view to its bundle has some similarities to the relationships of a subtype to its base type. I have not yet explored whether this could, or should, be exploited semantically and/or syntactically (bundle and subbundle). Intuitively, it seems that visibility aspects could be managed more easily this way than with a completely new concept, but the difficulties may be on the syntax side.
It should be noted that in SystemVerilog it is possible to declare a module port as an interface; the modport to be used is then specified as the actual in the corresponding instantiation statement of the module. For VHDL this approach is not appropriate because the VHDL rules about reading and writing interface objects depend on their mode. These rules mandate that the mode be known from the port declaration.
Using Elements of a Bundle Object or a Bundle View in Behavioral Code
The elements of a bundle object/instance or one of its views must have a name to refer to them in behavioral code. On basic requirement is that the form of the name for an element of a bundle object does not depend on whether the bundle object is declared/instantiated locally or is accessed through a view. If a bundle is accessed through a view it seems the most appropriate form of the name for an element of the view is that of a selected name:
architecture a1 of e is
begin
x.s2(0) <= x.s1; -- x is a formal bundle port with view v
end architecture a1;
If the objects that are part of a bundle are created by the instantiation of a bundle using a bundle instantiation statement, they exist at a place in the design hierarchy that is different from where the instantiation statement occurs. VHDL defines external names to refer to an object that exists elsewhere in the design hierarchy. Referring to the elements of a bundle instance would therefore look like this:
architecture a2 of e is
begin
b2: bundle b generic map (...) port map (...); -- A bundle instantiation statement
<<signal b2.s2 : std_logic_vector(...)>>(0) <= <<signal b2.s1 : std_logic>>; -- How would we know the vector bounds?
end architecture a2;
If the bundle declaration is first instantiated using a bundle instantiation declaration whose name is then used to declare a bundle object, a selected name seems appropriate to refer to one of the elements of a bundle:
architecture a3 of e is
-- bundle instantiation declaration to declare instantiated bundle bi, not even a tentative syntax yet
bundle object b3: bi;
begin
b3.s2(0) <= b3.s1;
end architecture a3;
Only this last approach allows us to use the same form for the name of an element of the bundle regardless of whether the bundle is accessed directly or through a view. It remains to be seen how an instantiation declaration could be extended to associate actual ports with formal ports to define the per instance objects of a bundle object.
It should be noted that such names are not restricted to behavioral code: an element of a bundle could also be used as an actual in a component instantiation statement, thereby bursting the bundle.
Bundle References
This corresponds to what SystemVerilog calls a
virtual interface. The corresponding requirements and their expression in VHDL context are TBD.
Issues, questions:
- What does it mean to create a reference to a bundle? It's not an assignment; the closest we have currently seems to be the port association, but this is static.
- Is there a possibility to align this functionality with access types? One difference is that we are not planning to dynamically manage bundle existence with new.
--
ErnstChristen - 2015-06-23