Retention Strategies
Not every bit of state in a powered-down domain is meant to be lost. Retention preserves selected flip-flop values through a power-down cycle, using a small supply that stays up even while the domain's main supply doesn't — the difference between a domain that comes back with no memory of where it was and one that resumes almost exactly where it left off.
Three commands working together
set_retention RET_RULE \
-domain PD_pwm \
-retention_supply_set PD_pwm.default_retention
set_retention_control RET_RULE \
-domain PD_pwm \
-save_signal {retn low} \
-restore_signal {retn high}
map_retention_cell RET_RULE \
-domain PD_pwm \
-lib_cell_type DRFF
set_retention declares which domain has retained state and which supply set (per Power Domains and Supplies, the default_retention handle exists for exactly this) keeps it alive. set_retention_control names the real save/restore signals and their active levels — here, retn low triggers a save, retn high triggers a restore. map_retention_cell picks which actual physical retention flop implementation gets used (-lib_cell_type) — the retained value has to live in real hardware, not just be declared in UPF.
Single-pin retention: one signal, two edges
set_retention_control pgd_retain -domain pd_gated \
-save_signal {aon_wrapper/pmu/ret_en high} \
-restore_signal {aon_wrapper/pmu/ret_en low}
Rather than two independent signals, a single control line can drive both operations — save on one level, restore on the opposite. Simpler wiring, at the cost of the two operations no longer being independently controllable.
A third variant, zero-pin retention, goes further still: no explicit save/restore control signal at all. Save and restore instead happen implicitly, tied directly to the domain's own power state transitions — save fires automatically on the NORMAL-to-CORRUPT transition, restore on the CORRUPT-to-NORMAL transition back. No set_retention_control call is needed, at the cost of losing any independent timing control over exactly when save/restore fire relative to the power transition itself.
Physically, a retention flop is often built as an ordinary flop plus a small extra latch — commonly called a balloon latch (or shadow latch) — wired to the always-on retention supply and sitting outside the flop's normal functional data path. The main flop still powers down and loses its value; the balloon latch is what actually holds A through the outage, exactly the "small supply that stays up" described above made concrete as real hardware.
A second cell style takes a different approach: master-slave-alive retention. Rather than adding a separate balloon latch outside the data path, one of the flop's own internal latches (the master or the slave, in the usual master-slave flip-flop construction) is itself wired to the always-on retention supply, so it stays alive and keeps holding the stored bit — no extra, dedicated retention element sitting outside the functional path at all. map_retention_cell's -lib_cell_type is what actually picks which of these two real cell styles gets used; UPF's set_retention/set_retention_control commands describe the same save/restore behavior either way.
The save/restore sequence relative to power itself
Save asserts and captures A into the retention flop before power actually drops. Once power drops, the main flop is gone, but the retention flop — on a separate supply — keeps holding A regardless. Once power is restored, restore_signal pulses and A flows back into the main flop.
Save has to happen before power actually drops — a retention flop that's told to save after its source has already lost power has nothing left to capture. Restore happens after power is back and stable, pushing the held value back into the domain's ordinary flops before normal operation resumes.
Not every flop should get this
Retention costs real silicon area and its own power draw on every flop it's applied to — a real design applies it selectively, to state that genuinely needs to survive a power cycle (configuration registers, state a wake-up sequence would otherwise have to painstakingly reconstruct), not blanket-wrapped across an entire domain. Concretely, a retention flop typically runs 25-30% larger in area than an ordinary flop of the same function, purely from the extra balloon-latch circuitry — a real, per-instance cost, not a rounding error, which is exactly why it's applied selectively rather than blanket-wrapped. The payoff for the flops that do get it is real and quantified: waking from retained state is a microsecond-scale restore, against a millisecond-scale full re-initialization for state that wasn't retained — the difference between a domain that's power-gated aggressively without a responsiveness penalty, and one where every power-down becomes a slow, disruptive reboot.
Naming which flops, not just deciding to: -elements
"Not every flop should get this" above is a design decision — this is the UPF mechanism that actually enforces it. set_retention accepts an -elements argument naming the specific registers a retention strategy applies to, rather than defaulting to every flop in the domain:
set_retention RET_RULE \
-domain PD_pwm \
-retention_supply_set PD_pwm.default_retention \
-elements {u_pwm_ctrl_reg u_pwm_period_reg u_pwm_duty_reg}
Without -elements, a retention strategy applies domain-wide — every flop in PD_pwm becomes a retention flop, paying the ~25-30% area overhead and extra always-on leakage on registers that may not need to survive a power cycle at all (a pipeline's transient datapath state, for instance, which a wake-up sequence can simply recompute rather than restore). With -elements, only the named instances — here, the configuration registers a wake-up sequence would otherwise have to painstakingly reconstruct — get retention flops; everything else in the same domain uses ordinary flops and is genuinely lost on power-down, exactly the selective application the earlier area/power tradeoff argues for.
The retention supply runs low, not full voltage
The "small supply that stays up" isn't simply the domain's normal operating voltage left untouched — a retention supply is typically held at a reduced voltage, just barely enough to still reliably hold a stored bit's state (commonly well under a domain's normal operating voltage, though the exact figure is technology-dependent), rather than the full voltage the domain would use while actively computing. This isn't a UPF construct itself (voltage magnitudes belong to the supply network, not the retention strategy commands), but it's the physical reason retention is worth doing at all: running the balloon latch at a deliberately minimal voltage keeps its leakage — and so its standby power draw — close to the power-gated domain's own near-zero leakage, instead of paying full-voltage leakage on every retained bit for the entire duration of the power-down.
What's next
Isolation, level shifting, and retention are all strategies applied at a domain boundary or within a domain. The final piece in this section is the physical element that actually removes and restores power in the first place — the thing every strategy above has implicitly assumed exists.