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
    • Interrupt Controller Integration
    • Interrupt Routing and Latency
      • From DMA irq to CPU Entry
      • Latency Budgets and Deadlines
      • Spurious and Lost Interrupts
    • DMA Integration
    • Peripheral Subsystem
    • Pad Muxing and GPIO
  • 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

←Interrupt Routing and Latency
  1. Topics
  2. SoC Design
  3. Interrupts, DMA and Peripherals
  4. Interrupt Routing and Latency
  5. Latency Budgets and Deadlines
On this page

    Part 7 of 14, lesson 5 of 15Part 7 of 14/Interrupts, DMA and Peripherals/Lesson 5 of 15All levels

    Latency Budgets and Deadlines

    The interrupt latency equation with NanoSoC numbers, checked against the UART overrun deadline.

    Why it matters

    This lesson has one job: turn the path of the previous lesson into a budget the integrator can sign against a deadline. A latency number without a deadline is trivia; a deadline without a latency budget is hope. NanoSoC has a genuine deadline to check: the UART holding register is one byte deep, so a received byte must be collected before the next one finishes arriving, or it is lost. The lesson prices the worst case end to end and asks whether the UART survives it.

    The core idea

    Total latency has four terms: synchroniser delay into the controller, controller decision time, CPU entry time, and the software prologue before the handler touches the peripheral. The first three are the routing topic's 182.3 ns worst case, which is the bound for a clk_sys source and a safe upper bound for the clk_per sources too. CPU entry is a handful of cycles to flush and fetch the vector; the prologue is the handler's own saving of state before it reads the peripheral. On top of the sum sits two kinds of waiting: the longest non-interruptible section the CPU may be inside when the irq arrives, and any higher-priority handler already running, because fixed priority means the UART handler waits behind power and DMA service. The budget is only closed when the worst pile-up still beats the deadline.

    Worked example: does the UART survive

    The UART runs at 115,384.6 baud with 10 bits per byte, so a byte arrives every 86.67 us and the one-byte holding register must be drained inside that window. The script below builds the full worst case: routing, CPU entry, prologue, the handler's own read of the UART DATA register (281.25 ns, a clk_per register read from the CPU), one higher-priority DMA handler ahead of it, and a short non-interruptible section, then checks the margin. All clock figures are NanoSoC teaching values; the entry, prologue and critical-section figures are labelled illustrative and kept consistent everywhere they appear.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    T_CPU = 1 / 192e6
    routing_worst = 182.3e-9       # worst case for a clk_sys source; used as a bound here
    cpu_entry = 10 * T_CPU         # illustrative: flush + vector fetch
    prologue = 40 * T_CPU          # illustrative: save state, read TOP
    data_read = 281.25e-9        # handler's own DATA read, clk_per register
    dma_handler = 200 * T_CPU      # illustrative: higher-priority DMA service
    crit_section = 50 * T_CPU      # illustrative: longest non-interruptible window
    total = (routing_worst + cpu_entry + prologue + data_read
             + dma_handler + crit_section)
    baud = 24e6 / (16 * 13)        # UART BAUDDIV reset value 13
    byte_time = 10 / baud          # 10 bits per byte on the wire
    ratio = byte_time / total
    print(f"worst-case UART latency: {total * 1e6:.3f} us")
    print(f"byte arrival period:     {byte_time * 1e6:.3f} us")
    print(f"deadline-to-cost ratio:  {ratio:.1f}x")
    assert total < byte_time
    assert 42 < ratio < 44
    print("PASS: worst-case latency 2.03 us against an 86.7 us deadline")

    What the review looks for

    • Every latency term names its source: NanoSoC reference numbers for routing and register reads, illustrative numbers labelled as such for software terms.

    • The worst case includes preemption by every higher-priority input, not just the lonely-interrupt case.

    • The tightest peripheral deadline in the design is named, and the margin is written down, not waved at.

    Verify and debug

    Stress the pile-up in simulation: assert the UART receive line while the DMA handler runs long, and confirm the byte is collected in time. If the margin ever inverts, the fixes in order of cheapness are: shorten the higher-priority handlers, raise the threatened input's priority in the next revision, deepen the peripheral holding, or quicken the peripheral clock. Never fix a missed deadline by trimming the synchroniser: those two flops are load-bearing.

    QoS starvation by another name: a bulk source with fixed higher priority starves a latency-critical one, and the symptom only appears with all masters active. The display-underrun version is famous; the UART-overrun version here is the same mechanism at interrupt level. Caught by performance simulation with real traffic, fixed by priority assignment and reserved budget, not by faster handlers alone.

    If asked to bound an interrupt latency, write the four terms plus preemption, price each in the destination clock, and finish with the deadline comparison. Examiners promote answers that name the non-interruptible section unprompted.

    Check yourself The GPIO input has the lowest priority. What is its worst-case wait, and why is there no deadline for it?

    It waits behind every higher-priority handler that is pending plus the routing, entry and prologue terms, unbounded if a chatty high-priority source never stops. There is no wire-speed deadline because GPIO levels persist until the pin condition changes; software polls or debounces at its own pace.

    Related topics

    • From DMA irq to CPU Entry

    • Next: Spurious and Lost Interrupts

    • Protocol First Principles: Little's Law

    Previous

    140 / 289

    Next: Spurious and Lost Interrupts

    Up next

    Up nextSpurious and Lost Interrupts

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error