Overview
On-the-Fly Instruction Stream Evolution is a simulation-based processor verification technique that generates one endless instruction stream without restrictions on the generated instructions by evolving that stream during simulation. In the cited RISC-V RTL verification approach, the generated stream is fed to both the RTL core under test and an Instruction Set Simulator (ISS) used as a reference model, and results are compared after each executed instruction to detect RTL errors immediately when they occur. [C1]
Motivation
The technique is presented as a contrast to flows where test generation and co-simulation are decoupled. In such decoupled flows, each test case may need to be generated, compiled, loaded, executed on both the reference simulator and test simulator, and then compared through logs; the evidence states that this makes feedback to the test generation engine more difficult. On-the-fly evolution avoids those restrictions by generating a single endless instruction stream during simulation. [C2]
Co-simulation role
The approach is used in a tightly coupled cross-level co-simulation setting. The ISS acts as the reference model for the RTL core, while the testbench feeds the generated instruction stream to both components and compares results after each executed instruction. This coupling is described as enabling an efficient and comprehensive testing process. [C1]
A test-memory diagram in the evidence shows the instruction generator producing the next instruction for both the RTL side and ISS side, while RTL and ISS test memories behave in the same way. [C3]
Generation strategy
The associated instruction stream generator supports endless generation of unrestricted instructions. Its baseline algorithm fully randomizes generated instructions, forming the foundation of the testing process. The evidence also describes modifications that guide generation toward interesting cases, including injecting a random instruction opcode to create a valid instruction while keeping instruction fields randomized. [C4]
The evidence includes pseudocode for InstrGenerator::next(), where an existing sequence can continue by returning sequence.next(), and with a stated random probability a new sequence can be started. [C5]
Handling pipeline effects
Generating an endless unrestricted stream complicates feeding the same instructions to an RTL core and an ISS because the RTL core may pre-fetch multiple instructions due to pipelining. Some pre-fetched instructions may not execute after a jump or trap, causing the ISS to fetch a different sequence of program counters than the RTL core. The cited method addresses this with instruction stream matching against a queue of pending instructions, reporting a mismatch if the ISS fetches an instruction that was not delivered to the RTL core. [C6]
The evidence also describes a core adapter that observes internal signal changes, especially in the pipeline, and notifies the test controller whenever the RTL core completes an instruction. It also provides access to RTL register values for comparison with the ISS. [C7]
Reported performance and effectiveness
The cited approach reports processing more than 200 million instructions per hour on a standard laptop, which the authors contrast with generate/compile/execute/compare loops. In a case study on a 32-bit pipelined RISC-V core from the MINRES The Good Folk Series, the approach is reported as effective in finding several serious bugs. [C8]
Relationship to implementation artifacts
The related Instruction Stream Generator is the code artifact that implements this technique by producing the evolving instruction stream used in the co-simulation flow. [C4]