Skip to main content

astli

SystemVerilog language tooling in pure Rust: a preprocessor, a lossless syntax tree, and a formatter built on them.

Why

A Rust tool that wants to understand SystemVerilog has had to bind a C++ frontend. That works, but the FFI hands back opaque objects: walking a syntax tree means writing a binding for every node and method you touch, and the C++ build is slow and hard to cache. bender is where that friction showed up.

astli is the frontend as a Rust library. The tree is ordinary Rust data that keeps every byte of the source, comments and whitespace included, so a tool can walk it, query it, and print it back exactly.

The formatter is the first thing built on it. A linter, a language server, or deeper analysis could follow.

Scope

astli lexes, preprocesses and parses; it does not elaborate or type-check. slang is the state of the art for SystemVerilog, a complete compiler, and the right tool whenever you need one. astli does not try to replace it.

Status

Pre-1.0, and the API still changes. What exists:

  • Preprocessor. All directives, macro expansion, includes, and filelists with +incdir+ and +define+.
  • Parser. Design units, declarations, classes, instances, generate blocks, statements and expressions, constraints, assertions, covergroups and clocking blocks. Rarer constructs such as specify, checker, gate primitives and UDPs are kept verbatim for now, so nothing is ever lost; docs/grammar-coverage.md has the detail.
  • Formatter. The lowRISC style. It checks that every result preprocesses to the same thing as its input, and refuses a file rather than change what it means.
  • Filelists. Trimmed to what a top needs, and put in dependency order.

All of it is tested against open-source designs, fetched by scripts/fetch-corpus.sh.

Install

The astli command comes prebuilt for Linux, macOS and Windows. With the installer script:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/fischeti/astli/releases/latest/download/astli-cli-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/fischeti/astli/releases/latest/download/astli-cli-installer.ps1 | iex"

With uv, or to run it once without installing:

uv tool install astli
uvx astli fmt top.sv

With cargo, as a prebuilt binary through cargo-binstall, or from source:

cargo binstall astli-cli
cargo install astli-cli

Formatting

astli fmt top.sv            # print the formatted file
astli fmt -w rtl/*.sv       # rewrite in place
astli fmt --check -f src.f  # fail if any file in a filelist is unformatted
astli fmt --diff top.sv     # show what would change
astli fmt -                 # stdin to stdout

Each file is formatted on its own: includes are not followed and no +define+ reaches the formatter, so the output depends only on the file.

To keep something as you wrote it, put // astli-fmt: skip on the line before it. It applies to the next item, statement or member, which is left as written and only moved to its indentation:

// astli-fmt: skip
assign out = sel ? a
               : b;

Filelists

astli files -f design.f --top soc_top          # only what soc_top needs
astli files -f design.f --top soc_top --order  # packages before their users
astli files -f design.f --emit tops            # modules nothing instantiates
astli files -f design.f --top soc_top --why rtl/fifo.sv

Each file is expanded as it would be compiled, with the filelist's +incdir+s and +define+s, so a module a macro instantiates counts. A name used and declared in no file is a warning.

As a library

[dependencies]
astli = "0.2"
use astli::parse::SyntaxTree;
use astli::syntax::ast::{AstNode, ModuleDecl};

let tree = SyntaxTree::read("top.sv")?;

for module in tree.root().descendants().filter_map(ModuleDecl::cast) {
    if let Some(name) = module.name() {
        println!("module {}", name.text());
    }
}

print!("{}", astli::fmt::format(&tree)?);

astli re-exports each astli-* crate as a module; they can also be used on their own. docs/api.md explains the shape of the API.

Development

astli-cli is the workspace's default member, so cargo run needs no -p. Besides fmt, the driver has one subcommand per stage, each printing what that stage made of a file:

cargo run -- lex        top.sv
cargo run -- preprocess top.sv -I include --emit text
cargo run -- parse      top.sv --quiet

The same default member means every other cargo command needs --workspace: cargo nextest run --workspace, not cargo nextest run. -P quick skips the tests that read the corpus. Hooks run through prek: prek install.

docs/plan.md has the architecture and the decisions behind it.

Path
crates/astli-text Spans, the file store, reading a file
crates/astli-diag Rendering a diagnostic, with its macro and include chain
crates/astli-syntax SyntaxKind, the lexer, the rowan tree types
crates/astli-preproc Directives, macros, includes
crates/astli-parse The grammar, and the tree it builds
crates/astli-fmt The formatter
crates/astli-index The top-level names files declare and use
crates/astli The umbrella: every library crate, as a module
crates/astli-cli The driver, a binary named astli
docs/ Design and planning

Acknowledgements

  • slang, the reference for how SystemVerilog behaves. The preprocessor is tested against it, file by file.
  • rust-analyzer, whose architecture this follows: an event-based parser, a lossless tree, and typed views generated from a tree grammar.
  • rowan, logos and ungrammar, which it is built on.
  • lowRISC's style guide, which the formatter implements.
  • The open-source designs in the test corpus, for being real code.

Licence

MIT or Apache-2.0, at your option. Unless you state otherwise, any contribution you submit is licensed the same way, without further terms.

Metadata

Release files for astli 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for astli 0.2.0
File Size Uploaded
astli-0.2.0.tar.gz 192.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for astli 0.2.0
File
astli-0.2.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
astli-0.2.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
astli-0.2.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
astli-0.2.0-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
astli-0.2.0-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details
astli-0.2.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
astli-0.2.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 8.4 MB

Release files / astli-0.2.0.tar.gz

Download URL astli-0.2.0.tar.gz
Size 192.9 kB
Tags Source
SHA-256 checksum
How to use checksums
809417af699c7af62c004ae159e6406d938e6f997a9b9e360fc63d19c37a3dce
BLAKE2b-256 checksum
How to use checksums
0826ca3c6f8004a5974e7b10d530da40e11cf3e9985c24729a8718627436eaf1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-win_amd64.whl

Download URL astli-0.2.0-py3-none-win_amd64.whl
Size 1.0 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
feea6573f065eac2af76adf56b59c5e54fce49a631e3bef3e7c3058af7c13cf4
BLAKE2b-256 checksum
How to use checksums
773bd57cb105a68dc4c090a6450bef4ad4491af8f7134d39e4cd0c9192c0b521
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-musllinux_1_2_x86_64.whl

Download URL astli-0.2.0-py3-none-musllinux_1_2_x86_64.whl
Size 1.3 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
c5fb6167fd619c8cddbe3ac0876792c96f95f8c597c760b42e6c89eae1740f2b
BLAKE2b-256 checksum
How to use checksums
b2f5834aabaa2b85c8874f10f9a35724f185c50454f8f3c09a6c5a488a9fcd51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-musllinux_1_2_aarch64.whl

Download URL astli-0.2.0-py3-none-musllinux_1_2_aarch64.whl
Size 1.2 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
cd8507c0767596a8212e59b054f151db4441730799cbc1b06098e6784c423e1a
BLAKE2b-256 checksum
How to use checksums
a218b38f05265129e7bc0f142b6093836756c00ea0b8cd619c17263f9a7e9372
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-manylinux_2_28_x86_64.whl

Download URL astli-0.2.0-py3-none-manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
d7842c113c9ca051d11f513c636d4db58a5f46eeb3480ee8352900be429c10eb
BLAKE2b-256 checksum
How to use checksums
4997b6b14006f5a2511532ad89ffd509f04ae99d9ea384b4c2478923407277ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-manylinux_2_28_aarch64.whl

Download URL astli-0.2.0-py3-none-manylinux_2_28_aarch64.whl
Size 1.2 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
48b114ba7460166cd4f83491d7e4a30fe70f4be5485eed286025f67e677f6831
BLAKE2b-256 checksum
How to use checksums
ff01811cfd0f3133bea80b4bad80b213183b9b339a603f452c76e2e13ff6ec7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-macosx_11_0_arm64.whl

Download URL astli-0.2.0-py3-none-macosx_11_0_arm64.whl
Size 1.1 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ea53eccdec7fcd3f765406c3038b378d5de18aab5724f734c38598fae53578d1
BLAKE2b-256 checksum
How to use checksums
cc039bba51f10eaea2b8b54bf2ecf1df0ac3ec6f32c381cf1caa09dd08c1653b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / astli-0.2.0-py3-none-macosx_10_12_x86_64.whl

Download URL astli-0.2.0-py3-none-macosx_10_12_x86_64.whl
Size 1.1 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
079d607b359c840abb7203d5192e48585f0e779ab6e07df455f411b0018f29bd
BLAKE2b-256 checksum
How to use checksums
f131916543278d9e7440b8ee91edc2d1131da9ba4f18d68c3a838c551a6b0c08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.3.0

8 release files

This release

0.2.0 This release

8 release files

0.1.1

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page