Skip to content

Go to Declaration

Put the caret on a name and choose Navigate | Declaration or Usages (⌘B on macOS, Ctrl+B on Windows/Linux), or hold ⌘ (Ctrl) and click the name. The editor opens the declaration, in whichever file it is.

What the video shows
  1. top.sv instantiates the module counter.
  2. Go to Declaration (⌘B / Ctrl+B) opens its definition in counter.sv.
  3. Find Usages (⌥F7 / Alt+F7) lists every usage, including the end label endmodule : counter.
  4. Names are colored by what they are (shown in the SystemVerilog Studio Dark color scheme).

Names are resolved the way a SystemVerilog tool resolves them: inner scopes first, then enclosing scopes, base classes, imported packages and finally the whole project. Two things with the same name in different scopes (a signal data in two modules, two classes item in two packages) are never confused. See How names are resolved for details.

You are on… You go to…
The module name in an instantiation counter u1(...) The module declaration
.clk(...) in a named port connection The port of the instantiated module
.MAX(...) in a parameter override #(.MAX(20)) The parameter
An interface type (my_if bus, virtual my_if vif) or a modport (bus_if.mp) The interface or modport
A class name in a declaration, extends, implements, #(my_item) or my_item::type_id The class
pkg::item, or an item imported with import pkg::*; or import pkg::item; The item in the package
A function or task call, including methods inherited from a base class and super.f() The function or task
obj.x, this.x, q[i].x, chains like env.agt.drv.vif The class member
vif.req, u1.sig, g_lane[0].busy, vif.cb.req The interface signal, instance signal, generate-block signal or clocking item
An enum member, typedef, struct field (s.inner.field) Its declaration
An end label (endmodule : counter, end : seq) The block or design element it closes

A name declared in a package is visible only where that package is imported (import my_pkg::*; or import my_pkg::my_item;) or when you write it qualified (my_pkg::my_item). If you use it without either, simulators report it as undeclared, and the plugin:

  • underlines it with the warning ‘my_item’ is declared in package ‘my_pkg’, which is not imported here;
  • offers the quick fix Import my_pkg::* (⌥⏎ / Alt+Enter). It adds the import after the module’s other imports, or after the module header. When the name is used in the module’s parameter or port list, or in a class outside any package, the import goes at file level (after the file’s imports, or right before the module or class). Applying the fix to several usages adds the import once;
  • still navigates: Go to Declaration opens the package member (if several packages declare the name, you choose).

There is no warning when the name may be visible after all: in a file that another file includes (`include "my_item.svh", typically inside a package — names that package declares or imports are visible there), or in a class whose base class is not in the project or is a typedef or type parameter (the name may be inherited from it, as with uvm_driver when UVM is not attached). Packages that re-export names (export other_pkg::*;) are followed, so names reached through them are visible, not reported.

Find Usages and Rename do not count such a usage until the package is imported. You can turn the warning off in Settings | Editor | Inspections | SystemVerilog | Name declared in a package that is not imported.

  • Names defined by macros (`define) or used inside macro arguments are not navigable.
  • See Known limitations for the complete list.
  1. Open rtl/top.sv from the sample project. ⌘-click (Ctrl-click) counter in counter #(.MAX(20)) u_counter. rtl/counter.sv opens at module counter.
  2. Back in rtl/top.sv, ⌘-click MAX in #(.MAX(20)). You land on parameter int MAX = 10 in rtl/counter.sv.
  3. In rtl/counter.sv, ⌘-click IDLE in state <= IDLE;. rtl/counter_pkg.sv opens at the enum member IDLE — the name comes from import counter_pkg::*;.
  4. In rtl/counter.sv, ⌘-click is_done in assign done = is_done(state);. You land on the function in rtl/counter_pkg.sv.
  5. In rtl/top.sv, ⌘-click busy in $display(g_lane[0].busy);. You land on logic busy; inside the generate loop.
  6. In uvm/my_pkg.sv, find agt.drv.vif = null; in class my_env and ⌘-click vif. You land on virtual my_if vif; in class my_driver: the chain agt → my_agent, drv → my_driver was followed.
  7. In rtl/counter.sv, add the line my_item x; after state_t state;. my_item is underlined: it is a class in my_pkg, which counter does not import. ⌘-click it: uvm/my_pkg.sv opens at class my_item.
  8. Back in rtl/counter.sv, put the caret on my_item, press ⌥⏎ (Alt+Enter) and choose Import my_pkg::*. The line import my_pkg::*; is added after import counter_pkg::*; and the warning goes away.