This lesson has one job: bring the chip out of sleep with its memory intact. NanoSoC powers off the whole switchable domain in SLEEP yet wakes straight into the SRAM0 image instead of reloading over SPI. That trick works only because SRAM0's arrays sit on the always-on rail in retention while their wrapper logic sleeps, and every signal crossing between them is clamped. Get the order wrong and the wake image is corrupt; miss a clamp and the wake interrupt fires spuriously.
Retention is a third power state for the memory: the array keeps its bits at a lowered leakage, here 60 percent of normal, while the periphery loses power. On NanoSoC the SRAM0 arrays live in PD_AON and the wrapper logic in PD_SW, so entering sleep isolates first, then resets, then opens the switch. Wake is not a plain reversal: it is the entry sequence with isolation released before the resets. The switch closes with a 64-cycle ramp, power-good is seen, the PLL relocks, the clocks open, isolation is released 4 system clocks later while the resets are still asserted, the system reset is released 18 system clocks after that, and the CPU reset is released last. The full sequences are 70 peripheral clocks down at 2.917 microseconds and 14.073 microseconds up. The isolation count is exact: 52 clamp cells on the SRAM0 macro port, part of the 114 total, and the two interrupt lines that were once missed are the warning that the count must be checked by a tool, not by eye.
# not-run: NanoSoC sleep arithmetic, NanoSoC teaching values
Power-down: 70 clk_per x 41.6667 ns = 2,916.7 ns = 2.917 us.
Power-up: (64 + 8 + 256 + 2) x 41.6667 ns + (4 + 18 + 8) x 10.4167 ns + 2 x 5.2083 ns
= 13,750 + 312.5 + 10.42 = 14,072.9 ns = 14.073 us.
SRAM0 retention leakage: 0.72 mW against 1.20 mW normal (0.6x factor).
Wake path: RST_CAUSE[3] set, ROM jumps to 0x2000_0000, no SPI reload.iso_sram0 = 14 + 32 + 4 + 2
iso_apb = 12 + 32 + 3
iso_rom = 12 + 1
iso_irq = 2
total = iso_sram0 + iso_apb + iso_rom + iso_irq
assert iso_sram0 == 52, iso_sram0
assert iso_apb == 47, iso_apb
assert iso_rom == 13, iso_rom
assert total == 114, total
print(f"SRAM0 {iso_sram0}, APB {iso_apb}, ROM {iso_rom}, IRQ {iso_irq}")
print("PASS: isolation adds to 114 clamp cells")The power intent names SRAM0 retention explicitly, with the array rail, the wrapper rail and the save condition each stated.
The isolation list totals 114 with the SRAM0 52 shown, and the check runs from the power-intent description.
The wake test reads back a known SRAM0 pattern written before sleep; retention is proven by data, not by a status bit.
On wake the ROM reads RST_CAUSE first and skips the SRAM0 clear, so the retained image is not wiped before the jump.
Write a checkerboard across all of SRAM0, enter and exit SLEEP in power-aware simulation, and read back every word: one mismatch means retention, isolation or sequencing failed, and the failing address says which. Check the interrupt lines first, because the missing-isolation failure shows up as a spurious wake before any data check runs. Confirm the ROM takes the retained-image branch by observing the jump to 0x2000_0000 with no SPI traffic.
Because SRAM0 holds the retained image the wake path jumps to. SRAM1 holds working data that sleep is allowed to discard, so it sleeps with the switchable domain to save its leakage.