SVD Generator
svd-generator is a project to generate SVD register definitions from a Flattened DeviceTree (.dtb) file.
It originally started as a fork of a Python project from SiFive, called cmsis-svd-generator.
Currently, there are a limited number of peripherals with known register definitions, based on those present on StarFive VisionFive2 compatible boards.
Other boards based on the JH7110 Soc from StarFive may also work, like the Star64 devboard from Pine64, the Milk-V Mars, etc.
The long-term goal of the project is also to support more input formats, like various flavors of HDL (VHDL, Verilog, SystemVerilog, etc.). However, not only will that require a parser for each format, but will also likely need a custom comment/attribute markup language to encode the necessary information.
Giant shoulders
The following is a list of dependencies used in svd-generator:
- svd-rs
- svd-encoder
-
- friendly fork of fdt
- clap
- log
- env_logger
What good is an SVD?
On its own, not much. However, with code-generation tools, SVD is a remarkably powerful description language.
svd2rust, and similar code-generation projects in the Rust ecosystem, generates a PAC (peripheral access crate) from an input SVD file.
This code-generation step replaces an enormously repetitive and tedious task with automation.
The generated PAC provides idiomatic Rust types and functions for manipulating peripheral registers.
Why not use a vendor SVD?
CMSIS-SVD was originally developed for ARM, but is also becoming common for RISC-V platforms.
Vendored SVD files, when they exist, are often full of bugs.
Much more frequently, the vendor will not even supply an SVD file, or require some pre-existing support contract and/or NDA for access.
However, especially for development boards, DeviceTree files are usually included in the vendor SDK.
Then why not just use the DeviceTree file?
DeviceTree is a great description language for:
- matching the board model
- enumerating peripherals present on the board
- getting basic information like memory regions, interrupts, etc.
Unfortunately, it is not intended to fully describe the hardware.
For example, Linux loads the basic parameters from the DeviceTree to compile drivers for each peripheral.
But we don’t have Linux drivers :(
How it all works
So, svd-generator stands as somewhat of a middleware tool to gather register definitions for known peripherals, and output a well-formed SVD file.
We parse the DeviceTree file in a similar way to an OS/firmware, in order to know which peripherals are present.
Then, for peripherals with known register definitions, we generate the necessary SVD data structures using the svd-rs crate.
Peripheral register definitions can come from vendor technical reference manuals, OS/firmware drivers, HDL files...
Really, any reliable source that provides valid register information can be used to manually create a peripheral module.