Formatter Options
All options live under [format] in lazyverilog.toml. The formatter never changes anything but whitespace; if a safety check fails, the edit is dropped and a warning is shown.
Every align option has an align_adaptive companion: when true, each line computes its own column widths instead of sharing the widest in the group.
Top-level options
indent_size
Number of spaces per indentation level.
[format]
indent_size = 4// indent_size = 2
module m_top;
logic a;
endmodule
// indent_size = 4
module m_top;
logic a;
endmoduleblank_lines_between_items
Number of blank lines kept wherever the source has at least one. 0 removes them. A gap that has no blank line is never given one. Blank lines inside parentheses or braces (a port list, a concatenation) are always removed, whatever this value is. Range 0 to 100.
[format]
blank_lines_between_items = 1// source: three blank lines between the assigns
// blank_lines_between_items = 1
assign a = b;
assign c = d;
// blank_lines_between_items = 0
assign a = b;
assign c = d;default_indent_level_inside_outmost_block
Indent levels to add inside the outermost design unit, 0 or 1 (other values are rejected with a warning and the default 1 is used): module, macromodule, interface, package, program, class, checker, primitive, or config. Set to 0 to keep its body at column 0. A unit nested inside another (a class in a package) always indents its body.
[format]
default_indent_level_inside_outmost_block = 1// default_indent_level_inside_outmost_block = 1
module m_top;
logic a;
endmodule
// default_indent_level_inside_outmost_block = 0
module m_top;
logic a;
endmoduletab_align
When true, alignment column widths are rounded up to the next multiple of indent_size. Produces cleaner tab-stop-aligned columns across port declarations, variable declarations, instances, enums, and modports.
[format]
tab_align = true
indent_size = 4
# the example below also uses
[format.port_declaration]
align = true
align_adaptive = false
section1_min_width = 1
section2_min_width = 1
section3_min_width = 1
section4_min_width = 1
section5_min_width = 0// tab_align = false, indent_size = 4
input logic [7:0] data,
output logic valid
// tab_align = true, indent_size = 4 (each column width rounded up to a multiple of 4)
input logic [7:0] data,
output logic validWith the default port widths (12, already a multiple of 4) the two settings give the same output.
log_path
A directory for the formatter's per-pass debug logs, for reporting a formatter bug. Empty (the default) writes nothing. A relative path is relative to the working directory of the server or lazyverilog-fmt process, not to lazyverilog.toml. The directory is created when needed, and every format, including format-on-save, writes to it, so leave it empty in normal use.
[format]
log_path = "/tmp/lazyverilog-fmt-log"enable_format_on_save
When true, the server formats the whole document on save. It does not stop other save-time generators such as [autoarg].autoarg_on_save.
Saving goes through LSP textDocument/willSaveWaitUntil, which the Neovim plugin and the VS Code extension both send on every save, so no editor-side setting such as editor.formatOnSave is needed. This option only controls saving: an explicit "Format Document" (:Format, vim.lsp.buf.format(), Shift+Alt+F) always formats, whatever it is set to.
[format]
enable_format_on_save = trueformat_off_comment_pattern / format_on_comment_pattern
Regex patterns used to detect line comments that disable and re-enable formatting. The regex is matched against the comment token text, for example // verilog_format: off.
[format]
format_off_comment_pattern = '//\s*verilog[-_]format\s*:\s*off\b'
format_on_comment_pattern = '//\s*verilog[-_]format\s*:\s*on\b'// verilog_format: off
assign a=b; // preserved verbatim
// verilog_format: on
assign a = b; // formatted normally[format.spacing]
Controls whitespace around operators, keywords, and delimiters.
control_keyword_space
Insert a space between control keywords (if, for, while, etc.) and the opening parenthesis.
[format.spacing]
control_keyword_space = true// control_keyword_space = true
if (a) begin
// control_keyword_space = false
if(a) beginspace_inside_parens
Insert spaces inside ordinary parentheses. Empty parentheses stay ().
[format.spacing]
space_inside_parens = false// space_inside_parens = false
assign a = foo(bar);
// space_inside_parens = true
assign a = foo( bar );space_inside_dimension_brackets
Insert spaces inside dimension brackets [ ].
[format.spacing]
space_inside_dimension_brackets = false// space_inside_dimension_brackets = false
logic [7:0] data;
// space_inside_dimension_brackets = true
logic [ 7:0 ] data;binary_operator_spacing
Controls spaces around binary operators (+, -, *, ==, etc.) outside dimension brackets.
Values: "none" | "before" | "after" | "both"
[format.spacing]
binary_operator_spacing = "both"// "both"
assign c = a + b;
// "none"
assign c = a+b;
// "before"
assign c = a +b;
// "after"
assign c = a+ b;dimension_binary_operator_spacing
Controls spaces around binary operators inside dimension brackets [...].
Values: "none" | "before" | "after" | "both"
[format.spacing]
dimension_binary_operator_spacing = "none"// "none"
logic [WIDTH-1:0] data;
// "both"
logic [WIDTH - 1:0] data;semicolon_spacing
Controls spaces around semicolons in for-loop headers.
Values: "none" | "before" | "after" | "both"
[format.spacing]
semicolon_spacing = "after"// "after"
for (int i = 0; i < 8; i++)
// "both"
for (int i = 0 ; i < 8 ; i++)
// "none"
for (int i = 0;i < 8;i++)range_colon_spacing
Controls spaces around the colon in range expressions inside [...].
Values: "none" | "before" | "after" | "both"
[format.spacing]
range_colon_spacing = "none"// "none"
logic [7:0] data;
// "both"
logic [7 : 0] data;It also spaces the colons of a min:typ:max triple (#(1:2:3), a specify path delay = (1:2:3)), which is one value rather than a ternary.
This option only affects ranges. A case item's colon is not configurable: it is always written label: statement, whether the label is a literal, an identifier, a macro, or default.
case (op)
`NOP: y = 0;
4'hc4: y = 1;
ST_IDLE: y = 2;
default: y = 3;
endcaseindexed_part_select_spacing
Controls spaces around indexed part-select operators +: and -:.
Values: "none" | "before" | "after" | "both"
[format.spacing]
indexed_part_select_spacing = "both"// "both"
data[offset +: WIDTH]
// "none"
data[offset+:WIDTH]procedural_event_control_at_spacing
Controls spaces around @ in procedural event control (always @(...)).
The space before @ follows this option only after a keyword. An intra-assignment event takes the assignment operator's spacing (q <= @(posedge clk) d;), and an @ after a control's ) or a delay (wait (a) @(e), #5 @(e)) is always separated from it. So is an @ after the name a clocking block or covergroup declares (clocking cb @(posedge clk);, covergroup cg @(posedge clk);).
Values: "none" | "before" | "after" | "both"
[format.spacing]
procedural_event_control_at_spacing = "before"// "before"
always @(posedge clk)
// "after"
always@ (posedge clk)
// "both"
always @ (posedge clk)
// "none"
always@(posedge clk)space_inside_event_control_parens
Insert spaces inside event control parentheses @(...).
[format.spacing]
space_inside_event_control_parens = false// false
always @(posedge clk)
// true
always @( posedge clk )assignment_operator_spacing
Controls spaces around assignment operators = and <=.
Values: "none" | "before" | "after" | "both"
[format.spacing]
assignment_operator_spacing = "both"// "both"
assign a = b;
q <= d;
// "none"
assign a=b;
q<=d;[format.statement]
Controls formatting of consecutive assignment statements.
align
Align = and <= operators across consecutive assignment lines.
[format.statement]
align = true// align = true
a = 1;
data = 2;
result = 3;
// align = false
a = 1;
data = 2;
result = 3;align_adaptive
When true, the operators line up at lhs_min_width and a longer left-hand side widens only its own line, which keeps one space before its operator. When false, all consecutive lines in a group share the column of the widest left-hand side.
[format.statement]
align_adaptive = false// align = true
// align_adaptive = false
a = 1;
data = 2;
result = 3;
very_long_text = 4;
// align = true
// align_adaptive = true
// lhs_min_width = 6
a = 1;
data = 2;
result = 3;
very_long_text = 4;lhs_min_width
Minimum character width of the left-hand side field when align is true.
[format.statement]
lhs_min_width = 6// lhs_min_width = 6
a = 1;
data = 2;
// lhs_min_width = 1
a = 1;
data = 2;begin_newline
When true, block openers are placed on a new line. When false, they stay on the line that introduces them. This applies to begin, fork, and every brace that opens a block: constraint and coverage braces, and the body brace of a struct or union.
An enum brace is not moved: it holds a list of names, not a block of declarations.
[format.statement]
begin_newline = false// begin_newline = false
if (a) begin
...
end
constraint c {
if (a) {
x == 1;
}
}
// begin_newline = true
if (a)
begin
...
end
constraint c
{
if (a)
{
x == 1;
}
}
typedef struct packed
{
logic a;
} s_t;
typedef enum logic {
A,
B
} e_t;wrap_end_else_clauses
When true (the default), else after end or } is placed on a new line. When false, end else or } else stays on the same line.
An else that follows a labelled end : name, or a comment after end, starts a new line under either value.
[format.statement]
wrap_end_else_clauses = true// wrap_end_else_clauses = true
end
else begin
...
end
}
else {
...
}
// wrap_end_else_clauses = false
end else begin
...
end
} else {
...
}[format.port_declaration]
Controls alignment of
- ANSI port declarations inside module header.
- non-ANSI port declarations inside module body.
Port declarations are split into 5 sections:
- Direction (
input,output,inout) - Type + qualifier (
logic,wire signed, etc.) - Packed dimension (
[7:0]) - Port name
- Trailing (unpacked dimensions,
= default, etc.)
align
Enable column alignment of the 5 sections across consecutive port declarations. Default: false.
[format.port_declaration]
align = true// align = true, default widths (align_adaptive = true, every section 12)
input logic [7:0] data ,
output logic valid
// align = true, align_adaptive = false,
// section1..4_min_width = 1, section5_min_width = 0
input logic [7:0] data,
output logic valid
// align = false
input logic [7:0] data,
output logic validalign_adaptive
When true (default), a section wider than its minimum widens only its own line instead of pushing every port in the group to the same column.
[format.port_declaration]
align_adaptive = truesection1_min_width .. section5_min_width
Minimum character width for each alignment section. When tab_align is true, these are snapped to indent grid. Section 5 pads the trailing column, so a port's , or ; lines up after it. Default: 12 for each section.
[format.port_declaration]
section1_min_width = 12 # direction column
section2_min_width = 12 # type column
section3_min_width = 12 # dimension column
section4_min_width = 12 # port name column
section5_min_width = 12 # trailing column// align = true
// align_adaptive = true
// section1_min_width = 10
// section2_min_width = 11
// section3_min_width = 12
// section4_min_width = 13
// section5_min_width = 14
// tab_align = false
input i_clk ;
input i_rst_n ;
input logic [1:0] i_data [7:0] ;
input var byte i_data2 ;
| | | | | |
section1 section2 section3 section4 section5[format.var_declaration]
Controls alignment of variable/signal declarations (logic, wire, reg, etc.) in module body.
Declarations are split into 4 sections:
- Type + qualifier (
logic,wire signed, etc.) - Packed dimension (
[7:0]) - Signal name
- Trailing (unpacked dimensions, initializers, etc.)
align
Enable column alignment across consecutive variable declarations.
[format.var_declaration]
align = true// align = true, default widths (section1 0, section2 30, section3 30, section4 0)
logic [7:0] data ;
logic valid ;
// align = true, section1..3_min_width = 1, section4_min_width = 0
logic [7:0] data ;
logic valid ;
// align = false
logic [7:0] data;
logic valid;section1_min_width .. section4_min_width
Minimum character width for each section.
section1_min_width = 0 (the default) selects a simpler mode. Only the type column is lined up across the group. The dimension and name sections are each padded to their own minimum width, line by line, so names and = line up only when every dimension and name fits in that width. A section whose width is 0 gets no padding at all, and the ; is not aligned. Set section1_min_width to 1 or more to line up every section, the = and the ; across the group.
// align = true, section1_min_width = 0, section2_min_width = 8, section3_min_width = 8
logic [7:0] data = 1;
logic valid ;
int [15:0] a_very_long_name_x = 0;
packet_t p ;
// align = true, section1_min_width = 1, section2_min_width = 8, section3_min_width = 8
logic [7:0] data = 1;
logic valid ;
int [15:0] a_very_long_name_x = 0;
packet_t p ;[format.var_declaration]
section1_min_width = 16 # type column
section2_min_width = 12 # dimension column
section3_min_width = 20 # signal name column
section4_min_width = 16 # trailing column (minimum width; 0 = no minimum)logic [7:0] dout = 8'hFF ;
logic [8:0] din = 8'hFF ;
packet_t [1:0] test_init = 8'hFF ;
packet_t test_init2 = 8'hFF ;
| | | | |
section1 section2 section3 section4[format.instance]
Controls formatting of module instantiation port connections.
align
Align port connections across lines in an instance. With align = true, one space also separates the instance name from (; with align = false, the ( follows the name directly.
[format.instance]
align = true// align = true
m_fifo u_fifo (
.clk (clk ),
.data (data ),
.valid (valid)
);
// align = false
m_fifo u_fifo(
.clk(clk),
.data(data),
.valid(valid)
);port_indent_level
Number of indent levels for port lines relative to the instantiation line.
[format.instance]
port_indent_level = 1// port_indent_level = 1, indent_size = 4
m_fifo u_fifo(
.clk(clk)
);
// port_indent_level = 2, indent_size = 4
m_fifo u_fifo(
.clk(clk)
);instance_port_name_width
Total field width from . to ( — controls spacing between the port name and the opening parenthesis.
[format.instance]
instance_port_name_width = 10// instance_port_name_width = 10
m_fifo u_fifo (
.clk (clk ),
.data (data ),
);instance_port_between_paren_width
Total field width from ( to ) — controls spacing between the signal name and the closing parenthesis.
[format.instance]
instance_port_between_paren_width = 10// instance_port_between_paren_width = 10
m_fifo u_fifo (
.clk (clk ),
.data (data ),
);align_adaptive
When true, each port line computes its own gap. When false, all ports in the instance share common alignment columns.
[format.instance]
align_adaptive = false// align = true, align_adaptive = false
m_fifo u_fifo (
.clk (clk ),
.data (data ),
.very_long_text ( ),
.din (very_long_text)
);
// align = true, align_adaptive = true,
// instance_port_name_width = 6, instance_port_between_paren_width = 10
m_fifo u_fifo (
.clk (clk ),
.data (data ),
.very_long_text ( ),
.din (very_long_text)
);[format.function_call]
Controls formatting of function/task calls.
break_policy
When to break function call arguments onto separate lines.
"never"— always single-line"always"— always break (if args exist)"auto"— break when line exceedsline_lengthor argument count exceedsarg_count
[format.function_call]
break_policy = "auto"line_length
When break_policy = "auto", break if the single-line rendering exceeds this character width. The width is the whole line as it will be written, indentation included, so the limit is a column and a call nested four levels deep breaks at the same column as one at the top level.
[format.function_call]
line_length = 100The width is measured up to the call's closing ); a ; or , after it is not counted. The single-line call below ends at column 30.
// break_policy = auto
// line_length = 40
sum(.i_a(i_a2), .i_b(i_b));
// break_policy = auto
// line_length = 20
sum(
.i_a(i_a2),
.i_b(i_b)
);A call is not broken when that would not help: when the arguments would still start past the limit after the break (after the ( for layout = "hanging", one indent past the call's name for "block").
arg_count
When break_policy = "auto", break if the number of arguments is >= this value. Set to -1 to disable arg-count breaking.
[format.function_call]
arg_count = 3// arg_count = 3, 2 args → stays single-line
foo(a, b);
// arg_count = 3, 3 args → breaks
foo(
a,
b,
c
);layout
How to indent broken arguments.
"block"— arguments indented one level from the call"hanging"— arguments aligned to the opening parenthesis
[format.function_call]
layout = "block"// layout = "block"
foo(
a,
b,
c
);
// layout = "hanging"
foo(a,
b,
c);space_before_paren
Insert a space between the function name and the opening (.
[format.function_call]
space_before_paren = false// false
foo(a, b);
// true
foo (a, b);space_inside_paren
Insert spaces inside function call parentheses. An empty argument list stays ().
[format.function_call]
space_inside_paren = false// false
foo(a, b);
// true
foo( a, b );[format.function_declaration]
Controls formatting of function and task declaration port lists.
Declaration spacing is intentionally limited to the gap before the opening parenthesis. Unlike [format.function_call], declarations do not currently expose space_inside_paren; declaration port-list interior spacing is normalized by the formatter's declaration layout rules.
layout
How to indent broken port arguments.
"block"— ports indented one level from the declaration"hanging"— ports aligned to the opening parenthesis
[format.function_declaration]
layout = "block"// layout = "block"
function void foo(
input logic a,
input logic b
);
// layout = "hanging"
function void foo(input logic a,
input logic b);line_length
Declarations shorter than this stay single-line. Declarations exceeding this are broken according to layout. The width includes the declaration's indentation, as it does for function_call.line_length.
[format.function_declaration]
line_length = 100// line_length = 100, short declaration stays single-line
function void foo(input logic a, input logic b);
// line_length = 40, same declaration breaks
function void foo(
input logic a,
input logic b
);space_before_paren
Insert a space between the declared function/task name and the opening (.
[format.function_declaration]
space_before_paren = false// space_before_paren = false
function int add_number(
input int a,
input int b,
output int result
);
// space_before_paren = true
function int add_number (
input int a,
input int b,
output int result
);[format.module]
Controls module header formatting.
parameter_layout
"block"— parameters indented one level"hanging"— parameters aligned to#(
[format.module]
parameter_layout = "block"// parameter_layout = "block"
module m_top #(
parameter WIDTH = 8,
parameter DEPTH = 16
)(
...
);
// parameter_layout = "hanging"
module m_top #(parameter WIDTH = 8,
parameter DEPTH = 16)(
...
);non_ansi_port_per_line_enabled / non_ansi_port_per_line
When enabled, non-ANSI port lists are wrapped with a fixed number of ports per line.
[format.module]
non_ansi_port_per_line_enabled = true
non_ansi_port_per_line = 3// non_ansi_port_per_line = 3
module m_top(
a, b, c,
d, e, f,
g
);non_ansi_port_max_line_length_enabled / non_ansi_port_max_line_length
When enabled, non-ANSI port lists are wrapped based on maximum line length. If both non_ansi_port_per_line_enabled and non_ansi_port_max_line_length_enabled are enabled, both constraints are applied: a line break is inserted when either the fixed port count is reached or adding the next port would exceed the maximum line length.
[format.module]
non_ansi_port_max_line_length_enabled = true
non_ansi_port_max_line_length = 80[format.enum_declaration]
Controls alignment of enum member declarations.
align
Align enum names and values across members.
[format.enum_declaration]
align = true// align = true
typedef enum logic [1:0] {
IDLE = 2'b00,
ACTIVE = 2'b01,
DONE = 2'b10
} state_t;
// align = false
typedef enum logic [1:0] {
IDLE = 2'b00,
ACTIVE = 2'b01,
DONE = 2'b10
} state_t;align_adaptive
Per-member adaptive alignment instead of block-wide alignment.
[format.enum_declaration]
align_adaptive = false// align = true
// align_adaptive = true
typedef enum logic [1:0] {
IDLE = 2'b00,
ACTIVE = 2'b01,
DONE = 2'b10,
VERY_LONG_TEXT = 2'b11
} state_t;
// align = true
// align_adaptive = false
typedef enum logic [1:0] {
IDLE = 2'b00,
ACTIVE = 2'b01,
DONE = 2'b10,
VERY_LONG_TEXT = 2'b11
} state_t;enum_name_min_width
Minimum character width for the enum member name column.
[format.enum_declaration]
enum_name_min_width = 1enum_value_min_width
Minimum character width for the enum value column. Set to 0 to disable value-column alignment.
[format.enum_declaration]
enum_value_min_width = 0[format.modport]
Controls alignment of modport declarations inside interfaces.
align
Align direction and signal columns across modport members.
[format.modport]
align = true// align = true (align_adaptive = false: the `,` lines up after the widest signal)
modport master (
input clk ,
input rst_n,
output valid
);
// align = true, align_adaptive = true
modport master (
input clk,
input rst_n,
output valid
);
// align = false
modport master (
input clk,
input rst_n,
output valid
);direction_min_width
Minimum character width for the direction column (input, output).
[format.modport]
direction_min_width = 1signal_min_width
Minimum character width for the signal name column.
[format.modport]
signal_min_width = 0[format.macros]
Controls how user-defined macros are classified for formatting purposes. Macro classification affects wrapping, indentation, and spacing decisions. See macros.md for the full option reference, available role lists, and examples.
The lists you set extend the built-in UVM defaults; they do not replace them. A built-in macro cannot be removed or moved to another role. See Built-in defaults for the list.
No macro is whitespace_sensitive by default. To keep a macro's arguments exactly as written, list it, for example OpenTitan's DV_CHECK_FATAL:
[format.macros]
whitespace_sensitive = ["DV_CHECK_FATAL"]