blob: b859cb5563853895dc3b736a4f7cb223a689c406 [file] [log] [blame] [view]
# SystemVerilog Formatter
<!--*
freshness: { owner: 'hzeller' reviewed: '2020-10-07' }
*-->
`verible-verilog-format` is the SystemVerilog formatter tool. You can can
get a full set of avilable flags using the `--helpfull` flag.
For automatic formatting suggestions on github pull requests, there is a
[easy to integrate github action available][github-format-action].
## Usage
```
usage: verible-verilog-format [options] <file> [<file...>]
To pipe from stdin, use '-' as <file>.
Flags from common/formatting/basic_format_style_init.cc:
--column_limit (Target line length limit to stay under when formatting.);
default: 100;
--indentation_spaces (Each indentation level adds this many spaces.);
default: 2;
--line_break_penalty (Penalty added to solution for each introduced line
break.); default: 2;
--over_column_limit_penalty (For penalty minimization, this represents the
baseline penalty value of exceeding the column limit. Additional penalty
of 1 is incurred for each character over this limit); default: 100;
--wrap_spaces (Each wrap level adds this many spaces. This applies when the
first element after an open-group section is wrapped. Otherwise, the
indentation level is set to the column position of the open-group
operator.); default: 4;
Flags from verilog/formatting/format_style_init.cc:
--assignment_statement_alignment (Format various assignments:
{align,flush-left,preserve,infer}); default: infer;
--case_items_alignment (Format case items:
{align,flush-left,preserve,infer}); default: infer;
--class_member_variable_alignment (Format class member variables:
{align,flush-left,preserve,infer}); default: infer;
--compact_indexing_and_selections (Use compact binary expressions inside
indexing / bit selection operators); default: true;
--distribution_items_alignment (Aligh distribution items:
{align,flush-left,preserve,infer}); default: infer;
--enum_assignment_statement_alignment (Format assignments with enums:
{align,flush-left,preserve,infer}); default: infer;
--expand_coverpoints (If true, always expand coverpoints.); default: false;
--formal_parameters_alignment (Format formal parameters:
{align,flush-left,preserve,infer}); default: infer;
--formal_parameters_indentation (Indent formal parameters: {indent,wrap});
default: wrap;
--module_net_variable_alignment (Format net/variable declarations:
{align,flush-left,preserve,infer}); default: infer;
--named_parameter_alignment (Format named actual parameters:
{align,flush-left,preserve,infer}); default: infer;
--named_parameter_indentation (Indent named parameter assignments:
{indent,wrap}); default: wrap;
--named_port_alignment (Format named port connections:
{align,flush-left,preserve,infer}); default: infer;
--named_port_indentation (Indent named port connections: {indent,wrap});
default: wrap;
--port_declarations_alignment (Format port declarations:
{align,flush-left,preserve,infer}); default: infer;
--port_declarations_indentation (Indent port declarations: {indent,wrap});
default: wrap;
--port_declarations_right_align_packed_dimensions (If true, packed
dimensions in contexts with enabled alignment are aligned to the right.);
default: false;
--port_declarations_right_align_unpacked_dimensions (If true, unpacked
dimensions in contexts with enabled alignment are aligned to the right.);
default: false;
--struct_union_members_alignment (Format struct/union members:
{align,flush-left,preserve,infer}); default: infer;
--try_wrap_long_lines (If true, let the formatter attempt to optimize line
wrapping decisions where wrapping is needed, else leave them unformatted.
This is a short-term measure to reduce risk-of-harm.); default: false;
Flags from verilog/tools/formatter/verilog_format.cc:
--failsafe_success (If true, always exit with 0 status, even if there were
input errors or internal errors. In all error conditions, the original
text is always preserved. This is useful in deploying services where
fail-safe behaviors should be considered a success.); default: true;
--inplace (If true, overwrite the input file on successful conditions.);
default: false;
--lines (Specific lines to format, 1-based, comma-separated, inclusive N-M
ranges, N is short for N-N. By default, left unspecified, all lines are
enabled for formatting. (repeatable, cumulative)); default: ;
--max_search_states (Limits the number of search states explored during line
wrap optimization.); default: 100000;
--show_equally_optimal_wrappings (If true, print when multiple optimal
solutions are found (stderr), but continue to operate normally.);
default: false;
--show_inter_token_info (If true, along with show_token_partition_tree,
include inter-token information such as spacing and break penalties.);
default: false;
--show_largest_token_partitions (If > 0, print token partitioning and then
exit without formatting output.); default: 0;
--show_token_partition_tree (If true, print diagnostics after token
partitioning and then exit without formatting output.); default: false;
--stdin_name (When using '-' to read from stdin, this gives an alternate
name for diagnostic purposes. Otherwise this is ignored.);
default: "<stdin>";
--verbose (Be more verbose.); default: false;
--verify_convergence (If true, and not incrementally formatting with
--lines, verify that re-formatting the formatted output yields no further
changes, i.e. formatting is convergent.); default: true;
```
## Disabling Formatting {#disable-formatting}
When you want to exempt a range of text from formatting, write:
```
// verilog_format: off
... untouched code ...
// verilog_format: on
```
or
```
/* verilog_format: off */
... untouched code ...
/* verilog_format: on */
```
As a good practice, include a reason why you choose to disable a section.
```
// verilog_format: off // my alignment is prettier than the tool's
// verilog_format: off // issue #N: working around.
```
These directives take precedence over `--lines` specifications.
## Formatting included files
For files that are included as snippets in other contexts, e.g. only statements,
or only module body items, adding a
[parsing mode directive](../../analysis#alternative-parsing-modes) (such as `//
verilog_syntax: parse-as-module-body`) will let the formatter parse and format
such files successfully.
## Interactive Formatting
The formatter is ever a work-in-progress and may not always behave the way a
user would like it to behave. If you wish to review changes introduced by the
formatter and apply them interactively, we've provided a helper script (that is
actually formatter-agnostic) for the job.
```
verible-transform-interactive.sh -- verible-verilog-format -- files...
```
This will run the formatter on the affected files without modifying them
initially, and pass the `diff`-generated patch into a tool
(`verible-patch-tool`) that interactively applies patch hunks.
Answer the \[y/n\] prompts.
The original files will be modified in-place with the elected changes.
For convenience, one could create an alias like:
```
alias verilog-format-interactive='verible-transform-interactive.sh -- verible-verilog-format --'
```
## Incremental Formatting
If you wish to format only changed lines (a.k.a. incremental or partial
formatting), the following tools are provided to assist.
### Git users
`git-verible-verilog-format.sh` (installed along with `verible-verilog-format`)
can be run from within any subdirectory of a Git project. It automatically
detects new and changed lines, and generates the `--lines` flag for each
modified file in your workspace.
From `--help`:
```
git-verible-verilog-format.sh:
Performs incremental file formatting (verible-verilog-format) based on current diffs.
New files explicitly git-add-ed by the user are wholly formatted.
Actions:
1) Runs 'git add -u' to stage currently modified files to the index.
To format new files (wholly), 'git add' those before calling this script.
2) Runs 'git diff -u --cached' to generate a unified diff.
3) Diff is scanned to determine added or modified lines in each file.
4) Invokes 'verible-verilog-format --inplace' on all touched or new Verilog files,
but does not 'git add' so that the changes may be examined and tested.
Formatting can be easily undone with:
'git diff | git apply --reverse -'.
usage: git-verible-verilog-format.sh [script options] [-- [verilog_format options]]
(no positional arguments)
Run from anywhere inside a git project tree.
script options: (options with arguments can be: --flag=VALUE or --flag VALUE)
--help | -h : print help and exit
--verbose | -v : execute verbosely
--dry-run : stop before running formatter, and print formatting commands
--formatter TOOL : path to verilog_format binary
[using: /usr/local/bin/verible-verilog-format]
-- : stops option processing, and forwards remaining args as flags to the
underlying --formatter tool.
```
## Incremental Interactive Formatting
In your locally modified client (p4, git) run:
```shell
verible-verilog-format-changed-lines-interactive.sh
```
and follow the prompts.
> NOTE: git and hg users can pass in a different base revision to diff against:
>
> ```shell
> # Diff against the previous revision in hg
> verible-verilog-format-changed-lines-interactive.sh --rev .^
> # Diff against upstream mainline in git
> verible-verilog-format-changed-lines-interactive.sh --rev origin/main
> ```
## Aligned Formatting
There are several sections of code that are eligible for aligned formatting. In
each of these contexts, the user has some control over the alignment behavior.
Without alignment, the default behavior is to flush-left, which respects
indentation and minimum inter-token spacing constraints.
Yet, alignment is not always desired. So how does the formatter know whether or
not the user intended for alignment? It can only examine the original code and
make some judgment.
Consider the following example (module formal parameters):
```
module m #(
int W,
type T
);
...
endmodule
```
With alignment, this formats to:
```
module m #(
int W,
type T
);
...
endmodule
```
When the spacing difference between between aligned and flushed-left formatting
is "sufficiently small", the formatter will align because the small difference
has low risk of compromising readability.
In contrast, aligning the following example _could_ be considered less readable.
original:
```systemverilog
module m #(
int W,
some_long_name T
);
...
endmodule
```
aligned:
```systemverilog
module m #(
int W,
some_long_name T
);
...
endmodule
```
To detect the above condition, the formatter examines the number of _excess_
spaces (spacing errors) within an alignment group (original vs. flushed-left).
If that value is lower than a threshold, the formatter infers that the author
intended flush-left formatting.
To induce alignment, the author needs to _inject_ four excess spaces _between_
any two tokens in any row in the aligned section, not before first tokens (which
fall under indentation, not alignment). In this example, spaces are deliberately
injected before `W` (but after `W` would work too):
```systemverilog
module m #(
int W,
some_long_name T
);
...
endmodule
```
formatted with alignment:
```
module m #(
int W,
some_long_name T
);
...
endmodule
```
This also implies that previously aligned code will most likely remain aligned.
Finally, if none of the above conditions hold, the formatter will leave the
original code as-is, preserving all pre-existing spaces.
## Failsafe Behavior
_A formatter must not corrupt data._
On rare conditions, you may observe that the formatter leaves the original code
untouched. You may have encountered a fail-safe condition, in which the
formatter conservatively gives up to keep your code from being corrupted. This
can happen for one of several reasons.
### Syntax Errors
On failure to lex/parse, the formatter gives up because it doesn't have a syntax
tree to work with.
### Internal Verification
Before outputting the formatted result, several properties are checked:
* **Equivalence**: The output is lexically equivalent to the input, meaning
that only whitespaces may have changed, but all other tokens are equal. For
example, if two identifiers accidentally got merged together into one (by
removing spaces between them), this check would fail. Lexical equivalence
also implies that the output is still parseable.
* **Convergence**: Re-formatting the _output_ results in no further changes.
This property is particularly important when the formatter is used to
_check_ that a file is formatted properly. Without convergence, such a check
would fail after formatting, potentially asking the user to run formatting
two or more times. Note that this requirement is stricter than _eventual
convergence_, which allows multiple iterations before reaching a
fixed-point.
### Internal Limits
If an optimization such as line-wrapping optimization fails to complete within
time resource limits, then the formatter also gives up to avoid hanging.
### Fatal Error
If the formatter crashes for any other reason, it will leave the original file
intact. The formatter does not attempt to open any file for writing in-place
until all formatting calculations have been done and internal verifications
pass.
[github-format-action]: https://github.com/chipsalliance/verible-formatter-action