# QtRvSim: a RISC-V simulator built to be taught with

> QtRvSim is a RISC-V CPU simulator from the Computer Architectures Education project at the Czech Technical University, with a Qt interface, an integrated assembler, peripherals, register and interrupt views, and a WebAssembly build that runs in a browser. It accepts statically linked ELF binaries for RV32 and RV64 and traces them instruction by instruction.

**cvut/qtrvsim** — RISC-V CPU simulator for education purposes

- Repository: https://github.com/cvut/qtrvsim
- Stars: 645 · Forks: 96
- Language: C++
- License: GPL-3.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/cvut-qtrvsim

## A teaching tool, and the README says so first

QtRvSim is described as a RISC-V CPU simulator for education purposes, and the project was developed and extended as theses by Karel Kočí, Jakub Dupak and Max Hollmann at the Computer Architectures Education project at the Czech Technical University.

That origin explains the whole shape of the project. This is not a general purpose emulator and not a research platform. It exists so that a class of students can watch a RISC-V program execute and understand what the hardware is doing. Every design decision follows from that, including the deliberate omissions later in the README.

The most unusual feature is the WebAssembly build. QtRvSim is experimentally available for WebAssembly and can be run in most browsers without installation, at a hosted address. The README marks the WebAssembly version as experimental and asks that difficulties be reported through GitHub issues.

That is a genuinely useful property for the target audience. A course can put a link in a slide, and a student on a locked-down machine can still open the simulator without a build toolchain, without Qt and without a local install. For a teaching tool, the browser build removes almost all of the friction that would otherwise stop students from using it at all.

The primary language is C++ and the licence is GPL-3.0. The project is maintained under the cvut organisation, the last push was on 2026-09-29, and the current release is v0.9.9 from the same day, following v0.9.8 and v0.9.7 from 2024. The README also asks organisations using the tool to say so in a discussion thread, which tells you the audience includes universities.

## It takes ELF binaries, and the accepted set is narrow

The simulator accepts statically linked little-endian ELF executables compiled for the RISC-V target, and the accepted ISA range is spelled out precisely.

For 32-bit, the GCC options run from -mabi=ilp32 -march=rv32i up to rv32ima_zicsr. For 64-bit, from -mabi=lp64 -march=rv64i up to rv64ima_zicsr. The simulator executes them as XLEN=32 or XLEN=64 according to the ELF file header, and there is even initial support for endianness selection based on that header.

So this is a bare-metal simulator. There is no operating system, no bootloader and no system call layer beyond what the project itself provides for educational purposes. You compile a freestanding program, point the simulator at the ELF, and watch it run.

The toolchain is up to you. You can use a specialised RISC-V GCC and Binutils toolchain named riscv32-elf, or the unified Clang and LLVM toolchain with LLD, and the README notes that if you have Clang installed you do not need the specialised one.

There is one constraint on debugging that is easy to miss. Source-level navigation and the --trace-source option need -g -gdwarf-4. DWARF5 binaries still run, but source tracing is unavailable and a warning is shown. So if you are on a modern compiler emitting DWARF5 by default, the tracing feature is the thing that will not work, and the fix is a compiler flag rather than a simulator setting.

The list of currently supported instructions is its own section in the README, and one line in the feature summary is worth reading on its own: compressed instructions are not yet supported. For a course that covers the C extension, that is a gap, and the simulator is explicit about it.

## The integrated assembler and the external make support

Two features in the table of contents describe how code gets into the simulator, and they are what make it usable in a lecture rather than only in a lab.

The integrated assembler means you can write assembly in the interface itself and assemble it there, which removes the round trip of compiling on the command line and reloading. For a classroom, that is the difference between demonstrating an instruction and demonstrating a build.

The support to call an external make utility is the complement to that. It means a course can keep its examples as a Makefile and have the simulator drive the build, so the student sees the real toolchain and the simulator is the thing that runs the result.

The advanced functionality section lists what else is in the box. There are peripherals, an interrupts and control and status registers view, and system calls support. The CSRs matter for teaching, because reading and writing the status register is where privilege levels and interrupt handling become visible rather than abstract, and the documentation has a dedicated section for it.

So the tool is not only a CPU and a memory. It presents the parts of the machine a student needs to reason about: the registers, the interrupt and CSR machinery, the peripherals, and the system call path. The peripheral set is what the README describes as advanced functionality, and the actual list of peripherals is in the section itself rather than in the summary, so it is worth reading there before choosing it for a course that involves I/O.

The documentation lives in the README and in two subdirectories, docs/user and docs/developer, with a Resources and Publications section that links the theses the project grew out of.

## Building it needs Qt, CMake and the submodules

The build dependency list is short: Qt 6 or Qt 5, with a minimal tested version of 5.9.5.

The clone has to be recursive because the project vendors its dependencies as submodules.

```shell
git clone --recurse-submodules https://github.com/cvut/qtrvsim.git
```

And an existing checkout can be repaired with the submodule update command.

```shell
git submodule update --init --recursive
```

A pull on an existing clone has to bring the submodules along too.

```shell
git pull --recurse-submodules
```

The general compilation is CMake, and the binaries land in a target directory inside the build directory.

```shell
cmake -DCMAKE_BUILD_TYPE=Release /path/to/qtrvsim
make
```

If no build type is supplied, Debug is the default, and the Debug build includes sanitizers, which is the one you want while developing the simulator itself rather than while using it.

On Linux there is a wrapper Makefile in the project root that creates a build directory and runs CMake in it, with release as the default target and debug as the other. The note for packagers matters if you are packaging: that Makefile is deleted by CMake when the source archive is created, to avoid any ambiguity, and packages should invoke CMake directly. The generated source archive vendors all submodule contents and can be built without Git metadata or network access, which is what makes the distribution packages reproducible.

On macOS you install Xcode, run xcode-select --install for the command line tools, accept the licence, choose an SDK version, then install Qt through Homebrew with brew install qt, and macOS builds must use the bundled libelf. After that the general compilation applies.

The tests are managed by CTest, and the sequence to run them is the same build plus ctest.

## Packaging is broad, and the WebAssembly build has its own targets

The distribution picture is unusually wide for a university project, and it is the part that makes the tool usable beyond one lab.

Binary packages come from the GitHub releases page, which has archives with Windows and generic GNU/Linux binaries, from the openSUSE Build Service repository, from the Open Build Service download page, and from an Ubuntu PPA.

```bash
sudo add-apt-repository ppa:qtrvsimteam/ppa
sudo apt-get update
sudo apt-get install qtrvsim
```

A repology badge tracks how many distributions package it, and the openSUSE build service result badge points at the package build for home:jdupak.

There is also a Nix package provided as part of the repository, and the README says updates have to be done manually by checking out the git, with the nixpkgs package still in the pull request phase.

```shell
nix-env -if .
```

The WebAssembly build has its own set of Makefile targets, and they explain what the browser version costs. The wasm target runs a shell script from extras/building that takes the Emscripten version, the Qt WASM path and the EmsDK path as arguments. There is a wasm-clean target, a wasm-clean-deep that clears the emscripten cache directories, a wasm-serve target that copies the data files into the build target and starts a Python HTTP server because a server is necessary due to CORS, and a wasm-install-qt target that uses the aqt installer to put the Qt WASM build in place.

The CORS note is the tell that the browser build is a real engineering effort rather than a convenience wrapper: serving the compiled output over a local HTTP server rather than opening it from the filesystem is a requirement, not a stylistic choice.

The repository root shows the rest of the layout: a CMakeLists.txt, the top level Makefile, a cmake/ directory, an external/ directory for the vendored dependencies, an extras/ directory holding the WASM build scripts, a src/ directory, a tests/ directory, a data/ directory, docs/, a default.nix, a .clang-format, a qtlogging.ini and a .dev-config.local.mk that the Makefile includes.

## Where QtRvSim is the wrong tool

The first wrong-tool case is a developer who wants to run a real RISC-V system. QtRvSim simulates the CPU and a set of peripherals for teaching, and it does not boot Linux, run a filesystem or emulate a full SoC with a UART and a network card. If the goal is running an operating system, you want a system emulator, and the README does not claim to provide one.

The second case is a course that covers the compressed instruction extension. The README states plainly that compressed instructions are not yet supported, and that is a significant gap for any course content on the C extension, which is part of the standard RISC-V profiles.

The third case is a student or a lecturer who expects a hosted, always-current service. The WebAssembly build is explicitly marked experimental, and the Nix package needs manual git checkouts, so the supported path for a classroom is still a local build or a downloaded binary. A course that wants the students on a locked-down machine to have it working in five minutes gets that from the hosted app, but the documentation is clear that this is a preview.

There is also the licensing dimension for a commercial or institutional use. The project is GPL-3.0, so a university can use and modify it freely, and a company distributing a modified build as a binary has source obligations. The README's ask to organisations to say so in a discussion thread is a good sign about the community's attitude to institutional use, but it is not a licence grant beyond what GPL-3.0 provides.

What you get in exchange is a simulator that makes the machine state visible. The register view, the CSR and interrupt view, the integrated assembler, the source-level tracing and the step-by-step execution are the reason a lecturer would pick this over a text-mode emulator, and the browser build is the reason a student would not have to install anything to try it.

## Conclusion

QtRvSim suits a computer architecture lecturer or a student who needs to step through RISC-V instructions and see the register file change, because it presents the machine state rather than a black box. It does not suit a developer who wants a full system emulator, since there is no operating system to boot and no full instruction set coverage. Before adopting, check the supported instruction list for the extensions your course needs, since compressed instructions are not yet supported, and build with the WebAssembly target if the point of the tool is to let students run it without installing anything.

## FAQ

### What is QtRvSim?

QtRvSim is a RISC-V CPU simulator for education, developed by the Computer Architectures Education project at the Czech Technical University. It provides a Qt interface, an integrated assembler, peripherals, control and status register views, system call support and source-level tracing.

### How do I build QtRvSim from source?

Clone the repository with --recurse-submodules, then configure with cmake -DCMAKE_BUILD_TYPE=Release pointing at the project root and run make. The binaries end up in the target directory of the build directory, and Debug is the default build type if none is supplied.

### Which binaries does the QtRvSim simulator accept?

Statically linked little-endian ELF executables for RISC-V, either 32-bit with -mabi=ilp32 -march=rv32i up to rv32ima_zicsr or 64-bit with -mabi=lp64 -march=rv64i up to rv64ima_zicsr. The simulator picks XLEN=32 or 64 from the ELF header, and compressed instructions are not yet supported.

### Can I run QtRvSim in a browser?

Yes, experimentally. A WebAssembly build is available and runs in most browsers without installation, and the Makefile has wasm targets for building it, serving it over a local HTTP server for CORS reasons and installing the Qt WASM build.

### What license is QtRvSim released under?

The project is licensed under GPL-3.0, with the LICENSE file at the root of the repository. The current release is v0.9.9, tagged on 2026-09-29, and binary packages are published for Windows, GNU/Linux, openSUSE and Ubuntu.

## Sources

- [cvut/qtrvsim on GitHub](https://github.com/cvut/qtrvsim)
- [Issues](https://github.com/cvut/qtrvsim/issues)
- [License: GPL-3.0](https://github.com/cvut/qtrvsim/blob/master/LICENSE)
- [README](https://github.com/cvut/qtrvsim/blob/master/README.md)
- [Releases](https://github.com/cvut/qtrvsim/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cvut-qtrvsim
