Self-hosted service
riscv/riscv-debug-spec avatar
riscv/riscv-debug-spec

riscv-debug-spec: the RISC-V Debug Specification as a buildable document

RISC-V Debug Specification Standard

530 stars101 forksPythonNOASSERTION

At a glance

What is it?
The RISC-V Debug Specification is a ratified standard written in AsciiDoc, with a Makefile that builds the PDF and two extra targets that emit machine readable register definitions for C and for Scala. It suits anyone implementing or verifying a RISC-V debug transport, and it is a specification document rather than an implementation, so there is nothing here to link against.
Who is it for?
Adopt this repository if you are implementing a RISC-V debug transport, a debug module or a trigger unit, because it is the normative source for the register layout and the abstract commands, and the `make debug_defines` target turns that into C constants you can compile against.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 57 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the specification covers, and who implements it

This repository holds the source of the RISC-V Debug Specification, the standard that describes how a RISC-V core is debugged.

The scope is visible in the file names at the root of the tree, and it is broader than the word debug suggests. There is `debug_module.adoc` for the debug module, `dtm.adoc` for the debug transport module, `jtagdtm.adoc` for the JTAG variant of that transport, `Sdext.adoc` for the external debug support, `Sdtrig.adoc` for the debug trigger module, `debugger_implementation.adoc` for how an implementation is expected to behave, `registers.py` for the register definitions, and `overview.adoc`, `introduction.adoc`, `preamble.adoc` and `preface.adoc` for the front matter. There is a `fig/` directory for the figures, a `xml/` directory, a `docs-resources` directory, and `future.adoc` for material that is not yet normative.

So the document defines a layered system: a debug module with registers that sit in the implementation's address space, a transport module that carries commands to it, an external support interface for a debugger on the other side of that transport, and a trigger module for signalling events into the debug logic. `implementations.adoc` then says what a conforming implementation must do.

The audience is therefore two groups. One writes hardware: a core designer or a debug module implementer who needs the exact register offsets, field positions and abstract command encodings. The other writes software on top: a debugger, a GDB stub, a simulation environment or a test harness that has to drive that hardware the same way anyone else does.

The release history shows the document has reached ratified status. The releases are 1.0, marked Specification Ratified and dated 2025-02-21, preceded by 1.0.0-rc4 from 2024-12-10 and 1.0.0-rc3 from 2024-05-15. The repository is not archived, and the last push to the tree was on 2026-08-26.

The two build targets that turn prose into code

The most useful thing in this repository is not the PDF. It is the pair of make targets that extract the register definitions from the specification and emit them as source code.

The first is `make debug_defines`. It creates a C header and implementation files containing constants for addresses and fields of all the registers and abstract commands, as well as functions and structures used to decode register values. The README points at `debug_reg_printer.c/h` as an example of such a decoder, and both of those files sit at the root of the repository, so the format of the generated output is visible without running anything.

The second is `make chisel`. It creates Scala files for DM registers and abstract commands with the same information. Chisel is a hardware description DSL, and the point of the target is the same as the C one: a hardware engineer implementing the debug module in Chisel should not be transcribing register offsets out of a PDF by hand, and now does not have to.

The design decision worth naming is that the source of truth is the prose. The register descriptions live in the AsciiDoc, and the generator reads them. That means a change to the specification and a change to the generated constants cannot drift apart, because there is only one place where the information is written down. A tool that instead shipped a header file next to a PDF would have two sources of truth, and the header would be wrong the moment someone edited the text.

It also means the generated files are a build output rather than a committed artefact, and the `registers.py` file at the root is the script that does the work. A contributor who adds a register to the specification gets the C constants and the Scala definitions for free, which lowers the barrier to keeping an implementation in sync with the standard.

Building the PDF: a container image and a submodule

The build instructions assume a container, because the document toolchain is heavy and the project publishes an image with it already assembled.

The steps are: install Docker and python3-sympy if they are not installed already, pull the RISC-V Docs container image, clone the repository, optionally check out a specific revision, initialise the submodules, then run make in the build directory.

bash
# Install docker and python3-sympy, if not installed already.

# Pull the latest RISC-V Docs container image:
docker pull riscvintl/riscv-docs-base-container-image:latest

git clone https://github.com/riscv/riscv-debug-spec.git
cd riscv-debug-spec

# Optionally, check out a specific revision:
# git checkout <rev>

git submodule update --init --recursive

cd build
make

The submodule step matters, because the `.gitmodules` file at the root and the `build/` directory in the tree tell you that the AsciiDoc build pulls in external content, and the recursive flag is needed for that to work.

The `git checkout <rev>` line is commented out in the instructions but kept in the text, and its presence is a hint about how this repository is used in practice. Pinning a revision is how you build the specification version that matches the hardware you care about, rather than whatever is at the head of the branch. For a standard that has been ratified, and whose release history includes several release candidates before ratification, that distinction is not academic.

The README also lists two places to find a ready made PDF: the latest release candidate on the releases page, and a release PDF on the `release` branch, which the README annotates as outdated at this point and of historical interest only. So the honest reading is that the pre-built artefacts are a convenience for reading, while the build instructions are what you use when you need the version that matches your implementation.

Contributing, and the membership condition on pull requests

The contributing section is short and contains one condition that shapes the whole process.

Pull requests will only be reviewed and accepted from RISC-V Foundation members. That is stated plainly, and it is the defining constraint on the project. The specification is not a wiki that anyone can patch; changes to a ratified architecture standard go through a process with a membership gate, which is a different kind of governance from an ordinary open source project.

Within that constraint there are three routes, and the README ranks them. Making a PR is described as the best way to deal with minor typos and edits. Filing an issue with something you want to know or see is the second option. Discussing higher-level questions or ideas on the riscv-debug-group mailing list at lists.riscv.org is the third, and it is the one that suits design discussions rather than text changes.

The split is sensible on its own terms. A typo fix is a diff, and reviewing a diff is cheap. A question about whether a field should be reserved is not a diff, and settling it in a mailing list avoids a pull request that would need a maintainer to argue about the design rather than the wording.

For additional information, the README points at the debug task group repository at github.com/riscv/debug-taskgroup, and the homepage of the project is the Atlassian tracker at riscv.atlassian.net/browse/RVG-94. The task group repository is where the wider work of the debug specification lives, and the tracker is where the individual review items are managed.

Where a specification stops and an implementation begins

The limitation of this repository is inherent to what it is, and it is worth being precise about it.

First, it is a document, not an implementation. There is no library to link, no reference code to run, and no simulator. If you are looking for a working debug transport, a debug module RTL, or a GDB remote stub, none of that is here. The only executable artefacts are the generated constant files and the PDF, and the `debug_reg_printer.c/h` pair is described as an example of a decoder rather than as a product.

Second, the generated constants are only as good as the specification revision you built. This is the practical trap. The release history contains 1.0.0-rc3, 1.0.0-rc4 and then the ratified 1.0, and the released PDF on the `release` branch is described as outdated. A hardware team that built against a release candidate and a software team that built against the ratified version can find themselves with different register layouts, and the mismatch will not announce itself. This is why the build instructions keep the `git checkout <rev>` line, and why the generated headers should be regenerated from the same commit the hardware was verified against.

Third, the specification is deliberately not an implementation guide in the sense a software developer might want. `implementations.adoc` says what a conforming implementation must do, and `future.adoc` holds what is not yet normative, but the document does not tell you how to write a driver for it, how to sequence the commands, or what a debugger is expected to do first. That knowledge lives in the implementers' repositories and in the debug task group's other work.

The alternative approach is to write the register definitions by hand from the PDF and keep them in your own tree. The difference in approach is direct. A hand-maintained header drifts from the standard the first time the standard changes and nobody notices, because the header still compiles and the hardware still responds. The generated approach costs you a build step and a container, and it makes the specification the single source of truth. For a team implementing the debug spec, that trade is usually obvious.

Editorial conclusion

Adopt this repository if you are implementing a RISC-V debug transport, a debug module or a trigger unit, because it is the normative source for the register layout and the abstract commands, and the `make debug_defines` target turns that into C constants you can compile against. Do not adopt it as a software dependency, since it produces documents and generated constants rather than a library, and the released PDF on the `release` branch is described as outdated and of historical interest. Before you rely on it, check that the commit you are building from matches the specification version your silicon implements, because the ratified 1.0 release and the release candidates in the repository history are not the same thing.

Frequently asked questions

How do I build the RISC-V Debug Specification PDF?

Install Docker and python3-sympy, pull the container image with `docker pull riscvintl/riscv-docs-base-container-image:latest`, clone the repository, run `git submodule update --init --recursive`, then run make in the `build` directory.

Can the RISC-V debug spec generate code instead of just a PDF?

Yes. `make debug_defines` creates a C header and implementation files with constants for the addresses and fields of all registers and abstract commands, plus decoder functions and structures, and `make chisel` creates Scala files for DM registers and abstract commands with the same information.

Who can contribute changes to the RISC-V Debug Specification?

The README states that pull requests will only be reviewed and accepted from RISC-V Foundation members. It also lists filing an issue and discussing higher-level questions on the riscv-debug-group mailing list as the other two ways to contribute.

Where can I find a pre-built PDF of the RISC-V Debug Specification?

The README points to the latest release candidate on the GitHub releases page, and to a release PDF on the `release` branch, which it notes is outdated at this point and of only historical interest.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. riscv/riscv-debug-spec on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/riscv-riscv-debug-spec.svg)](https://hysenlabs.com/projects/riscv-riscv-debug-spec)

Was this useful?