Defining Interface Bundles Based on Record Types or Array Types - An Analysis
Ernst Christen, September 30, 2015
Updated October 8, 2015: Clarifications and corrections after WG meeting
Updated October 21, 2015: Analysis of use cases
Introduction
A major goal of VHDL 201x is to define a class of composite ports that has capabilities beyond these of the currently available interface objects. These new capabilities have been described elsewhere. It has been proposed to extend record types to assume the desired new capabilities. This is an analysis of the feasibility of this approach.
Foundation
The new functionality has to be embedded in the framework of the existing language, and it has to be cognizant of the large number of VHDL design descriptions in existence. Both these aspects constrain what we can do, and we must be aware of them at all time.
Language Design Principles
There are a number of principles that we should strive for to successfully extend the functionality of VHDL. In no order of precedence:
- Any language change ought to be backward compatible, i.e. it must not invalidate existing descriptions. In particular, old syntax cannot be given new semantics; rather, we must define new syntax to represent new semantics, but should reuse existing concepts to the extent possible.
- Language definition should be constructive.
- Language definition should be parsimonious.
- Syntax ought to be driven by semantics, not the other way around. If we get the semantics right, the syntax will be a byproduct.
Types and Objects in VHDL
The concept of a type is fundamental to VHDL's strong typing system. Each object has a type. According to the LRM
“A type is characterized by a set of values and a set of operations.“
These operations are:
- Basic operations: assignment; allocator; selected, indexed, slice names; qualification; numeric literal
- Predefined operations
Note that not all types support all basic operations, for example no assignment for file types or protected types.
An object that is a named entity gets its properties through a declaration.
- An explicitly declared object: through an object declaration
- An interface object: through an interface declaration
For an interface object, the mode is a property of the object, not one of its type. The mode applies to all subelements of an interface object.
If a subelement of a resolved composite signal object has a driver in a process, then every scalar subelement of the signal has a driver in the same process [LRM 6.4.2.3]. Note that this differs from SV, where a composite is in essence a bundle of scalars. The behavior is related to the concept of a basic signal, which is, in essence, a resolved signal or a scalar signal that is not a subelement of a resolved composite signal [LRM 14.7.3.2].
Analysis of Record Type Proposal
To avoid any confusion with the current properties of a type, I have previously proposed to use the term
bundle for the new concept to add to VHDL. The following non-exhaustive list summarizes the desired properties of the new functionality; it focuses on aspects that relate to the VHDL type system.
- An ability to compose a bundle from elements that are signals or bundles. The lower priority behavioral bundles could also contain objects other than signals.
- An ability to declare a port to be of class bundle. Let’s call this an interface bundle.
- An ability to declare a non-port object of class bundle. In accordance with LRM terminology this would be an explicitly declared bundle.
- An ability to assign a waveform to a subelement of a bundle without affecting the driving properties of the other subelements or the bundle as a whole.
- An ability to specify the mode independently for each subelement of an interface bundle.
- An ability to associate an interface bundle as a formal with an actual that is either an explicitly declared bundle or an interface bundle.
- An ability to specify a subset of a bundle (decomposition) and use this subset in place of an interface bundle, i.e. declare a port whose properties are defined by this subset. Let’s call this a view of the bundle. If an actual bundle is associated as an actual with a formal that has been defined as a view of the bundle, only the elements that are part of this view are visible in the instantiated design unit.
Since the record type proposal subsumes several different ideas, it is somewhat in flux as different use cases emphasize different points. However, there is a core that has been used in a variety of places. This is a summary; again many details are left out:
- A bundle is represented by an object of a record type or an array type.
- An interface bundle is represented by an interface object of a record view or an array view. A record view or array view defines a view of the bundle. It associates a mode with each subelement of the bundle. It may also restrict access to certain elements of the bundle.
- Both record view and array view can have generic list that includes interface constants. It should be noted that generic types for a view are not meaningful because the view needs to retain compatibility with its bundle.
Here now the analysis. I am using the terms
record type bundle and
record type view to refer to a bundle or a view based on a record type, and
array type bundle and
array type view for bundles and views related to an array type.
%TABLE{ databg="#ffffff" tableborder="0" }%
Ad 1. |
Since a record type can be constructed from elements that may themselves be of a record type, a record type bundle has the above property 1. The same is true for an array type. However, neither is suited as a solution for the lower priority behavioral bundle because the object class of an element is not part of the declaration of the element. |
Ad 2. |
Since VHDL supports declaring a port of a record type (albeit with uniform mode for all its elements), a record type bundle has property 2. The same holds for an array type. |
Ad 3. |
Since VHDL supports declaring a signal of a record type (i.e. an explicitly declared signal), a record type bundle has property 3. The same holds for an array type. |
Ad 4. |
Since a record type is a composite type, a record type bundle does not have property 4 “out of the box”. This manifests itself, for example, if subelements of a signal of a composite type are driven by more than one component instance, even if different subelements are driven: in this case the composite type must be a resolved type. To acquire this property without breaking backward compatibility, a record type bundle must be distinguishable from a signal declared with a record type. I believe that the only reliable distinction is through syntactic means, e.g. a record type bundle would not be just of a record type, but tagged in some way, for example by declaring it as type myBundle is scalarized record ... end record; This new scalarized record type would have to be declared to not be a composite type. As a result, the syntax of the type declaration is largely the same as that of a traditional record type, but the two can be distinguished. However, it creates a new concept and along with it a number of open questions that have to be answered: - Having elements, an object of a scalarized record type appears syntactically as a composite, but according to its semantics it isn’t.
- What objects can be declared to be of a scalarized record type: just signals or also variables and constants?
- A scalarized record type and a record type with the same elements are different types, not unlike two record types declared to have the same elements.
- Does an object of a scalarized record type have a value, or is it just the atomic elements that have values? This question is crucial for deciding whether an object of a scalarized record type can appear in an expression or as the target of an assignment. It also affects whether a resolution indication is legal in a subtype indication whose type mark is a scalarized record type. Finally, it affects whether an aggregate of a scalarized record type can exist. It should be noted that assignment of a bundle as a whole is marked with a question mark in the most recent requirements collection, i.e. it is of questionable value. In previous discussions it was deemed unnecessary.
Similar arguments could be made about array type bundles, but declaring a scalarized array type is more than odd, as it indicates that we are only interested in the syntactic aspects of an array declaration, not the array semantics. An alternative, proposed at the meeting on October 1, 2015, might be to declare the object as scalarized instead of the type, e.g. scalarized signal s: MyType. I believe this is not a good solution because it would make it possible to associate a signal declared as scalarized with a port that is a "regular" signal. |
Ad 5. |
Supporting a mode specific to each subelement of a record type view is an integral part of the Record Type proposal. Associating the mode with a record type view, not with the record type bundle, keeps the type itself clean. The record type view is a new concept that combines aspects of a subtype (e.g. compatibility with base type) and a port (the modes). The same applies to an array type view. |
Ad 6. |
I do not see any particular difficulty to define an association element whose formal is a record type view and whose actual is a record type bundle or a record type view. The following issues must be considered: - Association in whole seems straightforward. Individual association may be defined similarly as for a composite type, but this needs more investigation.
- If the actual is a record type bundle, the mode-related restrictions on associations ought to be enforced for the subelements of the interface bundle.
|
Ad 7. |
The concept of a record type view has already been discussed above as it relates to specifying the mode of an element of a scalarized record type. To use the record type view to also restrict access to selected elements of a scalarized record type, additional considerations are necessary. First and foremost, any such restriction must not affect type compatibility of a formal and its associated actual. In essence, we are trying to do something similar to entity e is port (p : in sub1); end entity e; ... signal s: sub2; ... i1: entity work.e port map (p => s); where the two subtypes sub1 and sub2 are std_logic_vectors of different lengths. This is not possible because, among other things, of the composite driver. It may be possible to define access restrictions for a record type bundle by manipulating the visibility rules, i.e. elements of the record type bundle that are not listed in a record type view are not visible in the scope of the record type view, neither directly nor by selection. This requires careful analysis. It is not so clear whether it is possible to do something similar with arrays, as has been proposed by the array view in one of the use cases. The difficulty here is that a restriction to only view certain array elements punches holes into the index range of an array object. There is no way to describe this with today’s infrastructure. |
Analysis of Use Cases
Minimal RTL
The
example consists of
- A generic package containing
- A record type declaration that declares the elements of the bundle. Any parameterization for bus widths etc. is done with the generic list of the package containing the record type declaration.
- Several record view declarations. A record view is associated with a record type, and it contains declarations that look like interface declarations without the (optional) reserved word signal.
- The proposed new attributes 'CONVERSE and 'MONITOR are used in some of the record views
- An example consisting of a transmitter, a receiver and a monitor
- In a port declaration, a signal of the record type specifies the reserved word view instead of the mode, followed by the name of a record view.
Issues/questions
- In the example, the design units include local signals and signal assignment statements assigning inputs of the bundle to the local signal and local signals to outputs of the bundle. This introduces delta delays. Why not use aliases?
UCMinimalRTLSignalInterface: alias comment. --
Brent Hayhoe - 2015-10-22
- What about initial values at the port?
Clarification from WG meeting on Oct.22, 2015: There is no use case, so unless there is value added it has low priority. There is also a concern that declaring initial values may prevent port collapsing (which isn't part of VHDL).
- 'CONVERSE is ambiguous: the "opposite" of mode in can be out or buffer. It seems that 'CONVERSE has limited use: only for simple buses. As soon as there are multiple instances on a bus its utility becomes questionable.
UCMinimalRTLSignalInterface: CONVERSE attribute with open/buffer. --
Brent Hayhoe - 2015-10-22
Complex RTL
The
example consists of
- A generic package containing
- Several type and subtype declarations, plus a constant declaration
- Several record type declarations. There is no distinction between record types where all elements are intended to have the same mode (corresponding to current functionality)and record types where elements are intended to have different modes (illustrating desired new functionality)
- The elements of the record types are either of a predefined type (std_logic or std_logic_vector) or of one of the record types.
- Record views and aray views. Both consist of two parts: a generic clause and an element clause that contains a list of declarations similar to interface declarations (without the reserved word signal). Record views and array views can be constructed from other record view and array views.
- The new null mode indicates that a port is neither driven nor read.
- The new view mode is followed by the name of a record view or array view optionally followed by a generic map.
- 7 design unit, each consisting of an entity/architecture pair. The design units illustrate the following
- Declaration of a signal representing the main bus and whose type is the record type cpu_bus_r, in DU CPU_bus_top_ent
- Use of named record views in port declarations, including the use of generic maps to specialize the record view
- Use of unnamed record views and unnamed array views, with inlined element clauses
Issues/questions
- The main bus contains an element arbiter_al, an array of length 2 whose element type is a record type. Element 1, while part of the bus, is driven and read in AMandS, and nowhere else. This is why in the record view for the port of AMandS this element has mode null. What is the value of the subelements of element 1 outside AMandS, in particular at the top?
Clarification from WG meeting on Oct.22, 2015: The intent is that a null mode severs the port association, i.e. the actual and the formal are separate signals. From the formal's perspective null mode is equivalent to an open actual, while the actual is neither read nor driven by the formal.
- Similar to the Minimal RTL use case, local signals are used instead of aliases. Why? See UCMinimalRTLSignalInterface: alias comment..
- There are several places where in an unnamed view the wrong type name is used. An example is MplusS, where arbiter_al refers (correctly) to the type arbiter_a, but for the elements of arbiter_al a reference is made (incorrectly) to arbiter_a; it should be arbiter_r.
Clarification from WG meeting on Oct.22, 2015: This has been corrected in the example.
- In the signal assignment statements in slave_ent, master_ent, and arbiter_ent, there are extraneous levels in the selected names. For example:
cpu_bus_rif.slave_al(slave_id_jg).slave_rl.data_vl <= data_out_vs;
The slave_rl. portion is wrong; the array element is selected with the slave_al(slave_id_jg). part, and this element has the subelement data_vl
Clarification from WG meeting on Oct.22, 2015: Will be corrected.
SPI Bus
The
example consists of
- A generic package containing
- Declarations of a record type that describes a bundle and of 3 record views
- Two of the record views are parameterized with a generic clause
- The simple record views only specify the mode for each element, i.e. they don't repeat the type as it's done in the other two use cases
- The view may select only a subset of the scalar signals of record type. The record view allows this subset to be given an implicit alias a local name. This alias name can be used in place of the name of the corresponding record element to denote the subset.
- No null mode is specified for the left out elements as it's done in the RTL examples.
- The design units making up the example
- a port bundle declaration has the reserved word view instead of the mode, followed by the name of the view and an optional generic map
Issues/questions
- How are elements and subsets of elements that are not selected by a record view treated? Are they not visible at all, do they have an implicit null mode, etc.
Clarification from WG meeting on Oct.22, 2015: Elements that are not listed in the view are not visible.
- If a subelement of an element is given an alias in the record view, can the other subelements also be made visible?
Clarification from WG meeting on Oct.22, 2015: It's not an alias, it is an association. The original name is no longer visible.
Preliminary Conclusions
The analysis indicates that two new concepts are required to support the basic capabilities of a bundle using the record type approach:
- A scalarized record type and/or a scalarized array type, to allow a distinction between an object of this kind of type type and an object of a traditional record type or array type. A record type bundle must be of a scalarized record type. An array type bundle must be of a scalarized array type.It must be possible to compose each from simple objects or types and from bundles or bundle types.
- The concept of a view on a record type and an array type. It must be possible to parameterize such views in various ways:
- Specification of modes for elements of the scalarized type
- Selection of a subset of the elements of a scalarized type, or a subset of an element
- It is desirable to allow an alias to be defined for a subset of an element
- Named views (similar to a declared subtype)
- Unnamed views (similar to a subtype indication in an object declaration)
The issues related to defining these concepts as extensions to VHDL have been touched upon, but additional investigations will be required.
--
ErnstChristen - 2015-09-30
Comments & Questions
UCMinimalRTLSignalInterface: alias comment
This possibility of using aliases to compose/decompose the record bundle was brought up by Jim, I think, at the first or second WG meeting in which we discussed this use case. The answer is (and was): yes of course aliases could be used.
Why weren't they used in this use case? - In my experience not many RTL design users utilize aliases very often and will decompose using an assignment. They are also not very bothered with deltas that may or may not be incurred. I'm primarily an RTL FPGA designer and I don't think of them as my first choice. I think I should, but historically in tools, they haven't always been supported very well.
Verification users on the other hand may have a very different outlook!
--
Brent Hayhoe - 2015-10-22
Return back to source.
UCMinimalRTLSignalInterface: CONVERSE attribute with open/buffer
In my FPGA designs I always use buffers as outputs on entities internally within designs because of their advantages. However, many people will not use them and there is a pervasive myth propagating that buffer ports are bad and should be avoided.
It is for this reason that I included them in these use cases in order to highlight and prompt this question. I think the CONVERSE attribute should be modified to have an out/buffer parameter included such that either option can be selected.
--
Brent Hayhoe - 2015-10-22
Return back to source.