Crates.io | rust_hls |
lib.rs | rust_hls |
version | 0.2.0 |
source | src |
created_at | 2023-04-19 08:59:30.281516 |
updated_at | 2023-06-21 15:44:00.035142 |
description | Support crate for rust_hls |
homepage | https://github.com/zebreus/bachelor-thesis/tree/master/bambu-macro/rust_hls |
repository | https://github.com/zebreus/bachelor-thesis |
max_upload_size | |
id | 843355 |
size | 171,758 |
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 rust_hdl_macro 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:
fn main() {
// Finds all modules annotated with `#[hls]` and generates synthesized versions of them
rust_hls::Build::new().synthesize();
}
#[rust_hls_macro::hls]
pub mod your_module {
#[hls]
pub extern "C" fn your_function(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.connect_all();
let data = generate_verilog(&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.