Random Instruction Generation

Writing directed tests is slow. We need an automated generator to produce valid execution streams with high randomness.

Why Random?

Randomly mixing arithmetic and load/store operations exposes pipeline hazards that humans miss.

  • Back-to-back dependent instructions (RAW hazard).
  • Branch misprediction sequences.
  • Random stalls and memory delays.

Constrained Random (SystemVerilog)

Building a custom generator allows fine-grained control. Here is a simple transaction class:


class riscv_instr_seq extends uvm_sequence;
    rand bit [6:0] opcode;
    rand bit [4:0] rd, rs1, rs2;
    rand bit [31:0] imm;
    // Constraints to ensure legal instructions
    constraint valid_opcode_c {
        opcode inside {OP_LUI, OP_JAL, OP_BRANCH, OP_LOAD, OP_STORE, OP_OP_IMM, OP_OP};
    }
    // Constraint: 20% chance of using x1 (RA) or x2 (SP) to stress test ABI
    constraint abi_stress_c {
        rs1 dist { [1:2] := 20, [3:31] := 80 };
    }
    // Constraint: 10% chance of creating a hazard (Src1 == PrevDest)
    constraint hazard_bias_c {
        rs1 == local_prev_rd dist { 1 := 10, 0 := 90 };
    }
    task body();
        repeat(1000) begin
            randomize();
            // ... send to driver ...
        end
    endtask
endclass
                            

Existing Tools

Don't reinvent the wheel. Industry standard open-source tools exist:

Tool Language Description
Google riscv-dv SystemVerilog The gold standard. Uses UVM to generate random assembly tests.
Torture Scala Older tool from UC Berkeley. Generates very complex sequences.
Force-RISCV C++ High-performance generator from the OpenHW Group.