SystemVerilog Pro
Fast, practical SystemVerilog, Verilog, and UVM support for VS Code.
Created and maintained by Taher Anaya
Contact and support: anaya.taher@gmail.com
SystemVerilog Pro helps you understand and edit hardware code with autocomplete, code navigation, Parameter Hints, highlighting, formatting, and fast workspace indexing. It works without a separate language server and does not send your source code anywhere.
Highlights
- Find definitions and inspect symbols across the workspace.
- Follow
super, super.method, and super.new through the parent-class hierarchy.
- Get useful autocomplete for SystemVerilog, Verilog, UVM, and your own code.
- See complete function, task, and macro parameters while typing calls.
- Format
.sv, .svh, .v, and .vh code when you choose, or enable VS Code's built-in Editor: Format On Save option.
- Right-click a folder to format its editable Verilog and SystemVerilog files recursively.
- Browse large local or remote projects with background indexing.
- Index only
.sv, .svh, .v, .vh, .gsv, and .gsvh files, including uppercase extensions.
What it does
- Go to definitions for supported modules, classes, interfaces, packages, functions, tasks, types, variables, macros, and include files.
- Hover over a supported symbol to see its type, source file, line number, and declaration.
- Keep hover responsive on Remote SSH and slow filesystems while declaration previews load into cache.
- See function and task parameters while you type a call.
- Get suggestions for SystemVerilog keywords, system tasks, UVM items, and workspace symbols.
- Use colorful completion icons to tell tasks, functions, variables, fields, classes, and other symbol types apart.
- Complete the right members after a dot, including members inherited from a parent class.
- Complete members after function and method calls, including chains such as
factory.get_item().child.
- Complete class members after selecting an array element, such as
items[0]., without showing element members for the array itself.
- Follow nested structure fields, such as
data.child.value, including package-qualified and array-valued fields.
- Show only real structure fields in member lists, without leaking the typedef name or unrelated global symbols.
- See package and class members after
::, such as demo_pkg::packet_t.
- Keep package-qualified class instances separate, so
demo_pkg::cl c completes and navigates to members of the correct class.
- Match names in a flexible way. For example,
pack_stat can find packet_status.
- Highlight syntax, ports, parameters, and matching block keywords.
- Browse symbols in the Outline view and format editable source files on demand or with VS Code's built-in Format on Save option.
The extension builds a background index: a list of symbols found in supported workspace files. It incrementally updates the index when files are edited, saved, created, deleted, renamed, or changed externally. Simply opening or closing an unchanged file does not count as incremental indexing. No separate language server is required. Autocomplete searches this complete index cooperatively, keeping manual typing, saves, formatting, cancellation, and status updates responsive even over Remote SSH.
Background workers parse files in controlled batches and store symbols compactly to keep large local and SSH workspaces responsive. Workers process files from different folders so difficult generated sources do not hold up every worker at once. Output › SystemVerilog Pro records progress, failures, and memory measurements.
The extension does not apply workspace-wide, per-file, or large-file symbol budgets. Unopened files receive the same complete symbol extraction, port pass, and container assignment as opened files, so navigation does not depend on opening the declaration file first.
Autocomplete and workspace-symbol searches return a bounded response window when a short query matches a very large number of symbols. This protects the shared extension host without removing anything from the index; typing a narrower name can retrieve any stored symbol.
Large HDL sources are read in pages instead of one whole-file JavaScript string. Generated sources larger than the runtime string limit can therefore be indexed while preserving declaration positions and scopes. Large retry and disk-update parses also run in the background. Files with no recognized declarations complete successfully with an empty symbol index.
If a file cannot be read or parsed during full indexing, the extension retries it three times with increasing delays through VS Code's workspace filesystem. A successful retry is indexed normally. If a file still fails, the status bar keeps a warning and Output › SystemVerilog Pro lists its exact path and final error. Files confirmed to have been deleted or renamed after discovery are removed from the report because they are no longer part of the workspace.
Get started
- Install SystemVerilog Pro from the VS Code Marketplace.
- Open a folder that contains SystemVerilog or Verilog files.
- Open a supported file and start typing.
- To rebuild the index, open the Command Palette and run SystemVerilog Pro: Rebuild Workspace Index.
Common actions
| Action |
macOS |
Windows/Linux |
| Go to Definition |
Cmd+Click or F12 |
Ctrl+Click or F12 |
| Format Document |
Shift+Option+F |
Shift+Alt+F |
| Format Selected Lines |
Select lines, then right-click in the editor |
Select lines, then right-click in the editor |
| Format a folder recursively |
Right-click the folder in Explorer |
Right-click the folder in Explorer |
| Show suggestions or parameter help |
Option+Space |
Alt+Space |
| Delete left and keep indentation |
Cmd+Delete |
— |
Press Escape to close a popup. Press Option+Space or Alt+Space to bring it back. Inside a function, task, or known UVM macro call, the shortcut opens parameter help. Everywhere else, it opens code suggestions.
Arguments use VS Code's original Parameter Hints popup. It shows full declarations, such as string s, and follows the cursor from one argument to the next. Press Option+Space or Alt+Space to bring it back after closing it. VS Code controls this popup's font and scales it with editor zoom.
On macOS, Cmd+Delete normally removes indentation too. In SystemVerilog and Verilog files, the extension keeps the leading indentation and deletes only the text after it. Other languages keep their normal VS Code behavior.
Autocomplete also uses VS Code's normal font sizing and follows the editor zoom. The extension does not override editor.suggestFontSize.
You can also:
- Type
$ to see system tasks such as $display and $clog2.
- Type a backtick to see compiler directives, macros, and UVM snippets.
- Inside a known UVM macro call, see its arguments; for example,
`uvm_info shows id, message, and verbosity.
- Type
obj. to see known members of obj.
- Hover over a symbol to see its declaration.
- Select a block keyword such as
begin, module, or class to highlight its matching end keyword.
Supported files
| Extension |
Language |
.sv |
SystemVerilog |
.svh |
SystemVerilog header |
.v |
Verilog |
.vh |
Verilog header |
.gsv |
Generated SystemVerilog |
.gsvh |
Generated SystemVerilog header |
Only these six file extensions enter the workspace symbol index. Extension matching is case-insensitive, so .SV and .SVH work too. Python, shell scripts, Tcl, Makefiles, logs, and other file types are excluded, even if you manually associate them with the SystemVerilog or Verilog language in your editor.
The same file check applies to workspace discovery, opening and editing files, saves, filesystem changes, renames, and background workers. Generated .gsv and .gsvh files are indexed for navigation and autocomplete and are excluded from formatting.
Code navigation
The workspace index supports common declarations, including:
- modules, classes, interfaces, packages, and programs;
- functions, tasks, ports, parameters, variables, and typedefs;
- structs, unions, enums, covergroups, properties, and sequences;
- macros, clocking blocks, modports, and virtual interfaces;
- common UVM classes, phases, macros, and
p_sequencer declarations.
Definition, hover, completion, and Parameter Hints prefer declarations in the current lexical scope and then the nearest inherited class. Method arguments and block locals keep their own scopes. Member lookup follows typedef aliases, scoped package imports, simple macro-selected parent types, and positional, named, or default class type parameters.
The extension can follow many dot-access chains across line breaks, indexed arrays, virtual interfaces, method return types, and package or specialized class scopes. Clicking super opens the immediate parent class. Clicking super.method or super.new searches upward for the nearest matching parent declaration. An unresolved receiver or member stays unresolved. Complex generated code or heavy macro use can reduce accuracy because the index is not a full compiler.
Indexing and privacy
Indexing starts when you open a supported file or a workspace that contains supported files. It runs where the workspace extension is installed: on your computer for local folders, or in the remote environment for Remote SSH and similar setups. The extension does not send source code, telemetry, or usage data over the network.
The published extension contains its runtime, language definitions, documentation, and icon. It does not contain project source files, workspace indexes, diagnostic logs, or private project paths. Documentation examples use generic names.
The status bar shows only current progress while full indexing is running and a brief incremental-indexing activity message when files change. Refocusing the editor does not show historical indexing timestamps.
Workspace indexing intentionally ignores VS Code's files.exclude setting so hidden generated, vendor, RTL, and verification paths remain available to navigation.
The extension explicitly requests all matching HDL files so large local and remote workspaces are not silently cut off at the editor's normal 20,000-result search ceiling. Edits and external changes reported by the editor's file watchers are indexed incrementally. Changes received during a full scan are reconciled into that active scan and do not start it again. When no full scan is active and 100 or more unique HDL files change in one burst, the extension waits five seconds after the final event and then performs one clean workspace rebuild. Structural changes that cannot be reconciled incrementally may also request one rebuild. The manual SystemVerilog Pro: Rebuild Workspace Index command remains available.
File save and reload names are off by default; enable SystemVerilog Pro › Status Bar: Show File Updates to display those short details.
SystemVerilog Pro supports local folders, Remote SSH, WSL, Dev Containers, Codespaces, and virtual workspaces. When background workers cannot read a workspace directly, the extension uses the VS Code file system instead.
The extension provides TextMate syntax highlighting and semantic highlighting for input, output, and inout ports and for parameters. The default semantic colors can be changed with VS Code's editor.semanticTokenColorCustomizations setting.
The formatter can format .sv, .svh, .v, and .vh files when you save. Generated .gsv and .gsvh files keep highlighting, autocomplete, navigation, and indexing, but the formatter never changes them. To limit changes in a shared file, select the lines you want and right-click Format Selected Lines. The command includes complete lines touched by the selection and changes only those lines; it also supports multiple selections. Selecting the entire file removes trailing empty lines and the terminal newline. A partial selection reaching the end of the file also trims selected trailing blanks.
To format a complete folder, right-click it in VS Code Explorer and choose Format Folder. The command scans all nested folders, saves changed .sv, .svh, .v, and .vh files, skips generated, read-only, and symbolic-link files, and continues if one other file cannot be read or saved. For files it formats, it uses these simple rules:
- Put a declaration and its name together, such as
module tb;.
- Put
begin on the same line as initial, always, if, while, for, and similar statements.
- Move syntax after
begin to the next line. A trailing comment may stay beside begin.
- Put constraint bodies and
std::randomize(...) with bodies on the line after their opening {, including when randomization follows an if (...) condition.
- Put
typedef struct bodies on the line after their opening {.
- Put each statement after a semicolon on a new line, while preserving semicolons inside
for (...) headers.
- Put
else on the line after end.
- Use two-space indentation for blocks and continued expressions. Whole-document formatting uses LF line endings; selected-line formatting keeps the document's existing line ending style.
- Indent a single statement below
if, while, or another control by one level.
- Indent a statement below a case-item label when it starts on the next line; keep a same-line case-item statement on that line.
- Keep complete function and task calls on one line when comments do not require the call to stay split.
- Join a split
return {…} === {…}; comparison of concatenations onto one line when no comment or blank line separates its operands.
- Format simple ranges as
[a:b]; use [a+b : c] when either endpoint contains an expression, with compact operators inside each endpoint.
- Indent lines after a trailing expression operator, such as
||, by one continuation level.
- Keep multiline module ports two spaces inside the module header and align the closing
); with module.
- Keep multiline module instance parameters and ports one indentation level inside the instance header.
- Align branching compiler directives, such as
`ifdef and `endif, with their current code block. Align `include and other branch contents at the same indentation level.
- Keep an adjacent
`include directly below endfunction when no blank line was present.
- Keep indentation on blank lines inside blocks, so indentation guides remain continuous.
- Remove blank lines at the end of the file. The last line contains code, not an empty line.
- Write parameterized types compactly as
type#(...), while keeping delay controls such as #10 separate.
- Reconnect a detached standalone semicolon to its custom-type declaration when only blank lines separate them.
- Rebuild a declaration split across separate type, variable, and semicolon lines when it is safe to do so.
It also fixes common spacing around operators, assignments, commas, parentheses, calls, ranges, and control statements. It protects strings, comments, multiline macros, escaped identifiers, numeric literals, UDP tables, and encrypted code. Review changes in files that use unusual or preprocessor-heavy syntax.
Files larger than 1 MiB use a lighter indentation and spacing pass, so vertical joins such as the split return comparison do not run. Files larger than 8 MiB are left unchanged. These limits also apply to Format Selected Lines, which reads the file for surrounding context.
Document and selected-line formatting run in an isolated worker so incomplete or unusually difficult code cannot freeze the shared extension host, including over Remote SSH. VS Code can cancel an outdated document-formatting request, and a size-aware safety deadline lets the file save continue if formatting takes exceptionally long. The extension records that rare fallback in Output › SystemVerilog Pro without removing or changing any formatter rule.
Automatic formatting is off by default. Format Selected Lines works without enabling automatic formatting. To enable formatting on save, check VS Code's built-in Editor: Format On Save setting. SystemVerilog Pro remains the default formatter for supported HDL files, so no extension-specific setting is needed.
Scope
SystemVerilog Pro helps you read, navigate, and edit source code. It does not compile, simulate, lint, or run tests.
Help and feedback
To report a problem or request a feature, email anaya.taher@gmail.com.
Requirements
VS Code 1.85 or newer.
License
MIT
Maintainer
Taher Anaya · anaya.taher@gmail.com