Beyond chaining sequences with ##, SystemVerilog provides five operators for combining two sequences into a single, more expressive check: and, or, intersect, within, and throughout. Two of these — and and intersect — look similar but behave differently in a way that's easy to get wrong.

13 min read | Intermediate Level

What You'll Learn

  • How and combines two sequences that may finish at different times
  • Why intersect requires both sequences to end at the exact same cycle, unlike and
  • How or matches as soon as either sequence succeeds, without waiting for the other
  • The difference between within (one sequence contained inside another) and throughout (a boolean holding true for a sequence's entire span)

and: Both Must Match, Different Lengths Allowed

seq1 and seq2 requires both operand sequences to match, starting from the same clock tick — but they don't need to be the same length. The overall match completes at whichever of the two finishes later:


sequence seq_a;
  x ##1 y;      // 2-cycle sequence
endsequence

sequence seq_b;
  p ##2 q;      // 3-cycle sequence
endsequence

sequence s_and;
  seq_a and seq_b;
endsequence

Both sequences start together, at cycle 1: x=1 and p=1. seq_a matches at cycle 2 (y=1). seq_b matches at cycle 3 (q=1). Since and only requires both to eventually succeed, and takes the later of the two end times, seq_a and seq_b matches at cycle 3 — even though the two operands finished at different times.

intersect: Both Must Match, and End at the Same Time

intersect looks almost identical to and, with one added requirement: both operand sequences must end at exactly the same cycle:


sequence s_intersect;
  seq_a intersect seq_b;
endsequence

Using the exact same seq_a and seq_b from above — matching at cycle 2 and cycle 3 respectively — seq_a intersect seq_b fails. Both sequences did genuinely match, but their end times don't coincide (2 ≠ 3), and intersect requires them to.

This is the entire practical difference between the two operators: and tolerates sequences of different lengths, taking the later finish; intersect demands they finish together. The exact same pair of underlying sequences can pass under and and fail under intersect, as shown above.

Quick Check

Q: If seq_b were changed to p ##1 q (a 2-cycle sequence instead of 3), so both operands now match at cycle 2, would seq_a intersect seq_b pass?

Show Answer

Yes. With both sequences now ending at the same cycle (2), intersect's requirement is satisfied — it would pass under both and and intersect in that case, since there's no longer any mismatch in end times to distinguish them.

or: Matches as Soon as Either One Does

seq1 or seq2 matches the moment either operand succeeds — it doesn't wait around for the other one to resolve first:


sequence s_or;
  seq_a or seq_b;
endsequence

Suppose seq_b's q never actually appears (seq_b is doomed to eventually fail). seq_a still matches normally at cycle 2 (x=1 at cycle 1, y=1 at cycle 2). Since or only needs one operand to succeed, seq_a or seq_b matches at cycle 2 — it doesn't need to wait until cycle 3 to find out that seq_b would have failed anyway.

Quick Check

Q: If both seq_a and seq_b succeed (as in the and/intersect examples above), at which cycle does seq_a or seq_b match?

Show Answer

Cycle 2 — as soon as the first of the two (seq_a) succeeds. or doesn't wait for the later one to finish the way and does; it's satisfied the instant either side matches.

within: One Sequence Fully Contained in Another

seq1 within seq2 requires seq1's entire occurrence — from its own start to its own end — to fall completely inside the span during which seq2 is occurring:


sequence s_within;
  (req ##1 ack) within busy[*5];
endsequence

Say busy stays high for cycles 1 through 5 (matching busy[*5], a span from cycle 1 to cycle 5). If req is 1 at cycle 2 and ack is 1 at cycle 3, the inner sequence's own span (cycles 2–3) sits entirely inside busy's span (cycles 1–5) — within passes.

If ack were instead delayed until cycle 6, the inner sequence's span would become cycles 4–6 — extending one cycle past where busy's own span ends at cycle 5. Since the inner sequence is no longer fully contained, within would fail, even though req and ack both still occurred while busy happened to be nearby.

throughout: A Boolean That Must Hold for the Whole Span

bool_expr throughout seq checks that a plain boolean expression — not another full sequence — stays true for every single cycle of seq's entire duration:


sequence s_throughout;
  !reset throughout (req ##1 gnt ##1 valid);
endsequence

Here, req ##1 gnt ##1 valid spans 3 cycles (say req at cycle 1, gnt at cycle 2, valid at cycle 3). If reset stays low across all three of those cycles, throughout passes.

If reset instead glitched high for just one cycle in the middle — say, at cycle 2 — throughout would fail, even though req, gnt, and valid each still occurred exactly on schedule. Catching that kind of mid-sequence glitch, which a plain chained sequence would never notice on its own, is exactly what throughout is for.

Quick Check

Q: Could throughout's left-hand side be a full sequence, like (a ##1 b), instead of a plain boolean?

Show Answer

No. The left-hand side of throughout must be a simple boolean expression, checked fresh at every single cycle of the right-hand sequence's span — it isn't itself a temporal sequence with its own multi-cycle extent.

Where Are These Used?

intersect is the standard way to check that no new request of the same kind arrives while an earlier one of unknown, variable duration is still being serviced — both events must span exactly the same window. throughout is the standard way to check that reset, or some other invalidating condition, never glitches partway through a multi-cycle transaction that's otherwise behaving correctly.

Common Beginner Mistakes

Mistake #1: Using and when intersect was actually intended

As the contrasting example shows, and happily accepts two sequences that finish at different times — if the intent was specifically to check that both events span the exact same window, and silently allows a mismatch that intersect would correctly reject.

Mistake #2: Assuming or waits for both operands to resolve

or matches the instant either operand succeeds, without waiting to see what the other one eventually does. Why? If the two sequences have different lengths, the match time can end up being much earlier than either operand's own natural resolution point, which can be surprising if you expected both sides to be evaluated symmetrically.

Mistake #3: Confusing within with throughout

within checks that one entire sequence's span fits inside another's; throughout checks that a single boolean condition holds continuously across a sequence's span. Why? They solve genuinely different problems — containment of one temporal event inside another, versus a simple condition never glitching during an event — and reaching for the wrong one won't express the intended check at all.

Mistake #4: Using a full sequence on the left of throughout

Only a plain boolean expression belongs on the left-hand side of throughout. Why? The whole point of throughout is checking a simple condition at every cycle across another sequence's span — the left-hand side isn't meant to have its own independent temporal behavior.

Practice Exercise

Challenge: Predict and vs intersect on a New Pair

Given seq_c: m ##1 n (matching at cycle 2, same as seq_a above) and seq_d: r ##1 s (also matching at cycle 2), predict the result of both seq_c and seq_d and seq_c intersect seq_d.

Hint

Both sequences here have the same length. Does that change anything about which operator behaves differently from the other?

Solution

Both pass, matching at cycle 2. Since seq_c and seq_d both happen to end at the same cycle, there's no mismatch for intersect to catch — and and intersect only produce different results when the two operand sequences' end times actually differ, as in this article's main example.

Summary

In this tutorial, you learned:

  • and requires both sequences to match, starting together, and completes at whichever finishes later — different lengths are fine
  • intersect adds the extra requirement that both sequences finish at exactly the same cycle
  • or matches as soon as either operand succeeds, without waiting for the other to resolve
  • within checks that one sequence's entire span is fully contained inside another's
  • throughout checks that a plain boolean condition holds true for every cycle of another sequence's span, catching mid-sequence glitches a plain chained sequence would miss
Did you find what you were looking for?

Quiz

Test Your Knowledge

1 of 5 Score: 0 / 5