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:
- Immediate Assertions
- 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
| Feature | Immediate Assertions | Concurrent Assertions |
|---|---|---|
| Evaluation | At the point in simulation | Over a period of simulation cycles |
| Scope | Procedural blocks (initial, always) | Outside procedural blocks |
| Usage | Simple conditions or checks | Temporal checks and protocols |
| Example Use Case | Checking initialization conditions | Ensuring protocol compliance |
Benefits of Using Assertions
- Improved Debugging: Assertions make it easier to identify issues early in the simulation.
- Enhanced Verification: They provide a clear, concise way to express and verify design requirements.
- Reusable Code: Assertions can be reused across different verification environments.