15 min read | Intermediate Level
What You'll Learn
- Understand state retention concepts and when retention is needed
- Define retention strategies using set_retention
- Specify retention supply and control signals
- Implement selective retention for critical state
Understanding State Retention
State retention is a power management technique that preserves the contents of flip-flops during power domain shutoff, enabling fast wake-up without software re-initialization.
The State Loss Problem
When a power domain is gated off:
Power-Down Sequence (Without Retention): 1. Software prepares for power-down 2. Power switch opens → VDD_domain disconnected 3. All flip-flops lose state (reset to unknown) 4. Domain fully off (zero leakage) Power-Up Sequence (Without Retention): 1. Power switch closes → VDD_domain restored 2. Domain reset 3. Software re-initializes all registers 4. System returns to operational state Total Wake Time: Milliseconds (due to software initialization)
This long wake latency makes power gating impractical for frequently-accessed blocks.
State Retention Solution
Retention flip-flops have dual power supplies:
- Primary Supply (VDD_domain): Normal operation power
- Retention Supply (VDD_RET): Always-on, low-voltage (0.6-0.8V) for state preservation
Power-Down with Retention: 1. Assert retention control signal 2. Retention FFs switch from VDD_domain to VDD_RET 3. Power switch opens → VDD_domain off 4. Retention cells maintain state using VDD_RET (minimal leakage) Power-Up with Retention: 1. Power switch closes → VDD_domain restored 2. De-assert retention control 3. Retention FFs switch back to VDD_domain 4. Domain resumes with preserved state Total Wake Time: Microseconds (no software initialization)
Retention supply (VDD_RET) is always-on at minimal voltage (~0.6V) sufficient to preserve state but low enough to minimize leakage. This achieves near-power-gated leakage levels while enabling fast wake-up.
Retention in Mobile Processors
When a smartphone's display turns off, the application processor enters sleep mode with CPU cores power-gated. Without retention, waking up would require milliseconds of re-initialization (reloading OS state, cache configuration, etc.), creating noticeable lag. With retention, the processor wakes in 10-50 microseconds with all state intact, providing instant responsiveness when the user touches the screen.
Quick Check
Q: Why not just keep the entire domain at low voltage instead of using retention cells?
Show Answer
Retention cells only preserve flip-flop state, not combinational logic. Keeping the entire domain at low voltage (~0.6V) would maintain all leakage (combinational + sequential). Retention cells allow the domain to be completely powered off (zero combinational leakage) while preserving only critical state in special retention flip-flops, achieving optimal power savings.
When to Use Retention
Retention is beneficial when:
| Scenario | Use Retention? | Rationale |
|---|---|---|
| Frequent power cycling | Yes | Fast wake-up justifies retention overhead |
| Critical state to preserve | Yes | Re-initialization expensive or impossible |
| Long sleep periods (hours) | Maybe | Retention leakage over time may exceed re-init cost |
| Short sleep periods (< 1ms) | Yes | Re-init overhead dominates power savings |
| Infrequent power-down | No | Simpler to re-initialize on rare wake events |
Retention is a tradeoff: faster wake-up and lower software complexity vs. additional area (retention cells) and non-zero retention supply power. Use retention for blocks that power-cycle frequently (multiple times per second) where wake latency matters.
Retention Flip-Flop Cells
Retention flip-flops are special library cells with additional circuitry:
Standard vs Retention Flip-Flop
| Aspect | Standard FF | Retention FF |
|---|---|---|
| Power Supplies | VDD, VSS | VDD, VDD_RET, VSS |
| Control Signals | CLK, D, RST | CLK, D, RST, SAVE, RESTORE |
| Area | 1× baseline | 1.3-1.5× (30-50% larger) |
| Power (active) | Baseline | +5-10% (extra circuitry) |
| Cost | Baseline | Higher (special cell) |
Common retention FF signals:
- SAVE/RESTORE (or RET_CTRL): Control signal to switch between VDD and VDD_RET
- VDD_RET: Retention supply port (always-on, low voltage)
Retention cells have area and power overhead. Don't use retention for all flip-flops—only critical state that must be preserved. Non-critical state (can be re-initialized quickly) should use standard cells to minimize area.
Syntax: set_retention
The set_retention command defines which flip-flops get retention and how retention is controlled.
Basic Form
set_retention strategy_name -domain domain_name \
-retention_supply_set supply_set_name \
[options]
Key Parameters
- strategy_name - Unique identifier for retention strategy (required)
- -domain domain_name - Domain where retention is applied (required)
- -retention_supply_set set_name - Supply set for retention power (required)
- -retention_condition {expr} - Boolean expression controlling retention
- -save_signal {signal sense} - Signal to save state
- -restore_signal {signal sense} - Signal to restore state
- -elements {instance_list} - Specific instances to retain (optional, default = all FFs)
Usage Variations
1. Basic Retention (All FFs in Domain):
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {cpu_retention_enable}
2. Retention with Explicit Save/Restore:
set_retention RET_GPU -domain PD_GPU \
-retention_supply_set SS_GPU_RET \
-save_signal {gpu_save_state high} \
-restore_signal {gpu_restore_state high}
3. Selective Retention (Specific Instances):
set_retention RET_CRITICAL -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {retention_en} \
-elements {cpu_inst/control_regs cpu_inst/status_regs}
Defining Retention Supply Sets
Retention requires a separate supply set with always-on retention supply.
# ===================================================================
# Power Domain with Retention
# ===================================================================
create_power_domain PD_CPU -elements {cpu_inst}
# Supply nets
create_supply_net VDD_CPU -domain PD_CPU # Primary (switchable)
create_supply_net VDD_RET -domain PD_CPU # Retention (always-on)
create_supply_net VSS -domain PD_CPU
# Active supply set (normal operation)
create_supply_set SS_CPU_ACTIVE \
-function {power VDD_CPU} \
-function {ground VSS}
# Retention supply set (state preservation)
create_supply_set SS_CPU_RET \
-function {power VDD_RET} \
-function {ground VSS}
associate_supply_set SS_CPU_ACTIVE -handle PD_CPU
# Power states
add_power_state VDD_CPU \
-state {ACTIVE 1.0} \
-state {OFF off}
add_power_state VDD_RET \
-state {RETENTION 0.6}
# Retention strategy
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {cpu_save_state}
# ===================================================================
# Behavior:
# - Normal operation: FFs use VDD_CPU (1.0V)
# - Power-down: cpu_save_state asserted → FFs switch to VDD_RET
# - VDD_CPU turned off, retention cells hold state at 0.6V
# - Power-up: VDD_CPU restored, cpu_save_state de-asserted
# ===================================================================
Retention Supply Voltage
Retention voltage is process-dependent, typically 0.6-0.8V at 28nm and below. This voltage must be: (1) High enough to prevent data loss in retention cells (minimum retention voltage ~0.5-0.6V), (2) Low enough to minimize leakage during retention (each 100mV increases leakage ~2-3×). Technology libraries specify safe retention voltage range; stay within this range for reliable operation.
Retention Control Signals
Retention requires control signals to trigger save/restore operations.
Using -retention_condition
Simple retention control with a single signal:
set_retention RET_GPU -domain PD_GPU \
-retention_supply_set SS_GPU_RET \
-retention_condition {gpu_retention_enable}
Behavior:
gpu_retention_enable = 1: Retention active (FFs use VDD_RET)gpu_retention_enable = 0: Normal operation (FFs use VDD_GPU)
Using -save_signal and -restore_signal
Explicit save and restore control:
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-save_signal {cpu_save high} \
-restore_signal {cpu_restore high}
Power-Down Sequence:
- Assert
cpu_save(high) → Retention cells save state to VDD_RET - Power down VDD_CPU
Power-Up Sequence:
- Power up VDD_CPU
- Assert
cpu_restore(high) → Retention cells restore state from VDD_RET - De-assert
cpu_restore
The -save_signal and -restore_signal approach provides explicit control over retention timing, useful for complex power sequencing. The simpler -retention_condition is sufficient for most designs.
Signal Sense (high/low)
The sense parameter specifies active polarity:
# Active-high retention (retention when signal = 1)
-retention_condition {ret_en}
# Active-low retention (retention when signal = 0)
-retention_condition {!ret_en_n}
# Save on rising edge
-save_signal {save high}
# Restore on falling edge
-restore_signal {restore low}
Quick Check
Q: What happens if you forget to assert retention control before powering down?
Show Answer
If retention control is not asserted before power-down, retention cells won't switch to VDD_RET. When VDD_CPU turns off, the retention cells lose power along with the rest of the domain, and all state is lost (same as non-retention power gating). Proper power sequencing—assert retention before power-down—is critical for retention to work.
Selective Retention
Retain only critical state to minimize area and retention supply power.
Retain Specific Instances
# Retain only control and status registers (not data path)
set_retention RET_CRITICAL -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {retention_enable} \
-elements {
cpu_inst/control_unit/config_regs
cpu_inst/control_unit/status_regs
cpu_inst/mmu/tlb_state
}
Benefits:
- Lower area (fewer retention cells)
- Lower retention power (less leakage on VDD_RET)
- Faster synthesis (less cell replacement)
Considerations:
- Non-retained state must be re-initialized on wake
- Requires careful analysis of which state is critical
- Software must handle partial retention correctly
Common candidates for selective retention: Control registers, cache tag arrays, TLB entries, power management state. Don't retain: Data path registers (ALU operands), temporary variables, re-computable state. Analyze software re-initialization cost vs. retention area/power tradeoff.
Complete Retention Example
# ===================================================================
# Complete Retention Implementation for CPU Domain
# ===================================================================
# TOP DOMAIN: Always-on
create_power_domain PD_TOP -include_scope
create_supply_net VDD_TOP -domain PD_TOP
create_supply_net VSS -domain PD_TOP
create_supply_set SS_TOP \
-function {power VDD_TOP} \
-function {ground VSS}
associate_supply_set SS_TOP -handle PD_TOP
add_power_state VDD_TOP -state {ON 1.2}
# CPU DOMAIN: Power-gated with retention
create_power_domain PD_CPU -elements {cpu_subsystem}
# Supply nets: Primary (switchable) + Retention (always-on)
create_supply_net VDD_CPU -domain PD_CPU
create_supply_net VDD_CPU_RET -domain PD_CPU
create_supply_net VSS -domain PD_CPU
# Active mode supply set
create_supply_set SS_CPU_ACTIVE \
-function {power VDD_CPU} \
-function {ground VSS}
# Retention mode supply set
create_supply_set SS_CPU_RET \
-function {power VDD_CPU_RET} \
-function {ground VSS}
associate_supply_set SS_CPU_ACTIVE -handle PD_CPU
# Power states
add_power_state VDD_CPU \
-state {ACTIVE 1.0} \
-state {OFF off}
add_power_state VDD_CPU_RET \
-state {RETENTION 0.6}
# Power switch
create_power_switch PSW_CPU -domain PD_CPU \
-input_supply_port {vin VDD_TOP} \
-output_supply_port {vout VDD_CPU} \
-control_port {ctrl cpu_power_enable} \
-on_state {on vin {ctrl}}
# Retention strategy
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {cpu_retention_enable}
# ===================================================================
# Power-Down Sequence:
# 1. Software prepares for sleep
# 2. Assert cpu_retention_enable (FFs switch to VDD_CPU_RET)
# 3. De-assert cpu_power_enable (VDD_CPU turns off)
# 4. CPU domain off, state preserved in retention cells
#
# Power-Up Sequence:
# 1. Assert cpu_power_enable (VDD_CPU restores to 1.0V)
# 2. Wait for VDD_CPU stable
# 3. De-assert cpu_retention_enable (FFs switch back to VDD_CPU)
# 4. Release reset, CPU resumes with preserved state
# ===================================================================
Retention Cell Mapping
During synthesis, UPF retention strategies are mapped to library cells.
Syntax: map_retention_cell
map_retention_cell strategy_name -domain domain_name \
-lib_cells {cell_list}
Example
# Map retention strategy to library retention flip-flops
map_retention_cell RET_CPU -domain PD_CPU \
-lib_cells {
DFFR_X1 # Standard drive strength
DFFR_X2 # 2× drive strength
DFFR_X4 # 4× drive strength
}
Synthesis tools will replace standard D flip-flops (DFF) with retention variants (DFFR) based on the UPF strategy and library cell availability.
Retention cell names are technology-specific. Common naming patterns: DFFR (D Flip-Flop with Retention), SDFFR (Scannable DFF with Retention), DFFSR (DFF with Set/Reset and Retention). Consult your library documentation for available cells.
Retention vs Re-Initialization Tradeoff
Deciding whether to use retention requires analyzing the tradeoff:
Retention Benefits
- Fast wake-up (microseconds vs milliseconds)
- Lower software complexity (no re-init code)
- Better responsiveness for interactive systems
Retention Costs
- Area overhead: 30-50% per retention FF
- Always-on retention supply (non-zero power)
- Additional control logic and sequencing
- Design/verification complexity
Break-Even Analysis
Retention is beneficial when: Wake_frequency × (Re_init_time - Retention_wake_time) × Software_cost > Retention_area_cost + (Retention_power × Sleep_time × Wake_frequency) Example: - Wake 100× per second - Re-init time: 1ms, Retention wake: 10µs - Retention saves 990µs per wake - Total time saved: 99ms/sec (10% CPU availability gain) - If retention area < 10% and retention power negligible → use retention
For blocks that sleep >99% of the time with frequent wake events (e.g., sensor hubs in smartphones), retention is almost always worthwhile. For blocks that sleep rarely or for very long periods (hours), simple re-initialization may be more efficient.
Common Beginner Mistakes
Mistake #1: Forgetting to create retention supply set
# WRONG: No retention supply set defined
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \ # SS_CPU_RET doesn't exist
-retention_condition {ret_en}
# CORRECT: Create retention supply set first
create_supply_set SS_CPU_RET \
-function {power VDD_CPU_RET} \
-function {ground VSS}
set_retention RET_CPU -domain PD_CPU \
-retention_supply_set SS_CPU_RET \
-retention_condition {ret_en}
Why? Retention cells need a separate supply set with always-on retention supply (VDD_RET). This supply set must exist before referencing it in set_retention.
Mistake #2: Using switchable supply for retention
# WRONG: Retention supply set uses switchable VDD_CPU
create_supply_set SS_CPU_RET \
-function {power VDD_CPU} \ # This will be turned off!
-function {ground VSS}
# CORRECT: Use always-on retention supply
create_supply_set SS_CPU_RET \
-function {power VDD_CPU_RET} \ # Always-on, separate supply
-function {ground VSS}
Why? Retention supply must remain on during power-down. If you use the main domain supply (VDD_CPU) for retention, state is lost when that supply is gated off.
Mistake #3: Retaining all FFs unnecessarily
Problem: Using retention for all flip-flops wastes area and power.
Solution: Analyze which state is critical and use selective retention (-elements) for only necessary registers. Let non-critical state be re-initialized on wake.
Practice Exercise
Challenge: Implement Retention for GPU Domain
Create UPF for a GPU domain with selective retention:
- Primary supply: VDD_GPU (0.9V, switchable)
- Retention supply: VDD_GPU_RET (0.6V, always-on)
- Retain only: gpu_inst/config_regs and gpu_inst/shader_state
- Control: gpu_retention_enable (active-high)
Write complete UPF including domains, supplies, states, power switch, and retention strategy.
Hint
You need 2 supply sets (SS_GPU_ACTIVE and SS_GPU_RET), 2 power states for VDD_GPU (ACTIVE and OFF), 1 state for VDD_GPU_RET (RETENTION), a power switch, and a set_retention with -elements for selective retention.
Solution
# ===================================================================
# GPU Domain with Selective Retention
# ===================================================================
# TOP DOMAIN (always-on, for context)
create_power_domain PD_TOP -include_scope
create_supply_net VDD_TOP -domain PD_TOP
create_supply_net VSS -domain PD_TOP
create_supply_set SS_TOP \
-function {power VDD_TOP} \
-function {ground VSS}
associate_supply_set SS_TOP -handle PD_TOP
add_power_state VDD_TOP -state {ON 1.2}
# GPU DOMAIN with selective retention
create_power_domain PD_GPU -elements {gpu_inst}
# Supply nets
create_supply_net VDD_GPU -domain PD_GPU
create_supply_net VDD_GPU_RET -domain PD_GPU
create_supply_net VSS -domain PD_GPU
# Active supply set
create_supply_set SS_GPU_ACTIVE \
-function {power VDD_GPU} \
-function {ground VSS}
# Retention supply set
create_supply_set SS_GPU_RET \
-function {power VDD_GPU_RET} \
-function {ground VSS}
associate_supply_set SS_GPU_ACTIVE -handle PD_GPU
# Power states
add_power_state VDD_GPU \
-state {ACTIVE 0.9} \
-state {OFF off}
add_power_state VDD_GPU_RET \
-state {RETENTION 0.6}
add_power_state VSS -state {ON 0.0}
# Power switch
create_power_switch PSW_GPU -domain PD_GPU \
-input_supply_port {vin VDD_TOP} \
-output_supply_port {vout VDD_GPU} \
-control_port {ctrl gpu_power_enable} \
-on_state {on vin {ctrl}}
# Selective retention strategy (only critical state)
set_retention RET_GPU_CRITICAL -domain PD_GPU \
-retention_supply_set SS_GPU_RET \
-retention_condition {gpu_retention_enable} \
-elements {
gpu_inst/config_regs
gpu_inst/shader_state
}
# ===================================================================
# Notes:
# - Only config_regs and shader_state preserved during power-down
# - Other GPU state (shader ALU registers, temporary buffers) lost
# - Software must re-initialize non-retained state on wake
# - Area/power overhead minimized by selective retention
# ===================================================================
Summary
In this tutorial, you learned:
- State retention preserves flip-flop contents during power-down using always-on low-voltage retention supply, enabling fast wake-up (µs vs ms)
set_retentiondefines retention strategies with-retention_supply_set(always-on supply) and-retention_condition(control signal)- Retention cells have 30-50% area overhead and require dual supplies (VDD_domain for active, VDD_RET ~0.6V for retention)
- Selective retention with
-elementsretains only critical state, minimizing area and retention supply power - Retention is worthwhile for frequently-cycled domains where fast wake-up justifies overhead, not for infrequent or very long sleep periods
- Proper power sequencing critical: assert retention before power-down, de-assert after power-up and stable supply