peakrdl-cpp is a PeakRDL exporter plugin that generates C++ register access APIs
from SystemRDL designs.
python3 -m venv .venv
. .venv/bin/activate
pip install -e .Install from PyPI (after first release):
pip install peakrdl-cppGenerate a C++ header from an RDL file:
peakrdl cpp design.rdl -o regs.hpp \
--namespace my_block \
--class-name MyBlock \
--error-style exceptionsUse the Python API directly:
from systemrdl import RDLCompiler
from peakrdl_cpp import CppExporter
compiler = RDLCompiler()
compiler.compile_file("design.rdl")
root = compiler.elaborate()
CppExporter().export(
root.top, # RootNode also works
"regs.hpp",
namespace="my_block",
class_name="MyBlock",
error_style="exceptions", # or "status"
check_write_range=True, # optional, defaults to True
)Generated API shape:
- Hierarchical object access with array indexing:
my_root.regfile_1[3].sub_regfile.example_reg.field.write(13);auto v = my_root.regfile_1[3].sub_regfile.example_reg.field.read();
- Field APIs respect
swaccess rules:sw=r: nowrite()sw=w: noread()
- Shadow API:
field.rd_shadow.read()(reads register read-shadow)field.wr_shadow.read()/field.wr_shadow.write(...)(reads/updates register write-shadow)reg.rd_shadow.read_hw(),reg.wr_shadow.flush(),reg.wr_shadow.flush_always()regfile.rd_shadow.read_hw(),regfile.wr_shadow.flush(),regfile.wr_shadow.flush_always()addrmap.rd_shadow.read_hw(),addrmap.wr_shadow.flush(),addrmap.wr_shadow.flush_always()
- Hard generation error on reserved symbol conflicts (for example
rd_shadoworwr_shadow). - Error handling style:
--error-style exceptionsthrowsstd::runtime_error--error-style statusrecords errors and exposesok()/last_error()/clear_error()- In
exceptionsmode these status methods still exist, but are mainly useful instatusmode.
- Write range validation:
- enabled by default
- disable with
--no-write-range-checkto skip generated runtime range checks onwrite()andwr_shadow.write() write()/wr_shadow.write()accept both signed and unsigned integral input types regardless of field signedness.
- Access width:
data_tis deduced from SystemRDLaccesswidth.- If more than one numeric
accesswidthis present in the design, generation fails. - Registers may be wider than
accesswidthup to 64 bits. Multiword readable registers requirebuffer_reads=true; multiword writable registers requirebuffer_writes=true. - Fields wider than
data_tuse compactstd::array<data_t, N>values in generated read/write/shadow APIs. addr_tis fixed tostd::uint32_t.
Bus adapter requirements:
data_t read(addr_t addr);void write(addr_t addr, data_t value);- This contract is currently documented but not yet enforced via C++ concepts/static constraints.
See checked-in example case:
. .venv/bin/activate
pip install -e ".[test]"
pytestRun adaptive compile/run checks against an external RDL file:
PEAKRDL_CPP_TEST_RDL=/abs/path/to/design.rdl \
./.venv/bin/pytest -q tests/test_exporter_adaptive.pyOptional deterministic seed override:
PEAKRDL_CPP_TEST_RDL=/abs/path/to/design.rdl \
PEAKRDL_CPP_TEST_SEED=42 \
./.venv/bin/pytest -q tests/test_exporter_adaptive.pyThe test suite includes end-to-end validation:
- compile RDL
- generate C++
- compile and link C++ test bench against generated headers
- execute runtime behavior checks
Release instructions are documented in RELEASE.md.
LGPL-3.0 (GNU Lesser General Public License v3.0). See LICENSE.
Generated output exception:
- Output generated by this project (for example, generated C++ headers/sources) may be used, copied, modified, and distributed under terms of your choice, including proprietary terms.
- This exception does not change the license of this project's own source code.
- The exception is provided as an additional permission under GNU GPLv3 section 7 (as incorporated by LGPLv3).