Skip to content

astli

A SystemVerilog formatter and linter, and the preprocessor and lossless parser behind them, in pure Rust.

module counter #(
  parameter int Width = 8
) (
  input  logic             clk_i,
  input  logic             rst_ni,
  input  logic             en_i,
  output logic [Width-1:0] count_o
);
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) count_o <= '0;
    else if (en_i) count_o <= count_o + 1;
  end
endmodule

The astli command:

  • formats SystemVerilog in the lowRISC style, and refuses a file rather than change what it means;
  • lints it for likely bugs and for the same style;
  • checks a design for undeclared names and instances their definitions do not take;
  • trims and orders filelists to what a top module needs.

The libraries it is built on are on crates.io, documented on docs.rs.

Install

Prebuilt for Linux, macOS and Windows.

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/fischeti/astli/releases/latest/download/astli-cli-installer.sh | sh

On Windows:

powershell -ExecutionPolicy Bypass -c "irm https://github.com/fischeti/astli/releases/latest/download/astli-cli-installer.ps1 | iex"
uv tool install astli

Or run it once, without installing:

uvx astli fmt top.sv
pip install astli

Or with pipx, which installs it in an environment of its own and puts astli on your PATH, or runs it once without installing:

pipx install astli
pipx run astli fmt top.sv

A prebuilt binary through cargo-binstall, or from source:

cargo binstall astli-cli
cargo install astli-cli

Scope

astli lexes, preprocesses and parses; it does not elaborate or type-check. Constructs the parser does not handle yet, such as specify blocks, gate primitives and UDPs, are kept as written, so the formatter never loses code.