Skip to content

Undeclared names

A misspelled name such as IDEL for IDLE often survives until compile time. Some typos are worse: in a port connection, or as the target of an assign, Verilog quietly creates a new 1-bit wire with that name (an implicit net), and the bug shows up only in simulation. SystemVerilog Studio underlines an undeclared name as you type. When a declared name is spelt almost the same, it suggests that name and replaces it for you. This check is the Undeclared name inspection: a rule the IDE runs on your code as you type.

state <= IDEL; // red underline: 'IDEL' is not declared; did you mean 'IDLE'?
state <= IDLE; // after the fix
  1. Open rtl/counter.sv in the sample project and find the line state <= IDLE; (⌘F on macOS / Ctrl+F on Windows/Linux). IDLE is a state of the enum declared in rtl/counter_pkg.sv, which this module imports with import counter_pkg::*;.

  2. Change IDLE to IDEL. You should see IDEL underlined in red (nothing? see If it doesn’t work). Hover the mouse over IDEL to read the message: 'IDEL' is not declared; did you mean 'IDLE'?

    The always_ff block of rtl/counter.sv: IDEL in the reset branch is underlined in red, with the message ‘IDEL’ is not declared; did you mean ‘IDLE’? and the Change to ‘IDLE’ fix below it

  3. Click inside IDEL so the text cursor (the caret) is on it. Press ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) and choose Change to ‘IDLE’ from the popup. An entry like this, which edits the code for you, is a quick fix. The popup looks like this:

    The Alt+Enter popup under IDEL offering Change to ‘IDLE’, with a preview of the corrected line, IDLE highlighted

    You should see the line read state <= IDLE; again, with no underline. The file is back to how it was.

  4. Now the implicit-net case. Still in rtl/counter.sv, find assign done = is_done(state); near the end of the module. Change done to dnoe, so it reads assign dnoe = is_done(state);. You should see dnoe marked as a warning (yellow, rather than the red of an error), with the message 'dnoe' is not declared: an implicit net; did you mean 'done'? This warning is your only signal: the file would compile, Verilog would create a new 1-bit wire dnoe, and the output done would never be driven.

    The end of rtl/counter.sv: dnoe in the assign line is underlined in yellow, with the message ‘dnoe’ is not declared: an implicit net; did you mean ‘done’? and the Change to ‘done’ fix below it; the light bulb in the margin only shows that quick fixes are available

    Press ⌥⏎ / Alt+Enter on it and choose Change to ‘done’ to put the file back (the popup may list other actions too). Both edits are now reverted: rtl/counter.sv is unchanged and has no underlines. If you lose track, press ⌘Z / Ctrl+Z, or unzip the sample project again.

Why one is an error and the other a warning

Section titled “Why one is an error and the other a warning”

In step 2 nothing can make IDEL legal, so it is an error. In step 4 the code is legal: as the target of a continuous assignment (or in a port connection), an undeclared name declares a new wire (IEEE 1800-2017 §6.10). That is almost never what you meant, so it is reported as a warning. Only the first use of the name is underlined: later uses refer to the same wire.

An implicit net is created in three places: a port connection, the left side of a continuous assignment (also inside a concatenation {…}), and a gate primitive’s terminal (and g1(w2, a, b);, with w2 not declared). Anywhere else, such as the right side of an assignment, an undeclared name is an error.

You write (with enable, a and b declared) You see
assign y = enabel; red underline: 'enabel' is not declared; did you mean 'enable'?
sub u(.en(enabl)); yellow underline: 'enabl' is not declared: an implicit net; did you mean 'enable'?
assign w1 = a; (w1 declared nowhere) yellow underline: 'w1' is not declared: an implicit net
assign {co, s} = a + b; yellow underline on co ('co' is not declared: an implicit net) and on s
sub_p #(.Width(Widht)) u1 (); (a parameter value of an instance) red underline: 'Widht' is not declared (no suggestion: Width is a parameter of sub_p, not a name declared here)

To make implicit nets errors, as many teams do, put `default_nettype none before the module. The name is then reported as a red error, '…' is not declared, without the words “an implicit net”. `default_nettype wire switches back to warnings. A directive inside a comment or an inactive `ifdef branch has no effect. After any other net type, such as `default_nettype tri, a typo that creates an implicit net is not reported at all; use `default_nettype none to catch these.

The suggestion did you mean '…'? appears when a declared name is close to the one you typed:

  • one character added, removed or changed (swapping two neighbouring characters, IDEL → IDLE, counts as one) when the name you typed has four characters (letters, digits and _); up to two when it has five or more;
  • names of three characters or fewer get no suggestion;
  • of several equally close names, one of them is suggested.

A name no declared name is that close to, such as vld_x for x_valid, gets no suggestion: the message is just 'vld_x' is not declared, with no quick fix.

A misspelled base class is reported the same way: class my_vseq extends base_vsq; suggests base_vseq.

The IDE reports a name only when it is sure that nothing declares it. A macro whose `define it can find is no obstacle: it reads the macro’s text. With `define DECL(n) logic n;, the line `DECL(made) declares made, so made is not reported, while a typo such as mdae on a later line still is. It stays silent when the declaration could be in code it cannot fully see:

The name could be declared by… Example
a macro the IDE finds, when the name is written in its arguments or its body made in `DECL(made) is not reported
a macro defined nowhere the IDE can see, called in the module, class or package that contains the use after `UNDEFINED_DECL(x), no name in that module is reported
an inactive `ifdef branch (greyed out) `ifdef SIM int cnt; `endif
an `included file, imported package or base class the IDE cannot find UVM sources not in the project
code that does not parse a syntax error nearby
another file’s inactive code or a `define body a header has `define DECL_TOP int top_cnt;: top_cnt is not reported anywhere, because a call of `DECL_TOP may declare it

Names in a file that other files include are checked as if they were written at the `include line (How names are resolved).

In short: names whose meaning the IDE cannot be sure of are skipped.

The full list
  • A name followed by . or (, such as u_core.state or do_reset(). It may be an instance or a task higher up in the hierarchy.
  • A qualified name (pkg::x). A name declared in a package you did not import is reported by a different inspection, Name declared in a package that is not imported (Go to Declaration).
  • Names that are not values: a type ($bits(cfg_t)), a module ($dumpvars(0, tb)), a package, a function or task. In an instance’s parameter values a declared type name (#(.T(nib_t))) is not reported. Names in a parameterized class’s parameter list (uvm_driver #(my_item)) and the type before a cast (byte_t'(x)) are not checked.
  • Names inside: a macro’s arguments, randomize() with { … }, bind, defparam, a covergroup, a specify block, an out-of-class constraint constraint C::c { … }.
  • The formal arguments of a property, sequence, let or checker; a let’s own name; ST0 from typedef enum {ST[3]}; a clocking block’s input en = top.u.en;; a name imported explicitly with import p::x;.
  • A class’s own type parameter used as its base (class mixin #(type BASE) extends BASE), or a package-qualified base (extends uvm_pkg::uvm_test).
  • A header (.svh, .vh) that no file in the project includes.

Open Settings (⌘, on macOS / Ctrl+Alt+S on Windows/Linux) and go to Editor | Inspections | SystemVerilog | Undeclared name. The inspection is on by default and reports undeclared names as errors and implicit nets as warnings. You can turn it off there.

You see Likely cause What to do
Nothing is underlined The project is still indexing Wait until the progress bar in the status bar at the bottom finishes
Nothing is underlined The inspection is turned off Turn on Undeclared name under Settings | Editor | Inspections | SystemVerilog
Nothing is underlined The name is in greyed-out (inactive) code, or the declaration may be hidden (table above) Expected: the IDE does not guess. Check the defines of your compile file and that included files and packages are in the project
A name you did declare is reported It is declared only in a file generated at build time that is not in the project Generate the file and add its folder to the project
A name you did declare is reported A macro that declares it is called only in greyed-out `ifdef code and is defined nowhere the IDE can see (for example only on the simulator command line) Define the macro in your compile file or in Settings | Languages & Frameworks | SystemVerilog
A typo in an assign target or a port connection is only a warning It is a legal implicit net Add `default_nettype none to make it an error

See also Known limitations: Undeclared names and Troubleshooting.