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 fixTry it
Section titled “Try it”-
Open
rtl/counter.svin the sample project and find the linestate <= IDLE;(⌘F on macOS / Ctrl+F on Windows/Linux).IDLEis a state of the enum declared inrtl/counter_pkg.sv, which this module imports withimport counter_pkg::*;. -
Change
IDLEtoIDEL. You should seeIDELunderlined in red (nothing? see If it doesn’t work). Hover the mouse overIDELto read the message:'IDEL' is not declared; did you mean 'IDLE'?
-
Click inside
IDELso 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:
You should see the line read
state <= IDLE;again, with no underline. The file is back to how it was. -
Now the implicit-net case. Still in
rtl/counter.sv, findassign done = is_done(state);near the end of the module. Changedonetodnoe, so it readsassign dnoe = is_done(state);. You should seednoemarked 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 wirednoe, and the outputdonewould never be driven.
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.svis 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.
When a suggestion is offered
Section titled “When a suggestion is offered”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.
When the IDE stays silent on purpose
Section titled “When the IDE stays silent on purpose”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).
What is not checked
Section titled “What is not checked”In short: names whose meaning the IDE cannot be sure of are skipped.
The full list
- A name followed by
.or(, such asu_core.stateordo_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, aspecifyblock, an out-of-class constraintconstraint C::c { … }. - The formal arguments of a property, sequence,
letor checker; alet’s own name;ST0fromtypedef enum {ST[3]}; a clocking block’sinput en = top.u.en;; a name imported explicitly withimport 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.
Settings
Section titled “Settings”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.
If it doesn’t work
Section titled “If it doesn’t work”| 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.
Related
Section titled “Related”- Compiler checks (slang): with slang installed, slang reports this kind of problem too; the editor shows this page’s report once, with its quick fixes.
- Unknown members: the same check for
handle.member, a misspelled method or field of a class. - Instance connections: wrong or missing port connections.
- How names are resolved: where the IDE looks for a declaration.