Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.

Another RISC-V ISA simulator.

This code is suitable to hard refactor at any time

This is another RISC-V ISA simulator, this is coded in SystemC + TLM-2. It supports RV32IMAC Instruction set by now.

travis Codacy Badge Coverity Scan Build Status license last commit commit activity Docker Twitter URL

Table of Contents


Brief description of the modules:

  • CPU: Top entity that includes all other modules.
  • Memory: Memory highly based on TLM-2 example with read file capability
  • Registers: Implements the register file, PC register & CSR registers
  • Instruction: Decodes instruction type and keeps instruction field
  • BASE_ISA: Executes Base ISA, Zifencei and Zicsr.
    • C_extension: Decodes & Executes Compressed instructions (C extension)
    • M_extension: Decodes & Executes Multiplication and Division instructions (M extension)
    • A_extension: Decodes & Executes Atomic instructions (A extension)
  • Simulator: Top-level entity that builds & starts the simulation
  • BusCtrl: Simple bus manager
  • Trace: Simple trace peripheral
  • Timer: Simple IRQ programable real-time counter peripheral
  • Debug: GDB server for remote debugging (Beta)

Helper classes:

  • Performance: Performance indicators stores here (singleton class)
  • Log: Log class to log them all (singleton class)

Current performance is about 3.000.000 instructions / sec in a Intel Core i5-5200@2.2Ghz and about 4.500.000 instructions / sec in a Intel Core i7-8550U@1.8Ghz.

Trace perihperal creates a xterm window where it prints out all received data.


Modules' hierarchy

Memory map

Base Module Description
0x40000000 Trace Output data to xterm
0x40004000 Timer LSB Timer
0x40004004 Timer MSB Timer
0x40004008 Timer MSB Timer Comparator
0x4000400C Timer LSB Timer Comparator


This is a preliminar and incomplete version.

Task to do:

  • Implement all missing instructions (Execute)
  • Implement CSRs (where/how?)
  • Add full support to read file with memory contents (to memory.h)
    • .elf files
    • .hex files (only partial .hex support)
  • Connect some TLM peripherals
    • Debug module similiar to ARM's ITM
    • Some standard UART model
    • ...
  • Implement interrupts
    • implement timer (mtimecmp) & timer interrupt
    • generic IRQ comtroller
  • Test, test, test & test. I'm sure there are a lot of some bugs in the code
    • riscv-test almost complete (see Test)
    • riscv-compliance
  • Improve structure and modules hierarchy
  • Add 64 & 128 bits architecture (RV64I, RV128I)
  • Debug capabilities


In order to compile the project you need SystemC-2.3.2 installed in your system. Just change SYSTEMC path in Makefile.

$ make

Then, you need to modifiy your LD_LIBRARY_PATH environtment variable to add path systemc library. In my case:

$ export LD_LIBRARY_PATH=/home/marius/Work/RiscV/code/systemc-2.3.2/lib-linux64

And then you can execute the simulator:

$ ./RISCV_TLM asm/BasicLoop.hex

Using cmake

It is possible to use cmake:

mkdir build
cd build
cmake ..

note that SystemC must be compiled with cmake:

cd <systemc directory>
mkdir build
cd build


-L loglevel: 3 for detailed (INFO) log, 0 to ERROR log level

-f filename .hex filename to use

-D Enter in Debug mode, simulator starts gdb server (Beta)


It is possible to use gcc as risc-v compiler. Follow the instructions (from

$ git clone --recursive
$ cd riscv-gnu-toolchain
$ ./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32
$ make
wait for long time ...
$ export PATH=$PATH:/opt/riscv/bin

In test/C/long_test/ example there is a Makefile that compiles a project with any .c files and links them against new-lib nano. There is a Helper_functions.c file with defiitions of all missing functions needed by the library (_read(), _close(), _fstat_r(), _lseek_r(), _isatty_r(), _write()). All of them are defined empty except _write() that is written to use the Trace perihperal. The definition of the function _write() allows developer to use printf() as usual and the stdout will be redirected to the Trace perihperal.


It is possible to debug an application running in RISC-V-TLM simulator. It is tested with riscv32-unknown-elf-gdb version and eclipse. Configure a "C/C++ Remote Application" debug configuration as the figure

Modules' hierarchy

gdbinit.txt file must contain:

set debug remote 1
set arch riscv:rv32

With this configuration, eclipse debuggins is almost normal (I experienced some problems wiith "step-over" and "step-into" commands)

Docker container

There is a Docker container available with the latest release at This container has RISCV-TLM already build at /usr/src/riscv64/RISCV-TLM directory.

How to use Docker

$ docker pull mariusmm/riscv-tlm
$ docker run -v <path_to_RISCV-V-TLM>/:/tmp -u $UID -e DISPLAY=$DISPLAY --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"  -it mariusmm/riscv-tlm /bin/bash

# cd /usr/src/riscv64/RISC-V-TLM/
# ./RISCV_TLM /tmp/<your_hex_file>

or you can call binary inside docker image directly:

$ docker run -v <path_to_RISCV-V-TLM>/:/tmp -u $UID -e DISPLAY=$DISPLAY --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"  -it mariusmm/riscv-tlm /usr/src/riscv64/RISC-V-TLM/RISCV_TLM /tmp/<your_hex_file>

I'm using docker image zmors/riscv_gcc to have a cross-compiler, I'm using both docker images this way:

$ docker run -v /tmp:/PRJ -it zmors/riscv_gcc:1  bash

# cd /PRJ/func3
# make

$ docker run -v /tmp:/tmp -u $UID -e DISPLAY=$DISPLAY --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" -it mariusmm/riscv-tlm /bin/bash

# cd /usr/src/riscv64/RISC-V-TLM/ 
# ./RISCV-TLM /tmp/file.hex


console 2:
$  docker run -v /tmp/tmp -it  mariusmm/riscv-tlm /usr/src/riscv64/RISC-V-TLM/RISCV_TLM /tmp/file.hex

Performance is not affected by running the simulator inside the container


See Test page for more information.

In the asm directory there are some basic assembly examples.

I "compile" one file with the follwing command:

$ cd asm
$ riscv32-unknown-elf-as  EternalLoop.asm -o EternalLoop.o
$ riscv32-unknown-elf-ld EternalLoop.o -o EternalLoop.elf
$ riscv32-unknown-elf-objcopy -O ihex EternalLoop.elf EternalLoop.hex
$ cd ..
$ ./RISCV_SCTLM asm/EternalLoop.hex

This example needs that you hit Ctr+C to stop execution.

C code

The C directory contains simple examples in C. Each directory contains an example, to compile it just:

$ make

and then execute the .hex file like the example before.


FreeRTOS can run in this simulator!

In test/FreeRTOS/ directory there is portable files (port.c, portmacro.c portasm.S) and main file (freertos_test.c) ported to this RISC-V model.


The code is documented using doxygen. In the doc folder there is a Doxygen.cfg file ready to be used.


There are several ways to contribute to this project:

  • Test
  • Pull request are welcome (see TODO list)
  • Good documentation
  • RTL-Level simulation

Authors and credits

RISC-V-TLM is managed by Màrius Montón.

If you find this code useful, please consider citing:

        title = {A {RISC}-{V} {SystemC}-{TLM} simulator},
        booktitle = {Workshop on {Computer} {Architecture} {Research} with {RISC}-{V} ({CARRV 2020}),
        author = {Montón, Màrius},
        year = {2020}


I've published a paper describing the RISC-V simulator in CARRV 2020 conference (pdf).


Copyright (C) 2018, 2019, 2020 Màrius Montón (@mariusmonton)

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see