Pages

Tuesday, August 4, 2026

Bringing the RISC-V Simulator into VS Code

One of the goals of my RiscV toolchain project has always been more than simply generating RISC-V assembly.

I want to build a complete toolchain that makes writing, compiling, and debugging RISC-V programs feel natural. This week, I reached another milestone: my RISC-V simulator can now debug programs directly inside Visual Studio Code.

Seeing breakpoints, registers, and single-step execution inside VS Code is surprisingly satisfying. It makes the project feel much closer to a real development environment.

 


Why a VS Code Debugger?

When developing a compiler, debugging generated assembly is just as important as generating it.

Previously, my workflow looked something like this:

  1. Compile C source code.
  2. Generate RISC-V assembly.
  3. Run the simulator.
  4. Print register values.
  5. Repeat.

That works for small programs, but it quickly becomes painful as the compiler grows.

Having an interactive debugger completely changes the experience.

Instead of inserting print statements everywhere, I can now:

  • set breakpoints
  • single-step through instructions
  • inspect registers
  • follow the execution flow
  • verify generated assembly interactively

It dramatically shortens the feedback loop when tracking down compiler bugs.

Using the Debug Adapter Protocol

Rather than inventing my own debugger UI, I decided to integrate with Visual Studio Code's Debug Adapter Protocol (DAP).

This means the extension can take advantage of the debugger interface that developers already know.

Currently the debugger supports:

  • launching a RISC-V program
  • breakpoints
  • stepping through instructions
  • viewing all integer registers
  • inspecting the current execution point
  • displaying the call stack

Because the simulator acts as the debugging backend, every instruction executed is under complete control of the debugger.

Connecting the Pieces

This project has gradually evolved into several independent components that now work together:

C Source

     │

    

 C Compiler

     │

    

RISC-V Assembly

     │

    

Simulator

     │

    

 VS Code Debugger

Each component was originally developed independently.

Connecting them together has been one of the most rewarding parts of the project.

When I hit F5 in VS Code, the debugger launches the simulator, loads the executable, and immediately allows me to step through the generated instructions.

That is a much nicer workflow than running individual command-line tools.

The Screenshot

The screenshot below shows the debugger paused on an instruction.

On the left, VS Code displays the complete register set.

On the right, the current instruction is highlighted while breakpoints are shown directly in the editor.

Watching the register values change after each instruction has already helped me identify several code-generation issues that would have been much harder to diagnose otherwise.

 

No comments: