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.

diagram
[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)
systemverilog
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
endclass

Key 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.

systemverilog
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
endclass

FLAGS reference

diagram
[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
systemverilog
`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.