Overview
The Random Instruction Generator (RIG) is a verification code artifact used to generate instruction sequences for the top-level verification of a full RISC-V processor. In the cited RISC-V verification flow, the device under verification is a two-way superscalar out-of-order microprocessor implementing the RISC-V ISA, and top-level tests interact with the processor through assembly-language instruction sequences. The RIG was developed together with an Instruction Set Simulator (ISS) to help exercise architectural features of the processor, including rarely encountered corner cases. [1] [2]
Purpose in verification
The generator is described as a constrained random instruction generator. Its verification goal is to produce instruction sequences that can effectively hit processor architectural features. It supports:
- Instruction-level randomization, such as varying operands and immediate values.
- Sequence-level randomization, such as instruction ordering and dependencies. [2]
The RIG can generate both generic and directed test instruction sequences by changing generation parameters, and it also exposes an interface for handwritten assembly to support more directed tests. [3]
Inputs and tunable parameters
The RIG is controlled by parameters that shape the generated program. The documented parameter groups include:
| Parameter group | Examples |
|---|---|
| Instruction type mix | shifts, compares, arithmetic/logical operations, loads, stores |
| Dependencies | read-after-write (RAW), write-after-read (WAR), write-after-write (WAW), memory-address dependency between load/store pairs |
| Loops and branches | for-loop rate, nested-loop rate, forward-branch rate |
The instruction-type probabilities for shifts, compares, operations, loads, and stores are defined to add up to 1. Example semantics include a RAW hazard-rate parameter of 0.1, meaning the newly generated instruction has a 10% chance of using the previous instruction's destination register as a source operand, and a store parameter of 0.2, meaning a 20% chance that a newly generated instruction is a store. [2]
Outputs
The RIG generates the main program, any generated functions, and data. It emits two output files:
- A hex file containing instructions in little-endian hex format, positioned in memory.
- An assembly file showing the instructions in assembly format with their corresponding memory addresses. [2]
Load/store generation
For load and store tests, the generator must create memory accesses that target valid data locations. The effective memory address is computed from a base register and a sign-extended 12-bit offset:
BaseAddress = RF[rs1] + Immediate
Before emitting a load/store instruction, the RIG emits an ADDI instruction to set up the base register value used by the load/store instruction. The implementation uses SystemVerilog randomization with constraints over two randomized vectors so that their sum:
- lies within the configured data-memory address range,
- is word-aligned by requiring the sum modulo 4 to equal zero,
- avoids negative sign extension by requiring the most-significant bit of each value to be zero. [3]
Loop generation
The RIG can generate for-loop code structures to resemble real-world program constructs. A generated loop contains:
- an iteration counter register,
- a parameterized number of random instructions inside the loop,
- a flag register that records the exit condition,
- a backward branch if the exit condition has not been triggered. [3]
The documented example initializes an index register, emits random instructions in the loop body, increments the index register, compares it with the loop iteration count, and branches backward while the flag remains set. [4]
Role in MAB-driven simulation
In the referenced verification methodology, the RIG is used in a flow that applies a Multi-Armed Bandit (MAB) approach to automate test application for the full RISC-V processor. At the top level, each test sequence corresponds to an assembly instruction sequence executed on the processor. [2]