RISC-V custom instruction verification workflow using reference models, test generation, RTL comparison, functional coverage and sign-off
Published On: 23rd August 2026|Last Updated: 23rd August 2026|By |
Share This Article

RISC-V gives processor designers an unusual degree of architectural freedom. A team can implement the standard base ISA and extensions while adding proprietary instructions for signal processing, AI, cryptography, bit manipulation, control, or other workload-specific functions. Adding an instruction to the RTL, however, is only the beginning.

A custom instruction changes several verification artefacts at the same time: the architectural specification, decoder, execution logic, reference model, instruction generator, test suite, coverage model and often the software toolchain. If those components interpret the new instruction differently, a regression can look healthy while the processor is wrong.

The practical rule is therefore simple: verify a custom RISC-V instruction as a new architectural contract, not merely as a new RTL datapath operation.

A defensible flow requires an independently defined expected behaviour, a targeted and constrained-random stimulus, an architectural comparison, functional coverage, and regression evidence demonstrating that the extension has not changed standard RISC-V behaviour. The current RISC-V specification deliberately reserves major opcode space labelled custom-0 through custom-3 for custom extensions in the base 32-bit instruction format and recommends these areas instead of opcode space reserved for future standard extensions [1]. That makes extension design easier. It does not make verification automatic.

Why custom instructions create a different verification problem

For a standard RISC-V instruction, a verification team has several independent sources of truth: the ratified specification, architectural tests, mature reference models and existing software tools. A proprietary instruction does not begin with the same ecosystem. Your own project must define what the instruction means.

That immediately raises questions such as:

  • Which bit pattern identifies it?
  • Which operands are read?
  • Which architectural state can it modify?
  • What happens when source and destination registers alias?
  • Does XLEN change the result?
  • Is the operation legal in every supported privilege mode?
  • Can it trap?
  • Does it access memory?
  • What happens on arithmetic boundaries?
  • Does it interact with CSRs or exceptions?
  • What should happen for unused encodings?
  • Can the new decoder pattern overlap an existing or future instruction?

If these questions are answered only inside the RTL, verification has already lost an important degree of independence.

Start with a custom-instruction verification contract

Before writing random constraints or coverage bins, turn the architectural proposal into an explicit verification contract. A useful contract separates architecturally visible behaviour from implementation detail.

Contract itemWhat should be defined
EncodingOpcode, funct fields, instruction format and all legal encoding combinations
OperandsSource registers, destination registers, immediates and operand interpretation
ResultExact architectural result for every legal operand class
XLEN behaviourRV32/RV64 differences, truncation, sign extension or zero extension
Architectural stateGPR, CSR, memory, flags or other architecturally visible effects
LegalitySupported modes/configurations and conditions that make the instruction illegal
ExceptionsExpected exception or trap behaviour and whether state may change
Memory semanticsAddress generation, alignment, ordering and side effects where relevant
AliasingBehaviour when rd, rs1 or rs2 refer to the same register
Reserved casesRequired behaviour for unimplemented or invalid encodings

This contract should be version-controlled and reviewed by architecture, design, verification and software stakeholders.

RISC-V’s toolchain conventions also distinguish non-standard extensions using X-prefixed extension names and provide conventions for vendor-extension naming, which is useful when the instruction must propagate into the broader software environment.[2]

Keep architecture and microarchitecture separate

Suppose a custom multiply-accumulate operation takes three cycles internally. If the ISA contract says only that the correct result appears architecturally when the instruction retires, a verification environment should not accidentally define “three-cycle latency” as an architectural requirement unless software or another architectural interface can observe it. Unit-level checks may need to verify latency, stalls or pipeline handshaking. CPU-level architectural checking should focus on externally visible behaviour.

Keeping those levels distinct avoids making the reference model unnecessarily dependent on the RTL implementation.

The reference model must be an oracle, not a copy of the RTL

A reference model is useful because the RTL and model can execute the same programme and their architecturally visible behaviour can be compared. But adding a custom instruction creates a subtle risk: the team can put the same misunderstanding into both implementations.

If the RTL designer and model author copy the same pseudo-code without independently checking the specification, RTL-versus-model agreement proves only that the two implementations agree.

It does not prove that the intended architecture is correct.

A stronger process is:

  1. Freeze the instruction contract
  2. Derive independent expected-value examples
  3. Validate the reference-model implementation against those examples
  4. Then use the model for large-scale RTL comparison

Spike, for example, provides mechanisms for adding the behaviour, encoding and build support required to simulate new instructions [5].

Whether Spike, Sail, a commercial model or an internal model is used, the verification principle is the same: model configuration must match the actual processor configuration, and custom semantics must be reviewed independently.

Alpinum’s existing guide to retirement-level RISC-V lockstep co-simulation explains the broader step-and-compare methodology in more detail.

Do not start with constrained random: start with semantic tests

A random generator is excellent for interaction testing. It is not the best first mechanism for establishing that the instruction itself has the right semantics. Begin with small directed tests that are easy to reason about.

For an arithmetic custom instruction, that normally means representative cases such as:

  • Zero operands
  • Minimum and maximum values
  • Positive and negative values where signed arithmetic is relevant
  • Values around overflow or saturation boundaries
  • Destination equal to one source
  • Destination equal to both sources where legal
  • Register x0 as a source or destination
  • RV32 versus RV64 behaviour where applicable

For an instruction that can trap, deliberately include both legal and illegal cases.

For a memory-related custom instruction, add alignment boundaries, permissions, page or region boundaries, faults and ordering cases relevant to the architectural contract. The objective is not to produce hundreds of hand-written tests. It is to establish a trusted semantic baseline before broad exploration begins.

Then extend the instruction generator

Once individual semantics are stable, the extension must participate in generated instruction streams.

CHIPS Alliance’s open-source riscv-dv supports custom processor targets, user extensions, directed instruction streams, hand-coded assembly/C tests, multiple instruction-set simulators and instruction-generation coverage[3]. 

Its configuration mechanism also allows engineers to adapt the generator to processor capabilities and add new instruction streams rather than modifying upstream classes unnecessarily[4]. 

For the custom instruction, the generator needs more than knowledge of the mnemonic. It needs constraints that describe when the instruction is legal and stimulus rules that create useful surrounding context.

That surrounding context matters because many processor failures are not visible when an instruction is executed in isolation.

Useful generated interactions include:

  • Data dependencies on the immediately preceding instruction
  • Consumers immediately after the custom instruction
  • rd/rs aliasing
  • Branches around the custom instruction
  • Exceptions and interrupts near execution
  • Back-to-back custom instructions
  • Transitions between custom and standard instructions
  • Privilege transitions where relevant
  • Memory-system activity for stateful or memory-related operations

For a broader explanation of when constrained-random and directed stimulus should be used, see Alpinum’s RISC-V test-generation and coverage-closure guide.

Engineers developing these wider CPU-verification capabilities can also use Alpinum’s RISC-V CPU verification and riscv-dv training programme. The verified course covers instruction-stream generation, riscv-dv, constraints, functional coverage and practical CPU/SoC workflows; it explains the impact of custom instructions at a high level rather than claiming to teach design-specific custom-extension implementation.

Build functional coverage around verification risk

Seeing the new opcode one thousand times does not demonstrate meaningful verification.

The coverage model should answer:

Which semantically distinct situations must occur before we are prepared to sign off this custom instruction?

That normally requires several dimensions.

A practical custom-instruction coverage matrix

Coverage dimensionExample bins
InstructionEvery custom opcode/variant
Operand classzero, one, maximum, minimum, typical, boundary
Register behaviourrd != rs1/rs2, rd=rs1, rd=rs2, x0 cases
XLEN/configurationsupported 32/64-bit or implementation variants
Privilegeevery legal privilege mode
Legalitylegal and deliberately illegal encodings
Exceptionno exception, each applicable exception type
Dependencyindependent, RAW/WAW-relevant sequences
Neighbour instructionALU, branch, load/store, CSR, another custom instruction
Result classnormal result, overflow boundary, saturation boundary or other operation-specific category
State effectexpected GPR/CSR/memory change and expected no-change cases

Cross coverage is valuable, but it should be selective. Crossing every operand category with every instruction, privilege state, exception and surrounding instruction can create an enormous model containing combinations that are meaningless or impossible.

The verification plan should therefore classify crosses as:

  • Required
  • Useful
  • Illegal
  • Structurally unreachable

Alpinum’s broader article on functional coverage for RISC-V verification discusses coverpoints, cross-coverage, and closure in greater depth.

Compare architectural state at instruction retirement

Once a trusted model and generated stimulus exist, CPU-level checking becomes much stronger. Both the DUT and reference model execute the same programme. At instruction retirement, the environment compares the architectural effects that are relevant to the implementation.

Depending on the design, that can include:

  • Program counter
  • Destination GPR value
  • Relevant CSR changes
  • Exceptions
  • Privilege state
  • Selected memory effects

Retirement-level comparison is useful because transient pipeline states can differ legitimately between implementations. The comparison focuses instead on the state software is architecturally entitled to observe.

When a custom instruction diverges from the reference model, capturing the first mismatching retirement point also makes debug considerably more focused than waiting for a final software signature to fail.

Verify what the custom instruction must not break

This is one of the most important parts of custom-extension verification. The new instruction is not verified merely because it produces correct results. The extension must also leave the standard processor behaviour intact.

That includes checking for:

  • Accidental decode overlap
  • Standard instructions being reinterpreted
  • Illegal encodings becoming legal unintentionally
  • Incorrect trap behaviour
  • Unintended CSR changes
  • Pipeline hazards introduced by the new execution path
  • Corruption caused by stall or flush handling
  • Standard-instruction regressions near the custom decoder
  • Reset behaviour of any new architectural state

RISC-V’s current Architectural Certification Tests explicitly state that the tests are designed to demonstrate conformance to the RISC-V specification and are not verification tests; additional verification should be run on processors. The current ACT4 framework uses configuration data and the Sail reference model to generate expected results for standard architectural behaviour.[6]

That distinction is especially important for a custom extension. Run the relevant standard architectural tests again after the extension is integrated, but do not treat them as proof that the proprietary instruction itself is fully verified.

Software validation is a separate but connected problem

A processor can implement a custom instruction correctly in RTL while the software toolchain still emits the wrong encoding, uses the wrong operand order or fails to expose the operation correctly to application software. That means hardware verification and software enablement should be connected but not conflated.

A useful staging strategy is:

Early verification: inject known machine encodings or controlled assembly so CPU behaviour can be tested before a full compiler implementation exists. Toolchain verification: confirm assembler encoding, disassembly and any compiler intrinsic or built-in behaviour once software support is available. System verification: execute representative application code and ensure the software stack uses the extension as intended.

Recent Canonical guidance on RISC-V custom instructions illustrates how custom architectural features also require deliberate software support rather than ending at the hardware boundary.[8] 

Where formal verification can add value

Simulation and reference-model comparison answer many custom-instruction questions well. Formal verification can complement them where the state space is narrow enough and the property can be stated precisely.

Examples include proving that:

  • A custom decoder cannot overlap selected standard decoder patterns
  • An illegal form never writes architectural state
  • A mathematical operation satisfies its specified relation for every possible operand
  • Privilege conditions prevent execution in a forbidden mode
  • Flush or exception behaviour cannot incorrectly commit the instruction
  • A selected implementation is equivalent to a simpler architectural function

Formal should be applied where it creates stronger evidence than another large simulation campaign, not because every custom instruction needs a whole-processor proof.

For the broader methodology, see Alpinum’s guide to formal verification in RISC-V verification.

Seven common custom-instruction verification mistakes

MistakeWhy it is dangerousBetter approach
Treating RTL as the specificationModel and testbench may copy the same bugFreeze an architectural contract first
Updating the model and RTL from identical implementation codeCreates correlated errorsReview independent expected semantics
Verifying only nominal operandsBoundary failures remain invisiblePartition operand space deliberately
Counting opcode hits as coverageRepeated execution may exercise only one semantic caseCover operand/state/interaction classes
Randomising before directed semantics workFailures become hard to diagnoseEstablish small trusted tests first
Testing only the new featureStandard ISA regressions can escapeRerun base/extension architectural and DV regressions
Modifying the compiler too earlyToolchain bugs can obscure CPU bugsDecouple early hardware verification from full compiler enablement

A sign-off framework for a custom RISC-V instruction

A useful sign-off review can be organised around six independent evidence gates.

Gate 1: Specification consistency

Every encoding, operand, result, exception and state effect is explicitly defined.

Gate 2: Reference-model confidence

The model supports the production configuration and has been validated against independent expected-value tests.

Gate 3: Stimulus completeness

Directed tests establish semantics; generated tests exercise dependencies, interactions and corner conditions.

Gate 4: Checking quality

Architectural mismatches are detected reliably, with sufficient state visibility to identify the first divergence.

Gate 5: Functional coverage closure

Required semantic bins and crosses are hit, or justified as illegal/unreachable.

Gate 6: Regression protection

Standard RISC-V architectural behaviour and surrounding microarchitecture continue to pass after the extension is enabled.

A project that cannot provide evidence for all six gates may have a working instruction, but it does not yet have a defensible verification argument.

How this fits into the wider RISC-V verification strategy

Custom instructions should not become an isolated verification activity. They sit within a larger CPU programme that encompasses architectural configuration, privilege behaviour, instruction generation, compliance, coverage, microarchitecture, software, and SoC integration.

Alpinum’s analysis of where RISC-V projects typically lose verification time makes the same wider point: reference-model assumptions, stimulus quality, configuration scope and system integration all need to remain aligned.

This matters particularly for custom extensions because the project itself must define and maintain several pieces of verification infrastructure that standard ISA features already provide.

Conclusion

Verifying a custom RISC-V instruction is not primarily a question of how many tests execute the opcode. It is a question of whether the project can show consistent evidence from specification to sign-off.

The strongest flow begins with a precise architectural contract, validates an independent reference model, establishes semantics with directed tests, expands exploration through constrained instruction generation, measures meaningful functional coverage, compares architectural behaviour and finally proves that the standard ISA still behaves correctly.

That methodology keeps architectural customisation from becoming verification ambiguity.

For engineers who want to build the broader CPU-verification capability behind this process: including RISC-V architecture, riscv-dv, instruction generation, functional coverage, UVM workflows, architectural verification and software-driven SoC testing—Alpinum provides RISC-V verification training for CPU and SoC engineers.

References

[1] RISC-V International, “RV32/64G Instruction Set Listings,” RISC-V Ratified Specifications Library, 2026. https://docs.riscv.org/reference/isa/v20260120/unpriv/rv-32-64g.html

[2] RISC-V International, “Conventions for Vendor Extensions,” RISC-V Toolchain Conventions, accessed Aug. 22, 2026. https://github.com/riscv-non-isa/riscv-toolchain-conventions/blob/main/src/toolchain-conventions.adoc

[3] CHIPS Alliance, “riscv-dv: Random Instruction Generator for RISC-V Processor Verification,” GitHub repository, accessed Aug. 22, 2026. https://github.com/chipsalliance/riscv-dv

[4] CHIPS Alliance, “riscv-dv Configuration,” accessed Aug. 22, 2026. https://github.com/chipsalliance/riscv-dv/blob/master/docs/source/configuration.rst

[5] RISC-V Software Source, “Spike RISC-V ISA Simulator,” GitHub repository, accessed Aug. 22, 2026. https://github.com/riscv-software-src/riscv-isa-sim

[6] RISC-V International, “RISC-V Architectural Certification Tests,” GitHub repository, accessed Aug. 22, 2026. https://github.com/riscv/riscv-arch-test

[7] K. McDermott, “Getting Started with RISC-V Verification,” RISC-V International, May 18, 2020. https://riscv.org/blog/getting-started-with-risc-v-verification/

FAQs

How do you verify a custom RISC-V instruction?

Define its architectural semantics first, implement an independently reviewed reference model, create directed semantic tests, add constrained instruction generation, compare architectural state and close functional coverage before regression sign-off.

Does riscv-dv support custom RISC-V processors and instructions?

riscv-dv supports custom processor targets, user extensions, additional instruction streams, directed assembly/C tests and ISS-based co-simulation. The project still needs to provide the custom instruction semantics and appropriate checking/coverage.

Do the RISC-V Architectural Certification Tests fully verify custom instructions?

No. The RISC-V project explicitly states that the Architectural Certification Tests are not verification tests and that additional processor verification is required. Proprietary custom instructions also require project-specific verification evidence.

Should a custom RISC-V instruction be added to the reference model?

Yes, when model-based comparison is part of the verification strategy. The model must implement the intended architectural behaviour and should be validated independently, so that the same interpretation error is not propagated into both the RTL and the model.

What functional coverage is useful for custom instructions?

Useful coverage normally includes instruction variants, operand classes, register aliasing, legal and illegal states, privilege conditions, exceptions, dependencies and interactions with surrounding standard instructions

Do custom instructions need compiler support before hardware verification can begin?

Not necessarily. Early CPU verification can use controlled machine encodings or assembly. Compiler, assembler and application-level support can then be verified as a separate software-enablement layer.

Share This Article
Persian Pick
Written by : Mike Bartley

Mike started in software testing in 1988 after completing a PhD in Math, moving to semiconductor Design Verification (DV) in 1994, verifying designs (on Silicon and FPGA) going into commercial and safety-related sectors such as mobile phones, automotive, comms, cloud/data servers, and Artificial Intelligence. Mike built and managed state-of-the-art DV teams inside several companies, specialising in CPU verification.

Mike founded and grew a DV services company to 450+ engineers globally, successfully delivering services and solutions to over 50+ clients.

Mike started Alpinum in April 2016 to deliver a range of start-of-the art industry solutions:

Alpinum AI provides tools and automations using Artificial Intelligence to help companies reduce development costs (by up to 90%!) Alpinum Services provides RTL to GDS VLSI services from nearshore and offshore centres in Vietnam, India, Egypt, Eastern Europe, Mexico and Costa Rica. Alpinum Consulting also provides strategic board level consultancy services, helping companies to grow. Alpinum training department provides self-paced, fully online training in System Verilog, UVM Introduction and Advanced, Formal Verification, DV methodologies for SV, UVM, VHDL and OSVVM and CPU/RISC-V. Alpinum Events organises a number of free-to-attend industry events

You can contact Mike (mike@alpinumconsulting.com or +44 7796 307958) or book a meeting with Mike using Calendly (https://calendly.com/mike-alpinum-consulting).

Connect With Us

We understand that you might have a unique situation that you would like to discuss with us, or just be curious to learn more about our service offerings. Regardless, we would like to hear from you – please feel free to contact us.