Skip to content

Known limitations

These are known gaps in the current release. Where they apply, navigation usually finds nothing (rather than the wrong declaration) and Rename leaves that code unchanged; the exceptions are noted below.

  • Conditional compilation (`ifdef, `ifndef, `elsif, `else, `endif) may appear anywhere, including port lists. Only the active branch is code (see Conditional compilation), with the macros the file, the headers it includes, the files before it in the active compile file (.f), the compile file and the settings define. Headers that no source of the compile file includes are not known, and macros from other files take effect when those are saved. Rename does not change names in inactive code. SystemVerilog 2023 condition expressions (`ifdef (A && !B)) are not supported (false).
  • Line directives (`timescale, `default_nettype, `resetall, `celldefine / `endcelldefine, `unconnected_drive, `pragma, `line, `begin_keywords / `end_keywords, `undef, `undefineall) are recognized anywhere and highlighted, but their effect is not modelled (for example `default_nettype none does not report implicit nets).
  • Escaped identifiers (\bus[0] ) are not supported and are reported as syntax errors.
  • The encrypted lines of a `pragma protect data block are not SystemVerilog and are reported as syntax errors.
  • Macros are not expanded. Macro names and the names passed to a macro (for example my_driver in `uvm_component_utils(my_driver)) are navigable (see Macros), but names declared by the code a macro expands to (for example type_id in my_item::type_id::create) are not. In a very long macro call, an argument more than about 200 tokens after the opening ( is treated as an ordinary name.
  • A macro used as a type or module name with the declared name on the next line (`WORD_T then w;, `MOD_NAME then u_inst (…);) is reported as a syntax error: a macro call that ends its line is read as a statement or item. Keep the name on the same line.
  • SystemVerilog 2009+ keywords (until, strong, weak, soft, global, implies, …) are keywords in .v files too, so Verilog-2005 code using them as names shows syntax errors.
  • `include is not followed: declarations reach other files only through the project-wide lookup (modules, interfaces, programs, packages, classes, functions).
  • A module or program declared inside a module is read as the next unit: the outer module ends before it, is reported as missing its endmodule, and its final endmodule is reported as a syntax error. Interfaces and classes may be nested.

  • A few SystemVerilog Assertion forms are reported as syntax errors (the rest of the file is not affected): an action block whose pass statement is a severity task (assert property (p) $info("ok"); else …), a clocking event as an argument of a sampled-value function ($rose(a, @(posedge clk))), and a sequence method on an instance with arguments (s(b ##1 c).triggered). Sequence and property operators are accepted permissively (a property operator such as |-> is also accepted inside a sequence). Sequence and property names are not yet navigable.

  • A property or sequence without its end keyword ends before the next keyword that starts a module or class item or a data-type keyword that starts a declaration; a declaration of a user-defined type (my_t z;) right after it is taken into the error. A covergroup without endgroup ends only before an item keyword or end keyword (int cp: coverpoint is a legal coverage item), so a variable declaration right after it (logic z;) is taken into the error.

  • A broken property/sequence body is skipped token by token, not bracket-balanced: a type inside brackets ($bits(logic [3:0]), type(int)) ends the skip early, giving a few extra errors.

  • A generate block without its end takes the rest of the module in (legal nesting), up to endmodule.

  • A Verilog-95 (non-ANSI) header without its ; (module m(a, b)) keeps the module’s name, but the port declarations that follow it are reported as syntax errors until the ; is added.

  • Rows of a primitive’s table are checked for their shape (inputs : [state :] output ;, edges in parentheses), not symbol by symbol: 1'b0 : 1; or an empty row ; are not reported.

  • A primitive instance without a name (my_udp (y, a, b);), timing checks in specify blocks ($setup, $hold, …) and edge-sensitive paths ((posedge clk => (q +: d)) = 1;) are reported as syntax errors; the rest of the module and the file keep their place.

  • Declarations at file level outside any module or package (compilation-unit scope) are visible in their own file. From other files, only modules, interfaces, programs, packages, classes and functions are found.

  • An import applies to its whole scope regardless of where the import statement is written.

  • Hierarchical paths that start at a top-level module name (tb.dut.u1.sig) and references into the local variables of functions and tasks are not resolved.

  • Checkers and user-defined primitives are not linked by Go to Declaration, Find Usages or Rename: an instantiation my_check u(...) or my_udp u(...) finds nothing, and names inside a primitive are not resolved. Names declared inside a checker (its ports and variables) are found inside the checker and do not clash with the module around it.

  • Bind targets given as an instance path (bind top.u1 chk …) are not supported.
  • Renaming a declaration to the name of an instance added by bind (or the reverse) is not reported as a conflict.
  • After . on a covergroup instance, its built-in methods (sample(), get_coverage(), …) are not offered, and constraint names (h.c_addr.constraint_mode(0)) are not offered.
  • Which keywords are listed first is decided from the code around the caret; where it cannot be told (after a macro call, inside a macro’s arguments), a keyword that fits may be listed with the others at the end.
  • Names are offered whether they are declared before or after the caret.
  • A statement you are still typing, with an open ( or without its ;, can hide the declarations that follow it in the same module until it is complete: names declared below it (for example an instance used before its instantiation line) may be missing from the list.
  • Nothing is offered after $root. or $unit::, after a macro followed by ., and for named arguments of a constructor (new(.).
  • A file included into a package with `include does not see the names of that package, and names declared by the code a macro expands to are not visible; both are offered only if the file uses them elsewhere (as used in this file).
  • A module is offered as an instance (and an instance’s name as u_…) only where an item starts after ;, begin, an end keyword, generate, a generate else, a case-generate item or an `include "…"/`define line (not after a macro call written without ; or an `include <…> line): not as the single item of a generate if (…) or for (…) without begin. A module nested in the module you are in is not offered as an instance.
  • A parameter without a default is taken as set by a defparam only when the defparam is in the same file as the instance; one in another file is not seen, and the instance is reported.
  • The width of what is connected to a port is compared only when both widths are constants the IDE can compute (see Instance connections); types are not compared. A defparam in another file is not seen, so a port width computed from a parameter it sets may be reported wrongly.
  • Connect missing ports adds connections after the last one, before any `ifdef lines that follow it; a port connected only inside an inactive `ifdef branch is added again.
  • Declare missing signals does not see a name written through a task’s output or ref argument (t(x);, $sscanf(s, "%d", x)): such a name is declared a wire, which may not be written there — change it to logic. It reads `default_nettype only in the instance’s own file: one set in a file compiled before it is not seen.
  • A macro and named connections in the same list (u(`PORTS, .rst(rst))) do not parse yet.
  • In the instance itself, connections and parameter values inside an `ifdef branch the IDE sees as inactive count as absent: set the defines of your build in the compile settings so the right branch is active.
  • An interface port of a non-ANSI header (module m(bus, x); my_if bus; …) is not known to be one, so leaving it out is not reported.
  • Tab does not move between the arguments of a call (the platform needs the parsed argument list, which code being typed usually does not have yet).
  • In a list with more than about 4000 tokens before the caret, nothing is shown.
  • Nothing is shown for the arguments of a covergroup’s new( (its formal arguments), of a let (mx(a, b)), or of a base class or interface class after extends or implements (extends base #(, extends base(, implements ic #().
  • Nothing is shown for a sequence or property instance (s(a, of sequence s(x, y)), or for a later handle of a declaration with several (k a = new("a", 1), b = new().
  • The body of an out-of-block method (function void C::f(); … endfunction) has no Structure View entry of its own (its prototype in the class is listed); with the caret in such a body, Autoscroll from Source selects the enclosing package.
  • Port and argument lists and { … } bodies (constraints, structs, coverpoint bins) do not fold.
  • The closing keyword added on Enter is decided by counting openers and closers in the whole file; code in both branches of `ifdef … `else counts, so an opener repeated in both branches can get an extra closer.
  • A module header with more than eight package imports (module m import a::*; import b::*; …) gets no endmodule on Enter; the indent is still right.
  • New lines are indented with the code style’s indent (spaces unless Use tab character is set), also in files indented with tabs.
  • Run configurations run only (no debugging); a compile file must be on the local disk to be passed to a tool.
  • Tool output locations are recognised only for paths without spaces; in consoles other than the SystemVerilog run configurations, relative paths are resolved against the project directory only.
  • Verilator’s Build and run expects the simulation at obj_dir/Vsim (do not override -o/--Mdir); Icarus writes sim.vvp into the working directory.
  • A relative location that exists both under a run’s working directory and under the project directory gets two links (rare).
  • The run configurations are tested on macOS and Linux only.
  • Settings of run configurations created with versions before 2.0 are not carried over (the configurations keep their type).
  • Names from the UVM library resolve only if the UVM sources are in the IDE (inside the project or attached as a library).
  • Without the base class in the IDE, renaming a method that overrides a base-class method (for example a UVM build_phase override) is not checked: the rename goes ahead and the method no longer overrides.