RISC-V RTOS-enabled multi-core SoC using Wishbone4 interconnect.
CPU is a single-issue in-order 4 stages pipeline with branch-JAL-RET-prediction (BHT: 4096 entries, RAS: 8 entries). The stages are IF (Fetch) ID (Decode) EX (Execute) WB (WriteBack). Memory access is not considered a stage in the design, but just another late result that takes multiple cycles like division.
Software toolchain includes libc with builtin RTOS named _OS (underLineOS) which implements preemptive multi-threading (SMP capable load balanced per-cpu runqueue), sw-timer, mutex, semaphore, fifo.
git clone https://github.com/fontamsoc/rvpu.git
git -C rvpu/ submodule update --init
wget https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2025-09-15/oss-cad-suite-linux-x64-20250915.tgz
sudo tar -C /opt/ -xf oss-cad-suite-linux-x64-20250915.tgz
PATH="/opt/oss-cad-suite/bin:${PATH}"
sudo tee /etc/profile.d/fpga-toolchain.sh <<'EOF'
PATH="/opt/oss-cad-suite/bin:${PATH}"
EOF
A number of sample applications are available under rvpu/hw/rv32-sim/apps/ along with their prebuilt .hex file:
coremark donut helloworld isatests isatests2 smp_pi thrdtst tinyraytracer
cd rvpu/hw/rv32-sim/
make clean sim run SRAM_INITFILE=apps/coremark/rv32/coremark.32.hex CLKFREQ=1000000
cd -
Output:
rm -rf obj_dir *.vcd *.log
make TB=sim obj_dir/Vsim
make[1]: Entering directory '/tmp/rvpu/hw/rv32-sim'
verilator -cc --exe \
--x-assign 1 --x-initial-edge \
--relative-includes -I.. -Wno-lint \
-DCLKFREQ=1000000 \
-DCPU_COUNT=1 \
-DXWORDBITSZ=32 \
-DSRAM_INITFILE='"apps/coremark/rv32/coremark.32.hex"' \
-DSRAM_KBSIZE="(256/*KB*/)" \
sim.sv sim.cpp &>>build.log
make[1]: Leaving directory '/tmp/rvpu/hw/rv32-sim'
Fri Jan 2 07:42:46 PM CST 2026
apps/coremark/rv32/coremark.32.hex loaded
CoreMark @ 1000000 Hz
2K performance run parameters for coremark.
CoreMark Size : 666
Total ticks : 12503368
Total time (secs): 12.503368
Iterations/Sec : 3.199138
Iterations : 40
Compiler version : GCC13.4.0
Compiler flags : -O3 -DMULTITHREAD=4 -DUSE__OS=1 -DPERFORMANCE_RUN=1
Parallel threads : 1
Memory location : HEAP
seedcrc : 0xe9f5
[0]crclist : 0xe714
[0]crcmatrix : 0x1fd7
[0]crcstate : 0x8e3a
[0]crcfinal : 0x65c5
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 3.199138 / GCC13.4.0 -O3 -DMULTITHREAD=4 -DUSE__OS=1 -DPERFORMANCE_RUN=1 / HEAP / 1:threads
CoreMark done
- /tmp/rvpu/hw/rvxx/sys.pu.v:227: Verilog $finish
cd rvpu/hw/rv32-sim/
make clean sim run SRAM_INITFILE=apps/smp_pi/smp_pi.32.hex CPU_COUNT=4
cd -
Output:
rm -rf obj_dir *.vcd *.log
make TB=sim obj_dir/Vsim
make[1]: Entering directory '/tmp/rvpu/hw/rv32-sim'
verilator -cc --exe \
--x-assign 1 --x-initial-edge \
--relative-includes -I.. -Wno-lint \
-DCLKFREQ=100000000 \
-DCPU_COUNT=4 \
-DXWORDBITSZ=32 \
-DSRAM_INITFILE='"apps/smp_pi/smp_pi.32.hex"' \
-DSRAM_KBSIZE="(256/*KB*/)" \
sim.sv sim.cpp &>>build.log
make[1]: Leaving directory '/tmp/rvpu/hw/rv32-sim'
Fri Jan 2 07:49:33 PM CST 2026
apps/smp_pi/smp_pi.32.hex loaded
Calculate first 240 digits of Pi independently by 16 threads.
Pi value calculated by thread #0: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #1: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #2: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #3: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #4: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #5: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #6: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #7: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #8: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #9: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #10: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #11: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #12: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #13: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #14: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
Pi value calculated by thread #15: 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316
All 16 threads executed by 4 cores in 80 ms
- /tmp/rvpu/hw/rvxx/sys.pu.v:227: Verilog $finish
cd rvpu/hw/rv32-sim/
make clean sim run SRAM_INITFILE=apps/tinyraytracer/tinyraytracer.32.hex CPU_COUNT=4
cd -
Output:
cd rvpu/hw/rv32-sim/
make clean sim run SRAM_INITFILE=apps/donut/donut.32.hex
cd -
Output:
FPGA support is available under rvpu/hw/:
rv32-artya7100 rv32-nexysa7100 rv32-orangecrab0285
The easiest FPGA support to work with is the rv32-orangecrab0285 because its sram can be updated without rebuilding the bitstream:
cd rvpu/hw/rv32-orangecrab0285/yosys/
make updsram SRAM_INITFILE=../../rv32-sim/apps/coremark/rv32/coremark.32.hex
# While holding the button on the OrangeCrab, plug it in;
# it enters the bootloader and enables programming a new bitstream.
make prog
cd -
Set SRAM_INITFILE of make updsram to a different .hex to use a different application.
To rebuild the rv32-orangecrab0285 bitstream, use make clean all.
The bitstreams for the xilinx FPGAs, such as rv32-artya7100, need to be built from their Vivado project file (ie: rvpu/hw/rv32-artya7100/vivado2020/artya7100.xpr).
Build sw toolchain (or download prebuilt
)
Only needed in order to build software.
sudo ln -snf /bin/bash /bin/sh
mkdir rvpu-build && cd rvpu-build
make -f ../rvpu/makefile clean all
The toolchain gets generated under /opt/rvpu-toolchain/.
sudo tar -xf rvpu-toolchain-linux-x64.tar.xz -C /opt/
PATH="/opt/rvpu-toolchain/bin:${PATH}"
sudo tee /etc/profile.d/rvpu-toolchain.sh <<'EOF'
PATH="/opt/rvpu-toolchain/bin:${PATH}"
EOF