Part 3 · Factory & Configuration · Intermediate
Print, Copy, Compare, and Pack: Using Generated Object Methods
Practical workflows for sprint, copy, compare, and pack on transaction and config objects — the methods field macros generate for you.
Auto-generated method workflows
Field macros generate do_print, do_copy, do_compare, do_pack so scoreboards, predictors, and debug logs can introspect transactions without hand-written boilerplate.
[UVM] generated method call graph
sprint() -> do_print() -> per-field print per FLAGS
copy(rhs) -> do_copy() -> deep copy per uvm_field_object
compare(rhs) -> do_compare() -> field-by-field per FLAGS
pack/pack_bytes -> do_pack() -> binary packing per FLAGSbus_txn a = bus_txn::type_id::create("a");
assert(a.randomize());
`uvm_info("TXN", a.sprint(), UVM_MEDIUM)
bus_txn b = bus_txn::type_id::create("b");
b.copy(a);
if (!a.compare(b)) `uvm_error("CMP", "copy/compare mismatch after clone")Key takeaways
sprint() is the fastest debug path for transaction contents.
copy() + compare() is the standard scoreboard reference-model check.
Custom do_compare overrides auto-compare when semantics are non-trivial.
Common pitfalls
Comparing before randomize settles — stale fields cause false mismatches.
Shallow copy on nested objects when uvm_field_object was omitted.
Calling compare() across unrelated types without casting guard.
Compare customization and pack patterns
When auto-compare is too strict, override do_compare. Use pack for streaming or recording, with NOPACK on heavy fields.
Custom compare
class timed_txn extends bus_txn;
int cycle;
`uvm_object_utils_begin(timed_txn)
`uvm_field_int(cycle, UVM_ALL_ON | UVM_NOCOMPARE)
`uvm_object_utils_end
function bit do_compare(uvm_object rhs, uvm_comparer comparer);
timed_txn r = timed_txn'(rhs);
return (addr == r.addr && data == r.data); // ignore cycle
endfunction
endclass[UVM] compare decision tree
fields match with same semantics?
yes -> rely on auto-compare via field macros
no -> UVM_NOCOMPARE on excluded fields
OR override do_compare for composite rulesPack and record usage
// Pack for streaming or waveform record
bit [7:0] bytes[];
a.pack_bytes(bytes);
// Selective pack: exclude large payload
`uvm_field_array_int(payload, UVM_ALL_ON | UVM_NOPACK | UVM_NOCOMPARE)Use UVM_NOCOMPARE on timestamps and simulator-time fields.
Use UVM_NOPACK on large arrays used only for stimulus, not checking.
Prefer sprint at UVM_MEDIUM for interactive debug, UVM_HIGH for field dumps.
Common pitfalls
Overriding do_compare without calling super when base fields still matter.
Packing objects with UVM_ALL_ON on multi-kilobyte arrays — regression slowdown.
Using compare() in hot loops without trimming FLAGS first.