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
  • 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
    • SoC Verification Strategy
    • Integration and Connectivity Tests
    • Firmware Co-Simulation
    • Performance Verification
    • Gate-Level and Power-Aware Simulation
      • What Gate-Level Simulation Finds
      • X-Propagation, Reset Order and Timing
      • Power-Aware Simulation and Isolation Checks
    • Emulation and FPGA Prototyping
    • Bring-Up Readiness
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Gate-Level and Power-Aware Simulation
  1. Topics
  2. SoC Design
  3. Top-Level Verification and Bring-up
  4. Gate-Level and Power-Aware Simulation
  5. Power-Aware Simulation and Isolation Checks
On this page

    Part 10 of 14, lesson 15 of 21Part 10 of 14/Top-Level Verification and Bring-up/Lesson 15 of 21All levels

    Power-Aware Simulation and Isolation Checks

    Checking isolation, retention and sequencing with the power intent active: what fails and in what order.

    Why it matters

    Without the power intent, simulation assumes every domain is always on — and the sleep-wake sequence passes by assumption. With the intent active, the simulator corrupts what the intent says is off, clamps what isolation says is clamped, and keeps what retention says is retained. NanoSoC's two missing interrupt clamps turn this run from green to red in one cycle: entering SLEEP drives the interrupt lines to X, INTC RAW shows X, and the wake logic sees an interrupt that is not there. Its one job is the power-aware check set: isolation, sequence, retention, each with its expected failure.

    The core idea

    Three checks run in the power intent's order. Isolation first: with PD_SW powered down, every one of the 114 signals into the always-on domain must read 0 — the two interrupt lines included — and any X is a missing or wrong-polarity clamp, with planted bug 6 as its NanoSoC instance. Sequence second: the power-down order is isolate, gate clocks, assert reset, open the switch over a 64-cycle clk_per ramp, 2.917 us total; the wake order reverses it with the PLL relock and the staged reset release, 14.073 us total. The simulator asserts each step against its window: isolation before the switch opens, reset before isolation releases, restore after power is stable. Retention third: SRAM0 content survives SLEEP, so a pattern written before SLEEP must read back unchanged after wake, RST_CAUSE bit 3 (WAKE) must be set, and the ROM must jump to 0x2000_0000 without reloading. The CPU and the PD_SW logic keep nothing: whatever software needs after wake is saved into SRAM0 first.

    nano_iso_clamp0.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // NanoSoC teaching values: clamp-0 isolation cell. When the switchable domain
    // powers down, the enable clamps the output to 0; otherwise it passes through.
    module nano_iso_clamp0 (
      input  logic in,      // from the switchable domain
      input  logic iso_en,  // asserted before power-down, released after restore
      output logic out       // to the always-on domain
    );
      assign out = iso_en ? 1'b0 : in;
    endmodule
    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
    # Power-sequence audit: build the down sequence as timed events, then check the
    # ordering rules and the isolation list so each check can fail. Power sequence and isolation tables.
    T_PER_NS, T_SYS_NS, T_CPU_NS = 1e9 / 24e6, 1e9 / 96e6, 1e9 / 192e6
    def down_sequence(iso_first=True):
        steps = [("iso_sw_en", 2), ("clocks_gated", 2), ("resets_asserted", 2), ("switch_open", 64)]
        if not iso_first:
            steps = [steps[1], steps[2], steps[3], steps[0]] # clamp enabled too late
        t, events = 0.0, {}
        for name, cycles in steps:
            t += cycles * T_PER_NS
            events[name] = t
        return events, t
    def order_ok(ev):
        return ev["iso_sw_en"] < ev["clocks_gated"] < ev["resets_asserted"] < ev["switch_open"]
    ev, down_ns = down_sequence()
    assert order_ok(ev) and abs(down_ns - 2916.7) < 0.5, down_ns
    assert not order_ok(down_sequence(iso_first=False)[0]) # bug: isolation after power is off
    up_ns = (64 + 8 + 256 + 2) * T_PER_NS + (4 + 18 + 8) * T_SYS_NS + 2 * T_CPU_NS
    assert abs(up_ns - 14072.9) < 0.5, up_ns
    EXPECT = {"apb_cdc": 47, "sram0": 52, "rom": 13, "irq": 2}
    def clamp_gaps(present):
        return {g: EXPECT[g] - present.get(g, 0) for g in EXPECT if present.get(g, 0) != EXPECT[g]}
    assert sum(EXPECT.values()) == 114 and clamp_gaps(dict(EXPECT)) == {}
    assert clamp_gaps({"apb_cdc": 47, "sram0": 52, "rom": 13}) == {"irq": 2} # planted bug 6
    print(f"power-down {down_ns / 1000:.3f} us, wake {up_ns / 1000:.3f} us")
    print("PASS: isolate-first order enforced, 2.917 us down, 14.073 us up, bug 6 names its group")

    What the review looks for

    • The isolation list per group totals 114 with the two interrupt lines named, the pair planted bug 6 left out.

    • Sequence assertions bind every order step: isolate before switch, reset before release, restore after stable.

    • Retention proves content equality across SLEEP, not just that the wake interrupt fires.

    Verify and debug

    An X on an always-on input during power-down is isolation until proved otherwise: check the cell exists, the enable timing, then the polarity. A wake that hangs points at the release order — isolation released before reset is stable glitches the on domain. A retention mismatch points at what software saved before SLEEP: state added after the save routine was written is the usual gap, found by comparing the save list against the registers and variables the wake path needs, not by staring at the waveform.

    Isolation sequence error: isolation enabled after power is already off, or released before power and clocks are stable, glitching the always-on domain. The order above (software quiesces and saves, then isolate, gate clocks, assert reset, open the switch, and the reverse on wake) is enforced by sequencing assertions in the power-aware run, not by code review.

    If asked what power-aware simulation adds, answer corruption, clamping and randomisation per the intent — then the NanoSoC story: two missing clamps, a spurious wake, an infinite sleep-wake loop, found in one SLEEP entry.

    Check yourself Wake fires at once after every SLEEP entry, looping sleep and wake. What is the first check?

    Read the interrupt controller RAW during power-down: an X or 1 on an interrupt input means a missing clamp. Planted bug 6 predicts exactly this loop, and the isolation list names the two cells to add.

    Related topics

    • X-Propagation, Reset Order and Timing

    • Power: Isolation and Retention Integration

    • Power: Cold-Start Power-Up Sequence

    • Verification First Principles: Low-Power Verification Strategy

    • Verification First Principles: CDC and RDC in the Plan

    Previous

    207 / 289

    Next: Package, Pads and I/O

    Up next

    Up nextPackage, Pads and I/O

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • What Gate-Level Simulation Finds