Find Usages
Use Find Usages before you change or delete a declaration, to see everything that depends on it, or to find where a signal is read or driven. Put the caret (the text cursor) on a declaration, or on any place it is used, and choose Edit | Find Usages | Find Usages (⌥F7 on macOS, Alt+F7 on Windows/Linux; Shift+Alt+7 with the GNOME or KDE keymap on Linux). The Find tool window (a panel at the bottom) lists every usage, grouped by file.
Try it
Section titled “Try it”The steps use the sample project. Open it and wait until indexing has finished (the IDE scans the project; the progress bar at the bottom right disappears when it is done). Each row of the Find panel shows a line number and the code; click a row to jump to it. Nothing is edited, so there is nothing to undo.
-
Open
rtl/counter.sv, put the caret oncounterinmodule counterand press ⌥F7 (Alt+F7). Three usages are listed: the instantiation inrtl/top.sv, the end labelendmodule : counter, and the macroCOUNTERinrtl/defines.svh, whose body instantiatescounter. -
Open
uvm/my_pkg.sv, put the caret onmy_iteminclass my_item extends uvm_sequence_item;and press ⌥F7 (Alt+F7). Five usages are listed:uvm_sequence #(my_item),my_item it;,my_item::type_id::create,uvm_driver #(my_item)andendclass : my_item. The string"my_item"is not among them. (Scroll the Find panel if you see fewer rows.)
-
In
rtl/counter.sv, put the caret on the portdonein the port list and press ⌥F7 (Alt+F7). Three usages are listed: theassign done = is_done(state);inrtl/counter.sv, the connection.done(done)inrtl/top.sv, and.done()in the body of the macroCOUNTERinrtl/defines.svh. -
In
rtl/counter.sv, put the caret on the portcountinoutput logic [7:0] countand press ⌥F7 (Alt+F7). The usages are in two groups. Under Value write:count <= 0;and thecountbefore<=incount <= count + 1;, the places that drive the port, and also.count()in the body of the macroCOUNTERinrtl/defines.svh(a connection written in a macro body counts as both a read and a write, and such usages are listed once, under Value write). Under Value read: thecountafter<=in that line,if (count == MAX - 1) state <= DONE;and the connection.count(count)inrtl/top.sv(the parent reads the output). If you see one flat list instead, see If it doesn’t work. The order of the two groups may differ. Three rows are under each group: the linecount <= count + 1;appears once in each, with a differentcounthighlighted.
If a list is empty or shorter, see If it doesn’t work.
What is found
Section titled “What is found”Find Usages works for every kind of declaration: modules, interfaces, programs, packages, classes (including interface classes), functions, tasks, modports, clocking blocks, ports, parameters, type parameters, variables, nets, typedefs, enum members, struct fields, genvars, instances and named blocks. The full list is in Supported constructs.
Usages include end labels (endclass : my_item), named port and parameter connections, pkg:: and Class::
references, #(my_item) type arguments, member access chains and hierarchical references into generate blocks: the same
references that Go to Declaration follows. Text in
comments and string literals is not a usage: "my_item" in function new(string name = "my_item") is not
listed.
A `define body that instantiates a module, interface or program by its name is a usage of it, and of each
port and parameter it connects by name (the text is compiled at every call of the macro). In the sample project the
body of COUNTER in rtl/defines.svh (counter __name (.clk(__clk), .rst_n(__rst_n), .count(), .done())) is listed for
counter and for its ports clk, rst_n, count and done. A name that is one of the macro’s formals (__name,
__clk: the parameters the macro takes) is what each call passes, so it is not a usage; nor is a name in a macro that does
not instantiate it (an expression, a call, class items). Go to Declaration works from these names too.
A module’s name at the head of an Emacs verilog-mode AUTO_TEMPLATE comment (verilog-mode AUTOs) (/* sub AUTO_TEMPLATE (, starting its
line) is a usage of the module: the template applies to its instances.
Reads and writes
Section titled “Reads and writes”For a signal (a variable, net or port), each usage is either a write, which drives the signal, or a read. The Find
panel groups them under Value write and Value read, so “who drives count?” is the Value write group.
| You write | The usage of the signal x is |
|---|---|
assign x = …;, x <= …; or x = …; in a process, task or function, force x = …; |
a write |
x[3] <= …;, s.f = …; (a select or a field of x) |
a write (of part of x) |
x++;, x += 1;, y = x++; |
a write and a read (listed under Value write) |
x = new(); |
a write |
t(x) where x is the task’s or function’s output, inout or ref argument; $readmemh("f.hex", x), $cast(x, …), $sscanf(s, "%d", x), std::randomize(x), mbx.get(x) |
a write |
obj.x = 1; where obj is a class handle or an interface |
a write of x (and a read of obj) |
`MY_FLOP(x, d) (an argument of a macro call) |
a write and a read: what the expansion does with it is not known |
y = x;, if (x), @(posedge x), v[x] <= …; (x as an index) |
a read |
.d(x) connected to an input port of the instance |
a read: the child reads it |
.q(x) connected to an output port |
a write: the child drives it |
.io(x) connected to an inout or ref port |
a write and a read |
.clk (the port and the signal of one name) |
a write and a read: .clk is both the port and the signal, so it is listed under Value write whichever of the two you searched |
and g(x, a, b); (a gate’s first terminal is its output) |
a write |
For a port, a connection in a parent counts from the port’s side: the parent writes an input port and reads an output
port (step 4: .count(count) reads the output count). Search from the signal count in rtl/top.sv
(logic [7:0] count;) instead, and .count(count) is under Value write: the child drives the signal; this is what
sv_drivers reports. A connection written in a `define body counts as both. A connection to an instance of a module the IDE does not find (or finds
more than once) counts as both (listed under Value write). A coding agent gets the same split, through the hierarchy, from
sv_drivers.
Only real references are found: a signal count in another module, or a class of the same name in another
package, is not listed.
If it doesn’t work
Section titled “If it doesn’t work”| You see | Likely cause | What to do |
|---|---|---|
| The panel is empty or says nothing was found | The caret is not on a name, or the project is still indexing | Click on the name itself; wait for the progress bar at the bottom right to finish |
| A usage you expect is missing | The file is not in the project (or its compile file), or the usage is in code an `ifdef switches off |
See Conditional compilation and Known limitations |
| A usage is listed that is a different declaration | The name resolves to this declaration, for example because it is imported or inherited | Press Go to Declaration (⌘B / Ctrl+B) on that usage to see which declaration it jumps to |
| The usages of a signal are one list, not Value read and Value write | Grouping by usage type is off in the Find panel | Turn it back on in the panel’s view options (grouping by Usage Type) |
| The shortcut does nothing | Your keymap differs, or on a laptop you must hold Fn | Use Edit | Find Usages | Find Usages |