{"id":15220474,"url":"https://github.com/trmckay/lib-rv32","last_synced_at":"2025-10-30T06:32:03.770Z","repository":{"id":45222452,"uuid":"391748029","full_name":"trmckay/lib-rv32","owner":"trmckay","description":"Rust library for emulating RISC-V rv32imac","archived":false,"fork":false,"pushed_at":"2021-12-30T09:09:50.000Z","size":263,"stargazers_count":19,"open_issues_count":2,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-04-28T19:45:06.235Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trmckay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-01T22:00:13.000Z","updated_at":"2024-02-07T13:15:21.000Z","dependencies_parsed_at":"2022-09-05T05:11:51.075Z","dependency_job_id":null,"html_url":"https://github.com/trmckay/lib-rv32","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trmckay%2Flib-rv32","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trmckay%2Flib-rv32/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trmckay%2Flib-rv32/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trmckay%2Flib-rv32/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trmckay","download_url":"https://codeload.github.com/trmckay/lib-rv32/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219856579,"owners_count":16556082,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-28T13:10:31.436Z","updated_at":"2025-10-30T06:31:58.475Z","avatar_url":"https://github.com/trmckay.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lib-rv32\n\n![build](https://github.com/trmckay/lib-rv32i/actions/workflows/build.yml/badge.svg)\n![tests](https://github.com/trmckay/lib-rv32i/actions/workflows/test.yml/badge.svg)\n\n## Overview\n\nlib-rv32 is a collection of Rust libraries for emulating, learning, and assembling 32-bit RISC-V\ninteger ISAs.\n\n- [lib-rv32-isa](https://crates.io/crates/lib-rv32-isa): library for ISA simulation\n- [lib-rv32-mcu](https://crates.io/crates/lib-rv32-mcu): reference implemenation of an MCU used in conjunction with lib_rv32_isa\n- [lib-rv32-asm](https://crates.io/crates/lib-rv32-asm): library for assembling RISC-V programs\n- [lib-rv32-cli](https://crates.io/crates/lib-rv32-cli): CLI tool exposing the libraries\n- [lib-rv32-wasm](https://rvwasm.trmckay.com): An webapp using the library's WASM bindings.\n\n---\n\n## Libraries\n\n### ISA simulator\n\nThis library can execute instructions against any memory and register file that implements\nthe required primitives in the traits `lib_rv32_common::traits::{Memory, RegisterFile}`. This is to\nencourage usage with whatever frontend you desire.\n\nHowever, reference implementations are provided in `lib_rv32_mcu::*`. The library provides\nfunctions to read from the memory, registers, and step a single instruction. Since, the\nuser decides when to call these functions, these will probably fit most use-cases.\n\n### MCU\n\nThe MCU crate provides an implemenation of `Memory` and `RegisterFile` for use with the ISA\nsimulator. With this, one can fully emulate an embedded RISC-V core.\n\n### Assembler\n\nThis crate can be used to assemble simple RISC-V assembly programs. The main functions offered\nby this library are:\n\n- `assemble_ir`: assemble an instruction `\u0026str` to a `u32`\n- `assemble_program`: assemble a program `\u0026str` to a `Vec\u003cu32\u003e`\n- `assemble_program_buf`: assemble a `BufRead` to a `Vec\u003cu32\u003e`\n\n\n## CLI\n\n### Emulator\n\nThe primary use of the emulator is tracing execution of RISC-V programs and making assertions\nabout their behavior. It currently only supports simple binary memory images\n(not ELF binaries).\n\nEnter assertions into a JSON file (note: all numbers are strings to allow for hex or decimal radices).\n\n`assert.json`:\n```json\n{\n    \"registers\": {\n        \"x0\": \"0x0\",\n        \"a0\": \"20\"\n    },\n    \"memory\": {\n        \"0x0000\": \"0x00010117\"\n    }\n}\n```\n\nThen run:\n```\nlrv-cli -v ./prog.bin -s 24 -a assert.json\n```\n\nThis will execute `prog.bin`, stop at the PC value 0x24, and then make the assertions from `assert.json`.\n\nThe program will trace the execution instruction-by-instruction:\n```\n[0000]  00010117  |  auipc  sp, 0x10           |  sp \u003c- 0x10000 (65536);\n[0004]  fe010113  |  addi   sp, sp, -32        |  sp \u003c- 0xffe0 (65504);\n[0008]  00400513  |  addi   a0, zero, 4        |  a0 \u003c- 0x4 (4);\n[000c]  00500593  |  addi   a1, zero, 5        |  a1 \u003c- 0x5 (5);\n[0010]  00000097  |  auipc  ra, 0x0            |  ra \u003c- 0x10 (16);\n[0014]  018080e7  |  jalr   ra, (24)ra         |  ra \u003c- 0x18 (24); pc \u003c- 0x28;\n...\n```\n\nWhen complete, it will summarize results:\n```\n...\n[001c]  f0028293  |  addi   t0, t0, -256       |  t0 \u003c- 0xf00 (3840);\n[0020]  00a2a023  |  sw     a0, 0(t0)          |  (word *)0x00000f00 \u003c- 0x14 (20);\n\nReached stop-PC.\n\na0 == 20\n*0x00000000 == 65815\n```\n\n### Assembler\n\nThe CLI also exposes the assembler via the command line. You can assemble the file\n`program.s` to `program.bin` using\n\n`lrv-cli -cv program.s -o program.bin`\n\n---\n\n## Testing\n\nThis project has a very flexible testing system.\n\nUnit-tests are provided wherever appropriate.\n\nAdditionally, to test the whole system, test programs can be added to `mcu/tests/programs`.\nA test is simply a directory containing `.c` and `.s` source files and a `test_case.json`\nconsisting of assertions about the state of the MCU after the program is complete.\n\nDuring testing, Cargo will for each test:\n\n1. Compile it for RISC-V\n2. Spin up a new MCU\n3. Program it with the generated binary\n4. Run the test program for some number of cycles\n5. Make assertions\n6. Report succes or failure\n\nIf a test fails, it will describe the error that caused the crash or the assertion that failed\nand print an object dump of the compiled test binary:\n\n```\n...\n[001c]  f0028293  |  addi   t0, t0, -256       |  t0 \u003c- 0xf00 (3840);\n[0020]  00a2a023  |  sw     a0, 0(t0)          |  (word *)0x00000f00 \u003c- 0x14 (20);\nStopping because the stop PC 0x24 was reached.\n\n\nFailed test: tests/programs/mul@0x00000024: Register assertion failed: (x10=0x00000014) != 0x00000018.\n\nprog.elf:     file format elf32-littleriscv\n\n\nDisassembly of section .text.init:\n\n00000000 \u003cstart\u003e:\n   0:   00010117                auipc   sp,0x10\n   4:   fe010113                addi    sp,sp,-32 # ffe0 \u003c__global_pointer$+0xf75c\u003e\n   8:   00400513                li      a0,4\n   c:   00500593                li      a1,5\n...\n```\n\nTests are run in CI, but can be run locally provided your system has `riscv(32|64)-unknown-elf-gcc`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrmckay%2Flib-rv32","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrmckay%2Flib-rv32","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrmckay%2Flib-rv32/lists"}