Part 3 · Factory & Configuration · Intermediate
Field Automation Macros: Registration and Generated Methods
How uvm_field_* macros register members with the automation engine and auto-generate do_print, do_copy, do_compare, do_pack, and do_record.
What field macros generate
The `uvm_field_* macros register class members with UVM's automation engine. Once registered, the engine generates do_print, do_copy, do_compare, do_pack, and do_record implementations.
[UVM] field macro -> generated methods
uvm_field_int(addr, FLAGS) -> do_print, do_copy, do_compare, do_pack
uvm_field_enum(...) -> same + enum string names in print
uvm_field_object(...) -> nested uvm_object deep copy/compare
uvm_field_string(...) -> string compare and print
uvm_field_sarray_int(...) -> unpacked array automation (watch size)class bus_txn extends uvm_sequence_item;
rand bit [31:0] addr;
rand bit [31:0] data;
rand bit write;
time sample_time;
`uvm_object_utils_begin(bus_txn)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(write, UVM_ALL_ON | UVM_BIN)
`uvm_field_int(sample_time, UVM_ALL_ON | UVM_NOCOMPARE)
`uvm_object_utils_end
function new(string name = "bus_txn"); super.new(name); endfunction
endclassKey takeaways
Field macros belong on uvm_object/uvm_sequence_item data classes.
FLAGS control which automation methods include each field.
uvm_component_utils does not use field macros — components are not cloned like transactions.
Common pitfalls
Placing field macros on uvm_component subclasses.
Omitting uvm_object_utils_begin/end wrapper around field registrations.
Registering handles or virtual interfaces — not supported and misleading.
Macro catalog and nested object patterns
Match the macro type to the member type. Nested uvm_objects require uvm_field_object for deep semantics.
Common macro types
`uvm_field_int` / `uvm_field_real` — scalar numeric members.
`uvm_field_enum` — SystemVerilog enums with string print names.
`uvm_field_object` — nested uvm_object pointers (deep copy).
`uvm_field_array_int` / `uvm_field_queue_int` — dynamic collections.
typedef enum { IDLE, BUSY, DONE } state_e;
class pkt extends uvm_sequence_item;
rand state_e state;
apb_item hdr;
`uvm_object_utils_begin(pkt)
`uvm_field_enum(state_e, state, UVM_ALL_ON)
`uvm_field_object(hdr, UVM_ALL_ON)
`uvm_object_utils_end
endclassFLAGS reference
[UVM] common FLAGS (combine with |)
UVM_ALL_ON print + compare + copy + record + pack
UVM_NOCOMPARE skip in compare (timestamps, cycle counts)
UVM_NOCOPY skip in copy
UVM_NOPACK skip in pack (large arrays)
UVM_NOPRINT skip in print
UVM_DEC / UVM_BIN / UVM_HEX display format in print`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(pkt_id, UVM_ALL_ON | UVM_NOCOMPARE | UVM_NOPACK)
`uvm_field_int(debug, UVM_ALL_ON | UVM_NOPRINT)Common pitfalls
Using UVM_ALL_ON on every field without reviewing compare semantics.
Forgetting null-check behavior on uvm_field_object before compare.
Mixing hand-written do_copy with field macros on the same fields.