Randcase Vs Randsequence in Systemverilog
In short: randcase picks one branch at random using weights: each branch weight divided by the sum of all weights is its chance of being taken. randsequence is bigger; it builds structured sequences from named productions, so it can produce ordered or branching stimulus such as instruction streams. Use randcase for a quick weighted choice among a few actions; use randsequence when you need grammar style sequences with order, choices, repeats, and conditions.
Both pick things at random, but at different scales. randcase chooses one action this time. randsequence lays out a whole sequence of actions with rules about how they follow each other. Knowing which to reach for keeps simple choices simple and complex stimulus manageable.
A simple way to picture it
Think of ordering food. randcase is spinning a wheel to pick one dish, where bigger wheel slices are chosen more often. randsequence is planning a full multi course meal from a menu grammar: a starter, then a main, then a dessert, with choices and repeats allowed at each step. One picks a single item; the other builds an ordered plan.
randcase: a weighted random branch
A randcase looks like a case statement, but the labels are weights, not match values. The solver adds all weights, picks a random point in that range, and runs the matching branch. A branch with a larger weight is chosen more often; a weight of zero is never chosen.
int x;
randcase
9 : x = 10; // chance 9/21
5 : x = 11; // chance 5/21
7 : x = 12; // chance 7/21
endcase
The weights 9, 5, and 7 add to 21, so the first branch runs about 43 percent of the time, the second about 24 percent, and the third about 33 percent. Weights can be any non negative expression, not just constants.
Checking the distribution over many runs
Run a randcase many times and count the branches to see the weights in action. Over 1000 iterations the counts land close to the expected shares.
int a, c1, c2, c3;
initial begin
repeat (1000) begin
randcase
7 : a = 1; // ~7/15
3 : a = 2; // ~3/15
5 : a = 3; // ~5/15
endcase
case (a)
1: c1++;
2: c2++;
3: c3++;
endcase
end
$display("c1=%0d c2=%0d c3=%0d", c1, c2, c3);
end
randsequence: structured random sequences
A randsequence is built from named productions. A production has a name and one or more items. Items are either terminals, which are code blocks that run, or non terminals, which expand into more productions. The generator starts at the main production and walks the grammar.
initial begin
randsequence (main)
main : one two three ; // run in order
one : { $write("one"); };
two : { $write(" two"); };
three : { $display(" three"); };
endsequence
end
// prints: one two three
Choices with the | operator
Separate items with | to make the generator pick one at random. This is how you get variety in the sequence.
randsequence (main)
main : one | two | three ; // pick one at random
one : { $display("one"); };
two : { $display("two"); };
three : { $display("three"); };
endsequence
Weights, conditions, case, and repeat
Productions accept weights with the := operator so some choices happen more often. They also support if..else conditions, a case selector, and a repeat count, which together let you shape rich stimulus.
// Weighted choice: three is picked most often
randsequence (main)
main : one := 1 | two := 2 | three := 3 ;
one : { cnt1++; };
two : { cnt2++; };
three : { cnt3++; };
endsequence
// Repeat a production a fixed number of times
randsequence (main)
main : one | repeat(3) two | repeat(5) three ;
one : { cnt1++; };
two : { cnt2++; };
three : { cnt3++; };
endsequence
Expected output, in plain words
The randcase distribution example prints three counts that sum to 1000, in roughly a 7 to 3 to 5 ratio, so about 467, 200, and 333. The ordered randsequence prints one two three on a line. The choice version prints one of the three names at random each pass. The weighted version makes three the most common and one the least. Exact counts vary by seed.
Note: these outputs describe what the code is written to produce from a read of the IEEE 1800 LRM. Confirm on your own simulator or EDA Playground.
randcase vs randsequence
| Point | randcase | randsequence |
|---|---|---|
| Picks | One branch | A structured sequence |
| Selection | Weighted random branch | Grammar of productions |
| Order | No order, single choice | Ordered items, choices, repeats |
| Features | Weights only | Weights, if..else, case, repeat |
| Best for | Quick weighted action | Instruction or traffic sequences |
When to use each
- Use randcase for a quick weighted choice among a few actions, such as picking a read, write, or idle this cycle.
- Use randsequence when you need an ordered or branching sequence, such as a stream of instructions or a traffic pattern.
- Use randcase inside a loop to build a rough sequence when you do not need grammar features.
- Use randsequence weights to bias which sub sequences appear more often.
Common mistakes to avoid
- Zero total weight in randcase: if every weight is zero, no branch runs and the tool may warn. Keep at least one non zero weight.
- Treating randcase labels as match values: they are weights, not values to compare.
- Missing terminals in randsequence: every non terminal must eventually reach a terminal code block.
- Overusing randsequence for a single choice: a plain randcase is simpler when there is no sequence to build.
For weighted value selection inside a constraint, see weighted distribution with dist. For the randomization entry points, read randomize vs std::randomize. More is in our SystemVerilog tutorials.
Frequently asked questions
What is the difference between randcase and randsequence?
randcase picks one branch at random using weights. randsequence builds a structured sequence from named productions with order, choices, repeats, and conditions. Use randcase for a quick weighted choice and randsequence for grammar style sequences.
How are randcase weights used?
Each branch has a non negative weight. The chance of a branch is its weight divided by the sum of all weights. A larger weight is chosen more often, and a weight of zero is never chosen.
What are terminals and non terminals in randsequence?
A terminal is a code block that runs directly. A non terminal expands into more productions. Every non terminal must eventually reach terminals when the grammar is walked.
How do I make random choices in randsequence?
Separate production items with the | operator so the generator picks one at random. Add weights with the := operator to make some choices more likely.
Can randsequence do conditions and repeats?
Yes. Productions support if..else conditions, a case selector, and a repeat count, so you can shape ordered, branching, and repeated stimulus.
When should I use randcase over randsequence?
Use randcase when you only need to pick one weighted action, such as read, write, or idle this cycle. Use randsequence when you need an ordered or branching sequence of actions.
Part of the learning path SystemVerilog for verification
