A comprehensive set of assertion macros for SystemVerilog verification, inspired by JUnit Assert.
uvmkit_assert provides a familiar and powerful way to validate test conditions in both UVM and non-UVM environments. Only failed assertions produce output, keeping simulation logs clean and focused on actual failures.
- JUnit-Inspired API - Familiar assertion methods for developers coming from software testing
- Universal Compatibility - Works with and without UVM
- Multi-Simulator Support - Verilator, Questa, VCS, and Xcelium
- Comprehensive Assertions - Boolean, equality, null checks, identity, real numbers, enums, strings, and UVM objects
- Clean Output - Only failures are reported; successful assertions pass silently
- Detailed Error Messages - Clear, actionable feedback when assertions fail
- Type-Safe Comparisons - Specialized macros for different data types
- Automatic Stacktraces - Context for debugging failures (simulator-dependent)
// Include the library
`include "uvmkit_assert.sv"
module my_test;
initial begin
logic [7:0] data = 8'hA5;
logic ready = 1'b1;
string name = "my_component";
// Boolean assertions
`uvmkit_assert_true(ready, "Ready signal must be high")
`uvmkit_assert_false(error, "No errors should occur")
// Equality assertions
`uvmkit_assert_equals(data, 8'hA5, "Data mismatch")
`uvmkit_assert_not_equals(count, 0, "Count should be non-zero")
// String assertions
`uvmkit_assert_equals_string(name, "my_component", "Name mismatch")
// Null checks
`uvmkit_assert_not_null(my_object, "Object must exist")
end
endmodule`include "uvm_macros.svh"
import uvm_pkg::*;
`include "uvmkit_assert.sv"
class my_test extends uvm_test;
`uvm_component_utils(my_test)
function void run_phase(uvm_phase phase);
my_transaction expected, actual;
// UVM object comparison using compare()
`uvmkit_assert_equals_uvm(expected, actual, "Transaction mismatch")
// All other assertions work the same
`uvmkit_assert_equals(actual.addr, 32'h1000, "Address incorrect")
endfunction
endclass- Copy
src/uvmkit_assert.svto your project - Include it in your testbench:
`include "uvmkit_assert.sv"
That's it! The library is header-only (macro-based) with no additional dependencies.
| Macro | Description |
|---|---|
uvmkit_assert_fail(msg) |
Forces unconditional test failure |
| Macro | Description |
|---|---|
uvmkit_assert_true(exp, msg) |
Asserts expression evaluates to true (non-zero) |
uvmkit_assert_false(exp, msg) |
Asserts expression evaluates to false (zero) |
| Macro | Description |
|---|---|
uvmkit_assert_equals(a, b, msg) |
Asserts two values are equal using case equality (===) |
uvmkit_assert_not_equals(a, b, msg) |
Asserts two values are not equal using case inequality (!==) |
| Macro | Description |
|---|---|
uvmkit_assert_null(obj, msg) |
Asserts object handle is null |
uvmkit_assert_not_null(obj, msg) |
Asserts object handle is not null |
| Macro | Description |
|---|---|
uvmkit_assert_same(a, b, msg) |
Asserts two handles refer to the same object instance |
uvmkit_assert_not_same(a, b, msg) |
Asserts two handles refer to different object instances |
| Macro | Description |
|---|---|
uvmkit_assert_equals_real(expected, actual, delta, msg) |
Asserts real values are equal within tolerance |
uvmkit_assert_not_equals_real(expected, actual, delta, msg) |
Asserts real values differ by more than tolerance |
| Macro | Description |
|---|---|
uvmkit_assert_equals_enum(enum_t, expected, actual, msg) |
Asserts enum values are equal |
uvmkit_assert_not_equals_enum(enum_t, expected, actual, msg) |
Asserts enum values are not equal |
| Macro | Description |
|---|---|
uvmkit_assert_equals_string(a, b, msg) |
Asserts strings are equal (case-sensitive) |
uvmkit_assert_not_equals_string(a, b, msg) |
Asserts strings are not equal |
| Macro | Description |
|---|---|
uvmkit_assert_equals_uvm(a, b, msg) |
Asserts UVM objects are equal using compare() |
uvmkit_assert_not_equals_uvm(a, b, msg) |
Asserts UVM objects are not equal using compare() |
Note: UVM assertions only available when UVM is included
bit enable = 1'b1;
bit [3:0] status = 4'b0000;
`uvmkit_assert_true(enable, "Enable must be high")
`uvmkit_assert_true(count > 0, "Count must be positive")
`uvmkit_assert_false(status[0], "Error bit must be clear")// Uses case equality (===) to properly handle X and Z
logic [7:0] data = 8'bxxxx_1010;
logic [7:0] expected = 8'bxxxx_1010;
`uvmkit_assert_equals(data, expected, "Match including X states")real voltage = 3.301;
real target = 3.300;
real tolerance = 0.05;
// Passes: |3.301 - 3.300| = 0.001 < 0.05
`uvmkit_assert_equals_real(target, voltage, tolerance, "Voltage in range")typedef enum {IDLE, ACTIVE, ERROR} state_t;
state_t current_state = IDLE;
`uvmkit_assert_equals_enum(state_t, IDLE, current_state, "Should be IDLE")
// Error output includes enum names: "Expected IDLE but got ACTIVE"my_class obj_a, obj_b, obj_c;
obj_a = new();
obj_b = obj_a; // Same object
obj_c = new(); // Different object
`uvmkit_assert_same(obj_a, obj_b, "Should reference same object") // PASS
`uvmkit_assert_not_same(obj_a, obj_c, "Should be different objects") // PASS| Simulator | Stacktrace | Method |
|---|---|---|
| Questa | ✅ Yes | $stacktrace |
| VCS | ✅ Yes | $stacktrace |
| Xcelium | ✅ Yes | $stacktrace |
| Verilator | ❌ No | Not supported |
| Riviera-Pro | ⚙️ Custom | Override uvmkit_stacktrace macro |
For simulators with different stacktrace commands:
// Before including uvmkit_assert.sv
`define uvmkit_stacktrace $callstack();
`include "uvmkit_assert.sv"The library automatically detects UVM and uses the appropriate error mechanism:
- With UVM: Uses
uvm_errorfor integration with UVM reporting system - Without UVM: Uses SystemVerilog
$errorwith formatted output
If you're familiar with JUnit, here's the mapping:
| JUnit Assert | uvmkit_assert | Notes |
|---|---|---|
fail() |
uvmkit_assert_fail() |
Unconditional failure |
assertTrue() |
uvmkit_assert_true() |
Boolean validation |
assertFalse() |
uvmkit_assert_false() |
Boolean validation |
assertEquals() |
uvmkit_assert_equals() |
Case equality (===) |
assertNotEquals() |
uvmkit_assert_not_equals() |
Case inequality (!==) |
assertNull() |
uvmkit_assert_null() |
Null check |
assertNotNull() |
uvmkit_assert_not_null() |
Not null check |
assertSame() |
uvmkit_assert_same() |
Reference equality |
assertNotSame() |
uvmkit_assert_not_same() |
Reference inequality |
assertEquals(double, delta) |
uvmkit_assert_equals_real() |
Floating-point with tolerance |
The msg parameter is always optional but recommended:
// Less helpful - just shows what failed
`uvmkit_assert_equals(data, expected)
// More helpful - provides context
`uvmkit_assert_equals(data, expected, "AXI read data mismatch at address 0x1000")
// Dynamic messages
`uvmkit_assert_true(valid, $sformatf("Cycle %0d: valid must be high", cycle))SVUNIT_INSTALL=$PWD/../svunit \
PATH=$PATH:$PWD/../svunit/bin \
runSVUnit -c -Wno-WIDTH -o obj_dir- SVUnit testing framework
- SystemVerilog simulator (Verilator recommended for development)
- Online Documentation: Natural Docs API Reference
- Source Documentation: Natural Docs style comments in
src/uvmkit_assert.sv - API Reference: See Assertion Reference above
- Examples: See examples/ directory