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
top.svinstantiates the modulecounter.- Go to Declaration (⌘B / Ctrl+B) opens its definition in
counter.sv. - Find Usages (⌥F7 / Alt+F7) lists every usage, including the end label
endmodule : counter. - 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.
What you can navigate from
Section titled “What you can navigate from”| 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 |
Names from a package that is not imported
Section titled “Names from a package that is not imported”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.
Limitations
Section titled “Limitations”- Names defined by macros (
`define) or used inside macro arguments are not navigable. - See Known limitations for the complete list.
Try it
Section titled “Try it”- Open
rtl/top.svfrom the sample project. ⌘-click (Ctrl-click)counterincounter #(.MAX(20)) u_counter.rtl/counter.svopens atmodule counter. - Back in
rtl/top.sv, ⌘-clickMAXin#(.MAX(20)). You land onparameter int MAX = 10inrtl/counter.sv. - In
rtl/counter.sv, ⌘-clickIDLEinstate <= IDLE;.rtl/counter_pkg.svopens at the enum memberIDLE— the name comes fromimport counter_pkg::*;. - In
rtl/counter.sv, ⌘-clickis_doneinassign done = is_done(state);. You land on the function inrtl/counter_pkg.sv. - In
rtl/top.sv, ⌘-clickbusyin$display(g_lane[0].busy);. You land onlogic busy;inside the generate loop. - In
uvm/my_pkg.sv, findagt.drv.vif = null;in classmy_envand ⌘-clickvif. You land onvirtual my_if vif;in classmy_driver: the chainagt→my_agent,drv→my_driverwas followed. - In
rtl/counter.sv, add the linemy_item x;afterstate_t state;.my_itemis underlined: it is a class inmy_pkg, whichcounterdoes not import. ⌘-click it:uvm/my_pkg.svopens atclass my_item. - Back in
rtl/counter.sv, put the caret onmy_item, press ⌥⏎ (Alt+Enter) and choose Import my_pkg::*. The lineimport my_pkg::*;is added afterimport counter_pkg::*;and the warning goes away.