SV-03
Constrained-Random
Verification in SystemVerilog
Directed Tests vs Constrained-Random — Coverage Space
Why Constrained-Random?
Writing directed tests for a 32-bit address bus requires 4 billion test cases to be exhaustive — obviously impossible. Constrained-random verification lets you define what is legal (the constraints) and let the solver pick random values within that legal space automatically. One test with 10,000 random transactions covers far more of the design space than 100 manually written directed tests.
1. rand and randc
| Keyword | Behavior | Use Case |
|---|---|---|
| rand | Random each call, repeats allowed | Most fields — address, data, control signals |
| randc | Cyclic — no repeat until all values seen | IDs, tags where exhaustive coverage matters |
SystemVerilog
class AXITxn; rand bit [31:0] addr; // random, repeats OK rand bit [31:0] data; rand bit [2:0] size; // AxSIZE: 0=byte, 1=half, 2=word rand bit [7:0] len; // AxLEN: burst length-1 randc bit [3:0] id; // cyclic IDs — exhaust all before repeat rand bit write; endclass initial begin AXITxn txn = new(); repeat (10) begin // randomize() returns 1 on success, 0 on constraint failure assert (txn.randomize()) else $fatal("Randomize failed!"); $display("addr=%0h len=%0d id=%0d", txn.addr, txn.len, txn.id); end end
2. Constraint Blocks
Constraints are Boolean expressions the solver must satisfy when generating random values:
SystemVerilog — Constraints
class AXITxn; rand bit [31:0] addr; rand bit [2:0] size; // 0-4 legal (byte to 16B) rand bit [7:0] len; // Address must be naturally aligned to transfer size constraint c_align { addr[2:0] == 3'b0 >> (3 - size); // alignment addr < 32'h8000_0000; // only low half of address space } // Burst length: AXI4 allows up to 256 beats constraint c_burst { len inside {[0:15]}; // short bursts for most tests size inside {0,1,2}; // byte, halfword, word only } // Weighted distribution: 70% writes, 30% reads rand bit write; constraint c_rw { write dist {1 := 70, 0 := 30}; } endclass
3. Constraint Operators
| Operator | Syntax | Example |
|---|---|---|
| inside | x inside {a, b, [c:d]} | len inside {[1:15]} |
| dist | x dist {v1 := w1, v2 := w2} | write dist {1:=70, 0:=30} |
| dist :/ | x dist {[a:b] :/ w} | addr dist {[0:'hFF]:/50, [0:'hFFFF]:/50} |
| implication | if (cond) {constraint} | if (write) {data != 0} |
| solve before | solve a before b | solve mode before len |
| unique | unique {a, b, c} | unique {id1, id2, id3} |
4. Inline Constraints — Overriding Per-Call
Override constraints for a specific randomize() call without modifying the class:
SystemVerilog — Inline constraints
AXITxn txn = new(); // Normal random assert (txn.randomize()); // Force a specific write to 4KB boundary — inline override assert (txn.randomize() with { write == 1; addr[11:0] == 0; // 4KB-aligned address len == 15; // max 16-beat burst }); // Temporarily disable a constraint txn.c_burst.constraint_mode(0); // disable c_burst assert (txn.randomize() with { len inside {[100:255]}; }); txn.c_burst.constraint_mode(1); // re-enable
5. Soft Constraints — Overridable Defaults
A soft constraint is a preference the solver honors unless a harder constraint from outside contradicts it:
SystemVerilog
class AXITxn; rand bit [7:0] len; // Default: prefer short bursts — but tests can override constraint c_default_len { soft len inside {[0:15]}; } endclass // Most tests: len will be 0..15 (soft constraint wins) txn.randomize(); // Stress test: force long bursts — inline overrides the soft txn.randomize() with { len inside {[200:255]}; }; // soft dropped
6. pre_randomize and post_randomize
SystemVerilog
class AXITxn; rand bit [31:0] addr; rand bit [7:0] len; bit is_last_beat; // derived field // Called BEFORE solver — enable corner-case mode if needed function void pre_randomize(); if ($urandom_range(0,9) == 0) // 10% chance c_burst.constraint_mode(0); // remove burst limit for stress endfunction // Called AFTER solver — compute fields the solver can't express function void post_randomize(); c_burst.constraint_mode(1); // always restore is_last_beat = (len == 0); // derived from randomized len addr[1:0] = 2'b00; // force word-align after solve endfunction constraint c_burst { len inside {[0:63]}; } endclass
7. Seed Control — Reproducibility
SystemVerilog + Simulator CLI
// Print seed at start so you can replay any failing run initial begin int seed; seed = $get_initial_random_seed(); $display("[SEED] %0d", seed); end // Per-object seed (for independently reproducible sub-components) txn.srandom(42); // fix this object's RNG to seed 42 // Simulator CLI seeds (to replay a specific run): // VCS: vcs +ntb_random_seed=12345 // Questa: vsim +seed=12345 // Xcelium: xrun -seed 12345
Next: Functional Coverage (SV-04) — now that you can generate random stimulus, measure which design behaviors have been exercised using covergroups and coverpoints.