Part 2 · Phases & Lifecycle · Intermediate

Multiple Domains Example: Main Fabric + Power Island

End-to-end walkthrough: creating two domains, assigning subtrees, and running independent reset/configure/main sequences.

Scenario

A SoC testbench has a main AXI fabric env on the common domain and a power-managed peripheral island (PMU) that powers up later. The PMU subtree needs its own reset/configure cycle independent of the main fabric's timeline.

diagram
[PHASE][UVM] two-subsystem topology

tb_top
 └── tb_env
      ├── axi_env        (common domain)
      └── pmu_env        (pmu_domain)
           ├── pmu_agent
           └── pmu_scoreboard

Reference implementation

systemverilog
class tb_env extends uvm_env;
  `uvm_component_utils(tb_env)
  axi_env axi;
  pmu_env pmu;
  uvm_domain pmu_dom;

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    axi = axi_env::type_id::create("axi", this);
    pmu = pmu_env::type_id::create("pmu", this);

    pmu_dom = new("pmu_domain");
    pmu.set_domain(pmu_dom);

    `uvm_info("DOM", $sformatf("axi on %s, pmu on %s",
      axi.get_domain().get_name(), pmu.get_domain().get_name()), UVM_LOW)
  endfunction
endclass
systemverilog
// PMU agent: runs on pmu_domain schedule
class pmu_agent extends uvm_agent;
  task reset_phase(uvm_phase phase);
    phase.raise_objection(this, "pmu reset");
    wait_for_power_good();
    apply_pmu_reset();
    phase.drop_objection(this, "pmu reset done");
  endtask

  task main_phase(uvm_phase phase);
    phase.raise_objection(this, "pmu traffic");
    // PMU-specific sequences
    phase.drop_objection(this, "pmu traffic done");
  endtask
endclass
systemverilog
// AXI agent: runs on common domain (default)
class axi_agent extends uvm_agent;
  task reset_phase(uvm_phase phase);
    phase.raise_objection(this, "axi reset");
    // fabric reset — may complete before PMU powers up
    phase.drop_objection(this, "axi reset done");
  endtask
endclass

Key takeaways

  • Assign domain at env build time for the whole subtree.

  • Each domain's agents implement the same phase callbacks independently.

  • Log domain names in build_phase to confirm assignment.

Common pitfalls

  • Setting domain on individual agents instead of the sub-env root.

  • Main fabric assuming PMU is ready because common domain left reset.


Verification steps

  1. Run +UVM_PHASE_TRACE and confirm two phase streams with different entry times.

  2. Confirm PMU reset_phase starts only after power-good (domain-local behavior).

  3. Add sync before any cross-domain transaction if hardware requires alignment.