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
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[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 subtreeEscalation 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.
Single domain + objections handles 90% of block-level TBs.
Add domain when power island or VIP requires independent schedule.
Add sync only at documented hardware handoff phases.
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
// 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);
endtaskIf sync debt outweighs benefit, collapsing to one domain with explicit readiness waits is often simpler and easier to debug.