Skip to content

Code completion

Code completion suggests names while you type: the members after a ., the ports of an instance, parameters, packages, keywords, system tasks, and even a whole module instance with its ports connected. You type less, and you do not misspell a name, because the list only offers what is visible at the caret (the text cursor).

The list opens by itself while you type a name and right after you type ., ::, $ or a backtick. Press ⌃Space (Ctrl+Space) to open it anywhere else. It does not open by itself in comments, strings, numbers and inactive code (code switched off by an `ifdef). Move in the list with the arrow keys and choose with Enter or Tab; Escape closes it. Each suggestion shows its kind on the right (variable, port, function, class, module, …), the label that tells two same-named suggestions apart.

The steps use the sample project; open it and wait for indexing first. The caret is the text cursor. Most steps type something into a file: to undo, press ⌘Z / Ctrl+Z until the text you typed is gone, and the file is as it was. If no list appears, see If it doesn’t work.

  1. Complete a name. Open rtl/top.sv, put the caret at the end of the line logic done; and press Enter. Type coun and press ⌃Space (Ctrl+Space). You should see counter (kind module), counter_pkg (package), count (variable) and a second counter, with the kind instance (a ready-made instance of the module counter; you insert it in step 6). Press Escape and undo.
  2. Complete members after a dot. Put the caret at the end of the line with the instance counter #(.MAX(20)) u_counter(…);, press Enter and type initial $display(u_counter.. The list opens by itself and offers the members of the instance u_counter: the ports, the parameter and the signals of the module counter: clk, rst_n, count, done, MAX, state. Press Escape and undo (the new line is gone).
  3. Complete a system task. Again put the caret at the end of the instance line, press Enter and type initial $disp. The list opens after the $ and offers $display, $displayb, $displayh and $displayo, each a system task with its arguments. Select $display and press Enter: the line reads initial $display() with the caret between the parentheses. Undo.
  4. Complete the methods of an enum. Open rtl/counter.sv. On a new line after state_t state;, type initial $display(state.. The list offers the methods of an enum: first, last, next, prev, num and name. Undo.
  5. See what fits. In rtl/counter.sv, put the caret at the end of the line always_ff @(posedge clk or negedge rst_n) begin : seq, press Enter and type i. Statement keywords such as if and data types such as int are listed; initial, input and interface, which cannot start a statement there, are not. Undo.
  6. Insert a whole instance. In rtl/top.sv, put the caret at the end of the line logic done;, press Enter, type coun and press ⌃Space (Ctrl+Space). The list now has two rows named counter: select the one whose kind reads instance (not module) and press Enter. An instance of counter is inserted, with .MAX(10), its ports connected to clk, rst_n, count and done of top, and the name u_counter_1 selected (u_counter is taken); Tab moves to the next value to fill in. Press Escape if a template field is still active, then undo.
  7. Complete a connection. In rtl/top.sv, put the caret right after .count( in the instance u_counter and press ⌃Space (Ctrl+Space): count, the signal of the same name as the port, is listed first. Press Escape; nothing was changed.
  8. Complete an instance name. In rtl/top.sv, on a new line after logic done;, type counter (with the space) and press ⌃Space (Ctrl+Space): u_counter_1 is offered first, because u_counter is taken. Undo.
  9. Change how an instance is written. Open Settings (⌘, on macOS / Ctrl+Alt+S on Windows/Linux), go to Editor | Code Style | SystemVerilog | Instances, choose Layout: On one line and set Instance name to i_$UNIT$. Repeat step 6 at the same place: the instance is counter #(.MAX(10)) i_counter (.clk(clk), .rst_n(rst_n), .count(count), .done(done));. Undo, then set the options back (Layout: One per line, aligned, Instance name u_$UNIT$).

What it offers depends on where the caret is. The common places:

Where Example The list offers
After . it., vif., agt.drv., slots[2]., get_cfg()., this., super. The members of that object: class properties and methods (inherited ones too, and those of every class object such as randomize() and srandom()), struct fields, the signals, modports and clocking blocks of an interface or instance, the names in a generate block; for mailbox, semaphore and process their methods; after super. also new. A class member declared local is offered only inside its class, a protected one also in subclasses
After a string, enum, event, array or queue name., state., ev., q., table. Its built-in methods: len(), substr(), name(), next(), triggered, size(), push_back(), exists(), find(), sort(), sum(), … (an element such as q[0]. offers the element’s members instead)
After :: my_pkg::, my_item::, registry#(int)::, pkg::cls:: The members of the package (including what it exports) or class (including inherited ones); in an out-of-block header (function my_item::) and after = (h = my_item::) also new
In an instance’s port list counter u_counter(.clk(clk), ., counter #8 u(. The ports of counter not yet connected. For a non-ANSI header, the names it gives the ports: a for module ex(.a(x)), with the type of x; a port such as {c, d} has no name and is connected by position only
Where an instance is named counter , counter #(.MAX(4)) , counter u1(…), First u_counter (kind instance name), numbered if that name is taken — also by an earlier instance of the same statement (after a comma it is the only suggestion)
In a port connection counter u(.count( The names visible at the caret that may be connected to the port, best match first: the one of the same name, then those of the same type, then those of a similar name (count_q, sys_count)
In a parameter list counter #(. The parameters counter lets you override (not its localparams)
In a call add(1, . The arguments of add not yet given by name
After extends, implements, typedef, a net kind, or a direction in a port list class c extends , wire , module m(input Classes and types
Anywhere else The names visible at the caret and the keywords that fit there; once you have typed the start of a name, also the modules, interfaces, programs, packages and file-level classes, functions and tasks of the project
More places: clocking blocks, imports, declarations, UDPs, DPI and others
Where Example The list offers
In a port connection (all the rules) counter u(.count( The names visible at the caret; first those that may be connected to the port — the one of the same name, then those of the same type (logic [7:0], a struct type; reg and implicit nets count as logic) and a similar name (count_q, sys_count). For an interface port, the instances and ports of its interface (any interface for a generic interface port); for an inout, nets (also the enclosing module’s input ports); constants only for an input
After a clocking block vif.cb. Its clocking items only
After import import , import a_pkg::*, Packages, and the built-in package std
After import pkg:: import my_pkg:: The members of the package, and *
After a direction in a modport or clocking block modport mp(input , output in clocking … endclocking The signals and other names visible there
In a non-ANSI port declaration module m(clk, q); … output The ports the header lists that are not declared yet, and types
After virtual virtual Interfaces
After a built-in type logic [7:0] , logic No keywords, except signed and unsigned directly after an integer type (logic , int ): you are declaring a new name (in a non-ANSI port declaration such as output reg [7:0] , the header’s undeclared ports)
At the start of a class or package item class c; Types only: classes, typedefs, type parameters and packages (for pkg::) — no modules, programs, interfaces, variables or calls — and the keywords that start a class or package item
At the start of an interface, program or checker item interface i; , program p; As anywhere else, but no design unit the construct cannot instantiate: no modules in an interface; no modules, interfaces or programs in a program or checker (a name already used in the file is still offered as a word of the file)
At the start of a UDP or config item primitive p(o, a); , config cfg; Only the keywords that start one (table, initial, design, instance, cell, …), no names; after cell or instance, the names visible there, the design units among them
A DPI import or export import "DPI-C" function , export "DPI-C" function After import … function: the result types a DPI function may have (void, byte, shortint, int, longint, real, shortreal, chandle, string, bit, logic) and typedefs. After export … function or task: the functions or tasks declared in the same module, interface, program, package or file. After import … task: nothing, you are naming a new task
A modport’s import/export prototype modport mp(import function , modport mp(export task After function: its return type (the data types, void, classes and typedefs). After task: the interface’s tasks

Each suggestion shows its kind on the right (variable, port, function, class, module, …) and an icon for it (the same as in the Structure View). Next to the name, a variable, port, argument, parameter or field shows its declared type (logic [7:0], output logic, int [$], rand bit [7:0]; a port declared without a type shows the type of the port before it), an enum member the name of its enum type, an instance its module, and a function or task its arguments and return type ((int lhs, int rhs): int). Long types are shortened. Keywords are shown in bold.

The list is ordered by how close a name is to the caret: names declared in the innermost scope come first, a class’s own members before inherited ones, then names from enclosing scopes and imported packages, then the modules, packages and other declarations of the project, then the keywords that fit, then the names the file only uses. Ports, parameters and arguments are listed in the order they are declared.

Visible names are those declared in the enclosing scopes (the block, function or task, class, module, package, file), the members of the enclosing class and its base classes (also in an out-of-block method function void c::f()), the members of imported packages (including what those packages export), and the instances that bind adds to the enclosing module. The variable of a for loop is visible in its body, also while you are still typing the body’s first statement. A local variable of another function, a signal of another module, or a function declared inside a package you have not imported is not offered: type pkg:: to reach it.

Names used in this file that are not declared anywhere the IDE can see (for example, the UVM names in a testbench when the UVM sources are not in the project) are offered after the others, labelled used in this file. After . or :: on something that does not resolve, the names used after . or :: elsewhere in the file are offered.

Which keywords are offered

Keywords that fit where the caret is are listed first: module items (always_ff, assign, generate, …) in a module, modport in an interface, class items (rand, local, constraint, …) in a class (after rand or randc, the data types), statements (if, foreach, fork, return, …) in procedural code (and input/output for the non-ANSI ports of a task or function), port declarations and table in a UDP, design/instance/cell in a config, std wherever an item or statement starts, posedge/negedge/iff in an event control @(…), inside/with after an operand, the constraint, covergroup, clocking and property keywords in those blocks (and a covergroup’s option and type_option, also in a coverpoint’s or cross’s { … }), the property operators inside assert property (…), the production keywords (rand join, repeat, …) in a randsequence and statements in its code blocks, and of the end keywords the one closing the construct you are in (endmodule, end, join, endcase, …; inside a begin of a case item, end rather than endcase); after a statement’s condition or delay (if (en) , @(posedge clk) , #5 ) the statement fits, not an end keyword. After a keyword that is usually followed by another, that one fits too (unique case, struct packed, assert property, wait fork, default clocking, parameter type). Only keywords that fit are offered — no initial or input in a class body, no fork among module items; inside a macro call’s arguments, which may hold statements, expressions or constraints, every keyword is offered after the fitting ones. No keyword is offered where a new name is declared (logic [7:0] , logic a, ; directly after an integer type, signed and unsigned) or after extends or implements. Keywords match from their start.

Matching ignores case. Each name appears once (a module, interface or program may appear a second time as an instance, see below): where a name is declared in several enclosing scopes, the innermost declaration is offered. Names declared in other files are listed from the index without opening those files, so the list stays fast in large projects.

After a backtick, the list offers macros and compiler directives instead; see Macros. In a modport, import lists the tasks and functions of the interface. There is no completion in comments, strings and numbers.

After $, the list offers the system tasks and functions of IEEE 1800-2017 ($display, $fopen, $sformatf, $urandom_range, $clog2, $bits, $rose, $past, $fatal, $dumpvars, …) with their arguments, and the scope names $unit and $root.

Where a module item can start, once you have typed the beginning of its name, each unit that may be instantiated there is offered a second time, as an instance (counter u_counter (…);, kind instance): in a module (also in its generate blocks) modules, interfaces and programs; in an interface, interfaces and programs; in a program, nothing. Choosing it with Enter or Tab replaces the name with a whole instance (choosing it with another character, such as a space, ; or (, writes just the name and that character):

counter #(
.MAX(10)
) u_counter (
.clk (clk),
.rst_n(rst_n),
.count(count),
.done ()
);

In this example no signal done is visible where the instance is inserted, so .done () is left empty.

  • The parameters an instance can override are listed with their defaults as written (not the localparams). A default that names something of the unit (D = W * 2) is left empty, .D(), which keeps the default; a parameter without a default is left empty for you to fill in, and so is a default longer than a line. Without parameters there is no #(…), without ports the list is ().
  • The lines are indented one level more than the instance, with tabs if the code style uses them.
  • Each port is connected to the signal of the same name visible where you are and declared before, if there is one and it fits: a data port to a variable (not an inout), net (not a ref port) or port, an input also to a parameter or genvar; an interface port to an interface instance or interface port; an array only to an array port and the reverse. The other connections are left empty.
  • The instance is named u_ and the unit’s name, numbered if that name is taken (u_counter_1).
  • Tab moves from the instance name to each parameter value and each connection, Shift+Tab back.

Settings | Editor | Code Style | SystemVerilog | Instances sets how an instance is written, with a preview. The settings are part of the code style, so a project’s code style (and .editorconfig, as ij_systemverilog_instance_connections, …_parameters, …_layout, …_name_pattern) shares them with the team:

Option Choices
Connect ports By name .clk(clk) (the default); Implicit where names match: .clk where a signal of the port’s name has the port’s type (the same width — .name allows no padding or truncation), else by name as before; Wildcard where names match: .* for those ports and the others by name
Parameters All that can be set (the default); Only those without a default, which must be set — without any, no #(…)
Layout One per line, aligned (the default); One per line; On one line: counter #(.MAX(10)) u_counter (.clk(clk), …);
Instance name A pattern, u_$UNIT$ by default: $UNIT$ is the module’s name ($UNIT$_inst gives counter_inst); a number is added if the name is taken. A pattern that does not give a SystemVerilog name is refused

Connect missing ports (Instance connections) follows the connection choice: with Implicit or Wildcard a port a same-named signal of its type is connected to is added as .clk.

It is not offered in procedural code, classes and packages, in expressions, where a name is being declared or an instance named (counter u), or for the module you are in.

Choosing a function or task inserts parentheses: add(|) with the caret inside when it has arguments, tick()| when it has none. A system task or function gets (|) when it is called with arguments ($display(|)), nothing when it takes none or only optional ones ($time, $finish), and a macro with arguments gets `MAX(|). When a ( already follows, no second one is inserted and the caret moves into it; typing ( to choose an item inserts one pair. No parentheses are inserted where a subroutine is named but not called: the name of an out-of-block method body (function void c::print), a task after disable (not disable iff), a name in import or export (also import in a modport), and, inside a function that returns a value, the function’s own name (its return variable, f = …). A task or void function naming itself inside its body is a recursive call and gets them.

While the IDE is indexing, the list offers keywords and the names declared in the current file around the caret; after this. the members of the enclosing class, without checking local and protected.

You see Likely cause What to do
Nothing opens after you type You are in a comment, a string, a number or inactive code, or the project is still indexing Move out of it; wait for the progress bar at the bottom right; press ⌃Space (Ctrl+Space)
Nothing opens by itself, but ⌃Space (Ctrl+Space) works The automatic popup is switched off in the IDE Check Settings | Editor | General | Code Completion
The list is short or only has keywords and names of the current file The IDE is indexing: it then offers only those Wait for indexing to finish
A name you expect is missing It is not visible at the caret (a local of another function, a signal of another module, a package you did not import) Type pkg:: to reach a package member; see Which names are offered
Names labelled used in this file instead of real declarations The declaration is not in the project (for example the UVM sources) Add the library to the project; see Known limitations
The instance row is missing You are in procedural code, a class, a package or an expression, or already naming an instance Start a new module item where an instance can go

See also Troubleshooting.