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
    • Clock Sources and PLLs
    • Dividers, Muxes and Glitch-Free Switching
    • Clock Gating Architecture
      • ICG Cells and Enable Timing
      • Hierarchical Gating and Enable Ownership
      • Failure: DMA Gated During an APB Access
    • Clock Domain Planning
    • Top-Level Crossings
    • Always-On Domain, Wake Policy and a Timer Extension
    • Reset Sources and Reset Tree
    • Reset Sequencing and Release
  • 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

←Clock Gating Architecture
  1. Topics
  2. SoC Design
  3. Clock and Reset Architecture
  4. Clock Gating Architecture
  5. Failure: DMA Gated During an APB Access
On this page

    Part 5 of 14, lesson 9 of 24Part 5 of 14/Clock and Reset Architecture/Lesson 9 of 24All levels

    Failure: DMA Gated During an APB Access

    The section's named failure: the DMA clock stops mid-access, the bus hangs, and the rule that prevents it.

    Why it matters

    A power engineer clears CLK_EN bit 0 to save the DMA's idle power while the CPU keeps polling DMA STATUS. The next APB read never completes, the bridge waits forever, and the CPU hangs in what looks like a fabric deadlock. Nothing is broken except the order: the clock stopped while the bus still needed the block. This is the failure the task names for this topic, told here as symptom, capture and fix. Its one job is this story; the general ownership rules belong to the previous lesson.

    The core idea

    The DMA answers APB accesses with one wait state: three clk_sys clocks per access, with pready low in the first access cycle and high in the second. That pready is generated by the DMA core on its gated clock. When software clears the enable, the bus side still accepts the address phase, because the fabric runs on, but the core never produces the completing cycle. The bridge holds the AXI response, the CPU holds the load, and every later master queues behind it. The CPU is itself blocked on the load, so it cannot re-enable the clock: only a reset recovers a chip whose bridge has no timeout.

    The fix has three parts. Software clears the enable only when the DMA is idle, STATUS BUSY read as 0, with no APB access in flight and the DONE interrupt already cleared; it sets the enable again before touching any DMA register. Hardware refuses to close a gate while the block's STATUS.BUSY is 1 (the DMA is executing a job), so a software mistake cannot stop a working job; it does not help when an idle, gated block is later read, which is why the third part matters. And the integrator's safety net: nano_axi2apb gets a 256-cycle access timeout that completes the access with PSLVERR (SLVERR on the AXI side). 256 clk_sys cycles is 256 x 10.417 ns = 2.667 us, against 31.25 ns for the normal three-clock access, so the timeout never fires on a healthy access and a stopped block costs the CPU 2.667 us and an error instead of a hang. The test clears CLK_EN mid-poll and demands completion or that clean error, never a hang.

    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
    # Model of the failure: a 3-clock APB access against a clock gated mid-access.
    # The core side must produce 3 gated edges; the bridge waits at most TIMEOUT.
    TIMEOUT = 256  # clk_sys cycles, the bridge watchdog
    
    def apb_access(ticks, timeout=None):
        # ticks: per-cycle state of the DMA core clock, True = ticking
        need, done = 3, 0
        for cycle, ticking in enumerate(ticks, start=1):
            if timeout is not None and cycle > timeout:
                return "PSLVERR"
            if ticking and done < need:
                done += 1
            if done == need:
                return "COMPLETES"
        return "HANGS"
    
    stuck = [True, True] + [False] * 400  # clock stops after two edges, never returns
    assert apb_access([True] * 6) == "COMPLETES"
    assert apb_access(stuck) == "HANGS"                    # no timeout: the failure
    assert apb_access(stuck, TIMEOUT) == "PSLVERR"         # with the watchdog: clean error
    assert apb_access([True] * 6, TIMEOUT) == "COMPLETES"  # healthy access never trips it
    assert abs(TIMEOUT * 1e3 / 96 - 2666.7) < 0.1          # 256 x 10.417 ns
    # Hardware refuses to close a gate while the block is BUSY.
    def may_gate(busy, in_flight):
        return (not busy) and (not in_flight)
    assert may_gate(False, False) and not may_gate(True, False) and not may_gate(False, True)
    print("PASS: mid-access gate hangs; timeout gives PSLVERR at 256 cycles; busy block is not gated")

    What the review looks for

    • The driver documents the idle-and-quiet precondition next to every write that clears a CLK_EN bit.

    • The verification plan contains the gate-mid-poll test by name, with hang forbidden and the 256-cycle bridge timeout (PSLVERR) as the expected outcome.

    • No power sequence gates a block clock while its bus segment is selected; the check is structural, not advisory.

    Verify and debug

    Reproduce with a single APB read issued one cycle before the enable clears: the response must arrive, or come back as PSLVERR after the 256-cycle timeout, and never hang. Remove the timeout in the model and the same test must fail. On silicon the same hang points here when the faulting address belongs to a gated block and the hang correlates with a power transition; read back CLK_EN and STATUS before suspecting the fabric. If the symptom persists with clocks on, the bridge's own wait-state handling is next, not this lesson.

    This failure generalises: any block whose response path needs its gated clock can hang its bus when gated mid-transfer. A bridge must not wait forever on PREADY: give it a timeout. Gate idle blocks only, and prove idleness from the block's own status, not from a timer.

    If asked how you gate a DMA clock safely, answer with the three reads: BUSY clear, no access in flight, interrupt cleared. Then add the hardware backstops: the clock enable refuses to close on a BUSY block, and the bridge completes a stuck access with PSLVERR after 256 cycles. Then describe the test that gates mid-poll.

    Check yourself Software wants to gate the SBR clock while a DMA job streams through it. Allowed?

    No. The SBR is the DMA's data source and sink; gating it mid-job stalls the streams and wedges the job. Gate only when both STATUS registers read idle, in either order, then re-enable before programming the next job.

    Related topics

    • Hierarchical Gating and Enable Ownership

    • The Ten Crossings

    • Protocol First Principles: Crossing at the Interface

    Previous

    99 / 289

    Next: Clock Domain Planning

    Up next

    Up nextClock Domain Planning

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • ICG Cells and Enable Timing