2. SVA Guide - Concurrent Assertions

Concurrent assertions check temporal relationships between signals over multiple clock cycles. Unlike immediate assertions that execute procedurally, concurrent assertions are evaluated continuously throughout simulation based on a sampling clock.

Concurrent vs Immediate Assertions

AspectImmediateConcurrent
EvaluationProcedural, single point in timeContinuous, across clock cycles
Syntaxassert(expression)assert property(...)
ClockNot requiredRequired (sampling event)
Use caseCombinational checksProtocol/timing checks

Basic Structure

Concurrent assertions use sequences and properties:

// Sequence: defines a pattern of signals over time
sequence req_ack_seq;
  req ##[1:3] ack;  // ack within 1-3 cycles after req
endsequence

// Property: adds temporal context (clock, disable conditions)
property req_ack_prop;
  @(posedge clk) disable iff (reset)
  req |-> req_ack_seq;
endproperty

// Assertion: activates the property check
assert property (req_ack_prop) else $error("Protocol violation");

Implication Operators

Implication defines a cause-effect relationship: "if antecedent is true, then consequent must follow."

Overlapping Implication |->

Consequent evaluation starts at the same cycle where antecedent matches.

property req_grant;
  @(posedge clk) req |-> ##2 grant;  // grant 2 cycles after req
endproperty
{ "signal": [
  { "name": "clk",   "wave": "p.....|..." },
  { "name": "req",   "wave": "0.1...|0.." },
  { "name": "grant", "wave": "0...1.|0..", "node": "....a" }
], "edge": [], "head": { "text": "Overlapping |->: grant checked 2 cycles from req" } }

Non-overlapping Implication |=>

Consequent evaluation starts at the next cycle after antecedent matches.

property req_grant_next;
  @(posedge clk) req |=> ##1 grant;  // grant 2 cycles after req (1+1)
endproperty

a |=> b is equivalent to a |-> ##1 b

Temporal Operators

OperatorMeaningExample
##nDelay of n cyclesreq ##2 ack
##[m:n]Delay range m to n cyclesreq ##[1:3] ack
##[0:$]Eventually (0 to infinity)req ##[0:$] ack
[*n]Consecutive repetition n timesbusy[*3]
[*m:n]Repetition m to n timesbusy[*1:4]
[->n]Goto repetition (non-consecutive)ack[->2]
[=n]Non-consecutive repetitionack[=2]

Common Patterns

Request-Acknowledge

property req_ack;
  @(posedge clk) disable iff (reset)
  req |-> ##[1:4] ack;  // ack within 1-4 cycles
endproperty
assert property (req_ack);

Signal Stability

property data_stable;
  @(posedge clk) disable iff (reset)
  valid |-> $stable(data) [*1:$] ##1 !valid;
endproperty

One-Hot Check

property onehot_state;
  @(posedge clk) $onehot(state);
endproperty

No Back-to-Back Requests

property no_b2b_req;
  @(posedge clk) disable iff (reset)
  req |=> !req;  // req cannot be high in consecutive cycles
endproperty

System Functions in Assertions

FunctionDescription
$rose(sig)True on 0→1 transition
$fell(sig)True on 1→0 transition
$stable(sig)True if value unchanged
$changed(sig)True if value changed
$past(sig, n)Value of sig n cycles ago
$onehot(sig)True if exactly one bit is 1
$onehot0(sig)True if at most one bit is 1
$countones(sig)Number of 1s in vector

Binding Assertions to Modules

Use bind to attach assertions to RTL without modifying it:

module apb_protocol_checker (input clk, psel, penable, pready);
  
  property apb_setup_phase;
    @(posedge clk) $rose(psel) |-> !penable;
  endproperty
  
  property apb_access_phase;
    @(posedge clk) (psel && !penable) |=> penable;
  endproperty
  
  assert property (apb_setup_phase) else $error("APB setup violation");
  assert property (apb_access_phase) else $error("APB access violation");
  
endmodule

// Bind to DUT
bind apb_master apb_protocol_checker chk (
  .clk(pclk), .psel(psel), .penable(penable), .pready(pready)
);

Cover Directive

Use cover to track if a scenario occurred during simulation:

cover property (@(posedge clk) req ##[1:2] ack);
// Reports how many times req was followed by ack in 1-2 cycles

Key Points

  • Concurrent assertions sample signals at clock edges (preponed region)
  • Use disable iff for reset conditions
  • Vacuous pass: if antecedent is false, assertion passes trivially
  • Assertions can be placed in modules, interfaces, or bound externally
  • Use $assertoff/$asserton to control assertion evaluation
Author
Mayur Kubavat
VLSI Design and Verification Engineer sharing knowledge about SystemVerilog, UVM, and hardware verification methodologies.

Comments (0)

Leave a Comment