Welcome back. In our previous lesson, we established the critical role of SVA implication operators (|-> and |=>) in creating conditional checks. You learned to distinguish their timing semantics and make strategic choices based on design intent. This understanding of when to check a sequence is the perfect foundation for our next topic.
This lesson dives into how to build the powerful, complex temporal sequences that are the heart of SVA. We will master the use of SVA's delay (##) and repetition operators ([*], [->], [=]). These are the tools you'll use to express intricate, multi-cycle behaviors like bus protocols, burst transfers, and state-machine transitions—patterns that are common targets for interview questions.
By the end of this lesson, you will be able to write and dissect SVA sequences that model sophisticated timing patterns with precision.
1. The Building Blocks: Delay and Consecutive Repetition
You're already familiar with the fundamental delay operator, ##, from our last lesson. It specifies a fixed or ranged delay between events in terms of clock cycles.
a ##1 b:boccurs one cycle aftera.a ##[2:4] b:boccurs between 2 and 4 cycles (inclusive) aftera.
While you can chain delays (a ##1 b ##1 b ##1 b), SVA provides a much cleaner syntax for patterns that repeat consecutively: the consecutive repetition operator [*].
b[*3]is equivalent tob ##1 b ##1 b.b[*2:4]meansbis true for 2, 3, or 4 consecutive cycles.
The following reading will walk you through these foundational operators.
System Verilog Assertion Constructs (1)
Let's review the delay operator and introduce the consecutive repetition operator. This article from The Octet Institute provides clear explanations and examples.
Read the sections 'Sequence in detail', 'Delay operator', and 'Consecutive repetition operator'. Focus on how ## with ranges and [*] provide concise ways to express timing.
A common use case is verifying handshake protocols where a signal must remain asserted for a specific duration. For instance, to check that after a req is seen, ack is asserted within 1 to 5 cycles and then stays high for exactly 4 cycles:
$rose(req) |=> ack[*4]; // This is too simple, ack must come 1-5 cycles later
A more accurate property would be:
$rose(req) |-> ##[1:5] ack[*4];
This sequence ##[1:5] ack[*4] means: wait 1 to 5 cycles, then find ack asserted, and then verify ack remains asserted for the next 3 cycles (totaling 4 consecutive cycles).
2. The Nuance of Grouping
A critical detail in SVA syntax is how operators apply to expressions. The repetition operator [*] binds to the immediate preceding expression. To repeat a multi-cycle sequence, you must group it with parentheses.

As you can see, valid ##2 ready[*3] is very different from valid (##2 ready)[*3]. This is a classic syntax trap and an easy source of bugs. Always be mindful of operator precedence.
3. Advanced Patterns: Non-Consecutive Repetition
Hardware protocols often involve events that must occur a certain number of times but not necessarily on back-to-back cycles. For this, SVA provides two powerful but often confused operators: non-consecutive [=] and goto [->].
b[=N](Non-consecutive repetition): This sequence matches ifbhas been trueNtimes. The matches forbcan be separated by any number of cycles. The sequence can continue its match check for a subsequent event anytime after the N-th occurrence ofb.b[->N](Goto repetition): This sequence also matches afterbhas been trueNtimes non-consecutively. The crucial difference is that the next part of the sequence must begin on the clock tick immediately following the N-th occurrence ofb.
Let's visualize this.
As the image shows, [->] is stricter. It forces the sequence to "go to" the next part immediately. [=] is more relaxed about when the next part begins.
Let's ground this with a concrete example and formal definitions.
System Verilog Assertion Constructs (1)
The Octet Institute article provides a great example comparing these two operators in a reset-checking scenario. Then, we'll look at a more formal definition from a Verification Academy forum.
First, read the sections 'Non-consecutive repetition operator' and 'Goto repetition operator'. Then, carefully study 'Example 2: reset checker' and its output. Note how sq1 (using [=3]) passes in the first scenario while sq2 (using [->3]) fails, and understand why.
The reset checker example brilliantly highlights the difference. The sequence with reset[=3] passes as long as reset_done eventually happens after the third reset. The sequence with reset[->3] ##2 reset_done requires reset_done to happen exactly two cycles after the third reset.
For a deeper, more formal understanding, which is valuable for complex debug scenarios, it helps to know how these operators can be expressed in terms of simpler constructs. The SVA expert Ben Cohen provides these equivalences:
b[->m]is equivalent to(!b[*0:$] ##1 b)[*m]- This means "wait for
bto be true, and do thismtimes." The sequence advances from the m-th occurrence.
- This means "wait for
b[=m]is equivalent to(b[->m] ##1 !b[*0:$])- This means "find
bmtimes, and then there can be any number of cycles wherebis false before the sequence continues."
- This means "find
This level of detail is what separates a good engineer from a great one, especially when debugging a failing property where the timing is subtle.
SVA Repetition operator [= - SystemVerilog - Verification Academy
Let's read Ben Cohen's explanation on the Verification Academy forums. This provides the formal equivalence I mentioned above.
In the forum thread, find the reply by 'Ben Cohen'. Read the first few lines where he defines the equivalents for b[=m] and b[->m]. This provides the rigorous definition behind the behavior we've observed.
4. Choosing the Right Operator
Your choice of repetition operator must precisely match the specification.
- Use
[*]for events that must be contiguous (e.g., a signal held stable). - Use
[->]when a specific count of non-contiguous events triggers an immediate next step in a protocol. This is common in state machines where exiting a state depends on seeing a trigger N times. - Use
[=]when you need to check that an event has occurredNtimes within a window, but the next step is not tightly coupled to the N-th occurrence. For example, "within a transaction frame, there must be exactly 4 data beats."
Conclusion
In this lesson, we've built a powerful vocabulary for describing complex temporal behavior in SVA. You can now express not just simple delays, but also consecutive and non-consecutive repetitions of events, which are essential for verifying realistic hardware protocols.
Key Takeaways:
##is the fundamental delay operator for fixed or ranged cycle delays.b[*N]verifies thatbis true forNconsecutive cycles.b[=N]verifies thatbhas been trueNtimes non-consecutively, and allows the rest of the sequence to match at any point after the N-th occurrence.b[->N](goto) verifiesbhas been trueNtimes non-consecutively, and requires the rest of the sequence to begin immediately after the N-th occurrence.- Use parentheses
()to group sequences when applying repetition operators to avoid common syntax errors.
In our next lesson, we will shift focus from sequence construction to the assertion statement itself, discussing the strategic choice between concurrent and immediate assertions.
🧠Interview & Practice Drill
Time to solidify your understanding under pressure.
🎤 Interview Drill Section
-
Rapid Fire Theory:
- What is the difference between
ack[*4]andack[=4]? - An engineer wants to check that after a
start_burstsignal, adata_validsignal asserts exactly 8 times before anend_burstsignal is seen. Thedata_validcycles are not necessarily consecutive. Which operator,[=8]or[->8], is more appropriate fordata_valid, and why? - Explain what the sequence
(a ##1 b)[*3]checks for. How is it different froma ##1 b[*3]? - "I wrote
req |=> busy[->5] ##1 done. The intent is that afterreq,busyhappens 5 times, and thendonehappens one cycle later. Is this correct? What could go wrong?"
- What is the difference between
-
Whiteboard Coding Problem:
- A DMA controller signals the start of a burst with
dma_start. It then performs a burst of exactly 4 data transfers, indicated bydma_validbeing high. These transfers can be stalled by the bus, so they are not guaranteed to be on consecutive cycles. One cycle after the 4th and finaldma_validpulse, the controller must assertdma_done. Write a single SVA property to verify this entire behavior.
- A DMA controller signals the start of a burst with
🧩 Coding Exercises
Write the SVA properties for the following scenarios. Assume a default clocking block @(posedge clk).
- Burst Write: After a write command (
wr_cmd) is asserted, a data valid signal (wr_dv) must be asserted for exactly 8 consecutive clock cycles. - Retry Mechanism: When a transaction fails (
txn_fail), the master must re-attempt the transaction by assertingtxn_reqexactly 3 times. The retries do not need to be on consecutive cycles. After the 3rd retry attempt, the master must wait at least 10 cycles before assertingtxn_reqagain. Write a property that checks for the 3 non-consecutive retries. (Hint: Focus on the retry part first). - Credit Counter: A module starts with 4 credits. Each time it sends a request (
send_req), it uses one credit. It must not send a request if it has no credits. Aget_creditsignal can arrive at any time, incrementing its credit count. For simplicity, let's check a slice of this behavior: After areset, the module can send at most 4 requests (send_req) before it receives aget_creditsignal. Write a property that checks that betweenresetand the firstget_credit,send_reqdoes not occur more than 4 times. (Hint: Use(send_req[=N]) throughout (!get_credit)logic).