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

Pointrandcaserandsequence
PicksOne branchA structured sequence
SelectionWeighted random branchGrammar of productions
OrderNo order, single choiceOrdered items, choices, repeats
FeaturesWeights onlyWeights, if..else, case, repeat
Best forQuick weighted actionInstruction 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.