Skip to content

Commit 7af0c33

Browse files
committed
Updated README
1 parent 55d1df9 commit 7af0c33

File tree

1 file changed

+14
-23
lines changed

1 file changed

+14
-23
lines changed

README.md

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
# 🐍 RISC-V Emulator in Python (RV32IMAC, machine mode, Newlib support)
22

3-
This is a simple and readable **RISC-V RV32IMAC emulator** written in pure Python. It supports machine mode, atomic instructions (A extension), compressed instructions (RVC extension), multiply/divide instructions (M extension), and can run programs compiled with **Newlib** or **Newlib-nano**. It is designed for educational use, experimentation, and portability — not for high performance or full system emulation.
3+
This is a simple and readable **RISC-V RV32IMAC emulator** written in pure Python. It supports machine mode, multiply/divide instructions (M extension), atomic instructions (A extension), compressed instructions (C extension), and can run programs compiled with **Newlib** or **Newlib-nano**. It is designed for educational use, experimentation, and portability — not for high performance or full system emulation.
44

55
## ✅ Features
66

7-
- **Implements the full RV32I base integer ISA**
8-
- **Implements the M extension** with multiply (`MUL`, `MULH`, `MULHSU`, `MULHU`) and divide (`DIV`, `DIVU`, `REM`, `REMU`) instructions
9-
- **Implements the A extension** with all 11 atomic memory operations (`LR.W`, `SC.W`, `AMOSWAP.W`, `AMOADD.W`, `AMOXOR.W`, `AMOAND.W`, `AMOOR.W`, `AMOMIN.W`, `AMOMAX.W`, `AMOMINU.W`, `AMOMAXU.W`) and proper LR/SC reservation tracking
10-
- **Implements the RVC (Compressed) extension** with full support for 16-bit compressed instructions, achieving 25-30% code density improvement
7+
- **Implements the full RV32I base integer ISA** with the **M extension** (multiply and divide instructions) and the **A extension** (atomic memory operations)
8+
- **Implements the C extension** (compressed instructions), switchable at run time
119
- **Implements all RV32MI machine-mode instructions and trap mechanisms**, including synchronous traps (`ecall`, `ebreak`, illegal instruction trap), asynchronous traps (machine timer interrupt), `mret`, and the **Zicsr (Control Status Registers) extension** and registers (`mstatus`, `mepc`, `mtvec`, `mcause`, `mscratch`, ...)
1210
- **Supports loading ELF and flat binary formats**
1311
- **Supports terminal I/O**, both "cooked" and raw
1412
- **Provides most of the system calls needed by [Newlib](https://en.wikipedia.org/wiki/Newlib)**: `_write`, `_read`, `_exit`, **dynamic memory allocation** (`_sbrk`), **file I/O** (`_open`, `_close`, `_fstat`, `_lseek`, ...)
1513
- **Supports argc/argv program arguments**
1614
- **Supports memory-mapped IO** and provides a **UART peripheral** using a pseudo-terminal, and a **memory-mapped block device** backed by an image file
17-
- **Passes all `rv32ui`, `rv32mi`, `rv32uc`, `rv32um`, and `rv32ua` unit tests** (60 tests total) provided by [RISC-V International](https://github.com/riscv-software-src/riscv-tests)
15+
- **Passes all `rv32ui`, `rv32mi`, `rv32um`, `rv32ua`, and `rv32uc` unit tests** provided by [RISC-V International](https://github.com/riscv-software-src/riscv-tests)
1816
- **Supports logging** of register values, function calls, system calls, traps, invalid memory accesses, and violations of invariants
1917
- Runs [MicroPython](https://micropython.org/), [CircuitPython](https://circuitpython.org/) with emulated peripherals, and [FreeRTOS](https://www.freertos.org/) with preemptive multitasking
2018
- Self-contained, modular, extensible codebase. Provides a **Python API** enabling users to control execution, inspect state, and script complex tests directly in Python.
@@ -34,6 +32,7 @@ pip install -r requirements.txt
3432
```
3533
├── riscv-emu.py # Emulator
3634
├── cpu.py # CPU emulation logic
35+
├── rvc.py # RVC logic
3736
├── ram.py # RAM emulation logic
3837
├── machine.py # Host logic (executable loading, invariants check)
3938
├── peripherals.py # Peripherals (UART, block device)
@@ -53,7 +52,7 @@ pip install -r requirements.txt
5352
├── tests/test_api*.py # Examples of programmatic control of the emulator in Python
5453
├── build/ # Executable and binaries
5554
├── prebuilt/ # Pre-built examples
56-
├── run_unit_tests.py # Runs RISC-V unit tests (RV32UI, RV32MI, RV32UC, RV32UM, and RV32UA)
55+
├── run_unit_tests.py # Runs RISC-V unit tests (RV32UI, RV32MI, RV32UM, RV32UA, and RV32UC)
5756
├── riscv-tests/ # Git submodule with RISC-V unit tests
5857
├── advanced/freertos/ # FreeRTOS port
5958
├── advanced/micropython/ # MicroPython port
@@ -70,6 +69,7 @@ pip install -r requirements.txt
7069

7170
| Option | Description |
7271
|-------------------------|-----------------------------------------------------------------------------|
72+
| `--rvc` | Enable RVC support (compressed instructions) |
7373
| `--regs REGS` | Print selected registers at each instruction |
7474
| `--trace` | Log the names of functions traversed during execution |
7575
| `--syscalls` | Log Newlib syscalls |
@@ -86,7 +86,6 @@ pip install -r requirements.txt
8686
| `--uart` | Enable PTY UART |
8787
| `--blkdev PATH` | Enable MMIO block device |
8888
| `--blkdev-size NUM` | Block device size in 512-byte blocks (default 1024) |
89-
| `--rvc` | Enable RVC (compressed instructions) support for 16-bit instructions |
9089
| `--raw-tty` | Enable raw terminal mode |
9190
| `--no-color` | Remove ANSI colors in debugging output |
9291
| `--log LOG_FILE` | Log debug information to file `LOG_FILE` |
@@ -99,7 +98,7 @@ make all
9998

10099
The Makefile supports building with different RISC-V extensions, e.g., to build with rv32iac_zicsr (RV32IMAC):
101100
```
102-
make RVC=1 MUL=1 RVA=1 all
101+
make RVM=1 RVA=1 RVC=1 all
103102
```
104103

105104
If you just want to **test the emulator without installing a RISC-V compiler**, you will find pre-built binaries in `prebuilt/`.
@@ -207,7 +206,7 @@ and connect to the console using your favorite terminal program, e.g., `screen /
207206

208207
### Using the Python API
209208

210-
The emulator provides a Python API that allows users to control execution, set and inspect state, and run complex tests directly from Python programs. Here is an example of how you can load and run a simple program:
209+
The emulator provides a Python API that allows users to control execution, set and inspect state, and run complex tests directly from Python programs. Here is an example of how you can load and run a simple RV32I program:
211210
```python
212211
from cpu import CPU
213212
from ram import RAM
@@ -250,7 +249,7 @@ make
250249
cd -
251250
```
252251

253-
The script automatically runs all RV32UI, RV32MI, RV32UC, and RV32UM [RISC-V unit tests](https://github.com/riscv-software-src/riscv-tests) in `riscv-tests/`. The emulator passes all of them.
252+
The script automatically runs all RV32UI, RV32MI, RV32UM, RV32UA, and RV32UC [RISC-V unit tests](https://github.com/riscv-software-src/riscv-tests) in `riscv-tests/`. The emulator passes all of them.
254253
```
255254
./run_unit_tests.py
256255
Test rv32ui-p-bltu : PASS
@@ -354,27 +353,19 @@ Test rv32uc-p-rvc : PASS
354353
The emulator achieves **over 2 MIPS** (million instructions per second) using Python 3.12 (Anaconda distribution) on a Macbook Pro (M1, 2020) running macOS Sequoia. Execution times for some binaries in `prebuilt/`:
355354
```
356355
time ./riscv-emu.py prebuilt/test_newlib2.elf
357-
./riscv-emu.py prebuilt/test_newlib2.elf 11.43s user 0.05s system 99% cpu 11.506 total
356+
./riscv-emu.py prebuilt/test_newlib2.elf 1.71s user 0.03s system 98% cpu 1.772 total
358357
```
359358
```
360359
time ./riscv-emu.py prebuilt/test_newlib4.elf
361-
./riscv-emu.py prebuilt/test_newlib4.elf 4.90s user 0.03s system 99% cpu 4.973 total
360+
./riscv-emu.py prebuilt/test_newlib4.elf 0.37s user 0.03s system 94% cpu 0.416 total
362361
```
363362
```
364363
time ./riscv-emu.py prebuilt/test_newlib6.elf
365-
./riscv-emu.py prebuilt/test_newlib6.elf 75.85s user 0.24s system 99% cpu 1:16.37 total
364+
./riscv-emu.py prebuilt/test_newlib6.elf 76.19s user 0.29s system 99% cpu 1:16.56 total
366365
```
367366

368367
Running the emulator with [PyPy](https://pypy.org/) yields a speedup of almost 4x over CPython, achieving **over 9 MIPS**.
369368
```
370-
time pypy3 ./riscv-emu.py prebuilt/test_newlib2.elf
371-
pypy3 ./riscv-emu.py prebuilt/test_newlib2.elf 2.76s user 0.06s system 97% cpu 2.891 total
372-
```
373-
```
374-
time pypy3 ./riscv-emu.py prebuilt/test_newlib4.elf
375-
pypy3 ./riscv-emu.py prebuilt/test_newlib4.elf 1.24s user 0.03s system 99% cpu 1.276 total
376-
```
377-
```
378369
time pypy3 ./riscv-emu.py prebuilt/test_newlib6.elf
379-
pypy3 ./riscv-emu.py prebuilt/test_newlib6.elf 19.82s user 0.15s system 99% cpu 20.046 total
370+
pypy3 ./riscv-emu.py prebuilt/test_newlib6.elf 19.77s user 0.11s system 99% cpu 20.009 total
380371
```

0 commit comments

Comments
 (0)