Crates.io | hw_regmap |
lib.rs | hw_regmap |
version | 0.1.0 |
created_at | 2025-05-09 08:26:21.041894+00 |
updated_at | 2025-05-12 12:42:54.898428+00 |
description | hw_regmap: A register map generation tool. |
homepage | https://zama.ai/ |
repository | https://github.com/zama-ai/hw_regmap |
max_upload_size | |
id | 1666604 |
size | 156,100 |
This repository contains a Hardware register map generation tool. Based on a TOML definition, this utility generates:
The main purpose is to ease the user experience on writing and using a register map. For example, inference, respecting a set of properties, is applied when an option is not specified. Property violations are reported by the tool with explicit and understandable error messages.
Register map is described with a hierarchical structure:
Define the general properties of the register map. Some entries are optional and are automatically computed. Available properties are:
0
]Registers are organized in sections. A section gathers sensible registers together, at a given address offset. Available properties are:
description: String describing the content of the section
offset: Offset of the section in the register map (byte-unit) [Optional][Default automatic
]
range: Range of addresses covered by the section (byte-unit) [Optional][Default automatic
]
bytes_align: Required address alignment for the section (byte-unit) [Optional][Default automatic
]
duplicate: Multiple instances with same set of registers. The argument is a list of suffix to be applied on the section name [Optional][Default None
]
Fine control of register read/write access is possible. Corresponding SystemVerilog code is implemented. Available properties are:
{Cst=0}
]automatic
]automatic
]Example 1: register exposing a RTL parameter to the user.
[section.rtl_properties.register.version]
description="Version of the current hardware"
owner="Parameter"
read_access="Read"
write_access="None"
default={Param="VERSION"}
Example 2: register storing runtime configuration defined by the user.
[section.rtl_properties.register.timeout_cnt]
description="Wrapping value of the timeout counter"
owner="User"
read_access="Read"
write_access="WriteNotify"
default={Cst=0x0000FFFF}
Example 3: register exposing performance counter.
[section.rtl_properties.register.perf_cnt]
description="Performance counter. Reset on Read"
owner="Kernel"
read_access="ReadNotify"
write_access="None"
A field is an optional property of registers. A Register can be composed of several fields. A set of functions is available to retrieve/update registers with a field aware method. A field has a name. Available field properties are:
automatic
]{Cst=0}
]Example: register describing the HW version, seen as composed by 3 fields:
[section.rtl_properties.register.version]
description="Version of the current HW"
owner="Parameter"
read_access="Read"
write_access="None"
field.vendor_id = { size_b=16, offset_b=0 , default={Cst=0xdead}, description="Vendor Id"}
field.major = { size_b=8, offset_b=16 , default={Param="MAJOR_REV"}, description="Major version number"}
field.minor = { size_b=8, offset_b=24 , default={Param="MINOR_REV"}, description="Minor version number"}
To generate RTL sources, the TOML register map is parsed by the tool. Missing optional fields are computed. The defined and inferred values are checked in compliance with a set of properties. A concrete register map is then built in memory and a set of Tera templates are used to convert it in a SystemVerilog description. The set of provided Tera templates can be easily edited by the user to adapt the generated construct to specific application needs.
This repository could be used as an external library. It enables software to digest the register map definition and provides a flat-map view of it for easy Register
to Address
translation.
This way, the same TOML description can be used for RTL generation and inside the SW driver.
From a SW perspective, the TOML definition can be parsed in a flat hash table that enables the SW to get register content from a name.
// ~~ ---
let reg = regmap
.register()
.get("rtl_properties::version")
.expect("Unknown register, check regmap definition");
let val = ffi_hw.read_reg(*reg.offset() as u64);
let fields = reg.as_field(val);
let vendor_id = *fields.get("vendor_id").expect("Unknown field");
let major_version = *fields.get("major").expect("Unknown field");
let minor_version = *fields.get("minor").expect("Unknown field");
// ~~ ---
The config folder contains some examples that show register map capabilities.
Example picturing available syntax flavors. A monolithic register map is generated.
cargo run -- --output-path gen --toml-file config/example.toml
Example playing with offset features. Offset can be fixed or computed by the tool.
cargo run -- --output-path gen --toml-file config/debug/offset.toml
Example demonstrating the multi-regmap capability. Register map can be split into multiple RTL modules to ease physical place and route. The tool enforces the overall coherency of the generated addresses while generating multiple RTL modules.
cargo run -- --output-path gen --toml-file config/debug/many/slice_a.toml --toml-file config/debug/many/slice_b.toml