# RiscEmu - RISC-V (userspace) emulator in python
[![Documentation Status](https://readthedocs.org/projects/riscemu/badge/?version=latest)](https://riscemu.readthedocs.io/en/latest/?badge=latest)
Implementing a basic RISC-V emulator, aimed at being easily extendable. Check out the docs at [readthedocs](https://riscemu.readthedocs.io/en/latest/index.html)
or [riscemu.datenvorr.at](https://riscemu.datenvorr.at/index.html).
This emulator contains:
* RISC-V Assembly parser
* RISC-V Assembly loader
* Emulation for most parts of the basic RISC-V instruction set and the M and A extensions
* Naive memory emulator
* Basic implementation of some syscalls
* A debugging environment
## Installation:
```bash
$ pip install riscemu
```
## Running simple Assembly:
A couple of basic assembly programs are provided inside `examples/`, such as [`hello-world.asm`](examples/hello-world.asm).
You can run it by typing `python -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 0
```
The [`read` syscall](docs/syscalls.md) defaults to readline behaviour. Reading "true chunks" (ignoring newlines) is currently not supported.
See the docs on [assembly](docs/assembly.md) for more detail on how to write assembly code for this emulator.
See the [list of implemented syscalls](docs/syscalls.md) for more details on how to syscall.
Currently, symbols (such as `main` or `loop`) 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 named `main`. if both
symbols were not found in the file, it simply starts at the beginning of the `.text` segment.
## Using the CLI:
*Current CLI is not final, options may change frequently until a stable version is reached*
This 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, RV32M
```
If multiple files are specified, all are loaded into memory, but only the last one is executed. This might be improved
later, maybe the `_init` section of each binary is executed before the main loop starts?
If `stack_size` is greater than zero, a stack is allocated and initialized, with the `sp` register pointing to the end of the stack.
## Debugging
Debugging is done using the `ebreak` (formerly `sbreak`) instruction, which will launch a debugging session if encountered.
See [docs/debugging.md](docs/debugging.md) for more info.
![debugging the fibs program](docs/debug-session.png)
## The source code:
Check out the [documentation](https://riscemu.readthedocs.io/en/latest/riscemu.html).
## Accessing local documentation:
To generate your local documentation, first install everything in `sphinx-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 running `open sphinx-docs/build/html/index.html`.
## Resources:
* RISC-V Programmers Handbook: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md
* Pseudo ops: https://www.codetd.com/article/8981522
* detailed instruction definition: https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#add
* RISC-V reference card: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf
## TODO:
* 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 loops
* Move away from `print` and use `logging.logger` instead
* Writer proper tests
## How To Release:
Create a new commit that:
1. Changes the "Upcoming" heading to the new versions number
2. Increments the version in the pyproject.toml to the next version
Commit this, and tag it with `v<version>`. Push the commit and the tag:
```bash
git push
git push origin "v<version>"
```
On GitHub, [draft a new release](https://github.com/AntonLydike/riscemu/releases/new), and
then approve the workflow run [here](https://github.com/AntonLydike/riscemu/actions).
Raw data
{
"_id": null,
"home_page": "https://github.com/antonlydike/riscemu",
"name": "riscemu",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "RISC-V",
"author": "Anton Lydike",
"author_email": "me@antonlydike.de",
"download_url": "https://files.pythonhosted.org/packages/66/f6/3aff01fdfc277cd2c2eecb153c39daa521624b41463e297a5e4214f7df1f/riscemu-2.2.7.tar.gz",
"platform": null,
"description": "# RiscEmu - RISC-V (userspace) emulator in python\n\n[![Documentation Status](https://readthedocs.org/projects/riscemu/badge/?version=latest)](https://riscemu.readthedocs.io/en/latest/?badge=latest)\n\nImplementing a basic RISC-V emulator, aimed at being easily extendable. Check out the docs at [readthedocs](https://riscemu.readthedocs.io/en/latest/index.html)\nor [riscemu.datenvorr.at](https://riscemu.datenvorr.at/index.html).\n\nThis emulator contains:\n* RISC-V Assembly parser\n* RISC-V Assembly loader\n* Emulation for most parts of the basic RISC-V instruction set and the M and A extensions\n* Naive memory emulator\n* Basic implementation of some syscalls\n* A debugging environment\n\n## Installation:\n\n```bash\n$ pip install riscemu\n```\n\n## Running simple Assembly:\nA couple of basic assembly programs are provided inside `examples/`, such as [`hello-world.asm`](examples/hello-world.asm).\n\nYou can run it by typing `python -m riscemu examples/hello-world.asm`. It will produce output similar to:\n```\n[MMU] Successfully loaded: LoadedExecutable[examples/hello-world.asm](base=0x00000100, size=24bytes, sections=data text, run_ptr=0x00000110)\n[CPU] Started running from 0x00000110 (examples/hello-world.asm)\nHello world\n\nProgram exited with code 0\n```\n\nThe [`read` syscall](docs/syscalls.md) defaults to readline behaviour. Reading \"true chunks\" (ignoring newlines) is currently not supported.\n\nSee the docs on [assembly](docs/assembly.md) for more detail on how to write assembly code for this emulator.\nSee the [list of implemented syscalls](docs/syscalls.md) for more details on how to syscall.\n\nCurrently, symbols (such as `main` or `loop`) are looked-up at runtime. This allows for better debugging, I believe.\n\nBasic IO should work, as open, read, write and close are supported for stdin/stdout/stderr and even arbitrary file paths (if enabled)\n\nWhen trying to run an assembly program, the emulator first tries to find a symbol named `_start`, then a symbol named `main`. if both\nsymbols were not found in the file, it simply starts at the beginning of the `.text` segment.\n\n## Using the CLI:\n*Current CLI is not final, options may change frequently until a stable version is reached*\n\nThis is how the interface is used:\n\n```\nusage: riscemu [-h] [--options OPTIONS] [--syscall-opts SYSCALL_OPTS] [--instruction-sets INSTRUCTION_SETS] [--stack_size stack-size] file.asm [file.asm ...]\n\n\n\nOPTIONS and SYSCALL_OPTIONS is a list of comma-separated flags that will be enabled\n\n--options OPTIONS: (-o)\ndisable_debug Disable the ebreak and sbreak instructions\nno_syscall_symbols Don't make syscall symbols globally available\nfail_on_ex Do not launch an interactive debugger when the CPU loop catches an exception\nadd_accept_imm accept \"add rd, rs, imm\" instructions, even though they are not standard\n\n--syscall-opts SYSCALL_OPTS: (-so)\n Options to control syscall behaviour\nfs_access Allow access to the filesystem\ndisable_io Disallow reading/writing from stdin/stdout/stderr\n\n--instruction-sets INSTRUCTION_SETS: (-is)\n A list of comma separated instruction sets you want to load:\n Currently implemented: RV32I, RV32M\n```\n\nIf multiple files are specified, all are loaded into memory, but only the last one is executed. This might be improved\nlater, maybe the `_init` section of each binary is executed before the main loop starts?\n\nIf `stack_size` is greater than zero, a stack is allocated and initialized, with the `sp` register pointing to the end of the stack.\n\n\n## Debugging\nDebugging is done using the `ebreak` (formerly `sbreak`) instruction, which will launch a debugging session if encountered.\nSee [docs/debugging.md](docs/debugging.md) for more info.\n\n![debugging the fibs program](docs/debug-session.png)\n\n\n## The source code:\nCheck out the [documentation](https://riscemu.readthedocs.io/en/latest/riscemu.html).\n\n## Accessing local documentation:\nTo generate your local documentation, first install everything in `sphinx-docs/requirements.txt`. Then run `./generate-docs.sh`, which will\ngenerate and make all doc files for you. Finally, you can open the docs locall by running `open sphinx-docs/build/html/index.html`.\n\n## Resources:\n * RISC-V Programmers Handbook: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md\n * Pseudo ops: https://www.codetd.com/article/8981522\n * detailed instruction definition: https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#add\n * RISC-V reference card: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf\n\n## TODO:\n * Correctly handle 12 and 20 bit immediate (currently not limited to bits at all)\n * Add a cycle limit to the options and CPU to catch infinite loops\n * Move away from `print` and use `logging.logger` instead\n * Writer proper tests\n\n\n## How To Release:\n\nCreate a new commit that:\n1. Changes the \"Upcoming\" heading to the new versions number\n2. Increments the version in the pyproject.toml to the next version\n\nCommit this, and tag it with `v<version>`. Push the commit and the tag:\n```bash\ngit push\ngit push origin \"v<version>\"\n```\n\nOn GitHub, [draft a new release](https://github.com/AntonLydike/riscemu/releases/new), and\nthen approve the workflow run [here](https://github.com/AntonLydike/riscemu/actions).\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A basic RISC-V emulator",
"version": "2.2.7",
"project_urls": {
"Bug Tracker": "https://github.com/antonlydike/riscemu/issues",
"Homepage": "https://github.com/antonlydike/riscemu",
"Repository": "https://github.com/antonlydike/riscemu"
},
"split_keywords": [
"risc-v"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "506cef41c869bd557f7a3e81ccea97aa8f57e4f8d637c24431299aa0547902ac",
"md5": "6fe3a27fb98605725c14fc9d7bf75154",
"sha256": "d8539c439e641ac7a0bb77d8f5039d664518d0ebaa26205cf4718573aa7c63a5"
},
"downloads": -1,
"filename": "riscemu-2.2.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6fe3a27fb98605725c14fc9d7bf75154",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 83397,
"upload_time": "2024-07-07T14:06:57",
"upload_time_iso_8601": "2024-07-07T14:06:57.754391Z",
"url": "https://files.pythonhosted.org/packages/50/6c/ef41c869bd557f7a3e81ccea97aa8f57e4f8d637c24431299aa0547902ac/riscemu-2.2.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "66f63aff01fdfc277cd2c2eecb153c39daa521624b41463e297a5e4214f7df1f",
"md5": "46d53cf54421c0c8f96824b7bab218a0",
"sha256": "9f206b195371cef4246a0d04cef6a439dc026396860c19a8850a761fd700c499"
},
"downloads": -1,
"filename": "riscemu-2.2.7.tar.gz",
"has_sig": false,
"md5_digest": "46d53cf54421c0c8f96824b7bab218a0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 63159,
"upload_time": "2024-07-07T14:06:59",
"upload_time_iso_8601": "2024-07-07T14:06:59.152015Z",
"url": "https://files.pythonhosted.org/packages/66/f6/3aff01fdfc277cd2c2eecb153c39daa521624b41463e297a5e4214f7df1f/riscemu-2.2.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-07 14:06:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "antonlydike",
"github_project": "riscemu",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "riscemu"
}