rv32emu
rv32emu copied to clipboard
Compact and Efficient RISC-V RV32I[MAFC] emulator
RISC-V RV32I[MAC] emulator with ELF support
/--===============------\
______ __ | |⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺| |
| _ \ \ / / | | | |
| |_) \ \ / / | | Emulator! | |
| _ < \ V / | | | |
|_| \_\ \_/ | |_______________| |
_________ | ::::|
|___ /___ \ '======================='
|_ \ __) | //-'-'-'-'-'-'-'-'-'-'-\\
___) / __/ //_'_'_'_'_'_'_'_'_'_'_'_\\
|____/_____| [-------------------------]
rv32emu
is an instruction set architecture (ISA) emulator implementing the 32 bit RISC-V processor model.
Build and Verify
rv32emu
relies on some third-party packages to be fully usable and to provide you full
access to all of its features. Your target system must have a functional SDL2 library.
- macOS:
brew install sdl2
- Ubuntu Linux / Debian:
sudo apt install libsdl2-dev
Build the emulator.
make
Run sample RV32I[MA] programs:
make check
Run Doom, the classical video game, via rv32emu
:
make doom
The build script will then download data file for Doom automatically. When Doom is loaded and run, an SDL2-based window ought to appear.
If RV32F support is enabled (turned on by default), Quake demo program can be launched via:
make quake
The usage and limitations of Doom and Quake demo are listed in docs/demo.md.
riscv-arch-test
The RISC-V Architectural Tests, also known as riscv-arch-test, provides the fundamental set of tests that can be used to confirm that the behavior of the risc-v model adheres to the RISC-V standards while executing certain applications. (not intended to replace thorough design verification)
There are reference signatures that generated by the formal RISC-V model RISC-V SAIL
in the Executable and Linkable Format (ELF) files. ELF files that have multiple
testing instructions, data, and signatures, like cadd-01.elf
. The specific data
places that must be written by the testing model (this emulator) throughout the test are
known as test signatures. The test signatures will be written after it has been completed,
and they will be compared to the reference signature. When both signatures exactly match,
the test is successful.
RISC-V GNU Compiler Toolchain should be prepared in advance. You can obtain prebuilt GNU toolchain for riscv32-elf
via Automated Nightly Release. Then, run the following command:
make arch-test
- To run the tests for specific extension, set the environmental variable
RISCV_DEVICE
to one ofI
,M
,C
,Zifencei
,privilege
.
make arch-test RISCV_DEVICE=I
- To run a specific test case,set both
RISCV_DEVICE
andRISCV_TEST
.For example:
make arch-test RISCV_DEVICE=M RISCV_TEST=div-01
The details about the setup environment variables can be found in the RISC-V Architectural Testing Framework, 5.1 Setup environment variables.
Current progress of this emulator in riscv-arch-test(RV32):
- Passed Tests
-
I
: Base Integer Instruction Set -
M
: Standard Extension for Integer Multiplication and Division -
Zifencei
: Instruction-Fetch Fence
-
- Failed Tests
-
C
: Standard Extension for Compressed Instruction-
cebreak
-
-
privilege
: RISCV Privileged Specification- 2 system calls
-
ebreak
-
ecall
-
- 5 misaligned CB-type instructions
-
misalign-beq
-
misalign-bge
-
misalign-bgeu
-
misalign-blt
-
misalign-bltu
-
- 1 misaligned CL-type instructions
-
misalign-lw
-
- 1 misaligned CS-type instructions
-
misalign-sw
-
- 2 system calls
-
- Unsupported tests
-
F
Standard Extension for Single-Precision Floating-Point
-
Detail in riscv-arch-test:
- riscv-arch-test repository
- RISC-V Architectural Testing Framework
- RISC-V Architecture Test Format Specification
Customization
rv32emu
is configurable, and you can modify Makefile
to fit your expectations:
-
ENABLE_RV32M
: Standard Extension for Integer Multiplication and Division -
ENABLE_RV32A
: Standard Extension for Atomic Instructions -
ENABLE_RV32C
: Standard Extension for Compressed Instructions (RV32C.F excluded) -
Zicsr
: Control and Status Register (CSR) -
Zifencei
: Instruction-Fetch Fence
Add -D
to enable and -U
to disable the specific ISA extensions.
GDB Remote Debugging
rv32emu
is permitted to operate as gdbstub in an experimental manner since it supports
a limited number of GDB Remote Serial Protocol (GDBRSP).
You must first build the emulator and set ENABLE_GDBSTUB
to 1
in the Makefile
in order
to activate this feature. After that, you might execute it using the command below.
build/rv32emu --gdbstub <binary>
The <binary>
should be the ELF file in RISC-V 32 bit format. Additionally, it is advised
that you compile programs with the -g
option in order to produce debug information in
your ELF files.
You can run riscv-gdb
if the emulator starts up correctly without an error. It takes two
GDB commands to connect to the emulator after giving GDB the supported architecture of the
emulator and any debugging symbols it may have.
$ riscv32-unknown-elf-gdb
(gdb) file <binary>
(gdb) target remote :1234
Congratulate yourself if riscv-gdb
does not produce an error message. Now that the GDB
command line is available, you can communicate with rv32emu
.
Limitation
The development of rv32emu
's GDBRSP functionality is still ongoing. Due to the current
unfinished design, various restrictions on this feature are known.
- Since the 'G' packet is not supported yet, writing emulator registers with GDB is not permitted.
- Consequently, the packets for binary download (the "X" packet) and memory writing (the "M" packet) specified in GDBRSP are not allowed. It is forbidden to use GDB commands such as "load" that aim to modify the emulator's internal memory.
- You can only set one breakpoint when debugging due to the inadequate breakpoint handling design.
External sources
In rv32emu
repository, there are some prebuilt ELF files for testing purpose.
-
coremark.elf
: See eembc/coremark -
dhrystone.elf
: See rv8-bench -
pi.elf
: See tests/pi.c -
quake.elf
: See sysprog21/quake-embedded -
doom.elf
: See sysprog21/doom_riscv
Reference
- Writing a simple RISC-V emulator in plain C
- Writing a RISC-V Emulator in Rust
- libriscv: RISC-V userspace emulator library
- Threaded Code
License
rv32emu
is released under the MIT License.
Use of this source code is governed by a MIT license that can be found in the LICENSE file.