Part 3 · Factory & Configuration · Intermediate

Factory Overview Debug: Introspection and Triage

Deterministic debug workflow for registration gaps, ignored overrides, wrong types at elaboration, and factory print interpretation.

Symptom-first triage order

Debug factory issues in strict order: registration, create path, override timing, path match, then Liskov compatibility.

diagram
[FACTORY][UVM] triage matrix

unexpected base type at runtime:
  -> was create() used?
  -> was override registered before create?
  -> does instance path match get_full_name()?

create compile error:
  -> missing utils macro / package import?

override appears in print but not effective:
  -> wrong requested base type in env create()
systemverilog
function void end_of_elaboration_phase(uvm_phase phase);
  super.end_of_elaboration_phase(phase);
  if ($test$plusargs("UVM_FACTORY_DEBUG")) begin
    factory.print(1);
    `uvm_info("FACTORY_DBG", {
      "agt_tx.drv=", env.agt_tx.drv.get_type_name(),
      " agt_rx.drv=", env.agt_rx.drv.get_type_name()
    }, UVM_NONE)
  end
endfunction

Key takeaways

  • factory.print() plus get_type_name() catches most factory bugs quickly.

  • Prove create() usage before investigating override syntax.

  • Treat wrong instance paths as the default root cause for partial overrides.

Common pitfalls

  • Deep sequence debug before confirming constructed driver type.

  • Changing overrides randomly without capturing factory.print baseline.

  • Using UVM_HIGH verbosity everywhere instead of targeted factory debug.


Deterministic debug toolkit

Keep low-cost factory diagnostics available in base test for every regression.

Instrumentation primitives

systemverilog
function void log_factory_stage(string stage);
  `uvm_info("FACTORY_STAGE",
    $sformatf("%s test=%s", stage, get_type_name()), UVM_LOW)
endfunction

function void build_phase(uvm_phase phase);
  log_factory_stage("pre_override");
  apply_factory_overrides();
  log_factory_stage("post_override_pre_super");
  super.build_phase(phase);
  log_factory_stage("post_super");
endfunction
diagram
[FACTORY] recommended counters

- override_register_count
- create_call_count_by_type
- factory_debug_print_invocations
- type_mismatch_detected_at_elab

Reproduction checklist

  1. Run single test with +UVM_FACTORY_DEBUG and UVM_LOW.

  2. Capture factory.print() after overrides, before env build if possible.

  3. Record get_type_name() for all override targets at elaboration.

  4. Re-run same seed twice to confirm deterministic type resolution.

  5. Only then inspect derivative class behavior internals.

diagram
[FACTORY][UVM] pass criteria

override target appears in factory.print
AND
get_type_name() matches expected derivative
AND
seed replay shows identical type resolution

Key takeaways

  • Factory debug is fast when staged logs exist in base test.

  • Always capture elaboration type names before behavioral debug.

  • Deterministic reproduction is mandatory for override regressions.

Common pitfalls

  • Removing factory debug hooks after one passing run.

  • Debugging config_db paths when the bug is factory construction.

  • Fixing symptoms by hardcoding derivative types in env.