At the last SV-BC meeting, I committed to sending out a preliminary version of a document outlining my thoughts on a framework for SV name resolution. Attached is an html version of that document. This is not intended to be an LRM proposal (yet) though at some point the issues and clarifications raised in the document need to become part of a combined 1364/1800 spec. Ideally, I would like to see this become the basis for a more systematic approach for reaching consensus on name resolution issues. Feedback is definitely welcome. This is also attached to Mantis 1043 as it is directly related. See: http://www.eda.org/svdb/bug_view_page.php?bug_id=0001043 for the attachment "name_resolution.htm" Gord. -- -------------------------------------------------------------------- Gordon Vreugdenhil 503-685-0808 Model Technology (Mentor Graphics) gordonv@model.com
In this document, all references to “Verilog” refer to IEEE 1364-2005 and all references to “SystemVerilog” refer to IEEE P1800-2005.
SystemVerilog has added several levels of complexity to Verilog name resolution. In Verilog, any sequence of identifiers (or indexed identifiers) with “dot” separators was considered a hierarchical name and followed the resolution rules in 1364-2005 Clause 12.5 – 12.7. In SystemVerilog such names could be either hierarchical names or selected names since simple variables can now have type structure. The package import rules and class derivation add additional complexity to the resolution.
The following document clarifies the relationships between various forms of name resolution in SystemVerilog with the goal of preserving compatibility with Verilog name resolution on all legacy Verilog designs.
The document incorporates some recent committee consensus that packages may not depend on compilation unit declarations.
The definitions and algorithms determine resolution for resolvable names; handling of incorrect references is an implementation issue. The algorithms are defined in terms of resolution of names within the fully elaborated design. Name resolution that occurs during elaboration (for defparam statements and similar) is not directly addressed but follows the same algorithm within the partially elaborated design.
Definitions
A name component is a simple identifier followed by an optional sequence of index expressions.
A dotted name is sequence of name components separated by dots.
A hierarchical name is a “topological reference” that is resolved in the context of the structure of the instantiated design.
A selected name is a “structure reference” that is resolved in the context of the types of the expressions.
The lexical parent of a scope is the enclosing scope in the text of the design. Compilation units and packages are the only scopes that do not have a lexical parent.
The topological parent of a scope is defined only for instantiations and is the scope of the instantiation statement within the parent instance (or top level module) in the elaborated design. Per the LRM, the parent must be either a top level module, an instantiation, or an elaborated generate scope.
Note that in the context of nested generate constructs, the “lexical parent” of an elaboration of the inner construct is the elaborated outer construct.
It is legal to have a dotted name composed of a hierarchical prefix followed by a dot followed by a selected name. It is not legal to have a dotted name composed of a selected name followed by a hierarchical name.
In Verilog, a name component in a hierarchical name can resolve in an upwards manner through the design topology following the rules in 1364-2005 Clause 12.6. A key aspect of the rules proposed here is that upwards name resolution shall only apply during resolution of the hierarchical portion of a dotted name; once the resolution of a dotted name begins treating name components as part of a selected name, upwards resolution no longer occurs.
The basic algorithm for resolving a dotted name follows three phases:
A name is locally visible at some point, P, in a scope, S, if one of the following holds:
1. the name denotes a scope within S
2. the name is declared within S before point P [1]
3. the name is visible from an import occurring within S before point P
For a class, a name is directly visible by inheritance if the name is a method or property of a class extended by this class unless the base class is either
1.
A type parameter
2.
A typedef
defined by a reference to an interface port type.
3. A forward type declaration whose full type has not been defined
4. A typedef of any of the preceding types
A design unit is a scope defined by a primitive, program, interface
module, macromodule or
package
declaration.
Let scope be the scope within the instantiation containing a dotted name reference
Let component be the first name component in the dotted name
Let name be the name portion of component
Phase 1
while (1)
if name is “this”[2]
scope = the class enclosing scope
break
else if name is “super”
scope = base class of the class enclosing scope
break
else if name is “$root”
name = next name component
scope = the top level design unit denoted by name
else if name is locally visible in scope[3]
break
else if scope is a class declaration and name is directly visible by inheritance
break
else if scope is a design unit
if topological_start is not set
toplogical_start = scope
scope = the lexical parent of scope
else if scope is the compilation unit
break
else
scope = the lexical parent of scope
if name was not found or name is an instantiation or a generate scope name
if name is not found in scope
scope = toplogical_start[4]
goto phase 2
else
goto phase 3
Phase 2[5]
while name is not found in scope or name does not denote a scope[6]
if the scope is an instantiation
scope = topological parent of scope
else
scope = lexical parent of scope
if name denotes a scope
scope = scope denoted by name[7]
name = next name component
goto Phase 2
else
goto Phase 3
Phase 3
name is a non-scope declaration within scope; resolve remaining name components as selects into the variable denoted by name
[1] The combination of points 1 and 2 require “declaration before use” for variables but not for scopes, including function or task references.
[2] The names “this” or “super” are reserved in SystemVerilog and can only be used as the first component of a dotted name. The description here ignores the effects of having a legal use of “this” or “super” when using the keywords directives to ignore SystemVerilog keywords.
[3] For modport and interface port handling, this implies that a dotted name becomes strictly downward after a modport or interface port. This preserves the expressed visibility. Additionally, the algorithm here assumes that for a modport, the “scope” contains only the names legally visible via the modport.
[4] This condition ensures that for nested design units, upwards toplogical references begin their resolution at the instantiation of the nested design unit
[5] Phase 2 is essentially a more algorithmic expression of the 1364-2005 12.6 rules for upwards name referencing rules.
[6] The “name does not denote a scope” part of this condition is for backwards compatibility. This condition implies that an upwards resolving “next” name must denote a scope and not a variable or net, etc. Topological upwards search is thus different than lexical upwards search that is done in phase 1.
[7] The algorithm assumes that the referenced name exists; in the context of a arrayed instance or a reference into an elaborated generate loop, if the name matches and the index is invalid, the upwards search does not continue and an error is reported.
This archive was generated by hypermail 2.1.8 : Fri Jun 02 2006 - 09:15:26 PDT