Part 2 · Phases & Lifecycle · Intermediate

Domains & Sync Patterns: Templates and Escalation Rules

Reusable integration templates, sync minimization strategy, and escalation rules for when to adopt or avoid domains.

Standard integration template

systemverilog
class multi_domain_env extends uvm_env;
  main_env main;
  island_env island;
  uvm_domain island_dom;

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    main   = main_env::type_id::create("main", this);
    island = island_env::type_id::create("island", this);
    island_dom = new("island_dom");
    island.set_domain(island_dom);
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    uvm_domain common = uvm_domain::get_common_domain();
    common.sync(.target(island_dom), .phase(uvm_reset_phase::get()));
    common.sync(.target(island_dom), .phase(uvm_main_phase::get()));
  endfunction
endclass
diagram
[PHASE][UVM] template checklist

build_phase:
  □ create subdomain envs
  □ create custom domain object
  □ set_domain on sub-env root (not per-agent)

connect_phase:
  □ sync at reset (minimum)
  □ sync at main if cross-domain traffic
  □ log installed barriers

run_phase:
  □ no set_domain calls
  □ objections scoped per domain subtree

Escalation rules

Start every project on a single domain. Escalate to multi-domain only when a documented hardware lifecycle independence requirement exists and objections cannot model it.

  1. Single domain + objections handles 90% of block-level TBs.

  2. Add domain when power island or VIP requires independent schedule.

  3. Add sync only at documented hardware handoff phases.

  4. Review sync count quarterly — each barrier is coupling debt.

Key takeaways

  • Use the build/connect template consistently across projects.

  • Minimum sync: reset barrier; add main barrier only if needed.

  • Default to single domain; domains are an escalation, not a default.

Common pitfalls

  • Copying multi-domain template into every env 'because UVM supports it'.

  • Never revisiting sync list as TB simplifies.

  • Documenting domains in code but not in integration README.


Single-domain fallback

systemverilog
// When removing domains, consolidate to objections:
task main_phase(uvm_phase phase);
  wait(island_power_good);   // hardware readiness
  phase.raise_objection(this);
  fork
    run_main_fabric();
    run_island_traffic();
  join
  phase.drop_objection(this);
endtask

If sync debt outweighs benefit, collapsing to one domain with explicit readiness waits is often simpler and easier to debug.