
Opinionated, production-tested auto-indent formatter for SystemVerilog
(.sv, .svh). Built and hardened against real UVM/DV codebases —
not toy examples — across months of iteration on constructs that
commonly break generic formatters.
Most generic indenters choke on SystemVerilog's ambiguous constructs.
This one is built specifically to get them right:
begin/end matching, including deeply nested dangling if/else
chains with no explicit begin/end.
do...while loops, fork/join/join_none/join_any.
randomize() with { ... } constraint blocks.
- Preprocessor
`ifdef/`elsif/`else/`endif
chains sharing a single trailing begin.
`pragma protect begin/`pragma protect end and
`protect/`endprotect regions — preserved without
disturbing surrounding indentation.
- Multi-line
if (... inside {...}) begin and other tricky
continuations.
Features
- One-command formatting — wire it up as your default formatter
and use
Format Document (or Format on Save) like any other
language.
- Configurable
begin style — same line (K&R) or its own line
(Allman), switchable instantly from Settings.
- Configurable indent width — 1 to 8 spaces per level.
- Zero external dependencies. The formatting engine ships as a
single, statically linked binary bundled inside the extension — no
Python, no runtime to install, no glibc version requirements.
- Works entirely over stdin/stdout — no temporary files ever touched
on disk.
Getting started
- Install the extension.
- Open a
.sv or .svh file.
- Run Format Document (
Shift+Alt+F / Ctrl+Shift+I), or set it
as your default formatter with Format on Save:
{
"[systemverilog]": {
"editor.defaultFormatter": "quindeptrai.systemverilog-formatter",
"editor.formatOnSave": true
}
}
Settings
| Setting |
Default |
Description |
svFormatter.beginStyle |
same |
same = begin on the same line as the block header (K&R). next = begin on its own line (Allman). |
svFormatter.indentSize |
4 |
Spaces per indentation level. |
Open Settings (Ctrl+,), search for SystemVerilog Formatter,
and change values there — no restart needed, just re-run Format
Document.
Example
svFormatter.beginStyle: "same" (default)
if (rw.kind == UVM_READ) begin
rd_wr_t = 1;
end
else begin
rd_wr_t = 0;
end
svFormatter.beginStyle: "next"
if (rw.kind == UVM_READ)
begin
rd_wr_t = 1;
end
else
begin
rd_wr_t = 0;
end
Requirements
The formatting engine ships as a fully self-contained, statically
linked binary — no separate runtime, no system libraries, no glibc
version dependency at all.
No Windows, macOS, or ARM support in this build.
Remote workspaces (SSH)
The extension is marked as a workspace extension
(extensionKind: ["workspace"]), so with Remote-SSH it always installs
and runs on the remote server automatically — never on your local
machine. Just install it while connected; no extra setup needed, as
long as the remote server meets the requirements above.
Known limitations
- Formats the whole document; range/selection formatting is not yet
supported.
- Designed for UVM-style RTL/testbench code; extremely unusual macro
usage may need manual touch-ups.
Contributing
Issues and pull requests are welcome — see
CONTRIBUTING if present, or open an issue directly.
Release Notes
See CHANGELOG.md.
License
MIT