Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
ref: master
path: svunit
- name: runSVUnit
run: (cd tests; SVUNIT_INSTALL=`pwd`/../svunit PATH=$PATH:$SVUNIT_INSTALL"/bin" runSVUnit -c -Wno-WIDTH -c_arg "-I../src" -c_arg "--assert" -c_arg "-j 0")
run: (cd tests; SVUNIT_INSTALL=`pwd`/../svunit PATH=$PATH:$SVUNIT_INSTALL"/bin" runSVUnit -c -Wno-WIDTH -c_arg "-I../src" -c_arg "-I../tests/stub" -c_arg "--assert" -c_arg "-j 0")
- name: Check log
run: '! grep "FAILED" tests/run.log; return $?;'
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ How to use
How to run unit tests
---------------------

SVUNIT_INSTALL=$PWD/../svunit PATH=$PATH:$PWD/../svunit/bin runSVUnit -c -Wno-WIDTH -o obj_dir -c_arg "-I../src"
SVUNIT_INSTALL=$PWD/../svunit PATH=$PATH:$PWD/../svunit/bin runSVUnit -c -Wno-WIDTH -o obj_dir -c_arg "-I../src" -c_arg "-I../tests/stub"


Aternaltive way to run unit tests
Expand Down
55 changes: 53 additions & 2 deletions src/uvmkit_check.sv
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,59 @@
end \
end

// TODO:
// - uvm objects
//===================================
// UVM Object Comparison Macros
//===================================
// These macros are only available when UVM is defined by including uvm_macros.svh.
// This allows uvmkit_check to be used in environments without UVM.

`ifdef uvm_error

// uvmkit_check_equals_uvm - Checks if two UVM objects are equal using compare()
// Parameters:
// a - First uvm_object to compare
// b - Second uvm_object to compare
// msg - Optional message to append to error output
`define uvmkit_check_equals_uvm(a, b, msg="") \
begin \
automatic uvm_object _a_obj = a; \
automatic uvm_object _b_obj = b; \
bit _compare_result; \
if (_a_obj == null || _b_obj == null) begin \
`uvmkit_error_msg_fmt("uvmkit_check_equals_uvm", "Cannot compare null objects", msg) \
end else begin \
_compare_result = _a_obj.compare(_b_obj); \
if (!_compare_result) begin \
`uvmkit_error_msg_fmt("uvmkit_check_equals_uvm", $sformatf("UVM objects do not match:\n Type: %s vs %s", _a_obj.get_type_name(), _b_obj.get_type_name()), msg) \
end \
end \
end

// uvmkit_check_not_equals_uvm - Checks if two UVM objects are not equal using compare()
// Parameters:
// a - First uvm_object to compare
// b - Second uvm_object to compare
// msg - Optional message to append to error output
`define uvmkit_check_not_equals_uvm(a, b, msg="") \
begin \
automatic uvm_object _a_obj = a; \
automatic uvm_object _b_obj = b; \
bit _compare_result; \
if (_a_obj == null || _b_obj == null) begin \
// If one or both are null, they are different (unless both are null) \
if (_a_obj == null && _b_obj == null) begin \
`uvmkit_error_msg_fmt("uvmkit_check_not_equals_uvm", "Both objects are null, so they are equal", msg) \
end \
// else: one is null and one is not, so they are different - pass \
end else begin \
_compare_result = _a_obj.compare(_b_obj); \
if (_compare_result) begin \
`uvmkit_error_msg_fmt("uvmkit_check_not_equals_uvm", $sformatf("UVM objects match, but expected them to be different:\n Type: %s", _a_obj.get_type_name()), msg) \
end \
end \
end

`endif // uvm_error

// TODOs pertaining to uvmkit_check_equals and uvmkit_check_not_equals
// TODO: if both inputs are x but their sizes differ, then this is not equal. this is correct, but hard to debug. can we add size information to each expression or is this too hard?
Expand Down
53 changes: 53 additions & 0 deletions tests/stub/packet.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// packet - Example UVM object for testing uvmkit_check UVM comparison macros
//-----------------------------------------------------------------------------
// This is a simple example class derived from uvm_object that demonstrates
// how to implement do_compare() for field-level comparison.
//-----------------------------------------------------------------------------

`include "uvm_object.sv"

class packet extends uvm_object;

// Packet fields
bit [31:0] addr;
bit [63:0] data;
bit [3:0] id;

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
function new(string name = "");
super.new(name);
addr = 0;
data = 0;
id = 0;
endfunction

//-----------------------------------------------------------------------------
// get_type_name - Returns the type identifier for this object
//-----------------------------------------------------------------------------
virtual function string get_type_name();
return "packet";
endfunction

//-----------------------------------------------------------------------------
// do_compare - Compares all fields of this packet with rhs
//-----------------------------------------------------------------------------
virtual function bit do_compare(uvm_object rhs);
packet rhs_packet;

// Cast to packet type
if (!$cast(rhs_packet, rhs)) begin
return 0; // Type mismatch
end

// Compare all fields
if (this.addr != rhs_packet.addr) return 0;
if (this.data != rhs_packet.data) return 0;
if (this.id != rhs_packet.id) return 0;

return 1; // All fields match
endfunction

endclass
69 changes: 69 additions & 0 deletions tests/stub/uvm_object.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
// uvm_object - Minimal UVM object stub for uvmkit_check
//-----------------------------------------------------------------------------
// This is a minimal implementation of uvm_object that provides just enough
// functionality for comparison checks. It is not a complete UVM implementation.
//-----------------------------------------------------------------------------

class uvm_object;

// Object name
protected string m_name;

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
function new(string name = "");
m_name = name;
endfunction

//-----------------------------------------------------------------------------
// get_name - Returns the instance name of the object
//-----------------------------------------------------------------------------
virtual function string get_name();
return m_name;
endfunction

//-----------------------------------------------------------------------------
// get_type_name - Returns the type identifier for this object
// This should be overridden in derived classes to return the actual type name
//-----------------------------------------------------------------------------
virtual function string get_type_name();
return "uvm_object";
endfunction

//-----------------------------------------------------------------------------
// compare - Deep compares this object with rhs
// Returns 1 if the objects match, 0 otherwise
//-----------------------------------------------------------------------------
virtual function bit compare(uvm_object rhs);
// Handle null case
if (rhs == null) begin
return 0;
end

// If comparing against self, always equal
if (this == rhs) begin
return 1;
end

// Type names must match
if (get_type_name() != rhs.get_type_name()) begin
return 0;
end

// Call do_compare for field comparison
return do_compare(rhs);
endfunction

//-----------------------------------------------------------------------------
// do_compare - User-overridable comparison hook
// Derived classes should override this to compare their specific fields
// Base implementation returns 1 (objects are equal if types match)
//-----------------------------------------------------------------------------
virtual function bit do_compare(uvm_object rhs);
// Base class has no fields to compare
return 1;
endfunction

endclass
122 changes: 122 additions & 0 deletions tests/unit/uvm_object_unit_test.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
`include "svunit_defines.svh"

module uvm_object_unit_test;
import svunit_pkg::svunit_testcase;

string name = "uvm_object_ut";
svunit_testcase svunit_ut;

//===================================
// This is the UUT that we're
// running the Unit Tests on
//===================================
`include "uvm_object.sv"

//===================================
// Build
//===================================
function void build();
svunit_ut = new(name);
endfunction


//===================================
// Setup for running the Unit Tests
//===================================
task setup();
svunit_ut.setup();
/* Place Setup Code Here */
endtask


//===================================
// Here we deconstruct anything we
// need after running the Unit Tests
//===================================
task teardown();
svunit_ut.teardown();
/* Place Teardown Code Here */
endtask


//===================================
// All tests are defined between the
// SVUNIT_TESTS_BEGIN/END macros
//===================================
`SVUNIT_TESTS_BEGIN

`SVTEST(uvm_object_new_test)
uvm_object obj;
obj = new("test_obj");
`FAIL_IF(obj == null)
`SVTEST_END

`SVTEST(uvm_object_get_name_test)
uvm_object obj;
string obj_name;
bit name_match;
obj = new("my_object");
obj_name = obj.get_name();
name_match = (obj_name == "my_object");
`FAIL_UNLESS(name_match)
`SVTEST_END

`SVTEST(uvm_object_get_name_empty_test)
uvm_object obj;
string obj_name;
bit name_match;
obj = new("");
obj_name = obj.get_name();
name_match = (obj_name == "");
`FAIL_UNLESS(name_match)
`SVTEST_END

`SVTEST(uvm_object_get_name_default_test)
uvm_object obj;
string obj_name;
bit name_match;
obj = new();
obj_name = obj.get_name();
name_match = (obj_name == "");
`FAIL_UNLESS(name_match)
`SVTEST_END

`SVTEST(uvm_object_get_type_name_test)
uvm_object obj;
string type_name;
bit type_match;
obj = new("test");
type_name = obj.get_type_name();
type_match = (type_name == "uvm_object");
`FAIL_UNLESS(type_match)
`SVTEST_END

`SVTEST(uvm_object_compare_same_object_test)
uvm_object obj;
bit result;
obj = new("test");
result = obj.compare(obj);
`FAIL_UNLESS(result == 1)
`SVTEST_END

`SVTEST(uvm_object_compare_null_test)
uvm_object obj;
bit result;
obj = new("test");
result = obj.compare(null);
`FAIL_UNLESS(result == 0)
`SVTEST_END

`SVTEST(uvm_object_compare_different_objects_test)
uvm_object obj1, obj2;
bit result;
obj1 = new("obj1");
obj2 = new("obj2");
// Base uvm_objects should compare equal (no fields to compare)
result = obj1.compare(obj2);
`FAIL_UNLESS(result == 1)
`SVTEST_END

`SVUNIT_TESTS_END

endmodule
Loading