commit 6b84f3c15862bbb0f449ea6867ff5237c25e8a0b
parent f03a0c9fd688ec40d0268660b221e742efc40a35
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Tue, 8 Sep 2026 14:34:41 +0300
Added README
Diffstat:
| A | README | | | 115 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | exec.c | | | 4 | ---- |
2 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/README b/README
@@ -0,0 +1,115 @@
+rvemu
+=====
+This is a compact RV32I instruction simulator written in C as part of a
+MEng thesis on low-latency execution strategies. It is still in development
+and there is no release version.
+
+So far, it can run handwritten RISC-V assembly programs, but also
+freestanding C code (tested with riscv64-unknown-elf-gcc), compiled as flat
+non-ELF binaries.
+
+Unlike my other tools, this project is an experimental environment and as
+such, it is intended for hands-on use. It includes separate execution,
+monitoring and testing components and offers an interface that requires
+familiarity with the projects internals.
+
+
+Features:
+---------
+- simple execution API for embedding in custom drivers
+- static disassembler with a single function API
+- interactive monitor supporting continuous execution, single-stepping,
+ memory/register inspection and static disassembly
+- separate regression harness with a couple dozen tests, including small
+ programs, instruction edge cases and expected traps
+
+
+Planned features:
+-----------------
+- ELF loading
+- JIT compilation component for x86-64 (including a wrapper)
+- latency benchmarking scaffolding
+
+
+Not currently planned:
+----------------------
+- further RISC-V extensions, like M
+- RV64 support
+- MMU, privileged modes
+- GDB protocol support
+- peripheral emulation such as UARTs
+
+
+Dependencies:
+-------------
+- C compiler, make, host C stdlib
+- Optional: GNU Readline
+- Optional: RISC-V cross-toolchain for building guest programs
+
+
+Clone and use
+-------------
+Clone the repository with:
+
+ $ git clone git://mcdim.xyz/revmu.git
+
+Build monitor environment without GNU readline:
+
+ $ make
+
+Build monitor environment with GNU readline):
+
+ $ make READLINE=1
+
+Run:
+
+ $ ./emu
+
+Build and run tests:
+
+ $ make test
+ $ ./test
+
+
+Design philosophy:
+------------------
+- keep the hot path clean and minimal for low latency and high throughput
+- traps are recorded by the core and returned to the driver to define
+ policy handling
+
+
+Interpreter API:
+----------------
+The interpreter itself consists of exec.c, exec.h, decode.h, mem.h, trap.h
+
+A driver needs to
+1. #include "exec.h"
+2. allocate and zero a uint8_t array of MEMSIZE bytes as memory
+ (here named mem)
+3. zero-initialize a cpu_state_t struct (here named cpu)
+
+To execute a step, use the function:
+
+ void cpu_step(cpu_state_t *cpu, uint8_t *mem);
+
+A step executions a single instruction or records a trap. The driver
+must inspect CPU status afterward.
+
+View exec.h and trap.h for CPU and trap internals/initializations.
+
+
+Disassembly API:
+----------------
+The disassembly component consits of disasm.c and disasm.h and works
+through this single function:
+
+ void disassemble_instruction(uint32_t inst);
+
+It prints directly to stdout.
+
+
+Memory size
+-----------
+The interpreter can handle arbitrary memory sizes, as long as they are
+defined in exec.h (MEMSIZE). Some tests, however, assume 4096 bytes and
+will fail otherwise.
diff --git a/exec.c b/exec.c
@@ -7,7 +7,6 @@
#include "exec.h"
#include "mem.h"
#include "decode.h"
-#include "disasm.h"
#include "trap.h"
static inline void print_bin16(uint16_t x) {
@@ -211,8 +210,6 @@ static void exec_itype_loads(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
uint32_t addr = (uint32_t)i.imm + cpu->x[i.rs1];
- /* TODO: do I need to check before loading halves and words */
-
uint32_t x;
switch(i.funct3) {
case 0x0:
@@ -395,7 +392,6 @@ static void exec_btype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
} else {
cpu->pc += 4;
}
-
}
static void exec_itype_jalr(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {