SystemVerilog Randomization I
rand/randc
Basic constraints
inside
Ranges and exclusions
Inline constraints
pre/post_randomize
Concept and setup
Understand what you will build
Day 28 — SystemVerilog Randomization I
Simulation status (28 Oct 2026): run_day28.sh builds and runs all three testbenches on Verilator 5.052, and all pass: 1,000 legal transactions, a full randc cycle and the impossible constraint rejected. Verilator needs the z3 solver installed to run randomize(). Details: Week 6 validation record (VALIDATION.md).
XLS objectives: rand/randc, basic constraints, inside, ranges/exclusions, inline constraints, pre/post_randomize.
Files: transaction.sv, tb_randomization.sv (1,000 samples), tb_randc_cycle.sv, tb_impossible_constraint.sv, randomization_flow.svg, LABS.md.
Learner validation sequence
- Constrain one field to a small legal range and check every generated item against that range.
- Add a relationship between two fields, then verify the relationship in the testbench rather than trusting the constraint text alone.
- Check the return value from
randomize()and treat failure as a test result that needs diagnosis. - Run the
randcdemonstration long enough to observe the full value cycle; a short sample does not prove the cycle property. - Reproduce any unexpected item by saving the seed, tool version, constraint set, and first failing transaction.
An inline constraint narrows the legal set for one call; it does not replace the class's base constraints. A contradictory inline condition should produce a reported randomization failure, not a fallback value that the test accepts.
Compatibility: class constraints and randc need Verilator 5 with the z3 solver, or a commercial simulator; Icarus Verilog 12 does not support them. run_day28.sh builds and runs all three testbenches and checks their PASS lines.
Acceptance: confirm 1,000 legal transactions, randc full cycle, inline override, and expected rejection of impossible constraints; attach compiler/runtime versions and logs.
Architecture
Follow the verification data flow
Worked source
Study the supplied implementation
tb_impossible_constraint.sv
`timescale 1ns/1ps
`include "transaction.sv"
module tb_impossible_constraint;
bus_transaction tx;
initial begin
tx=new();
// Deliberate negative test: address 0x0200 is excluded by class constraint.
if (tx.randomize() with { address == 16'h0200; })
$fatal(1,"NEGATIVE_TEST_FAILED: contradictory constraint unexpectedly solved");
$display("EXPECTED_RANDOMIZATION_FAILURE: impossible constraint rejected");
$finish;
end
endmodule
tb_randc_cycle.sv
`timescale 1ns/1ps
`include "transaction.sv"
module tb_randc_cycle;
bus_transaction tx;
bit [3:0] seen;
initial begin
tx=new();
for (int i=0;i<4;i++) begin
if (!tx.randomize()) $fatal(1,"randc solve failed");
if (seen[tx.channel]) $fatal(1,"randc repeated before completing cycle");
seen[tx.channel]=1'b1;
end
if (seen !== 4'b1111) $fatal(1,"randc did not cover all channels");
$display("RANDC_CYCLE_PASS");
$finish;
end
endmodule
tb_randomization.sv
`timescale 1ns/1ps
`include "transaction.sv"
module tb_randomization;
bus_transaction tx;
int unsigned op_count[8];
int unsigned channel_count[4];
int unsigned boundary_count;
initial begin
tx = new();
// Reproducibility is tool-specific; capture the simulator seed in logs.
for (int i=0; i<1000; i++) begin
if (!tx.randomize()) $fatal(1, "Randomization failed at iteration %0d",i);
if (tx.address < 16'h0100 || tx.address > 16'h0ffc || tx.address % 4 != 0 || tx.address == 16'h0200)
$fatal(1,"Address constraint violated");
if (!(tx.opcode inside {0,1,2,4})) $fatal(1,"Opcode constraint violated");
op_count[tx.opcode]++;
channel_count[tx.channel]++;
if (tx.address == 16'h0100 || tx.address == 16'h0ffc) boundary_count++;
end
if (tx.generated_count != 1000) $fatal(1,"post_randomize counter mismatch");
// Inline constraint forces a legal opcode, not an illegal override.
if (!tx.randomize() with { opcode == 4; }) $fatal(1,"Inline randomization failed");
if (tx.opcode != 4) $fatal(1,"Inline constraint ignored");
for (int ch=0;ch<4;ch++) if (channel_count[ch] == 0) $fatal(1,"randc channel missing %0d",ch);
$display("DAY28_PASS count=%0d boundary_hits=%0d opcode0=%0d opcode1=%0d opcode2=%0d opcode4=%0d", tx.generated_count, boundary_count, op_count[0],op_count[1],op_count[2],op_count[4]);
$finish;
end
endmodule
transaction.sv
// Day 28: constraints and randomization; requires an SV constraint-capable simulator.
class bus_transaction;
rand bit [15:0] address;
rand bit [7:0] data;
rand bit [2:0] opcode;
randc bit [1:0] channel;
int unsigned generated_count = 0;
int unsigned last_checksum;
constraint c_address { address inside {[16'h0100:16'h0ffc]}; address % 4 == 0; address != 16'h0200; }
constraint c_opcode { opcode inside {0, 1, 2, 4}; }
constraint c_data { data inside {[0:255]}; }
function void pre_randomize();
// Hook: state-dependent controls may be applied before solving.
endfunction
function void post_randomize();
generated_count++;
last_checksum = address ^ data ^ opcode ^ channel;
endfunction
function void display();
$display("TX address=%04h data=%02h opcode=%0d channel=%0d", address, data, opcode, channel);
endfunction
endclass
Guided and independent work
Complete the lab checklist
Day 28 — XLS lab traceability
- [ ] Lab 1 — rand address: Code and demonstrate rand address with simulation evidence; document observations or debug result.
- [ ] Lab 2 — rand data: Code and demonstrate rand data with simulation evidence; document observations or debug result.
- [ ] Lab 3 — randc opcode: Code and demonstrate randc opcode with simulation evidence; document observations or debug result.
- [ ] Lab 4 — Range constraint: Code and demonstrate range constraint with simulation evidence; document observations or debug result.
- [ ] Lab 5 — inside set: Code and demonstrate inside set with simulation evidence; document observations or debug result.
- [ ] Lab 6 — Exclusion constraint: Code and demonstrate exclusion constraint with simulation evidence; document observations or debug result.
- [ ] Lab 7 — Aligned address: Code and demonstrate aligned address with simulation evidence; document observations or debug result.
- [ ] Lab 8 — Legal opcode: Code and demonstrate legal opcode with simulation evidence; document observations or debug result.
- [ ] Lab 9 — Boundary values: Code and demonstrate boundary values with simulation evidence; document observations or debug result.
- [ ] Lab 10 — Inline constraint: Code and demonstrate inline constraint with simulation evidence; document observations or debug result.
- [ ] Lab 11 — pre_randomize: Code and demonstrate pre_randomize with simulation evidence; document observations or debug result.
- [ ] Lab 12 — post_randomize: Code and demonstrate post_randomize with simulation evidence; document observations or debug result.
- [ ] Lab 13 — 100 transactions: Code and demonstrate 100 transactions with simulation evidence; document observations or debug result.
- [ ] Lab 14 — 1000 transactions: Code and demonstrate 1000 transactions with simulation evidence; document observations or debug result.
- [ ] Lab 15 — Impossible-constraint debug: Code and demonstrate impossible-constraint debug with simulation evidence; document observations or debug result.
The supplied examples run on Verilator 5.052 and cover several labs; each lab still needs your own evidence and review.
Assignment and evidence
Demonstrate the required engineering outcome
Debug assignment
Debug impossible constraint
Create constrained transaction generator
Submission evidence
- Source files
- README with commands and environment
- Lab evidence log and screenshots if applicable
- Debug observations and outstanding issues
Review rubric
- Source and design
- 35
- Functional checks
- 30
- Debug and explanation
- 20
- Reproducibility
- 15
Personal evidence
This lesson is public; no account is needed to study it.
Knowledge check
Confirm the verification concepts
The scored check is being prepared.