1. SVA Guide - Immediate Assertions

Immediate assertions are non-temporal checks that evaluate an expression instantly, like a procedural if-statement with built-in reporting. They're essential for validating conditions in testbenches and RTL.

What are Immediate Assertions?

Immediate assertions:

  • Execute immediately when encountered (like procedural statements)
  • Evaluate expressions in the current time step
  • Have no temporal/clock relationship
  • Provide built-in pass/fail reporting
Key Difference: Immediate assertions check values right now. Concurrent assertions check sequences over time.

Syntax

// Basic syntax
assert (expression) [pass_statement] [else fail_statement];

// With label
label: assert (expression) pass_action; else fail_action;

// Simple form
assert (expression);

Types of Immediate Assertions

flowchart TD
    A["Immediate Assertions"] --> B["Simple Immediate"]
    A --> C["Deferred Immediate"]
    
    B --> B1["assert(expr)"]
    B --> B2["Executes instantly"]
    B --> B3["Glitch-sensitive"]
    
    C --> C1["assert #0 (expr)"]
    C --> C2["Executes at end of time step"]
    C --> C3["Avoids glitches"]
    
    style A fill:#dbeafe,stroke:#3b82f6
    style C fill:#d1fae5,stroke:#10b981
TypeSyntaxWhen EvaluatedUse Case
Simpleassert (expr)ImmediatelyProcedural checks
Deferred (observed)assert #0 (expr)Observed regionAvoid glitches
Deferred (final)assert final (expr)Final regionEnd-of-delta checks

Action Blocks

// Full syntax with action blocks
assert (condition)
  // Pass action - executed if assertion passes
  $display("PASS: condition met");
else
  // Fail action - executed if assertion fails
  $error("FAIL: condition not met");

Severity System Tasks

TaskSeveritySimulationUse When
$fatalFatalTerminatesUnrecoverable error
$errorErrorContinuesTest failure (default)
$warningWarningContinuesNon-critical issue
$infoInfoContinuesDebug information
// Severity examples
assert (data != 0) else $fatal(1, "Data is zero - cannot continue");
assert (valid)      else $error("Valid signal not asserted");
assert (ready)      else $warning("Ready not yet asserted");
assert (cfg_done)   else $info("Configuration pending");

Complete Examples

Example 1: Basic Immediate Assertion

module tb;

  logic [7:0] data;
  logic       valid;
  logic       ready;

  initial begin
    // Test case 1: Valid data
    data  = 8'hAB;
    valid = 1;
    ready = 1;
    
    check_data: assert (data != 0)
      $display("[PASS] Data is non-zero: 0x%0h", data);
    else
      $error("[FAIL] Data is zero!");

    check_handshake: assert (valid && ready)
      $display("[PASS] Handshake complete");
    else
      $error("[FAIL] Handshake failed: valid=%b ready=%b", valid, ready);

    // Test case 2: Invalid data
    data = 0;
    
    assert (data != 0)
      $display("[PASS] Data is valid");
    else
      $warning("[WARN] Data is zero");
  end

endmodule

Output

[PASS] Data is non-zero: 0xab
[PASS] Handshake complete
[WARN] Data is zero

Example 2: Assertions in Functions

function automatic logic [31:0] divide(input int a, input int b);
  // Check for divide by zero
  assert (b != 0) else begin
    $error("Division by zero! a=%0d, b=%0d", a, b);
    return 0;
  end
  return a / b;
endfunction

module tb;
  initial begin
    int result;
    
    result = divide(100, 5);   // OK: result = 20
    $display("100/5 = %0d", result);
    
    result = divide(50, 0);    // Assertion fires
    $display("50/0 = %0d", result);
  end
endmodule

Example 3: Deferred Assertions (Avoid Glitches)

module tb;

  logic a, b, c;

  // Simple immediate - may see glitches
  always @(a or b or c) begin
    simple_check: assert (a && b && c)
      else $warning("Simple: not all high");
  end

  // Deferred immediate - evaluates after all updates
  always @(a or b or c) begin
    deferred_check: assert #0 (a && b && c)
      else $warning("Deferred: not all high");
  end

  initial begin
    // All signals change, but at slightly different times
    a = 0; b = 0; c = 0;
    #1;
    a = 1;  // Simple assertion may fire here (glitch)
    b = 1;
    c = 1;  // All high now
    #1;
    $finish;
  end

endmodule

Immediate vs Concurrent Assertions

FeatureImmediateConcurrent
TimingInstant evaluationClock-based sampling
LocationProcedural blocksModule scope or procedural
Syntaxassert (expr)assert property (@(clk) p)
TemporalNo sequencesSupports sequences, delays
Use caseValue checksProtocol/timing checks
// Immediate: Check value NOW
always @(posedge clk) begin
  assert (count < MAX) else $error("Counter overflow");
end

// Concurrent: Check sequence over clock cycles
assert property (@(posedge clk) req |-> ##[1:3] ack);

Best Practices

1. Always Use Labels

// GOOD - labeled assertions
check_valid: assert (valid) else $error("Valid check failed");
check_range: assert (data < 256) else $error("Data out of range");

// BAD - anonymous assertions (hard to identify in logs)
assert (valid);
assert (data < 256);

2. Include Context in Messages

// GOOD - detailed message
assert (addr[1:0] == 2'b00) else
  $error("Unaligned address: addr=0x%0h at time %0t", addr, $time);

// BAD - vague message
assert (addr[1:0] == 2'b00) else
  $error("Error");

3. Use Appropriate Severity

// Fatal: Cannot continue
assert (clk !== 1'bx) else $fatal(1, "Clock is X");

// Error: Test failure but can continue
assert (data == expected) else $error("Data mismatch");

// Warning: Suspicious but not failure
assert (delay < 100) else $warning("Long delay: %0d cycles", delay);

Common Patterns

Range Check

check_range: assert (value inside {[0:MAX]})
  else $error("Value %0d out of range [0:%0d]", value, MAX);

Enum Validity

typedef enum logic [1:0] {IDLE, RUN, DONE} state_e;
state_e state;

check_state: assert (state inside {IDLE, RUN, DONE})
  else $error("Invalid state: %0d", state);

FIFO Checks

always @(posedge clk) begin
  if (push && !pop) begin
    no_overflow: assert (count < DEPTH)
      else $error("FIFO overflow! count=%0d", count);
  end
  
  if (pop && !push) begin
    no_underflow: assert (count > 0)
      else $error("FIFO underflow!");
  end
end

Mutual Exclusion

mutex_check: assert ($onehot0({read, write, idle}))
  else $error("Multiple states active: rd=%b wr=%b idle=%b", 
              read, write, idle);

Common Mistakes

MistakeProblemFix
Missing elseNo message on failureAdd else $error(...)
No labelHard to identify in logsAdd descriptive labels
Using in synthesizable codeSynthesis errorsWrap with `ifdef SIMULATION
Glitch sensitivityFalse failuresUse deferred assert #0

Synthesis Considerations

module rtl_with_assertions (
  input  logic       clk,
  input  logic [7:0] data,
  output logic [7:0] result
);

  always_ff @(posedge clk) begin
    result <= data + 1;
    
    // Wrap assertions for simulation only
    `ifdef SIMULATION
      assert (data < 255) else $warning("Data near overflow");
    `endif
  end

endmodule

Interview Questions

Q1: What is an immediate assertion?

Answer: An immediate assertion evaluates an expression at the instant it's executed, like a procedural if-statement. It checks the current value without any temporal/clock relationship.

Q2: What's the difference between simple and deferred immediate assertions?

Answer: Simple assertions (assert(expr)) execute immediately and may see glitches. Deferred assertions (assert #0) execute in the Observed region after all updates, avoiding glitches.

Q3: When would you use $fatal vs $error?

Answer: Use $fatal for unrecoverable errors where simulation cannot meaningfully continue (e.g., clock is X). Use $error for test failures that should be reported but allow simulation to continue checking other conditions.

Key Takeaways

  • Immediate assertions check values instantly (no clock)
  • Use assert #0 for deferred evaluation to avoid glitches
  • Always add labels and meaningful messages
  • Choose appropriate severity: $fatal, $error, $warning, $info
  • Wrap in `ifdef SIMULATION for synthesizable code
  • Use for value checks; use concurrent assertions for temporal checks
Author
Mayur Kubavat
VLSI Design and Verification Engineer sharing knowledge about SystemVerilog, UVM, and hardware verification methodologies.

Comments (0)

Leave a Comment