Skip to content
STIMSMITH

Control and Status Registers (CSRs)

Concept WIKI v7 · 7/12/2026

Control and Status Registers (CSRs) are processor registers defined as part of an ISA that hold the control and status state of the processor. In the RISC-V architecture, CSRs are special-purpose registers specified by the privileged architecture that enable trap handling, environment interaction, performance monitoring, and identification. They include identification registers (marchid, mvendorid, mhartid), trap delegation registers (medeleg, mideleg), the Machine Interrupt Register (mip), machine and unprivileged performance counters (mcycle, minstret, mcycleh, minstreth, cycle, cycleh, instret, instreth, time, timeh), and setup/enable registers (mhpmcounter3-31, mhpmcounter3-31h, mhpmevent3-31, mscratch, mcounteren). The article covers CSR-specific architectural rules (including mandatory illegal instruction exceptions on writes to read-only CSRs and on accesses to non-existent CSRs), CSR-aware test generation, CSR transitions as a fuzzing coverage signal in ProcessorFuzz, and CSR mismatches and bugs identified via symbolic co-simulation of MicroRV32.

Definition

Control and Status Registers (CSRs) are processor registers defined as part of an ISA that hold the control and status state of the processor. In the RISC-V architecture, CSRs are special-purpose registers specified by the privileged architecture that enable trap handling, environment interaction, performance monitoring, and identification. The set of RISC-V CSRs discussed in this article includes:

  • Identification (read-only): marchid (Machine Architecture ID Register), mvendorid (Machine Vendor ID Register), and mhartid (Hart ID Register).
  • Trap delegation (read/write): medeleg (Machine Exception Delegation Register) and mideleg (Machine Interrupt Delegation Register).
  • Interrupts: mip (Machine Interrupt Register).
  • Machine-mode performance counters: mcycle, minstret, mcycleh, minstreth, and mhpmcounter3-31 / mhpmcounter3-31h.
  • Unprivileged counters: cycle, cycleh, instret, instreth, time, timeh.
  • Counter setup/enable: mhpmevent3-31 (Machine Counter Setup CSR), mscratch (Machine Scratch CSR), and mcounteren (Machine Counter-Enable Register).

Architectural behavior and CSR-specific rules

Several CSR-access rules mandated by the RISC-V specification are explicit verification targets:

  • Illegal instruction exception on writes to read-only CSRs. The specification requires that an illegal instruction exception be raised if a write attempt to a read-only CSR occurs (e.g., marchid, mvendorid, mhartid).
  • Illegal instruction exception on accesses to non-existent CSRs. If a CSR instruction wants to access non-existent CSRs, the implementation must raise an illegal instruction exception. A non-compliant core that does not raise an exception in this case violates the specification.
  • Delegation to lower privilege. All traps at any privilege level are by default handled in machine mode. To increase performance, implementations can provide individual bits in medeleg (exceptions) and mideleg (interrupts) to delegate handling to a lower privilege level.
  • Writable machine-mode performance counters. mip, mcycle, minstret, mcycleh, and minstreth are writable; mcycle counts executed clock cycles and minstret counts retired instructions.

CSR instructions as a coverage group

In cross-level processor-verification work, the RISC-V instruction set is partitioned into six instruction groups for coverage purposes: Arithmetic, Control Flow, Memory, Special & System, Control & Status Register (CSR), and Other. The CSR group is described as equivalent to the Zicsr extension, and the cross-product of these six groups yields 36 coverage points in the corresponding case study.

CSRs in the RISC-V formal specification for functional test derivation

Because RISC-V's official ISA exists as formal specifications, these specifications form a ground truth that is directly reusable for test generation. In particular, RISC-V's formal specifications — the ISA itself, CSR behavior, and the memory model — serve as a cornerstone for functional test constraint derivation, providing the transition from a specification to functional test generation. A test specification built on these formal models includes, among other things, the set of allowed instructions as specified by the ISA, allowed CSR accesses and configurations, and the memory model. By transforming these specifications in a modular fashion, automatic SBST (Software-Based Self-Test) generation can target hard-to-test faults in scalar, single-issue pipelined processor core modules, with development effort scaling per supported extension module rather than per architecture. Test engineers formalize functional constraints in this test specification, which models the set of valid test behaviors that a BMC solver is allowed to generate.

CSR-aware test generation with RISC-V DV

The RISC-V DV framework supports CSR-related testing in multiple ways:

  • Specialized CSR test strategies: RISC-V DV provides additional specialized test strategies that focus on testing of CSRs, interrupts, and the MMU. These specialized strategies are documented as going beyond the default test strategies (such as basic_arithmetic_test, rand_instr_test, jump_stress_test, loop_test, and unaligned_load_store_test) used in evaluations that target the RV32IC ISA.
  • CSR state in the trace format: For each executed test, the RISC-V DV trace records changes of the internal simulation state, including the program counter, changes to a GPR or CSR, and a disassembly of the executed instruction. These traces are used to compare simulation results between a reference VP and a mutated VP, and the RISC-V DV framework can compute functional coverage information from them using SystemVerilog covergroup definitions.

CSR transitions as a coverage signal in hardware fuzzing

Motivation: limitations of register coverage

In DiFuzzRTL-style fuzzing, register coverage is used as the feedback signal. It is based on control registers instead of the mux control signals used by RFuzz, which makes it more scalable. For register coverage, DiFuzzRTL injects three new registers into each RTL module — regstate, covmap, and covsum — that are updated every clock cycle (making the metric clock-sensitive). All values in the control registers are hashed into regstate, which then selects a slot in covmap to attempt to write a 1. If that slot previously held 0, covsum is incremented. The covsum registers from all modules are summed to produce the final coverage value.

However, ProcessorFuzz (Canakci et al.) demonstrates a scenario where this register coverage can be misleading: a remainder register in a division module is 130 bits wide and controls multiple mux selection signals, so it qualifies as a control register. Most of the coverage increase comes from this wide remainder register, but in reality it does not contribute to real coverage because it is mostly concerned with the data-path and does not control the FSM.

ProcessorFuzz's CSR-transition coverage

ProcessorFuzz addresses this problem by using Control and Status Registers (CSRs) as the coverage signal. CSRs are the system registers in an ISA specification and are the registers that directly keep track of the current state of the processor. A value change in one of these registers most likely means a more significant change in the architectural state of the processor. ProcessorFuzz compares the CSR values of the previous instruction and the current instruction in an ISA simulation; if they differ in a new way not previously seen, the current input is considered interesting. The rationale for using transitions (rather than absolute values) is that this allows the previous state as well as the current state to be taken into account — a bug in one state may only occur if the state was reached via a certain other state.

ProcessorFuzz uses the same differential-fuzzing architecture as DiFuzzRTL — an ISA simulation as the golden reference model, with the result compared against an RTL simulation — but improves the coverage metric from DiFuzzRTL's register coverage to CSR-transition coverage. To optimize runtime, ProcessorFuzz executes the test case in the ISA simulation (which is generally faster than RTL simulation), determines whether the input is interesting from that simulation, and only runs the RTL simulation on inputs deemed interesting.

The rationale underlying ProcessorFuzz's choice is that CSRs are in charge of controlling and holding the state of the processor, so transitions in CSRs indicate that execution has reached a new processor state. Guiding the fuzzer with this feedback enables exploration of new processor states, and the approach is HDL-agnostic and does not require instrumentation in the processor design. ProcessorFuzz was evaluated on three open-source RISC-V processors (Rocket, BOOM, and BlackParrot) and reported triggering a set of ground-truth bugs 1.23× faster (on average) than DIFUZZRTL, while also exposing new bugs across the three cores and one new bug in a reference model (all confirmed by the corresponding developers).

CSRs in symbolic-execution-based cross-level verification

In a symbolic-execution + co-simulation case study using the MicroRV32 processor (RTL) and the open-source RISC-V VP's ISS (reference), the DUT/reference pair is configured for the RV32I+CSR ISA supported by MicroRV32, with CSR instructions generated by the symbolic-execution framework. CSRs are used both as targets for test generation and as sources of mismatches and bugs. The following findings were directly confirmed by the author of MicroRV32 and classified as an error in the RTL core (E), an error in the ISS (E*), or an implementation mismatch (M):

  • Non-existent CSR accesses must raise an exception. A CSR instruction that accesses non-existent CSRs must raise an illegal instruction exception. The RTL core does not raise this mandatory exception.
  • Read-only CSR bugs: The RTL core fails to raise the mandatory illegal instruction exceptions on writes to read-only CSRs (marchid, mvendorid, mhartid). The ISS is erroneous because it raises a trap at every read attempt of medeleg and mideleg.
  • Writable counter bugs: The RTL core raises a trap at every write access to mip, mcycle, minstret, mcycleh, and minstreth.
  • Counter mismatches (not bugs): Deviations in mcycle/minstret counter values between the RTL core and the ISS are classified as implementation mismatches rather than errors because the detailed counting behavior is not specified (mismatches in the cycle count are expected due to the abstract, non-cycle-accurate timing model in the ISS).
  • Set-of-CSR mismatches: Differences in the set of implemented CSRs are also captured:
    • The ISS additionally implements the unprivileged counters cycle, cycleh, instret, instreth, time, timeh, and the machine counters mhpmcounter3-31 / mhpmcounter3-31h.
    • The RTL core omits mhpmevent3-31, mscratch, and mcounteren.
    • These differences are reported in a table column whose values include "unimpl. Unprivileged CSR" and "unimpl. Privileged CSR" to indicate an implementation mismatch.
  • CSR filtering in injected-error experiments: In the bug-finding experiments on injected errors E0–E9 (24-hour runtime limit, RV32I support), the case study explicitly used assumptions that block the generation of CSR instructions (which are not part of RV32I) in order to filter the known CSR-related implementation mismatches found in the first part of the study.

CSRs as a target of instruction-category generation in CPU fuzzing (Cascade)

In the Cascade CPU-fuzzing tool, instructions are organized into hierarchical categories (listed in Appendix A of Cascade). Some groups of instructions behave in a context-dependent way — for example, all floating-point instructions are conditioned on whether an FPU is present and activated — and Cascade picks instructions hierarchically by first choosing a category and then a specific instruction, with both choices made randomly under probabilities that are varied between programs. CSRs are one of the architectural features that Cascade explicitly supports within this hierarchical category-based generation: the tool "supports complex FPU operations and CSR interactions," and "additionally supports exceptions and privilege switches as simple hopping instructions, which can only be picked under certain architectural conditions that are generated by the mechanism explained in Section 5." The operand-selection biases for these instructions grant higher probabilities to registers recently used as outputs. Because some CSR interactions are cf-ambiguous (their behavior depends on register values) and must be picked as either still or hopping, CSR instructions participate in the same control-flow sensitivity as other cf-ambiguous instructions (e.g., beq, lw) and are conditioned on the architectural state required for their execution.

Practical significance

For verification, CSRs are useful in several complementary roles:

  • As a formal specification input for functional test constraint derivation: The set of allowed CSR accesses and configurations, derived from the RISC-V formal specification, is embedded into test specifications consumed by SAT-solvers, evolutionary algorithms, bounded model checkers, genetic programming, and mutation-based greybox fuzzing, enabling tool-aided automatic SBST generation that targets hard-to-test faults in supported extension modules.
  • As instructions/state to generate: Generating CSR instructions and executing specialized CSR-focused test strategies exercises hardware/software interaction paths, including trap-handling and environment-interaction paths described in the RISC-V privileged architecture. In symbolic-execution-based verification of RV32I, CSR instructions are typically blocked to avoid known privileged-architecture mismatches. CPU fuzzers such as Cascade treat CSRs as a category of instructions selected hierarchically, support CSR interactions (alongside complex FPU operations, exceptions, and privilege switches), and condition CSR instruction generation on the architectural preconditions required for the interaction to occur.
  • As state to observe: Recording CSR (and GPR) changes in the RISC-V DV trace format, tracking CSR transitions for fuzzing feedback, and comparing CSR implementations across RTL and ISS surfaces specification violations, counter mismatches, and differences in the set of supported CSRs. Symbolic-execution-based cross-level verification specifically finds read-only CSR write-violation bugs, writable counter write-trap bugs, and non-existent-CSR access bugs, alongside counter and set-of-CSR implementation mismatches.
  • As a coverage signal: Tracking CSR transitions (comparing CSR values between consecutive instructions in the ISA simulation) enables a fuzzer to explore new processor states, since CSRs hold the processor's control and status state. Compared with DiFuzzRTL's control-register-based register coverage, CSR-transition coverage is motivated by avoiding misleading coverage increases from wide data-path registers that do not control the FSM, and is HDL-agnostic with no instrumentation in the processor design.

In evaluations of the RISC-V DV framework, the five default test strategies focus on arithmetic, branches, jumps, memory access, and randomized instructions; CSR-specific testing is treated as a separate, specialized capability that lies outside the default RV32IC evaluation scope but is provided by the framework.

LINKED ENTITIES

1 links

CITATIONS

6 sources
6 citations
[1] CSRs are system registers in an ISA specification that hold the architectural control and status state of the processor, and ProcessorFuzz compares CSR values between consecutive instructions in an ISA simulation to track CSR transitions for fuzzing feedback. ProcessorFuzz: Guiding Processor Fuzzing using Control and Status Registers
[2] In RISC-V, CSRs specified by the privileged architecture include identification registers (marchid, mvendorid, mhartid), trap delegation registers (medeleg, mideleg), the Machine Interrupt Register (mip), machine and unprivileged performance counters (mcycle, minstret, mcycleh, minstreth, cycle, cycleh, instret, instreth, time, timeh), and counter setup/enable registers (mhpmcounter3-31, mhpmcounter3-31h, mhpmevent3-31, mscratch, mcounteren). Processor Verification using Symbolic Execution - AGRA | Uni Bremen
[3] The RISC-V specification mandates that an illegal instruction exception be raised if a write attempt to a read-only CSR occurs (e.g., marchid, mvendorid, mhartid), and that an illegal instruction exception must be raised when a CSR instruction accesses non-existent CSRs. Processor Verification using Symbolic Execution - AGRA | Uni Bremen
[4] In the symbolic-execution + co-simulation case study on MicroRV32 and the open-source RISC-V VP ISS, the RTL core fails to raise the mandatory illegal instruction exceptions on writes to read-only CSRs and on accesses to non-existent CSRs; the ISS is erroneous because it raises a trap at every read attempt of medeleg and mideleg; and the RTL core raises a trap at every write access to mip, mcycle, minstret, mcycleh, and minstreth. Processor Verification using Symbolic Execution - AGRA | Uni Bremen
[5] Counter-value deviations between the RTL core and the ISS are classified as implementation mismatches rather than errors because the detailed counting behavior is not specified, and the ISS additionally implements unprivileged counters (cycle, cycleh, instret, instreth, time, timeh) and machine counters (mhpmcounter3-31, mhpmcounter3-31h) while the RTL core omits mhpmevent3-31, mscratch, and mcounteren. Processor Verification using Symbolic Execution - AGRA | Uni Bremen
[6] In injected-error experiments on E0–E9, the case study used assumptions that block the generation of CSR instructions (which are not part of RV32I) to filter the known CSR-related implementation mismatches. Processor Verification using Symbolic Execution - AGRA | Uni Bremen

VERSION HISTORY

v7 · 7/12/2026 · minimax/minimax-m3 (current)
v6 · 7/2/2026 · minimax/minimax-m3
v5 · 6/19/2026 · minimax/minimax-m3
v4 · 6/19/2026 · minimax/minimax-m3
v3 · 6/19/2026 · minimax/minimax-m3
v2 · 6/7/2026 · minimax/minimax-m3
v1 · 5/30/2026 · gpt-5.5