Python Bindings of Spike RISC-V ISA Simulator


Keywords
RISC-V, spike, ISA, simulator, verification
License
Other
Install
pip install spike==0.0.5.dev20

Documentation

Python Bindings of Spike RISC-V ISA Simulator

LIU Yu <liuy@huimtlab.org>
2026/3/1 (v0.0.5)

Introduction

This project provides Python bindings for the Spike RISC-V ISA Simulator. The Pythonic Spike (or PySpike) opens up Spike's C++ internals (such as RISC-V disassembler, processors, controllers, peripherals, etc.) for interoperation with Python scripts. It enables users to write ISA / RoCC extensions and MMIO device models in Python, and plug them into vanilla Spike for (co-)simulating complex hardware systems. Through integrating Spike more seamlessly into the Python ecosystem, PySpike aims to boost the agility of Python-based hardware verification tools and workflows.

PyPI package: spike

Getting Started

PySpike requires: Python 3.8+.

Install the wheel package with pip.

$ pip install --pre spike

PySpike ships the original command-line tool spike, a.k.a vanilla Spike, within its wheel package. You can confirm its availability using,

$ spike --help
Spike RISC-V ISA Simulator 0.0.5...
...

There is also a 100%-compatible command-line wrapper called pyspike, with additional support for Python-based ISA / MMIO / RoCC extensions via --extlib=<name>.

$ pyspike \
    --isa=rv32imc_xmyisa --priv=m \
    --pc=0x90000000 \
    -m0x90000000:0x4000000 \
    --extlib=myisa.py \
    --extlib=mydev.py \
    --device=mydev,0x20000000 \
    tests/data/libc-printf_hello.elf
Hello, World!

Quick ISA Extension

An ISA extension implements one or more custom instructions and / or control-state registers (CSRs) for Spike's RISC-V processor models. With PySpike, an ISA extension is a Python class that inherits riscv.isa.ISA. It should implement a minimum of two methods: get_instructions and get_disasms. The former provides functional models of one or more custom instructions, and the latter provides their disassemblers. Other optional methods include get_csrs and reset, for providing custom CSRs and resetting extension states, respectively. Use decorator @isa.register("myisa") to register the extension under the name myisa.

from typing import List
from riscv import isa
from riscv.csrs import csr_t
from riscv.disasm import disasm_insn_t
from riscv.processor import insn_desc_t, processor_t

@isa.register("myisa")
class MyISA(isa.ISA):
    def __init__(self): ...
    def get_instructions(self, proc: processor_t) -> List[insn_desc_t]: ...
    def get_disasms(self, proc: processor_t) -> List[disasm_insn_t]: ...
    def get_csrs(self, proc: processor_t) -> List[csr_t]: ...
    def reset(self, proc: processor_t) -> None: ...

Quick Device Model

Likewise to the ISA extension, a device model implements a custom memory-mapped input/output (MMIO) peripheral for Spike's simulated system bus. With PySpike, a device model is a Python class that inherits riscv.dev.MMIO. It should implement a minimum of three methods: __init__, load, and store. The former initializes the model, the latter two handle memory read and write operations. Other optional methods include size and tick, for obtaining the size of memory-mapped address space, and shifting device states, respectively. Use decorator @dev.register("mydev") to register the model under the name mydev.

from typing import Optional
from riscv import dev
from riscv.sim import sim_t

@dev.register("mydev")
class MyDEV(dev.MMIO):
    def __init__(self, sim: sim_t, args: Optional[str] = None): ...
    def load(self, addr: int, size: int) -> bytes: ...
    def store(self, addr: int, data: bytes) -> None: ...
    def size(self) -> int: ...
    def tick(self, rtc_ticks: int) -> None:

Development

Getting Source Code

$ git clone --recurse-submodules https://github.com/huimtlab/pyspike
$ cd pyspike

Setting Up Develop Environment

Install with pip in editable mode. This will setup development dependencies as well.

$ python -m venv .venv
$ source .venv/bin/activate
(.venv) $ python -m pip install -e '.[dev]'

Running Tests

Run the built-in test suite with pytest.

(.venv) $ python -m pytest -v

Running Tests with Coverage

To enable coverage report, rebuild the extension module with --cov option, then re-run the test suite also with --cov option. You should see the coverage report by the end of the test output.

Note, if leaving out the first step, the C++ code will not show up in the coverage report.

(.venv) $ python setup.py build_ext --inplace --cov
(.venv) $ python -m pytest -v --cov

Optionally, you can generate HTML coverage report from the lcov data files.

(.venv) $ genhtml -o coverage --substitute "s#^#$PWD/#g" *.lcov

Packaging

(.venv) $ python -m build