Introduction to Assertions

Assertions in SystemVerilog are a powerful feature used for design verification and debugging. They help ensure that certain properties or behaviors in a design are always met, both during simulation and in real-world usage. Assertions provide a concise, readable way to express conditions that must hold true. In this article, we’ll explore immediate and concurrent assertions, their differences, and examples to illustrate their usage.

What Are Assertions?

In the context of SystemVerilog, an assertion is a statement that checks a specific condition or set of conditions. If the condition fails during simulation, the assertion can generate a warning or error, allowing engineers to pinpoint issues in the design.

There are two primary types of assertions in SystemVerilog:

  1. Immediate Assertions
  2. Concurrent Assertions

Immediate Assertions

Immediate assertions are evaluated at the point in time they are encountered during the simulation. They are procedural statements that belong inside procedural blocks like initial, always, or task.

Syntax:

assert (condition) else $error("Error message");

We can also put pass statement with assertion. If the condition holds true, it will display pass statement otherwise else condition will be executed.

label: assert (condition) $display("assertion got passed");
       else $error("Error message");

Key Points:

  • Immediate assertions are executed immediately when encountered during simulation.
  • They are typically used to validate conditions within sequential code.

Example:

module immediate_assertion_example;
    logic clk, reset;
    initial begin
        clk = 0;
        reset = 0;
      
      #10 reset = 1;

        // Immediate assertion to ensure reset is active during initialization
      assert (reset == 1) $display("reset got asserted");
      else $error("Reset not asserted during initialization.");
    end
endmodule

In this example, the immediate assertion checks if reset is active (i.e., 1) at the start of the simulation. If not, an error is reported.

Output:

reset got asserted

Concurrent Assertions

Concurrent assertions, on the other hand, are evaluated over time and are used to validate temporal relationships between signals or events. They are typically declared outside procedural blocks and use property constructs.

Syntax:

property property_name;
    // Property definition
endproperty

// Assertion of the property
a1: assert property (property_name);

Key Points:

  • Concurrent assertions can monitor conditions over multiple simulation cycles.
  • They are ideal for checking complex temporal conditions or protocol compliance.

Example:

module concurrent_assertion_example;
    logic clk, req, ack;

    // Define a property to check handshake protocol
    property handshake_protocol;
        @(posedge clk) req |=> ack; // If req is high, ack must be high in the next cycle
    endproperty

    // Assert the property
  assert property (handshake_protocol) else $error("Handshake protocol violated.");
endmodule

In this example, the concurrent assertion ensures that whenever req is asserted (1), ack is asserted in the subsequent clock cycle. The |=> operator specifies this “next cycle” relationship. We will know about this operator in next chapters.

Assertion severity/Error Handling:

  • Assertion failure is associated with a severity message.
  • $fatal is a run time fatal.
  • $error is a run time error.
  • $warning is a run time warning which can be suppressed in a tool-specific manner.
  • $info indicates that assertion failure doesn’t have specific severity.
  • Severity level is included in the assertion failure message.

Immediate vs. Concurrent Assertions

FeatureImmediate AssertionsConcurrent Assertions
EvaluationAt the point in simulationOver a period of simulation cycles
ScopeProcedural blocks (initial, always)Outside procedural blocks
UsageSimple conditions or checksTemporal checks and protocols
Example Use CaseChecking initialization conditionsEnsuring protocol compliance

Benefits of Using Assertions

  1. Improved Debugging: Assertions make it easier to identify issues early in the simulation.
  2. Enhanced Verification: They provide a clear, concise way to express and verify design requirements.
  3. Reusable Code: Assertions can be reused across different verification environments.