Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • The NanoSoC Tour
  • Reading Path
  • SoC Glossary10
  • SoC Metrics Reference
  • SoC Cheatsheet
  • What SoC Integration Is12
  • Architecture and Budgets21
    • Partitioning and Hierarchy
    • Area Budgets
    • Timing Budgets Across Hierarchy
    • Power Budgets
      • Dynamic and Leakage Roll-Up
      • Thermal and Power Envelope
      • Budget Versus Measured
    • Bandwidth Budgets
    • Budget Governance
    • Multi-Die and Chiplet View
  • Memory Maps and Address Decode26
  • Interconnect and Bus Fabrics26
  • Clock and Reset Architecture24
  • Power Architecture21
  • Interrupts, DMA and Peripherals15
  • Memories, Boot and Security21
  • IP Integration and Handoff21
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Power Budgets
  1. Topics
  2. SoC Design
  3. Architecture and Budgets
  4. Power Budgets
  5. Dynamic and Leakage Roll-Up
On this page

    Part 2 of 14, lesson 10 of 21Part 2 of 14/Architecture and Budgets/Lesson 10 of 21All levels

    Dynamic and Leakage Roll-Up

    Adding the NanoSoC power table: dynamic plus leakage, per domain, per state, checked by script.

    Why it matters

    Three numbers decide the supply, the package and the battery story: 82.74, 16.89 and 1.40 mW. The power table has eighteen rows (sixteen blocks, with the CPU core and its cache and the power switches split out) with dynamic and leakage columns across three states, and the totals — 82.74, 16.89, 1.40 mW — decide nothing if they do not add up. The script below re-adds them independently, per domain and per state, so any stale copy is caught by arithmetic rather than by silicon.

    The core idea

    Each block contributes dynamic power when it switches plus leakage whenever it is powered. RUN switches everything a DMA job needs; IDLE gates the CPU, DMA and SBR clocks so their dynamic terms fall to near zero while leakage stays; SLEEP switches the whole PD_SW domain off so only 2% switch leakage plus retained SRAM0 remains, and the PLL goes dark. Two facts dominate the table. The CPU core is 39.20 mW of the 82.74 RUN total, 47.4%: the processor buys the performance and pays the power. And leakage in SLEEP is 1.24 of the 1.40 mW: when nothing switches, what leaks is everything.

    State

    PD_SW (mW)

    PD_AON (mW)

    Total (mW)

    RUN

    65.98

    16.76

    82.74

    IDLE

    6.83

    10.06

    16.89

    SLEEP

    0.06

    1.34

    1.40

    The calculator

    The script re-adds the dynamic and leakage columns per state and checks the domain splits and the two headline shares.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    dyn_run = [38.00, 4.00, 3.00, 5.00, 3.00, 2.00, 1.00, 0.50, 6.00,
        0.00, 6.00, 1.00, 0.30, 0.40, 0.20, 0.20, 0.50, 6.00]
    leak = [1.20, 0.30, 0.12, 0.32, 0.10, 0.08, 0.05, 0.03, 1.20,
        0.08, 1.20, 0.14, 0.06, 0.06, 0.05, 0.03, 0.12, 0.50]
    assert abs(sum(dyn_run) - 77.10) < 0.005
    assert abs(sum(leak) - 5.64) < 0.005
    assert abs(sum(dyn_run) + sum(leak) - 82.74) < 0.01
    dyn_idle = [1.90, 0.20, 0.30, 0.50, 0.00, 0.00, 0.10, 0.05, 0.30,
        0.00, 0.30, 0.00, 0.30, 0.40, 0.20, 0.20, 0.50, 6.00]
    assert abs(sum(dyn_idle) + sum(leak) - 16.89) < 0.02
    dyn_sleep = [0.00]*10 + [0.00, 0.00, 0.03, 0.04, 0.02, 0.02, 0.05, 0.00]
    leak_sleep = [0.02, 0.01, 0.00, 0.01, 0.00, 0.00, 0.00, 0.00, 0.02,
        0.00, 0.72, 0.14, 0.06, 0.06, 0.05, 0.03, 0.12, 0.00]
    assert abs(sum(dyn_sleep) + sum(leak_sleep) - 1.40) < 0.02
    cpu_share = (38.00 + 1.20) / 82.74
    assert abs(cpu_share - 0.474) < 0.002
    # Idle factors (specification 10): gated rows must fall by exactly their factor,
    # the always-on rows and the PLL must not move between RUN and IDLE.
    gated = {"cpu core": (38.00, 1.90, 0.05), "i-cache": (4.00, 0.20, 0.05),
             "async bridge": (3.00, 0.30, 0.10), "xbar": (5.00, 0.50, 0.10),
             "axi2apb": (1.00, 0.10, 0.10), "apb_cdc": (0.50, 0.05, 0.10),
             "sram1": (6.00, 0.30, 0.05), "sram0": (6.00, 0.30, 0.05)}
    for name, (run, idle, factor) in gated.items():
        assert abs(idle / run - factor) < 1e-9, name
    always_on = {"uart": (0.30, 0.30), "spi": (0.40, 0.40), "gpio": (0.20, 0.20),
                 "intc": (0.20, 0.20), "rstpwr": (0.50, 0.50), "pll": (6.00, 6.00)}
    assert all(run == idle for run, idle in always_on.values())
    print(f"PASS: RUN 82.74, IDLE 16.89, SLEEP 1.40 mW; CPU share {cpu_share*100:.1f}%; idle factors hold")

    What the review looks for

    • Dynamic and leakage quoted separately per row: a single blended column cannot size the supply or the battery.

    • Per-domain subtotals, because the switch and the always-on supply are sized independently.

    • The two headline facts (CPU share, SLEEP leakage dominance) stated, not left for the reader to compute.

    Verify and debug

    Re-run the script whenever any row changes; the usual breakage is an IDLE factor edited in prose but not in the table, or a new block added to RUN but forgotten in SLEEP. Check the SLEEP column hardest: every PD_SW row must read zero dynamic and near-zero leakage, and any nonzero is either a missing clock gate or a missing isolation entry.

    Power-gating without quiescing first. Shutting the switch while the DMA is mid-burst corrupts the transfer and strands the fabric. Quiesce, then isolate, then reset, then switch — the NanoSoC specification's power-down order — and verify each step with its own assertion.

    If asked where the power goes, answer CPU core first at 47% of RUN, then say what vanishes in IDLE: clock-gated dynamic, while leakage stays. That contrast is the whole lesson.

    Use the IDLE column as a clock-gating check on the rows that are meant to be gated: the CPU falls from 38.00 to 1.90 mW (factor 0.05), the fabric from 5.00 to 0.50 and the bridges to a tenth, while the PLL stays at 6.00 because wake latency forbids switching it off. The always-on peripherals (UART, SPI, GPIO, INTC, the reset controller) and the PLL sit at factor 1.0 in IDLE by assumption, so a flat row there is correct, not a finding. Among the gated rows (CPU, cache, fabric, bridges, SRAMs), one that barely moves between RUN and IDLE is a clock that is not really gated — usually a missing enable or an enable qualified in the wrong domain. Compare each gated row's RUN-to-IDLE ratio with its stated factor; a mismatch is the finding.

    Check yourself Why does SLEEP still burn 1.40 mW when PD_SW is off?

    Leakage: retained SRAM0 at 0.72 mW plus the always-on peripherals, controller and their leakage. Switching is nearly gone; leaking is not.

    Related topics

    • Next: Thermal and Power Envelope

    • Arch: Power and Energy

    Previous

    27 / 289

    Next: Thermal and Power Envelope

    Up next

    Up nextThermal and Power Envelope

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Budget Versus Measured