Introduction#

PeakRDL-Rust is a Python package which can be used to generate Rust code for accessing control/status registers from a SystemRDL definition.

Features:

  • Generates Rust types and accessor methods representing your hardware registers

  • Type-safe field access with compile-time guarantees

  • Includes component names and descriptions as doc comments in the generated code

  • Embedded-friendly code generation with no_std support

  • Preserves the hierarchical structure of SystemRDL

  • Supports complex nested regfiles, arrays, and memory components

  • Supports enumerated field types

  • Supports signed and fixed-point field types

Installing#

Install from PyPi using pip

python3 -m pip install peakrdl-rust[cli]

Or to integrate directly with your Rust code use the peakrdl-rust-build build utility crate.

Quick Start#

There are two primary ways to interact with this tool. The first (and recommended) way is by using the peakrdl-rust-build crate in your build.rs file.

// in build.rs
peakrdl_rust_build::Generator::new()
    .rdl_file("example.rdl")
    .top("example")
    .generate()
    .unwrap();

// in lib.rs
mod example {
    include!(concat!(env!("OUT_DIR"), "/example/mod.rs"));
}

The second way to use this tool is via the PeakRDL command line tool:

# Install the command line tool
python3 -m pip install peakrdl-rust[cli]

# Generate a Rust module in the example/ directory
peakrdl rust example.rdl -o example/

Using the generated Rust code, you can access your device registers in a type-safe manner. For example, the tool transforms this SystemRDL:

addrmap my_addrmap {
    reg {
        default sw = rw;
        default hw = r;
        field {} my_field1[15:0];
        field {} my_field2;
    } my_reg;
};

Into a Rust module you can use like:

registers: MyAddrmap = unsafe { MyAddrmap::from_ptr(/* some pointer */ as _) };

// read the register and print the values of its fields
let reg_value: MyReg = my_addrmap.my_reg().read();
println!("Register fields: {reg_value:?}");
let field1_value: u16 = reg_value.my_field1();

// read-modify-write to update a single field
my_addrmap.my_reg().modify(|value: &mut MyReg| {
    value.set_my_field2(1);
});

For more in-depth examples, see Examples.

Getting Started#

Ready to dive in? Here are the next steps:

  1. Examples - View generated Rust code for example inputs

  2. Generated Rust Code - Learn about the generated Rust code structure

  3. Configuring PeakRDL-rust - Customize the code generation to your needs

  4. Python API - Use PeakRDL-rust in your own Python scripts

For questions or issues, visit our issue tracker.