CPU Core
The core/ directory contains the CVA6 RISC-V CPU. It is designed to be
compiled, simulated, and synthesized stand-alone. It has no dependency on the
APU, the board layer, or the build platform.
This independence is the foundation of CVA6’s industrial value. In a commercial
IP flow, the CPU core is often licensed separately from the SoC integration
layer; it must compile in environments where the board, peripherals, and
foundry libraries are not yet known. By ensuring that core/ has no
dependency on the outer layers, CVA6 can be integrated into many SoCs without
forcing each integrator to adopt a specific tool chain or board definition. The
core is where the RISC-V architecture is realized; everything else is context.
What the core implements
- ISA: 64-bit RISC-V I, M, A, C with privilege modes M, S, U (extensions grow with package: H, Sstc, RVB, Zicbo*, optional RVV, …).
- Pipeline: 6-stage baseline; config-gated multi-issue, slice-OoO, and
full OoO (
OoOEn) on production packages. - Threads: optional SMT2 (
NrHarts=2) with banked arch state. - Memory: TLBs, hardware PTW, configurable L1; L2/L3 attach on the APU side when enabled.
- Branch prediction: BTB/BHT/RAS plus upgraded prediction fabric / FTQ on primary targets.
- Observability: RVFI probes, debug triggers, PMU counters (including OoO and cache hierarchy groups where wired).
The same RTL elaborates as a minimal embedded core, a Linux-capable application core, an OoO server package, or an SMT bring-up target by selecting the right config package. That is the product model — not separate forks.
Product-level pages
| Topic | Page |
|---|---|
| Roadmap / U1–U10 map | Upgrade Program |
| Package comparison | SKU Matrix |
| Prediction / FTQ | Frontend Extensions |
| Issue width | Multi-Issue |
| Rename / IQ / ROB / LSQ | Out-of-Order |
| Dual hardware threads | SMT |
| H + Sstc | Hypervisor & Sstc |
| RVV / Ara | Vector (RVV) & Ara |
| Named server packages | Server Profiles |
| L2/L3 (APU) | L2 / L3 Cache |
| Multi-core cluster | Multi-Core Cluster |
How to read the core
The core is organized by pipeline stage and subsystem:
| Area | Subdirectory / file | Responsibility |
|---|---|---|
| Fetch | frontend/ | Prediction fabric, FTQ, instruction queue |
| Decode / Issue | issue_stage.sv, issue_read_operands.sv | Scoreboard, operand read, multi-issue |
| Slice / full OoO | cva6_slice_*.sv, ooo/ | Slice path / rename·IQ·ROB·LSQ (gated) |
| SMT | smt/ | Thread select, banked RF/PC/CSR |
| Execute | ex_stage.sv | ALU, FPU, multiplier, divider, branch unit, CSR, CVXIF |
| Load / Store | load_store_unit.sv, load_unit.sv, store_unit.sv, store_buffer.sv | Memory access, ordering, MMU interaction |
| Commit | commit_stage.sv, controller.sv | Retire, exception/flush, redirect |
| Caches / MMU | cache_subsystem/, cva6_mmu/, pmp/ | L1, PTW, TLB, PMP |
The config struct is the gate
config_pkg::cva6_cfg_t (defined in core/include/config_pkg.sv) is the single
source of truth for feature selection. A feature is enabled by extending the
struct and the per-target config packages (core/include/cv64a6_*_config_pkg.sv,
core/include/cv32a6_*_config_pkg.sv), not by editing modules ad hoc.
Key config domains:
cache_type_t/DCacheType— D$ subsystem selection.bp_type_t/BPType/BTBEntries/BHTEntries/RASDepth— branch predictor.vm_mode_t— virtual-memory mode (Sv32, Sv39, Sv48, Sv57).Axi*Width— memory-side bus width.InstrTlbEntries/DataTlbEntries— TLB sizing.NrScoreboardEntries/NrLoadBufEntries/MaxOutstandingStores— speculation / in-flight window.NrIssuePorts/SuperscalarEn— multi-issue width.OoOEn/SliceOoOEn— full vs slice out-of-order (mutually exclusive).NrHarts/ SMT policy fields — simultaneous multithreading.- (APU-side)
L2En/L3En/ prefetch — not L1 fields; see L2/L3 page.
check_cfg(...) assertions enforce legality (power-of-two geometry, region-rule
counts, OoO/SMT legality, etc.).
check_cfg is the contract enforcer. It encodes the architectural and
microarchitectural invariants that the RTL assumes. For example, if a cache
geometry is not a power of two, the indexing logic will silently produce
incorrect results; if the RAS depth is zero, the return-address stack will
misbehave. By expressing these as assertions in the config package, CVA6 turns
configuration errors from runtime mysteries into elaboration-time failures. This
is especially important when an agent or a new contributor extends the struct:
the assertions teach the valid design space.
Development guidelines
- Spec-anchored. An ISA-visible change must start with the spec anchor in
specs/riscv-spec.htmland updateAGENTS-specs-to-impl.md. - Config-gated. Extend
cva6_cfg_tand the target packages before touching modules. - Synth-clean. Use
always_ff/always_comb; no simulation-only constructs in the logic path; respect the async-active-low reset strategy. - Backend-friendly. Memories go through
tc_sram; clock gating throughtc_clk_gating; power cells throughtc_pwr. - Observable. Add RVFI probes, PMU events, and debug trigger visibility.
- Verified. Add a directed test and keep the compliance regression green.
- Ecosystem-safe. The feature must be discoverable (
misa/ISA string) and toolchain/SBI/Linux-visible.
Each guideline addresses a failure mode that is expensive to fix late in the design cycle. Spec-anchoring prevents subtle ISA incompatibilities. Config gating prevents one target from breaking another. Synth-clean code ensures that a change that simulates can also be fabricated. Backend-friendly cells ensure that synthesis and place-and-route flows can target multiple processes. Observability ensures that post-silicon debug is possible. Verification parity prevents regression. And ecosystem safety ensures that the feature is usable by the broader software stack, which is the ultimate customer of the RTL.
Sanctioned seams for new features
- New instructions — prefer the CVXIF coprocessor boundary (
core/cvxif_fu.sv,core/acc_dispatcher.sv). - New cache policy / L1 geometry — extend
cva6_cfg_tand select incore/cva6.sv. - New branch predictor — extend
bp_type_tand implement incore/frontend/. - New memory/TLB feature — extend
vm_mode_tor TLB parameters and the MMU incore/cva6_mmu/.
These seams are not arbitrary boundaries; they are the points where the RTL
structure naturally accepts variation. The CVXIF coprocessor interface exists
precisely because custom accelerators should not perturb the in-order pipeline.
The cache selection in core/cva6.sv exists because cache subsystem design is
a target-specific decision. The branch-predictor enum exists because predictor
choice is a classic area/timing/accuracy trade-off. By routing all feature
additions through these seams, CVA6 preserves the integrity of the pipeline
while allowing rich configurability.
Agent workflow for core work
- Open
AGENTS.mdand find the intent row (branch prediction, RAM, L2/L3, speculation, etc.). - Read the linked
agents/guides/AGENTS-*.mdandagents/spec/*.html. - Plan the config change, the code seam, and the verification.
- Run
g6lc-build test --open-sourceor the relevant arch group. - Update
AGENTS-specs-to-impl.md,AGENTS-specs-to-tests.md, andAGENTS-dts-validation.mdif needed.
See CPU Architecture Guidelines for a deeper look at the development patterns.