Package: riscemu
RiscEmu - RISC-V (userspace) emulator in pythonImplementing a basic RISC-V emulator, aimed at being easily extendable. Check out the docs atreadthedocsorriscemu.datenvorr.at.This emulator contains:RISC-V Assembly parserRISC-V Assembly loaderEmulation for most parts of the basic RISC-V instruction set and the M and A extensionsNaive memory emulatorBasic implementation of some syscallsA debugging environmentInstallation:$pipinstallriscemuRunning simple Assembly:A couple of basic assembly programs are provided insideexamples/, such ashello-world.asm.You can run it by typingpython -m riscemu examples/hello-world.asm. It will produce output similar to:[MMU] Successfully loaded: LoadedExecutable[examples/hello-world.asm](base=0x00000100, size=24bytes, sections=data text, run_ptr=0x00000110)
[CPU] Started running from 0x00000110 (examples/hello-world.asm)
Hello world

Program exited with code 0Thereadsyscalldefaults to readline behaviour. Reading "true chunks" (ignoring newlines) is currently not supported.See the docs onassemblyfor more detail on how to write assembly code for this emulator.
See thelist of implemented syscallsfor more details on how to syscall.Currently, symbols (such asmainorloop) are looked-up at runtime. This allows for better debugging, I believe.Basic IO should work, as open, read, write and close are supported for stdin/stdout/stderr and even arbitrary file paths (if enabled)When trying to run an assembly program, the emulator first tries to find a symbol named_start, then a symbol namedmain. if both
symbols were not found in the file, it simply starts at the beginning of the.textsegment.Using the CLI:Current CLI is not final, options may change frequently until a stable version is reachedThis is how the interface is used:usage: riscemu [-h] [--options OPTIONS] [--syscall-opts SYSCALL_OPTS] [--instruction-sets INSTRUCTION_SETS] [--stack_size stack-size] file.asm [file.asm ...]



OPTIONS and SYSCALL_OPTIONS is a list of comma-separated flags that will be enabled

--options OPTIONS: (-o)
disable_debug           Disable the ebreak and sbreak instructions
no_syscall_symbols      Don't make syscall symbols globally available
fail_on_ex              Do not launch an interactive debugger when the CPU loop catches an exception
add_accept_imm          accept "add rd, rs, imm" instructions, even though they are not standard

--syscall-opts SYSCALL_OPTS: (-so)
                        Options to control syscall behaviour
fs_access               Allow access to the filesystem
disable_io              Disallow reading/writing from stdin/stdout/stderr

--instruction-sets INSTRUCTION_SETS: (-is)
                        A list of comma separated instruction sets you want to load:
                        Currently implemented: RV32I, RV32MIf multiple files are specified, all are loaded into memory, but only the last one is executed. This might be improved
later, maybe the_initsection of each binary is executed before the main loop starts?Ifstack_sizeis greater than zero, a stack is allocated and initialized, with thespregister pointing to the end of the stack.DebuggingDebugging is done using theebreak(formerlysbreak) instruction, which will launch a debugging session if encountered.
Seedocs/debugging.mdfor more info.The source code:Check out thedocumentation.Accessing local documentation:To generate your local documentation, first install everything insphinx-docs/requirements.txt. Then run./generate-docs.sh, which will
generate and make all doc files for you. Finally, you can open the docs locall by runningopen sphinx-docs/build/html/index.html.Resources:RISC-V Programmers Handbook:https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.mdPseudo ops:https://www.codetd.com/article/8981522detailed instruction definition:https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#addRISC-V reference card:https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdfTODO:Correctly handle 12 and 20 bit immediate (currently not limited to bits at all)Add a cycle limit to the options and CPU to catch infinite loopsMove away fromprintand uselogging.loggerinsteadWriter proper tests