SystemVerilog provides two types of assertions:
1. Immediate Assertions
Checked at a single point in time, like an if statement. Used in
procedural code (always blocks, tasks, functions).
always @(posedge clk) begin
// Simple immediate assertion
assert (data != 'x)
else $error("Data is unknown!");
// With pass action
assert (valid && ready)
$display("Handshake successful!")
else
$error("Handshake failed: valid=%b, ready=%b", valid, ready);
// Assert with severity levels
assert (count <= MAX_COUNT)
else begin
$fatal(1, "Counter overflow! count=%0d, max=%0d", count, MAX_COUNT);
end
end
2. Concurrent Assertions
Checked continuously over time, can span multiple clock cycles.
Used for protocol checking and temporal relationships.
// Property: After req goes high, ack must follow within 1-5 cycles
property req_ack_protocol;
@(posedge clk) disable iff (rst)
req |-> ##[1:5] ack;
endproperty
// Assert the property
assert property (req_ack_protocol)
else $error("Protocol violation: ack not received within 5 cycles of req");
// Cover the property (for verification)
cover property (req_ack_protocol)
$display("req->ack handshake observed");