Perform HLS from Rust
This crate uses bambu to synthesize Rust functions into HDL.
This crate is quite experimental, things may break. If you encounter problems please open an issue.
High-level synthesis is performed by ripping out a module that is annoted for hls and creating a new (temporary) crate that only contains that module.
The module is then compiled to LLVM IR.
The LLVM IR is then passed to bambu, which generates Verilog.
The Verilog file is then parsed by this crate and converted into a rust module containing a rust-hdl struct that wraps the HDL.
The rusthdlmacro crate then inserts the mod and use statements to use the synthsized module into the original crate.
You should add this crate to your [build-dependencies]
in Cargo.toml and add rust_hls_macro
to your [dependencies]
.
In your buildscript you should call rust_hls::Build::new().synthesize();
to synthesize all functions that are annotated with the hls macro (#[hls]
).
rust_hdl does not support to simulating embedded verilog.
To enable simulation you need to enable the "verilator"
feature on this crate.
This will integrate Verilator into the build process to allow simulation.
You need to have bambu installed locally to synthesize Verilog.
If you want to use verilator for simulations you need an old version of verilator installed. v4.108
works for me.
Especially the verilator version is quite tricky to get.
To get all dependencies you can use the nix package manager. nix develop github:zebreus/bachelor-thesis
to enter a shell with all dependencies installed. This may take a while as bambu will be compiled from source.
Build script:
rust
fn main() {
// Finds all modules annotated with `#[hls]` and generates synthesized versions of them
rust_hls::Build::new().synthesize();
}
```rust
pub mod yourmodule {
#[hls]
pub extern "C" fn yourfunction(a: u32, b: u32) -> u32 {
// You can insert any Rust code here
// The main restriction is that the code must never panic
// You cannot access things in your crate that are outside of your_module
// Accessing external crates is supported
a * b
}
}
// The macro will insert mod your_module_synthesized;
and use your_module_synthesized::YourFunction
here.
// The your_module_synthesized.rs
module is generated by the build script.
pub fn main() { // The generated module is the function name in PascalCase let mut device = YourFunction::new(); device.connectall(); let data = generateverilog(&device); std::fs::write("./multiplier.v", data).unwrap(); } ```
The hls macro has options for configuring rust_flags
and hls_flags
.
Currently there is not much more documentation than the rustdoc. If you need more documentation open an issue or an PR.
I am happy about any major or minor contributions.