Skip to content

Comments

Add slang bindings and pickle command#264

Open
fischeti wants to merge 34 commits intomasterfrom
fischeti/slang-pickler
Open

Add slang bindings and pickle command#264
fischeti wants to merge 34 commits intomasterfrom
fischeti/slang-pickler

Conversation

@fischeti
Copy link
Contributor

@fischeti fischeti commented Jan 28, 2026

This PR introduces first-class Slang integration to Bender via a new bender-slang crate and adds the new pickle command for preprocessing/rewrite/emit workflows on SystemVerilog sources.

Slang bindings

Slang is vendored in as a submodule and built with CMake during crate build, then linked statically into bender-slang (see build.rs)

Slang has a couple of other library dependencies (e.g. mimalloc, fmt) which are fetched by cmake and also statically linked to improve portability of the bender binary (at the expense of binary size). Those libraries are force-fetched to prevent using preinstalled system-libaries. I also investigated linking of libc++ statically, but this depends on the OS:

  • macOS: Only allows dynamic linking of libc++ apparently. But it never caused any problems so far.
  • Linux: build.rs tries to link libc++ statically, if no libstdc++.a exists, it falls back to dynamic linking. The idea was that this would also allow to run pre-compiled bender on older linux distributions without newer C++ features (Slang requires C++ 20)
  • Windows: Linked dynamically, could be possible to link statically I guess but it was not worth the effort to me.

Rust/C++ bridge design

The bindings between C++ and Rust are created with the cxx crate (from the one and only dtolnay). It allows to access native types from both sides (e.g. Rust's String and C++'s std::string), and cxx generates the necessary glue code underneath. It also statically checks at compile time for ABI mismatches etc.

You just need to create a bridge i.e. lib.rs on the Rust side and slang_bridge.h on the C++ side that define the FFI. Additionally, lib.rs wraps the FFI to provide a more idiomatic Rust API.

The pickle command

pickle is the first feature to use the Slang binding in the following way:

Source collection

  • Uses Bender manifest-driven source ordering/groups
  • Supports additional external files via CLI positional args
  • Supports additional include dirs (-I) and defines (-D)
  • Non-Verilog files (e.g. VHDL/unknown) are skipped with warnings

--top trimming

  • Supports one or more top modules via --top
  • Trimming granularity is syntax tree/file level, matching slang --depfile-trim behavior:
    • if a file defines multiple modules, it is retained/dropped as a whole
  • Finer-grained declaration-level stripping is theoretically possible but would require deeper AST rewriting and is deferred for now.

Renaming with --prefix and --suffix

  • Prefix/suffix rename support for modules/packages/interfaces
  • Explicit exclusions via --exclude-rename

Print options

Re-emitting the SV code from the syntax trees can be done with the following (self-explanatory) options currently:

  • --expand-macros
  • --strip-comments
  • --squash-newlines

Includes are always printed. Furthermore it is possible to print the Syntax trees instead of emitting SV code with --ast-json.

Error/Warning behaviour

  • Slang emits built-in diagnostics itself
  • Slang parse failures are propagated into Bender as structured errors, and command exits with failure
  • It would be possible to support permissive mode (e.g. downgrade to warnings), but not part of this PR

Related Changes

File type classification to (e.g. SourceType::Verilog) was moved from script.rs to sess.rs.

Open questions/TODOs

  • bender-slang currently is a path dependency and likely needs to be published as well. Otherwise cargo install -F slang will not work, only from source installation is supported.
  • Test and Release builds are WIP and in separate PRs (see below)

This is part 1 of 3 in a stack made with GitButler:

@fischeti fischeti force-pushed the fischeti/slang-pickler branch 2 times, most recently from faf42ab to a8e840c Compare January 29, 2026 11:29
@micprog micprog force-pushed the fischeti/slang-pickler branch from 448dbbf to d92fb2f Compare January 29, 2026 16:04
@fischeti fischeti force-pushed the fischeti/slang-pickler branch 2 times, most recently from 7dd5086 to ac6988a Compare January 30, 2026 15:21
@fischeti fischeti force-pushed the fischeti/slang-pickler branch 3 times, most recently from 95757fe to 79a2d1d Compare February 5, 2026 23:40
@fischeti fischeti force-pushed the fischeti/slang-pickler branch 15 times, most recently from d58af79 to 9ed2027 Compare February 17, 2026 11:04
@fischeti fischeti force-pushed the fischeti/slang-pickler branch from 9ed2027 to 6477e78 Compare February 17, 2026 12:25
@fischeti fischeti changed the title Add slang bindings and pickler Add slang bindings and pickler Feb 17, 2026
@fischeti fischeti changed the title Add slang bindings and pickler Add slang bindings and pickle command Feb 17, 2026
@fischeti fischeti force-pushed the fischeti/slang-pickler branch from 038b5fa to 3795c0a Compare February 17, 2026 17:16
micprog and others added 28 commits February 18, 2026 09:32
Will result in ABI mismatches i.e. segfaults otherwise
Prevent multiple inclusion of the header by adding a traditional
#ifndef/define/endif include guard (BENDER_SLANG_BRIDGE_H). This
replaces the lone #pragma once for better portability and ensures the
header can be safely included multiple times across translation units.
Introduce safe wrapper types for the opaque FFI objects and move the
extension methods into proper Rust structs to provide a clearer,
idiomatic API and safer ownership semantics.

- Add SyntaxTree wrapper around SharedPtr<ffi::SyntaxTree> with Clone,
  display, as_debug, rename, and fmt impls (Display/Debug).
- Add SlangContext wrapper around UniquePtr<ffi::SlangContext> with new,
  set_includes, set_defines, and parse returning a SyntaxTree.
- Replace new_session() to return SlangContext instead of raw pointer.
- Update callers: remove use of extension traits and change formatting
  at pickling to use Debug/Display impls (write!("{:?}", renamed_tree)).
bender-slang: Fix windows build 2
@fischeti fischeti force-pushed the fischeti/slang-pickler branch from 3795c0a to f295d10 Compare February 18, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants