Skip to content

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.

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.

  1. Open rtl/counter.sv, put the caret on counter in module counter and press ⌥F7 (Alt+F7). Three usages are listed: the instantiation in rtl/top.sv, the end label endmodule : counter, and the macro COUNTER in rtl/defines.svh, whose body instantiates counter.

  2. Open uvm/my_pkg.sv, put the caret on my_item in class 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) and endclass : my_item. The string "my_item" is not among them. (Scroll the Find panel if you see fewer rows.)

    The Find tool window listing the five usages of the class my_item in the sample project, with the selected usage previewed on the right

  3. In rtl/counter.sv, put the caret on the port done in the port list and press ⌥F7 (Alt+F7). Three usages are listed: the assign done = is_done(state); in rtl/counter.sv, the connection .done(done) in rtl/top.sv, and .done() in the body of the macro COUNTER in rtl/defines.svh.

  4. In rtl/counter.sv, put the caret on the port count in output logic [7:0] count and press ⌥F7 (Alt+F7). The usages are in two groups. Under Value write: count <= 0; and the count before <= in count <= count + 1;, the places that drive the port, and also .count() in the body of the macro COUNTER in rtl/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: the count after <= in that line, if (count == MAX - 1) state <= DONE; and the connection .count(count) in rtl/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 line count <= count + 1; appears once in each, with a different count highlighted.

If a list is empty or shorter, see If it doesn’t work.

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.

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.

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