How to Use Assertions in SystemVerilog: Syntax and Examples
In SystemVerilog, use
assert statements to check if conditions hold true during simulation. Assertions help catch design errors early by verifying expected behavior and can be written as immediate or concurrent assertions.Syntax
SystemVerilog assertions come in two main types: immediate and concurrent. Immediate assertions check conditions at a single simulation time, while concurrent assertions monitor conditions over time.
Immediate assertion syntax:
assert (condition) else $error("Error message");Concurrent assertion syntax:
assert property (property_expression);
Here, condition is a boolean expression, and property_expression describes temporal behavior using sequences and properties.
systemverilog
assert (a == b) else $error("a is not equal to b"); property p_check; @(posedge clk) disable iff (reset) (data == expected); endproperty assert property (p_check);
Example
This example shows an immediate assertion checking if a signal valid is high when ready is high, and a concurrent assertion verifying that data remains stable for one clock cycle after valid is asserted.
systemverilog
module assertion_example(input logic clk, reset, valid, ready, input logic [7:0] data); // Immediate assertion always_ff @(posedge clk) begin if (!reset) begin assert ( !(valid && !ready) ) else $error("valid is high but ready is low"); end end // Concurrent assertion: data stable after valid property data_stable; @(posedge clk) disable iff (reset) valid |-> ##1 (data == $past(data)); endproperty assert property (data_stable); endmodule
Output
If 'valid' is high while 'ready' is low, simulation prints: "valid is high but ready is low" error message.
Common Pitfalls
- Using immediate assertions for conditions that require checking over time instead of concurrent assertions.
- Not disabling assertions during reset, causing false failures.
- Writing assertions without clear error messages, making debugging harder.
- Forgetting to use
disable iff (reset)in concurrent assertions to avoid triggering during reset.
systemverilog
/* Wrong: Immediate assertion used for temporal check */ assert (data == $past(data)) else $error("Data changed unexpectedly"); /* Right: Use concurrent assertion with property */ property stable_data; @(posedge clk) disable iff (reset) (data == $past(data)); endproperty assert property (stable_data);
Quick Reference
| Assertion Type | Syntax Example | Use Case |
|---|---|---|
| Immediate | assert (cond) else $error("msg"); | Check condition at one simulation time |
| Concurrent | assert property (p); | Check conditions over time with sequences |
| Disable during reset | disable iff (reset) | Prevent false failures during reset |
| Error reporting | $error("message") | Print error message on failure |
Key Takeaways
Use immediate assertions for single-time checks and concurrent assertions for temporal behavior.
Always disable assertions during reset to avoid false failures.
Write clear error messages to help debug assertion failures.
Use properties and sequences for complex temporal checks.
Assertions help catch bugs early by verifying design correctness during simulation.