The first power decision on NanoSoC is a partition with no middle ground: every block is either always on or behind the switch, and a block in the wrong domain either burns leakage all night or cannot do its job when the chip sleeps. Put the wake-up GPIO in the switchable domain and the chip sleeps forever. Put the CPU in the always-on domain and SLEEP saves almost nothing. This lesson makes each placement once, with the reason attached, so the sequencer and isolation lessons can take the partition as given.
PD_AON is the minimum chip that can wake the rest: the reset and power controller, the PLL, the interrupt controller, the UART, SPI and GPIO peripherals (UART and GPIO double as wake sources; SPI stays on because it is on the always-on APB segment and costs only 0.06 mW leakage in SLEEP), the boot ROM, and the SRAM0 arrays that hold the resume image. PD_SW is everything else: the CPU, the fabric, SRAM1 and the SRAM0 wrapper logic, the DMA and its stream bridge, and both APB segments including the system-side half of the clock-domain bridge. There is one 0.9 V supply, so no level shifters exist anywhere; the only boundary cells are the isolation clamps taught in the next topic.
Domain | Supply | Blocks |
|---|---|---|
PD_AON (always on) | 0.9 V, never switched | nano_rstpwr, PLL, nano_intc, nano_uart, nano_spi, nano_gpio, nano_sram0 arrays, nano_rom |
PD_SW (switchable) | 0.9 V through a header switch | nano_cpu, nano_axi_cdc_m, nano_xbar, nano_sram1, nano_dma, nano_sbr, nano_axi2apb, nano_apb_dec, nano_apb_cdc, power switches and isolation cells |
Two placements deserve a second look because reviewers always ask. The SRAM0 memory arrays sit in PD_AON so the resume image survives, but their wrapper logic sits in PD_SW: the address and control inputs from the fabric therefore cross the boundary and need isolation, all 52 SRAM0 clamps of it. And nano_apb_cdc is wholly in PD_SW even though its far side talks only to always-on peripherals: its peripheral-side outputs (clocked by clk_per) drive PD_AON logic, which is exactly why the 47 APB clamps sit on those outputs. It is a clock-domain bridge, not a power-domain split. The always-on list to memorise is eight items: RSTPWR, PLL, INTC, UART, SPI, GPIO, SRAM0, ROM.
# not-run: PD_SW vs PD_AON area and SLEEP leakage, NanoSoC teaching values (mm2 / mW)
PD_AON area 0.213 mm2 (SRAM0 0.100 + PLL 0.060 + rstpwr 0.015 + rom 0.012
+ uart 0.008 + spi 0.008 + gpio 0.006 + intc 0.004)
PD_SW area 0.372 mm2; SLEEP leakage 1.24 mW, of which SRAM0 0.72 + ROM 0.14
= 0.86 mW (69 %) is the memory kept alive: switching is not free.Every block appears in exactly one domain, and the eight always-on items match the NanoSoC list with no additions.
Each wake source, GPIO, UART and the power interrupt, traces to PD_AON logic with no enable or reset from PD_SW.
The SRAM0 array-versus-wrapper split is drawn explicitly so the isolation count can be checked against it.
Check the partition with a script over the netlist or the UPF intent, not by eye: assert that no cell with a PD_SW supply powers a PD_AON input without an isolation cell in between, and that the always-on list has exactly the eight members. If a wake interrupt stops working after a power edit, the first suspect is a domain move, a wake flop that followed its block into PD_SW, which the next lesson's symptom makes unmistakable.
The ROM holds the reset vector and the wake-or-boot decision. It runs on every wake as well as every cold boot, and the SRAM0 image it jumps to lives in PD_AON, so the decision logic is kept alive with it. Moving it into PD_SW would save its 0.14 mW SLEEP leakage but add a boot dependency on the switch; NanoSoC keeps it always on.