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.
Writing directed tests is slow. We need an automated generator to produce valid execution streams with high randomness.
Randomly mixing arithmetic and load/store operations exposes pipeline hazards that humans miss.
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
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. |