Scopestack
Scopestacks deal with namespaces in SystemVerilog by tracking the
bindings of names in scopes. They provide a straightforward, correct way to
look up identifiers.
Namespaces in SystemVerilog
SystemVerilog has a complicated system of namespaces, but it mostly boils
down to a few categories of names for things:
- items, (our name), including nets/variables, parameters,
instances (of modules, gates, UDPs, and interfaces), typedefs, functions,
tasks, and named generate blocks;
- definitions, including module, UDP, interface, and program
declarations;
- ports;
- and packages.
The items are the most complicated. Packages occur only at the global
scope. Ports only occur in modules and interfaces. In principle the
SystemVerilog spec allows for nested modules and interfaces, but most
implementations don't support this and neither do we, so definitions can only
occur at the global scope. In contrast, to look for an item, we first look in
the most local scope; if it isn't found there, we search subsequent nested
scopes until we get to the global scope.
Scopestacks
A scopestack is a structure that holds representations of nested scopes.
Each scope may be one of several types, namely the types on the left-hand
column of the table *vl-scopes->items*:
(interface module
genblob blockscope design package)
Whenever we search a scope, we call a memoized function that turns
that scope representation into a fast alist, in which we look up the name.
That way, subsequent lookups in the same scope will be constant-time. This
design means that you may occasionally need to free up memory associated with
scopestacks; see vl-scopestacks-free.
Construction and Maintenance
- nil is an empty scopestack (without even the global design scope).
- (vl-scopestack-init design) creates a scopestack with only the global
scope of the design visible.
- (vl-scopestack-push scope ss) pushes a new nested scope onto the
scopestack. Typically you will need to call this function as you "enter" a
new scope, e.g., as your analysis or transformation descends into a particular
module, function, etc.
- (vl-scopestack-pop ss) removes the innermost scope from the
scopestack, but this is rarely needed because scopestacks are
applicative.
- (vl-scopestacks-free) clears the memoization tables associated with
scopestacks, which in CCL also will allow their associated fast-alists to be
garbage collected. We don't currently have a mechanism free these fast alists
otherwise.
Accessing Items
The interface for accessing items is more complex than for definitions and
packages because items may be found in multiple scopes.
- (vl-scopestack-find-item name ss) searches the scopestack for the
given name (a string). The declaration of the item is returned as a vl-scopeitem. The more specific type of the declaration, e.g., vl-vardecl, vl-modinst, etc., can be determined by examining its
tag.
- (vl-scopestack-find-item/ss name ss) returns (mv item new-ss),
where item is the same as returned by vl-scopestack-find-item and
new-ss is the scopestack visible from that item's declaration. For
instance, if you are deep within a bunch of nested begin/end blocks, the
new-ss you get back might be for some superior block, the whole module, or
the scopestack for some entirely different package where the item is
declared..
- (vl-scopestack-find-item/context name ss) returns (mv item ctx-ss
package). Here item is the same as above. The ctx-ss is similar
to the new-ss above but packages are handled differently. In
particular, ctx-ss here is always the scopestack for some superior scope
where the item was found. If item is imported from a package, then
- ctx-ss refers to, e.g., the module where the item was imported into, whereas
- new-ss refers to the package that the item was imported from
The separate package return value is a maybe-string that gives the name
of the package where the item was imported from, if applicable.
Accessing Non-Items
- (vl-scopestack-find-definition name ss) is similar to -find-item, but
finds a definition instead of an item. The definition/ss and
definition/context versions also exist, but aren't as informative since
the definition can (currently) only exist at the global scope.
- (vl-scopestack-find-package name ss), similar.
- (vl-scope-find-portdecl-fast name scope) is similar, but acts only on a
scope, not a stack of them, since searching beyond the local module for a port
doesn't make much sense.
Subtopics
- Vl-interfaceportlist->ifnames
- (vl-interfaceportlist->ifnames x) maps vl-interfaceport->ifname across a list.
- Vl-scope-find-item
- Look up a plain identifier to find an item in a scope.
- Vl-blockscope
- Abstract representation of a scope that just has vl-blockitems
in it, such as a function, task, or block statement.
- Vl-importlist-find-explicit-item
- Vl-scopestack-find-item/context
- Find an item declaration and information about where it was declared.
- Vl-importlist-find-implicit-item
- Vl-import-stars-find-item
- Vl-importlist->explicit-item-alist
- Vl-scopestack-find-definition/ss
- Find a __definition__, as well as info about where it was found.
- Vl-scopeitem
- Recognizer for Verilog structures that can occur as scope
items.
- Vl-scopestack-find-package/ss
- Find a __definition__, as well as info about where it was found.
- Vl-scopeinfo-find-item
- Vl-scopestack-find-item/ss
- Look up a plain identifier in the current scope stack.
- Vl-scopestack
- Vl-scopeinfo
- Scopestack-constants
- Meta-information about the kinds of scopes and the kinds of elements
they can contain.
- Vl-scopestack-push
- Vl-scope->scopeinfo
- Make a fast lookup table for items in a scope. Memoized
- Vl-scope-find-item-fast
- Like vl-scope-find-item, but uses a fast lookup table.
- Vl-module-scope-find-item
- Vl-importresult
- Information about an item that was imported from another package.
- Vl-genblob-scope-find-item
- Vl-design-scope-find-definition
- Vl-scopestack-find-item
- Look up a plain identifier in the current scope stack.
- Vl-scopestack-find-definition
- Look up a plain identifier in the current scope stack.
- Vl-scope-find-portdecl
- Look up a plain identifier to find a portdecl in a scope.
- Vl-scope-find-definition
- Look up a plain identifier to find a definition in a scope.
- Vl-package-scope-find-item
- Vl-interface-scope-find-portdecl
- Vl-interface-scope-find-item
- Vl-genblob-scope-find-portdecl
- Vl-design-scope-find-item
- Vl-blockscope-scope-find-item
- Vl-scopestack-find-package
- Look up a plain identifier in the current scope stack.
- Vl-scope-find-package
- Look up a plain identifier to find a package in a scope.
- Vl-module-scope-find-portdecl
- Vl-design-scope-find-package
- Vl-scope-find-portdecl-fast
- Like vl-scope-find-portdecl, but uses a fast lookup table
- Vl-package-scope-item-alist-top
- Vl-scopedef
- Recognizer for Verilog structures that can occur as scope
definitions.
- Vl-scope-portdecl-alist
- Make a fast lookup table for portdecls in a scope. Memoized.
- Vl-scope-package-alist
- Make a fast lookup table for packages in a scope. Memoized.
- Vl-scope-find-definition-fast
- Like vl-scope-find-definition, but uses a fast lookup table
- Vl-scope-definition-alist
- Make a fast lookup table for definitions in a scope. Memoized.
- Vl-scope-find-package-fast
- Like vl-scope-find-package, but uses a fast lookup table
- Vl-scopestack->path-aux
- Vl-scopestack->path
- Debugging aide: get the current path indicated by a scopestack.
- Vl-scopestack->design
- Vl-scopestack-init
- Create an initial scope stack for an entire design.
- Vl-scopeitem->name
- Vl-importlist->star-packages
- Vl-scopestack-pop
- Vl-scopestack-nesting-level
- Vl-scope
- Recognizer for a syntactic element that can have named elements within it.
- Vl-design-scope-package-alist-top
- Vl-scopestack-toplevel-p
- Does this scopestack refer to the top level of the design?
- Vl-scope->name
- Vl-scopestacks-free
- Frees memoization tables associated with scopestacks.
- Vl-importresult-alist
- An alist mapping stringp to vl-importresult-p.