Part 3 · Factory & Configuration · Intermediate

Create-Time Resolution: From Request to Built Type

Step-by-step factory resolution at create(), how instance paths are formed, and interaction points with override tables.

Resolution algorithm (practical view)

When type_id::create() runs, the factory computes the eventual full name, checks override tables, and selects the winning type proxy.

diagram
[FACTORY][UVM] create-time resolution flow

create(base_driver, "drv", parent=agt_tx)
  |
  +--> compute prospective full name:
  |      parent.get_full_name() + ".drv"
  |
  +--> check instance override table for full path
  |      hit? -> use instance target type
  |
  +--> else check type override for base_driver
  |      hit? -> use type target type
  |
  +--> else use requested base_driver
  |
  +--> call new(name, parent) on resolved type
  +--> return handle typed as base_driver
systemverilog
function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  `uvm_info("BUILD", $sformatf("parent=%s", get_full_name()), UVM_MEDIUM)
  drv = base_driver::type_id::create("drv", this);
  `uvm_info("BUILD", $sformatf("drv=%s type=%s",
    drv.get_full_name(), drv.get_type_name()), UVM_MEDIUM)
endfunction

Key takeaways

  • Resolution happens per create() call — not cached globally per type.

  • Parent hierarchy determines instance override path matching.

  • Returned handle is typed as requested base for polymorphic usage.

Common pitfalls

  • Assuming first create pins override policy for later creates.

  • Renaming parent components without updating override paths.

  • Expecting resolution to rewrite objects already constructed.


Multi-create scenarios and diagnostics

Large envs create many instances of the same requested type. Resolution is per-instance path, not per-type singleton.

Multi-agent diagram

diagram
[FACTORY] multi-agent resolution

type override: base_driver -> err_driver

create env.agt0.drv -> err_driver
create env.agt1.drv -> err_driver

instance override: env.agt1.drv -> stress_driver

create env.agt0.drv -> err_driver
create env.agt1.drv -> stress_driver  (instance wins)
create env.agt2.drv -> err_driver
systemverilog
function void debug_create_resolution();
  uvm_factory f = uvm_factory::get();
  f.debug_create_by_type(base_driver::get_type());
  f.debug_create_by_name("uvm_test_top.env.agt_tx.drv");
endfunction

Resolution verification checklist

  1. Log parent full name before each critical create().

  2. Register overrides, then create — never reverse order.

  3. At end_of_elaboration, print type names for each agent child.

  4. If mismatch, inspect instance path strings character by character.

  • Resolution is deterministic for a given override set and hierarchy.

  • Changing parent structure changes instance override matching.

  • Use debug_create_by_name for one failing path.

Common pitfalls

  • Wildcard path assumptions not supported by factory instance overrides.

  • Late-added generate blocks changing hierarchy between tests.

  • Comparing handles instead of get_type_name() for resolution checks.