Close Menu
VLSI Web
  • Home
    • About Us
    • Contact Us
    • Privacy Policy
  • Digital Design
    • Digital Circuits
    • Verilog
    • VHDL
    • System Verilog
    • UVM
  • VLSI Roles
    • RTL Design
    • Design Verification
    • Physical Design
    • DFT
    • STA
  • Interviews
  • Informative
  • VLSI Forge
Instagram LinkedIn WhatsApp Telegram
Instagram LinkedIn WhatsApp Telegram
VLSI Web
  • Home
    • About Us
    • Contact Us
    • Privacy Policy
  • Digital Design
    • Digital Circuits
    • Verilog
    • VHDL
    • System Verilog
    • UVM
  • VLSI Roles
    • RTL Design
    • Design Verification
    • Physical Design
    • DFT
    • STA
  • Interviews
  • Informative
  • VLSI Forge
VLSI Web
System Verilog

SystemVerilog Assertions (SVA) with Examples

Raju GorlaBy Raju Gorla12 July 2026Updated:11 October 2026No Comments4 Mins Read
SystemVerilog assertions
Share
Facebook Twitter LinkedIn Email Telegram WhatsApp

The short answer: SystemVerilog assertions (SVA) check design behaviour while it simulates, and can be proven by formal tools. Immediate assertions check a condition at one point in procedural code. Concurrent assertions are clocked and describe behaviour over time with sequences (##n delays, [*n] repetition), implication (|-> same cycle, |=> next cycle) and functions like $rose, $fell, $stable and $past. Put protocol checks on interfaces and invariants inside the RTL, and always disable them during reset.

Assertions are the best value-for-effort verification tool I know. A one-line property placed next to the RTL catches a bug at the cycle it happens, instead of hundreds of cycles later in a scoreboard. And the same property can be proven by a formal tool.

This post replaces my older posts on SystemVerilog assertions, assertion-based formal verification and assertions in Verilog.

  1. What an assertion checks
  2. Immediate vs concurrent
  3. The operators you’ll use most
  4. Assertions I add to almost every design
  5. assert, assume and cover
  6. Assertions and formal verification
  7. Habits that keep assertions useful

Table of Contents

  • Part 1: What an assertion checks
  • Part 2: Immediate vs concurrent
  • Part 3: The operators you’ll use most
  • Part 4: Assertions I add to almost every design
  • Part 5: assert, assume and cover
  • Part 6: Assertions and formal verification
  • Part 7: Habits that keep assertions useful
  • FAQ
    • What is the difference between |-> and |=>?
    • What is the difference between immediate and concurrent assertions?
    • Are assertions synthesisable?
    • What is disable iff used for?

Part 1: What an assertion checks

Waveform for the assertion req implies ack within 1 to 3 cycles: the first request passes, the second fails
Each req starts a new check; the assertion fails when no ack arrives in time.
property p_req_ack;
  @(posedge clk) disable iff (!rst_n)
    req |-> ##[1:3] ack;
endproperty
a_req_ack: assert property (p_req_ack)
  else $error("req at %0t not acknowledged within 3 cycles", $time);

Part 2: Immediate vs concurrent

// immediate: like an if, in procedural code
always_comb
  a_onehot: assert ($onehot0(grant)) else $error("grant not one-hot");

// concurrent: clocked, can describe sequences over time
a_no_ovf: assert property (@(posedge clk) disable iff (!rst_n)
            !(push && full));

Part 3: The operators you’ll use most

Operator Meaning Example
##n n clock cycles later a ##2 b
##[m:n] between m and n cycles later a ##[1:3] b
[*n] repeat n times (consecutive) busy [*4]
[->n] n occurrences, not necessarily consecutive ack [->2]
|-> overlapping implication (same cycle) req |-> gnt
|=> non-overlapping implication (next cycle) req |=> gnt
throughout condition holds during a sequence en throughout (a ##3 b)
$rose / $fell 0→1 / 1→0 since the last clock $rose(start) |=> busy
$stable / $past unchanged / value n cycles ago valid && !ready |=> $stable(data)

Part 4: Assertions I add to almost every design

// valid/ready: hold valid and data until accepted
a_hold: assert property (@(posedge clk) disable iff (!rst_n)
          valid && !ready |=> valid && $stable(data));

// FIFO: never push when full, never pop when empty
a_full:  assert property (@(posedge clk) disable iff (!rst_n) !(push && full));
a_empty: assert property (@(posedge clk) disable iff (!rst_n) !(pop  && empty));

// FSM: never reach an illegal state
a_state: assert property (@(posedge clk) disable iff (!rst_n)
           state inside {IDLE, RUN, DONE});

// no X on key control signals after reset
a_known: assert property (@(posedge clk) disable iff (!rst_n) !$isunknown(valid));

Part 5: assert, assume and cover

  • assert: this must always be true; report a failure if not.
  • assume: a constraint on the inputs. In simulation it behaves like an assertion; in formal it limits the inputs the tool explores.
  • cover: report when this sequence happens. Cover properties show that interesting scenarios were actually exercised.
c_back_to_back: cover property (@(posedge clk) push ##1 push ##1 push);

Part 6: Assertions and formal verification

Formal tools (like Jasper, VC Formal or Questa Formal) take the same properties and prove them for every possible input sequence, using assume properties to rule out illegal inputs. They’re excellent for arbiters, FIFOs, handshakes and control logic, and they return a short counter-example waveform when a property fails. Writing good assertions is the first step towards using formal.

Part 7: Habits that keep assertions useful

  • Always use disable iff (!rst_n) so assertions don’t fire during reset.
  • Name every assertion (a_hold:) so failures are easy to find.
  • Put interface protocol checks in the interface, and invariants next to the RTL they protect.
  • Bind assertion modules to a design with bind when you can’t edit the RTL.
  • Write a cover for every important assertion, so you know it was actually triggered.

Practise this on VLSI Forge

I built VLSI Forge so you can write RTL in your browser, run it on a real simulator and check every signal in the waveform. Free, nothing to install.

Design Verification problems · SVA and constraints problems

Previous in my SystemVerilog series: Threads and inter-process communication. Next: Functional coverage.

FAQ

What is the difference between |-> and |=>?

|-> checks the consequent in the same cycle the antecedent matches; |=> checks it in the next cycle. a |=> b equals a |-> ##1 b.

What is the difference between immediate and concurrent assertions?

Immediate assertions check a condition at one point in procedural code. Concurrent assertions are clocked and check behaviour across cycles.

Are assertions synthesisable?

No, synthesis ignores them. Some emulation and FPGA prototyping flows can compile a subset into hardware checkers.

What is disable iff used for?

To turn an assertion off while a condition is true, usually reset, so it doesn’t report false failures.

Assertions in SystemVerilog Formal verification Hardware Verification Property Specification SystemVerilog SystemVerilog syntax
Share. Facebook Twitter LinkedIn Email Telegram WhatsApp
Previous ArticleThreads in SystemVerilog: fork-join, Mailboxes, Semaphores and Events
Next Article Functional Coverage in SystemVerilog: Covergroups, Bins and Crosses
Raju Gorla
  • Website

Related Posts

Verilog

Verilog System Tasks: $display, $monitor, $readmemh and More

2 August 2026
System Verilog

Design Patterns in SystemVerilog Testbenches: Factory, Callbacks and More

16 July 2026
System Verilog

DPI in SystemVerilog: Calling C from Your Testbench (and Back)

15 July 2026
Add A Comment
Leave A Reply Cancel Reply

Topics
  • Digital Circuits
  • Informative
  • Interview Questions
  • Physical Design
  • RTL Design
  • STA
  • System Verilog
  • UVM
  • Verilog
Instagram LinkedIn WhatsApp Telegram
  • About
  • Contact
  • Privacy Policy
  • VLSI Forge
  • Courses
  • Feedback
© 2026 VLSI Web

Type above and press Enter to search. Press Esc to cancel.