Why SystemVerilog Randomization Fails (and How to Debug It)
randomize() returned 0? Six causes of SystemVerilog randomization failure, how to read the VCS solver log, a 5-minute triage, and a demo with real logs.
randomize() returned 0? Six causes of SystemVerilog randomization failure, how to read the VCS solver log, a 5-minute triage, and a demo with real logs.
In the fast-moving business of chip design, where logic and silicon come together to power the devices we rely on every day, a group of quiet problem solvers does the careful work behind the scenes: ASIC verification engineers. These are the people who chase down bugs before a chip ever reaches production, testing every path…
In short: Designs need many clock frequencies from one reference. Division is simple but only gives integer ratios below the reference and can pile up jitter across a long chain. Multiplication, usually via a PLL, reaches higher frequencies, supports non-integer ratios, and often has lower jitter, which is why it suits high-speed links, CPU cores,…
In short: Verifying a RISC-V design has two parts: prove the core is correct and ISA compliant, and prove the whole system built around it works. As the system grows with more cores, peripherals, and custom hardware, RTL simulation alone gets too slow. Transaction-level hardware emulation (ideally on the Accellera SCE-MI standard), with an ISS…
In short: A constraint override happens when a child class declares a constraint with the same name as one in its parent. The child version replaces the parent version, so the solver uses only the child rule. If instead the child uses a different name, both constraints stay active and must be satisfied together, and…
In short: The class method randomize() assigns random values to the rand and randc members of an object, using that class’s constraints. The scope function std::randomize() does the same job but for plain variables in the current scope, with no class needed. Use randomize() when your random data lives in a class with reusable constraints;…
In short: A randc variable walks through every value in its range once before any value repeats. You can copy that no repeat behaviour with a plain rand variable by keeping a list of values already produced and adding a constraint that excludes them. In post_randomize() you push the new value onto the list; a…
In short: To fill an array with values that never repeat, mark the array rand and add one line: constraint c { unique {arr}; }. The solver then gives every element a different value. On an old simulator that doesn’t know unique, use a nested foreach with !=. And if you don’t need the solver…
In short: When you need an array of distinct values in a mixed order but do not need full randomness, you can skip constraints. Fill the array with known distinct values, such as the index itself, then call the built in shuffle() method to rearrange them. The result has no repeats and a random order,…
In short: rand_mode() turns one random variable on or off. When it’s off, randomize() leaves that variable’s value alone. constraint_mode() turns one constraint block on or off. When it’s off, the solver ignores that rule. They are independent: freezing a variable does not switch off the constraints that use it, which is why randomize() often…