svfmt 是一个基于 tree-sitter-systemverilog 的 SystemVerilog 源码格式化工具。它先把源码解析成 CST,再根据可配置的规则重新排版输出,只调整排版、不改动任何 HDL 语义。
SystemVerilog Source
│
▼
tree-sitter-systemverilog
│
▼
CST
│
▼
Formatter
│
▼
Formatted SystemVerilog
- 语法级解析:基于 tree-sitter,不做字符串/正则替换,不会破坏代码结构
- 纯 source-to-source:只改空格、缩进、换行、括号位置、对齐与注释布局;不修改语义、不改变表达式含义、不改动端口/参数顺序
- 高度可配置:缩进、空格、空行、注释、对齐、模块/端口/实例布局等 40+ 项选项
- 配置文件:支持 TOML
- 管道友好:支持 stdin/stdout、
-o输出文件、--in-place就地覆盖 - 批量格式化:支持多个输入文件与 glob 模式(如
svfmt --in-place *.sv) - 调试支持:内置 CST 打印(
--cst/cst子命令)
需要 Rust 工具链(稳定版)。
git clone <repo-url> svfmt
cd svfmt
cargo build --release构建产物位于 target/release/svfmt,可将其加入 PATH:
cp target/release/svfmt ~/.local/bin/# 格式化文件,结果输出到 stdout
svfmt top.sv
# 输出到指定文件
svfmt top.sv -o top_formatted.sv
# 就地覆盖源文件
svfmt top.sv --in-place
# 批量就地格式化多个文件(shell 展开 glob)
svfmt --in-place *.sv
# 程序内 glob 展开(引号包裹时同样生效)
svfmt --in-place 'rtl/**/*.sv'
# 从 stdin 读取,结果写到 stdout(省略 FILE 或传 `-`)
cat top.sv | svfmt - > formatted.sv批量模式下:
-o只能配合单个输入文件;单个文件失败(如不存在)不影响其余文件,但进程以非零状态退出。
Usage: svfmt [OPTIONS] [FILE]... [COMMAND]
Commands:
cst 解析 SystemVerilog 文件并递归打印 CST
Arguments:
[FILE]... 输入 .sv 文件路径(可多个,支持 glob);省略或为 `-` 时从标准输入读取
Options:
-o, --output <OUT> 输出文件路径(默认输出到 stdout)
--in-place 就地格式化(覆盖输入文件)
--config <CONFIG> 配置文件路径(TOML)
--dump-config 打印默认配置并退出
--cst 解析并打印 CST(调试用)
-h, --help Print help
-V, --version Print version
除上述通用选项外,所有格式化配置项都可通过命令行覆盖(见下文「命令行覆盖配置」)。
svfmt cst top.sv # 打印 CST 树
svfmt cst top.sv --indent-width 4 # 调整打印缩进
svfmt cst top.sv --max-text-len 40 # 截断超长节点文本
svfmt cst top.sv --fail-on-error # 存在语法错误时以非零状态退出格式化行为由 FormatterConfig 控制,每个选项都有默认值。完整选项说明见 verilog_format.md。
svfmt --dump-config输出一份 TOML 格式的默认配置,可直接保存为配置文件后修改。
svfmt top.sv --config svfmt.toml配置文件使用 TOML 格式(.toml 扩展名)。未填写的选项使用默认值。
所有格式化配置项都可以直接作为命令行参数传入,优先级:命令行 > 配置文件 > 默认值。
flag 命名与配置键一致,布尔值支持 --flag(true)与 --flag=false 两种写法:
svfmt --column-limit 80 top.sv -o out.sv # 每行 80 列断行
svfmt --indent-width 2 --use-tab top.sv # 2 空格 / 改用 Tab
svfmt --align-case-items=false top.sv # 关闭 case 项对齐
svfmt --reformat-case casez top.sv # 统一为 casez
svfmt --config svfmt.toml --column-limit 120 top.sv # 覆盖配置文件常用示例 svfmt.toml:
indent_width = 4
use_tab = false
column_limit = 100
align_trailing_comments = true
comment_column = 40
[space]
around_binary_operator = true
after_comma = true
before_control_statement_parens = true
[module]
newline_per_port = true
port_alignment = true
begin_end_on_newline = true2 空格缩进 + if (...) 风格(控制语句前加空格)
indent_width = 2
[space]
before_control_statement_parens = true不限制行宽 + Tab 缩进
column_limit = 0
use_tab = true
tab_width = 4- 工具只负责排版,不修改代码语义:不会自动把
always改成always_ff、把wire改成logic,也不会改动端口/参数顺序 - 对语法错误(ERROR 节点)的代码段会尽量原样保留;如需检查语法,可用
svfmt cst --fail-on-error