Generates Zig bindings for CMSIS-SVD files
- Zig 97.1%
- Nix 2.9%
| pkgs/svd2zig | ||
| svd2zig | ||
| test | ||
| .envrc | ||
| .gitignore | ||
| build.zig | ||
| build.zig.zon | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| main.zig | ||
| README.md | ||
| svd2zig.zig | ||
| treefmt.nix | ||
svd2zig
Generates Zig bindings from CMSIS-SVD files.
svd2zig parses an SVD device description and emits Zig source for its
peripherals, registers, fields, and enumerated values. It can be run standalone
or wired into a downstream zig build.
Styles
Pick the output shape with --style (default conduit):
conduit— each peripheral is a struct holding a conduitMmio, with register accessor methods over packed-struct field types. Read-only registers get only a reader, write-only only a writer. The SVDbase_addressis exposed andfromBase()builds anMmio.directover it.regz— standalone, microzig-regz-like: each peripheral is anextern structof registers laid at their offsets, reached through a typed volatile pointer in aperipheralsnamespace. A smallMmiohelper is emitted inline.consts— plain offset/shift/mask/enum constants in nested namespaces. No structs or accessors.
All styles handle derivedFrom, dim arrays, clusters, and enumeratedValues.
Input that cannot be represented faithfully is a hard error, not a silent gap.
CLI
svd2zig [--style conduit|regz|consts] <input.svd> [-o output.zig]
Writes to -o or stdout. Names are converted to Zig conventions (TitleCase
types, snake_case declarations), with Zig keywords escaped as @"...".
Using it from zig build
Add svd2zig as a dependency, then generate a module from your SVD:
// build.zig
const svd2zig = @import("svd2zig");
const svd2zig_dep = b.dependency("svd2zig", .{});
const regs = svd2zig.addGenerate(b, svd2zig_dep, .{
.svd = b.path("chip.svd"),
.style = .conduit,
.name = "regs",
});
exe.root_module.addImport("regs", regs);
Development
zig build test # unit, golden, and compile tests
nix flake check # the above, hermetically, plus formatting
Golden output lives in test/golden/. When an emitter change is intentional,
regenerate it:
zig build
for s in consts regz conduit; do
./zig-out/bin/svd2zig --style "$s" test/fixtures/minimal.svd -o "test/golden/$s.zig"
done