Developer & Contributing Guide
This guide outlines the architecture, coding standards, branch lifecycle, and testing procedures for developers and contributors working on SimRV.
1. Project Organization & Subsystems
SimRV follows a strict separation between public header declarations (include/simrv/) and implementation source units (src/):
include/simrv/ | src/
├── core/ # Machine, CPU, ArchState, CSR registers, MMU, traps, state control
├── execute/ # ALU, Multiplier/Divider, FPU, Vector execution units
├── pipeline/ # In-order 6-stage pipeline (Fetch, Decode, Execute, Memory, Commit), Decoder
├── memory/ # Physical memory, MMU page table walker, MMIO router, TileLink bus
├── cache/ # L1 instruction & data cache hierarchy (ICache, DCache)
├── device/ # CLINT, PLIC, 16550A UART, VirtIO block, Console, Framebuffer, Power
├── tui/ # TUI framework, panels, modals, frame renderer, themes
├── debug/ # GDB RSP server, Spike lockstep co-simulation, SymbolTable, Breakpoints
└── util/ # CLI argument parser, instruction hazard explainer
2. Build Environment & CMake Presets
SimRV requires a modern C++23 compiler (Clang 20+ or GCC 14+), CMake 3.20+, and Ninja.
Preset Workflows
Always configure and build using CMake presets:
# RV64 targets
cmake --preset rv64-release
cmake --build --preset rv64-release -j$(nproc)
# RV32 targets
cmake --preset rv32-release
cmake --build --preset rv32-release -j$(nproc)
# Debug targets with AddressSanitizer (ASan) & UB-Sanitizer
cmake --preset rv64-debug
cmake --build --preset rv64-debug -j$(nproc)
Formatting Verification
Code formatting strictly follows Google C++ style with a 100-column margin. Run dry-run checks before committing:
3. C++23 Architectural & Coding Idioms
- Compile-Time Fixed XLEN:
- Architecture bitwidth is compile-time fixed via
SIMRV_XLEN(32 or 64). There is no runtime XLEN switching. - Domain-Specific Type Aliases:
- Avoid generic primitive types (
uint64_t,uint32_t,int) when domain aliases exist:Word,Address,PhysAddr,VirtAddr,RegId,CSRValue,TrapCause.
- Proactively declare strongly typed aliases for new architectural concepts.
- Logging & Tracing Standards:
- Use
simrv::log::info,simrv::log::warn, andsimrv::log::errorfromsimrv/core/Logger.hppfor console and TUI messages. - Never write raw
std::cout,std::cerr, orprintfcalls inside core simulation logic. - Use
simrv::core::Tracerfor architectural simulation artifacts intrace/(trace.txt,traplog.txt,bpred.txt,instmix.txt). - Privileged CSR & Memory Emulation:
- Privilege levels span Machine (M), Supervisor (S), and User (U) modes with Sv32 / Sv39 page table translation.
- Unimplemented PMP CSRs are safely hardwired to zero per privileged specification to maintain compatibility with guest firmware (e.g. OpenSBI) probes.
4. Branching & Commit Guidelines
SimRV development follows strict branch hygiene defined in .agents/rules/branching.md:
Feature & Topic Branches
- Naming: Use lowercase kebab-case naming:
feature/<name>for new features or subsystems (e.g.feature/dynamic-vlen)fix/<name>for bug fixes and regression remediationperf/<name>for targeted microarchitectural optimizationsrefactor/<name>for structural refactoring without behavioral divergence- Base Branch: Always base feature development on the latest
devbranch. - Pull Requests: Target PRs at
dev. Rebase ontodevto keep linear commit history.
Release Qualification Branches
- Naming: Strictly follow
release/<semver>(e.g.,release/2.0.2). - Release Metadata Bumps: Version bumps across
CMakeLists.txt,release/release-manifest.json,CITATION.cff,CHANGELOG.md, andTODO.mdmust be committed directly to the release branch with message:chore(release): bump version to <version> and update release metadata - Delivery Vehicle: Use the PR targeting
devas the delivery tracking vehicle. Do not create Git tags or publish GitHub releases until all CI matrix jobs are green and merged.
Commit Message Format
Follow the conventional commit format: <type>(<scope>): <summary>
- Types:
feat,fix,perf,refactor,test,docs,chore - Scopes:
pipeline,core,memory,tui,device,smp,release,bpred - Keep summary lines under 72 characters, written in the imperative mood (e.g.,
feat(pipeline): implement scoreboard).
5. Adding Regression Tests
Any architectural, pipeline, or device behavioral changes must be validated against both 64-bit and 32-bit targets.
Adding a Test Suite in CMakeLists.txt
Use the simrv_add_runtime_test helper macro rather than manually defining test targets:
simrv_add_runtime_test(
simrv-myfeature-tests
tests/MyFeatureTests.cpp
my-feature-test
"gate;regress;pipeline"
)
Running Validation Gates
Before submitting a pull request, run the dual-architecture validation gates: