Part 2 · Phases & Lifecycle · Intermediate

build_phase Hub: Top-Down Construction and Configuration

Hub - top-down ordering rationale, factory create patterns, config_db gets, conditional construction, full walkthrough, and build-phase debug checklists.

Overview

build_phase is where the UVM component tree materializes . Every parent creates its children, every component reads its configuration, and factory overrides take effect — all before a single TLM port is connected.

The phase runs top-down so parents exist before children build, which is the only safe order for hierarchical construction and config distribution.

Sub-lessons in this topic

  1. build-top-down-why - why parent-before-child ordering is non-negotiable.

  2. factory-create-pattern - type_id::create() and override timing.

  3. config-db-get-build - canonical get patterns and path discipline.

  4. conditional-construction - active/passive and feature-gated builds.

  5. build-phase-walkthrough - end-to-end build timeline on a real env.

  6. build-phase-debug - symptom-first triage for construction failures.

diagram
[PHASE][UVM] build_phase position

  uvm_root
    └─ uvm_test_top (test)
         └─ env
              ├─ agent[0]
              │    ├─ driver
              │    ├─ monitor
              │    └─ sequencer
              ├─ scoreboard
              └─ coverage

TRAVERSAL: top-down (parent build_phase before child)
TIME:      zero (function phase)
JOBS:      create children, get config, apply factory overrides
systemverilog
function void build_phase(uvm_phase phase);
  super.build_phase(phase);   // always first
  // 1) get config / vif from config_db
  // 2) register factory overrides (tests, before super in child)
  // 3) create children via type_id::create()
  // NEVER: connect ports, drive pins, consume time
endfunction

Key takeaways

  • build_phase answers: what components exist and with what configuration?

  • Top-down traversal guarantees parents can create children safely.

  • Factory create and config_db gets are the two core build mechanisms.

Common pitfalls

  • Using new() instead of type_id::create() — overrides silently ignored.

  • Connecting TLM ports in build_phase — endpoints may not exist yet.

  • Registering factory overrides after super.build_phase — too late.


Build-phase contract

Treat build_phase as a strict contract: structure only, zero simulation time, no wiring.

Allowed vs forbidden

diagram
[PHASE][UVM] build_phase rules

ALLOWED:
  super.build_phase(phase)
  uvm_config_db::get / set (with care)
  type_id::create() for children
  factory set_type_override / set_inst_override
  structural if/else from cfg

FORBIDDEN:
  #delay, wait(), @(event)
  port.connect() / export.bind()
  sequence.start()
  direct pin drive on vif
  • Every component override must call super.build_phase first.

  • Overrides registered before create() affect that create() call.

  • Gets must match the set path, instance name, and type exactly.

diagram
[PHASE] build  connect handoff

build_phase delivers:
  - complete component tree
  - resolved cfg objects
  - factory-substituted types

connect_phase expects:
  - all endpoints exist (non-null handles)
  - no new components created
  - topology stable for wiring

Common pitfalls

  • Lazy-creating components in run_phase — breaks connect and topology print.

  • Mixing config push and component create without documented order.

  • Skipping super.build_phase — field automation and callbacks missed.