Skip to content

An easy-to-use, still-in-development RISC-V 32-bit instruction-accurate (IA) simulator.

License

Notifications You must be signed in to change notification settings

ssayin/riscv32-sim

Repository files navigation

Coverage Lines of Code Technical Debt Reliability Rating

riscv32-sim

An easy-to-use, still-in-development RISC-V 32-bit instruction-accurate simulator.

Table of Contents

Why does this project exist?

The processor simulator is a lightweight alternative to existing IA (Instruction-accurate) processor simulators. Designed for the 32-bit RISC-V instruction set architecture and its extensions, it offers gentle learning curve, and optimizes performance. This also allows for simplified code base, faster simulation, accurate results, and increased productivity and efficiency in the development process.

Features

  • Supports the RV32I, RV32M, and RVC instruction set extensions

  • Supports machine timer interrupts

  • Supports CSRs (basic).

  • Supports M-mode

  • Exports hart-state in JSON format

  • Exports disassembly trace

Roadmap

In Progress

  • Implement WPRI, WLRL, WARL fields

  • TCP/IP-based external interrupts

  • GDB stub, attach/step, EBREAK

  • File and network I/O using ECALL

Planned

  • Toggle instructions in misa register

  • GPIO

  • UART

  • Ability to configure enabled/disabled extensions in CLI

  • Implement extension A (atomic instructions)

  • Implement extension F (single-precision floating-point)

  • Implement base extension E (embedded)

  • CSR field modulation (I and E)

Directory Structure

├── cmake
├── external
├── LICENSES
├── misc
│   └── images
├── riscv32-sim
│   ├── include
│   │   ├── iss
│   │   ├── memory
│   │   └── zicsr
│   ├── lib
│   │   ├── riscv32-decoder
│   │   │   ├── decoder
│   │   │   │   ├── include
│   │   │   │   │   └── decoder
│   │   │   │   └── src
│   │   │   └── LICENSES
│   │   └── riscv32-sim-common
│   │       └── include
│   │           └── common
│   ├── src
│   │   ├── iss
│   │   └── memory
│   └── unittest
├── runtime
│   ├── arch-test
│   ├── basic
│   │   ├── cmake
│   │   ├── crt
│   │   └── src
│   ├── riscv-tests
│   └── tvm
└── tools
  • cmake: Contains CMake related scripts and configuration files.
  • external: Houses external dependencies and libraries.
  • LICENSES: Contains the licenses for the project and its dependencies.
  • misc: Miscellaneous files, including images.
    • images: Image files used in the project documentation.
  • riscv32-sim: Main project source code and library.
    • include: Header files for the project, organized into subdirectories for different modules.
    • lib: Libraries used in the project.
      • riscv32-decoder: RISC-V instruction decoding library.
      • riscv32-sim-common: Shared data structures and utilities for decoding RISC-V instructions.
    • src: Source files for the project, organized into subdirectories for different modules.
  • unittest: Unit tests for the project.
  • runtime: Contains runtime support files, test programs, and test automation scripts for the simulator to generate coverage.
    • arch-test: Custom setup and riscv-arch-test suite integration for simulator verification.
    • basic: C programs and runtime support files for testing the simulator.
      • cmake: CMake scripts for building and testing.
      • crt: C runtime support files and linker scripts.
      • src: Source files for C programs used in testing.
    • riscv-tests: Includes a CMakeLists.txt file to locate available riscv-tests *.elf files. For information on building these files within the project, check out the relevant build.yml section. You can also visit riscv-tests for further details.
    • tvm: Hosts RISC-V 32-bit test programs and automation scripts, leveraging riscv-test-env to execute tests on the simulator.
  • tools: Additional tools and script utilities used in the project.

Getting Started

Build Requirements

Build Flags

Option Description
-DBUILD_TESTING=[ON/OFF] Enable/disable building tests (default: ON).
-DBUILD_RUNTIME=[ON/OFF] Cross-compile programs in the runtime directory and add them as test targets. Requires GCC RISC-V toolchain in your PATH and the RISCV variable set to the compiler root directory.
-DISA_TESTS_DIR=[PATH] Specify the path to riscv-tests binaries.
-DCOVERAGE=[ON/OFF] (GCC only) Compile with coverage flags and link gcov library.
-DENABLE_UBENCHMARKS=[ON/OFF] (REQUIRES Google Benchmarks) Compile benchmarks for ISS components.
-DTEST_EXPORT_JSON_HART_STATE=[ON/OFF] (CTest flag) Enable/disable exporting hart state as JSON (default: OFF).
-DTEST_EXPORT_TRACE_DISASSEMBLY=[ON/OFF] (CTest flag) Enable/disable exporting disassembly trace (default: OFF).

Building on Linux

Fire up your favorite terminal and run those programs in shell:

# clone the repo with submodules
git clone --recurse-submodules https://github.com/ssayin/riscv32-sim.git

# cd to local repo
cd riscv32-sim

# update submodules
git submodule update --init --recursive

# configure and generate
# see cmake documentation for other generators
# and how to configure them
cmake -DCMAKE_BUILD_TYPE=Release -S . -B build

# build using GNU Make
make -C build

I do not recommend installing the binary in your system path.

Building and Running Tests [Optional]

See build.sh.

Using

# with the executable in working directory
./riscv32-sim <your_elf_binary>

CLI Options and Flags

Note: The serialization format for exporting hart state may change in the future.

Flag Description
–dump Dump ELF header and exit
–step Enable Manual step mode
-j<filename>,–json-output<filename> Set JSON output (required for hart state export)
-d<filename>,–disas-output<filename> Set disassembly trace output (required for trace export)
–tohost <sym> Customize the tohost symbol. Useful for custom __start() and __exit(int) routines. Define the symbol in your linker script.

Caution: The following options are experimental and may cause your computer to malfunction.

  • --timer: Enable machine timer interrupts.
    • --mtime <address>: Set mtime memory address.
    • --mtimecmp <address>: Set mtimecmp memory address.
    • --interval <value>: Set timer interval.

How does the simulator determine when to halt?

The simulator can be instructed to stop in the following ways:

  1. Create a symbol in your linker script called "tohost." If this is something you have never done before, you can look at the documentation on this website: https://doc.ecoscentric.com/gnutools/doc/ld/Scripts.html#Scripts. Writing to tohost terminates the program.

  2. Declare a function with __naked__ attribute. In function definition, set register a7 (x17) to 93. Then ecall. Call this function in your __exit(int) routine. You can also set the other argument registers a0, a1, a2, a3, a4, a5, a6. The value in the a0 register will be reported as the exit code. For more information on how the linux kernel implements syscalls, visit https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/sbi.c.

Note: syscall(93) is handled by the simulator despite SBI not yet being implemented.

Troubleshooting

cc1: error: '-march=rv32im_zicsr': unsupported ISA subset 'z'

Check the relevant issues on riscv-gcc repository

  1. riscvarchive/riscv-gcc#339
  2. riscv-collab/riscv-gnu-toolchain#1053

Check the upstream patch: riscv-collab/riscv-gnu-toolchain#1054

UPDATE: On a second thought, you can set up your toolchain by setting -DCMAKE_TOOLCHAIN_FILE; build flag. This may help bypassing some issues related to incompatible ABIs. However, I cannot guarantee its effectiveness in all cases.

Example: cmake -DCMAKE_TOOLCHAIN_FILE=my_toolchain_file.cmake.

Or you can edit riscv.cmake and arch-test/CMakeLists.txt according to your needs.

Please keep in mind that this simulator only supports the 20191213 RISC-V specification.

/usr/lib/gcc/riscv64-unknown-elf/10.2.0/include/stdint.h:9:16: fatal error: stdint.h: No such file or directory 9 | # include_next <stdint.h>

Please refer to: ABI is incompatible with that of the selected emulation: target emulation 'elf64-littleriscv' does not match 'elf32-littleriscv'

ABI is incompatible with that of the selected emulation: target emulation 'elf64-littleriscv' does not match 'elf32-littleriscv'

If you encounter the error when building tests, try installing GCC binutils for RISC-V 32-bit.

However, if you're using Ubuntu LTS 20.04 or 22.04, unfortunately, the binutils for riscv32 is not available in the official repositories.

In that case, you can either compile it yourself or use Embecosm build which is used in the GitHub Actions build workflow. Check the relevant section of the build.yml file for extracting and setting up PATH on Linux.

If you're using Arch Linux, you can install binutils-riscv32 from the AUR.

Built With

  • CLI11 - CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

  • ELFIO - A header-only C++ library intended for reading and generating files in the ELF binary format.

  • json - JSON for Modern C++

  • riscv-disassembler - RISC-V Disassembler with support for RV32/RV64/RV128 IMAFDC

  • spdlog - Very fast, header-only/compiled, C++ logging library.

Author

Serdar Sayın - Initial work, project maintainer - GitHub

If you have any questions or suggestions, feel free to contact me at serdarsayin@pm.me.

License (Updated: 2023-04-11)

This project has multiple licenses:

Note: For more accurate licensing information, please check the individual files, as keeping this section up to date can be challenging.

Regents of the University of California License

Copyright (c) 2010-2017, The Regents of the University of California (Regents). All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the Regents nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

About

An easy-to-use, still-in-development RISC-V 32-bit instruction-accurate (IA) simulator.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published