Power Domains and Supplies
Every construct in this topic ultimately refers back to two foundational ideas: which logic shares power control (a power domain), and what that power actually consists of (a supply). This page covers both, in the order UPF itself builds them.
Power domains: grouping logic by shared power control
set_scope Video_SB
create_power_domain Video_PD -include_scope
create_power_domain V1_PD -elements {V1}
create_power_domain takes one of two shapes: -include_scope claims everything in the current hierarchical scope (set beforehand with set_scope) — the usual choice for a domain meant to cover an entire block. -elements {list} claims only the named instances (and their descendants) instead — and those instances don't have to share a single parent module. A domain built from -elements {A/inst1 B/inst2 C/D/inst3} is completely legal: UPF domains are defined by shared power behavior, not by RTL module boundaries, and the two frequently don't line up exactly. -exclude_elements carves specific instances back out of an otherwise broad domain.
Every UPF specification needs one primary power domain created at the top of the design (typically -include_scope at the top-level scope) — any element not explicitly claimed by a more specific domain belongs to it by default. In practice this top-level domain is often the always-on portion of the chip, and every other domain's boundary is understood relative to it.
Supply sets: an abstract role, not a raw net
A single wire has no meaning as "the power for this domain" on its own — a supply set is what gives it that meaning, bundling a power net and a ground net together under one named role:
create_supply_port VDD_pwm -direction in
create_supply_net VDD_pwm_net
connect_supply_net VDD_pwm_net -ports VDD_pwm
create_supply_set pwm_primary -function {power VDD_pwm_net} -function {ground VSS_net}
create_supply_port/create_supply_net build the concrete port/net layer; create_supply_set groups a power net and a ground net into one abstract set with a name. A power domain then adopts a supply set via a handle — not an arbitrary label, but one of four standard roles UPF itself defines:
Power and ground are the two functional roles used everywhere in this topic, but -function isn't limited to just those two — UPF defines up to six: power, ground, nwell, pwell, deepnwell, and deeppwell. The last four exist for substrate/well biasing (e.g. create_supply_set SS_VDD1p2 -function {power VDD1p2} -function {ground VSS} -function {nwell VDD1p2} -function {pwell VSS}), an advanced technique (body biasing) some low-power flows use alongside power gating — not something this topic's examples need, but worth knowing a supply set's role vocabulary isn't hardcoded to just power/ground.
| Handle | Role |
|---|---|
primary | The domain's main operating supply |
default_retention | The supply used to retain state while the domain's primary supply is off |
default_isolation | The supply the domain's isolation cells themselves draw power from |
extra_supplies_0, extra_supplies_1, ... | Any additional supplies smaller portions of the domain need |
associate_supply_set pwm_primary -handle primary
This indirection — a domain names a handle, not a literal net — is exactly what makes composing UPF hierarchically possible later (a later page in this section covers it directly): a block's UPF can say "my primary supply" without yet knowing which real net a top-level integrator will eventually connect it to.
A shortcut: assigning handles directly on create_power_domain
associate_supply_set ... -handle primary isn't the only way to wire a supply set to a domain's handle — create_power_domain itself accepts a -supply option that does the same job inline, at declaration time:
create_power_domain PWM_PD -elements {pwm_inst} \
-supply {primary pwm_primary} \
-supply {default_isolation pwm_iso_primary}
This is equivalent to declaring the domain plain and following it with one associate_supply_set ... -handle call per handle — -supply {handle_name supply_set_name} pairs, repeated once per handle being assigned. Which form to use is purely a style choice: -supply keeps a domain's handle assignments visible in the same command that creates it, while separate associate_supply_set calls read more like a sequential build-up, useful when a handle isn't known yet at domain-creation time (e.g. before a hierarchical block's supplies are connected by an integrator, covered on a later page). Neither form changes what the handle means — both still ultimately point a named role (primary, default_isolation, ...) at a create_supply_set-built supply set.
Always-on cells: the exception domain boundaries need
Not every cell at a domain boundary can afford to lose power along with the rest of the domain. A signal that's meant to pass through a powered-down domain to reach logic on the other side needs something to buffer and drive it — something that stays powered regardless of the domain's own state:
define_always_on_cell -cells AON_BUF \
-power_switchable VDD1P0_SW -ground_switchable VSS \
-power VDD1P0 -ground VSS
An always-on (AON) cell stays powered from a supply outside the switchable domain even when instantiated physically inside it — used for feed-through buffering, high-fanout net buffering, or driving a retention register's control input while the domain around it is off. Without one, a feed-through signal simply has nowhere to get drive strength from the moment its domain powers down.
What's next
Power domains and supplies establish what has power and from where. The next page covers when — the legal combinations of domain and supply states a design can actually be in, and what happens if it reaches one that isn't.