Constrained Randomization and Reproducibility | FPGA Pour Tous
Summary
Constrained Randomization and Reproducibility
Generate varied protocol-correct transactions and reproduce a failure exactly.
Random, but valid
Constrained randomization generates combinations within a defined space. It does not replace the verification plan. It explores more interactions than a short list of directed tests.
class dma_request; rand bit [31:0] address; rand int unsigned length; rand bit write; constraint legal_length { length inside {[1:256]}; } constraint aligned_address { address[1:0] == 2'b00; } constraint boundary { address[11:0] + length <= 4096;
}
endclass
These constraints define a legal command: bounded length, aligned address, and a transfer that does not cross a 4 KiB page.
A constraint is declarative: all active expressions are solved together, with no top-to-bottom execution order. An implication enables a conditional rule:
The implication works only in this direction: when write is 0, it imposes no restriction on length. solve write before length could change the resulting distribution, but it cannot add or remove legal solutions.
Always check the result
randomize() returns 1 when it finds a solution and 0 when constraints are inconsistent.
dma_request req = new();if (!req.randomize() with { write == 1'b1; length inside {16, 32, 64};}) $fatal(1, "Request constraints have no solution");
Ignoring the return value can send an old or default value to the driver. A randomization failure is a testbench error that needs diagnosis.
The with block adds constraints to the active class constraints; it does not replace them. An incompatible inline request must therefore fail, which is exactly why the return value needs to be checked.
Distribution and interesting cases
dist gives extra weight to selected values without making them mandatory.
Here the entire [2:63] range has a total weight of 20. This is not equivalent to assigning a weight of 20 to each of its 62 values.
randc cycles through a small domain before repeating values. It is not suitable for wide vectors whose complete cycle would be unrealistic.
Enable and disable without surprises
req.address.rand_mode(0) freezes address, but constraints that mention the field remain active. If the frozen value contradicts them, randomization fails. In contrast, req.legal_length.constraint_mode(0) disables the named constraint block.
Keeping validity constraints separate makes deliberate error injection easier: the test disables exactly the rule it intends to violate and preserves all others. Disabling one large undifferentiated block would expand the stimulus space far beyond the intended case.
Control widths and signedness
The solver follows the language's width and signedness rules. A sum held in a type that is too narrow can overflow and then satisfy a constraint with a wrapped value. Size expressions for the intended result, prefer unsigned lengths and addresses, and explicitly bound dynamic-array sizes.
Nested foreach constraints over every pair quickly create a quadratic problem. For large unique sets, a procedural algorithm or a reasonably sized randc domain may be clearer and faster.
Reproduce a bug
A pseudo-random generator is deterministic for a given seed as long as environment, call order, and tool remain comparable. Test logs should record:
the global or local seed;
test name and configuration;
DUT parameters;
failing transaction and sequence number;
code and simulator version.
Rerun with the same seed first. Then reduce the scenario to a few transactions to speed up diagnosis.
Key takeaways
Constraints define the valid or deliberately invalid space to explore.
Always check the return value of randomize().
An inline constraint is added to active constraints, and solve before changes only the distribution.
:= weights every value in a range; :/ distributes one total weight across the range.
rand_mode freezes a variable, while constraint_mode enables or disables a constraint block.
Distributions target important cases and coverage holes.
randc fits small domains.
Record seed, configuration, and the failing transaction.