Part 11 · Senior Prep · Intermediate

Build & Connect Phase Interview Q&A

Model answers on build_phase top-down construction, connect_phase bottom-up TLM wiring, and common ordering mistakes.

Build and connect fundamentals

These are the most common whiteboard questions — why top-down build and bottom-up connect must be explained with a concrete hierarchy example.

Q: Why is build_phase top-down?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Why build_phase top-down?

A:
  MECHANISM:  Phase scheduler visits parent before children; parent create()'s child
              components so handles exist before child build_phase runs.
  MOTIVATION:  Parent owns composition policy — env decides how many agents, test
              decides env type. Top-down guarantees parent context exists first.
  WHEN:       Standard UVM always — parent build creates children via type_id::create().
  PITFALL:    Child creates sibling in its build_phase — breaks composition ownership,
              hides dependencies, causes duplicate instances.
  EXAMPLE:    env.build creates agt_tx and agt_rx; each agent.build creates drv/mon/sqr
              only after env holds agent handle.

Q: Why is connect_phase bottom-up?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Why connect_phase bottom-up?

A:
  MECHANISM:  Scheduler visits children before parent; leaf components expose ports,
              parent connect_phase wires cross-hierarchy TLM after all endpoints exist.
  MOTIVATION:  You cannot connect to a port on a component not yet built; bottom-up
              ensures leaf ports exist before env aggregates monitor  scoreboard links.
  WHEN:       All TLM wiring in connect_phase — never in build_phase for standard TBs.
  PITFALL:    Connecting in build_phase — sibling may not exist yet, handle is null.
  EXAMPLE:    agt.mon.ap exists after agent.connect; env.connect links agt.mon.ap to
              scb.imp and cov.analysis_export after all agents built and connected.

Q: uvm_component vs uvm_object — when do you use each?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: uvm_component vs uvm_object?

A:
  MECHANISM:  Components live in hierarchy, have parents, participate in phases.
              Objects are transient — sequences, items, config blobs, register models.
  MOTIVATION:  Hierarchy + phases need stable anchors; stimulus data is created and
              destroyed per transaction or sequence invocation.
  WHEN:       Component for anything existing entire simulation (agent, env, scb).
              Object for payloads and short-lived control (seq_item, sequence, cfg).
  PITFALL:    Making a sequence a component to 'get phases' — use starting_phase
              objections in run_phase on a normal sequence instead.
  EXAMPLE:    axi_driver is a component; axi_item is an object randomized per txn.

Q: What belongs in build_phase vs connect_phase?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: build vs connect responsibilities?

A:
  MECHANISM:  build_phase creates children, reads config_db, applies factory overrides
              before create. connect_phase calls port.connect() between components.
  MOTIVATION:  Separates structure (what exists) from wiring (how data flows) — same
              env can be rewired in derived env without changing build policy.
  WHEN:       build for create + config_db get; connect for TLM links and virtual
              interface assignment to local handles if not done in build.
  PITFALL:    Randomizing cfg in connect_phase — downstream components already read
              stale values in their build_phase.
  EXAMPLE:    build: get vif, create drv/mon. connect: drv.seq_item_port to sqr.seq_item_export,
              mon.ap to scb.imp.

Key takeaways

  • build creates handles top-down; connect wires TLM bottom-up.

  • Components = hierarchy + phases; objects = transient data.

  • Never connect in build_phase — sibling endpoints may not exist.

Common pitfalls

  • Saying both phases traverse the same direction — they do not.

  • Creating components in connect_phase — too late for child build phases.


Build/connect debug and edge cases

Q: What happens if you forget super.build_phase()?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Forgetting super.build_phase()?

A:
  MECHANISM:  super.build_phase() triggers child creation for components created via
              create() in parent's factory flow; skipping super skips framework hooks.
  MOTIVATION:  UVM base classes register config_db automation, field macros, and child
              lifecycle — super call ensures framework bookkeeping runs.
  WHEN:       Always call super unless intentionally replacing entire phase behavior
              (extremely rare, document why).
  PITFALL:    Override build_phase, create children manually, skip super — config_db
              auto-get from uvm_component may not fire, subtle cfg bugs appear.
  EXAMPLE:    agent build skips super — sequencer export not initialized, driver
              connect fails with opaque TLM error at elaboration.

Q: Can you create components after build_phase?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: Dynamic component creation after build?

A:
  MECHANISM:  create() after build_phase skips normal phase traversal for the new
              component — it enters at current phase or requires explicit phase sync.
  MOTIVATION:  UVM assumes static hierarchy for standard TBs; dynamic creation is for
              advanced scenarios (late-binding VIP, power-domain hot-plug models).
  WHEN:       Almost never in block-level TBs. If required, use uvm_phase::jump or
              manual phase execution and document heavily.
  PITFALL:    Creating monitor in run_phase — misses connect_phase wiring, no analysis
              hookup unless manually connected at runtime.
  EXAMPLE:    Attempted late agent create in run_phase — driver never got build_phase
              config_db get, vif null, immediate fatal.
diagram
[INT][SENIOR][UVM] build/connect ordering (whiteboard)

  test.build      creates env
    env.build     creates agt[0..N]
      agt.build   creates drv, mon, sqr
  test.connect    (usually empty)
    env.connect   agt[i].mon.ap  scb.imp
      agt.connect  drv.seq_item_port  sqr.seq_item_export

Q: end_of_elaboration vs start_of_simulation — why two phases?

diagram
[INT][SENIOR][UVM] MODEL ANSWER

Q: end_of_elaboration vs start_of_simulation?

A:
  MECHANISM:  Both are function phases at time zero before run_phase. end_of_elaboration
              follows connect; start_of_simulation is last pre-time advance checkpoint.
  MOTIVATION:  end_of_elaboration validates structure (topology print, config audit);
              start_of_simulation is final hook before time-consuming task phases begin.
  WHEN:       end_of_elaboration for connectivity/config audit; start_of_simulation
              for last-moment register programming or clock enable assertions.
  PITFALL:    Putting stimulus in start_of_simulation — it is still zero-time function
              phase; use run_phase or runtime sub-phases for timed activity.
  EXAMPLE:    end_of_elaboration prints env topology and verifies all vif non-null;
              start_of_simulation triggers DUT deassert reset via HDL force.

Key takeaways

  • Always call super in phase methods unless intentionally overriding framework.

  • Dynamic create after build is advanced — avoid in standard block TBs.

  • end_of_elaboration audits structure; start_of_simulation is last pre-run hook.

Common pitfalls

  • Stimulus or delays in function phases — zero-time only.

  • Topology print in run_phase instead of end_of_elaboration — too late for audit.