The most dangerous gate is not the one that glitches but the one that never opens. A block whose wake-up condition is computed inside its own gated domain sleeps forever, and the symptom is a dead peripheral that passes every functional test because the tests never gate its clock. Ownership prevents this: every enable has exactly one driver, and every wake path comes from logic that is awake. This lesson assigns all three NanoSoC gates. Its one job is the hierarchy and its owners; the failure where ownership is ignored is next.
NanoSoC gates in three places. At the root, the PLL wrapper gates the fast clocks on the synchronised lock, owned by the nano_rstpwr controller in hardware. At the domain level, the CPU clock gate cell lives in nano_rstpwr and is requested by the core's wait-for-interrupt instruction, with wake on irq_cpu. At the block level, the DMA and stream-bridge clocks gate on RSTPWR CLK_EN bits 0 and 1, owned by software writing a secure-only register, both reset to enabled so no driver must opt in to a working chip. All gates are enabled by nano_rstpwr, and the CLK_EN enables are written in clk_per, so each is two-flop synchronised into clk_sys before it reaches its ICG, one branch of crossing X7.
The wake rule decides each owner. The CPU wakes on an interrupt computed outside its gated domain: the interrupt controller runs on clk_per, always on, and the wake signal crosses a synchroniser rather than depending on the sleeping clock. The DMA and bridge wake only by software setting CLK_EN again; while their clocks are stopped their registers do not answer, which is exactly the hazard the next lesson's failure makes concrete. Test mode overrides every gate through test_en, owned by the DFT integration, so scan shift never meets a gated clock.
Gate | Clock gated | Owner of the enable | Enable synchronised in | Wake source |
|---|---|---|---|---|
Root gate | clk_cpu, clk_sys | nano_rstpwr hardware (lock) | Already in nano_rstpwr | Lock re-qualifies |
CPU gate | clk_cpu | nano_rstpwr cell; request from CPU wfi | Gate logic in nano_rstpwr | irq_cpu |
DMA gate | clk_dma | Software via CLK_EN[0], secure-only | clk_sys via X7 two flops | Software sets the bit; registers do not answer while stopped |
SBR gate | clk_sbr | Software via CLK_EN[1], secure-only | clk_sys via X7 two flops | Software sets the bit; registers do not answer while stopped |
The wake latency sets how sleepy the CPU gate may be. An enabled interrupt reaches the gate logic through the two synchronisers in 135.4 ns at best, 26 CPU cycles at 192 MHz, after irq_dma rises; the clock then restarts after the ICG enable resync, an illustrative 2 CPU cycles. Deep-sleep policy therefore keeps only latency-insensitive work behind the CPU gate, and the DMA interrupt, which is the throughput-critical one, is exactly the path this latency bounds.
T_CPU_NS = 1e9 / 192e6 # 5.2083 ns
SYNC_IRQ_NS = 135.4 # NanoSoC specification: irq chain best case, 26 cpu cycles
assert abs(26 * T_CPU_NS - 135.4167) < 0.01
# ICG enable resync is illustrative (not in the NanoSoC specification): 2 cpu cycles.
wake_ns = SYNC_IRQ_NS + 2 * T_CPU_NS
assert abs(wake_ns - (135.4167 + 10.4167)) < 0.02, wake_ns
# The wake path must beat a 208.33 ns budget (one APB bridge round trip).
assert wake_ns < 208.33, wake_ns
print("PASS: irq to clock-restart about 145.8 ns (135.4 NanoSoC specification + 2 cycles illustrative)")Every gate has one named owner in the table above; no enable is driven from two places or from nowhere.
Every wake path is traced to logic outside the gated domain, on paper, before simulation.
The reset values leave every gate open except the lock gate, so the chip boots with clocks running.
Simulate each sleep-to-wake path end to end: execute wfi and confirm the CPU clock stops and restarts on the interrupt, clear each CLK_EN bit and confirm the block idles and revives. Then gate every clock and confirm the wake sources still toggle; a wake line frozen by its own gate is the bug this lesson exists to prevent. Crossings with gated clocks need their own treatment, covered under CDC and RDC: Clock Gating and Muxing.
No: CLK_EN lives in the secure-only RSTPWR block, so a non-secure write is refused. Power policy stays with the secure world even when data movement does not.