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
    • The Integrator Role and Handoffs
      • What the Integrator Owns
      • Anatomy of a Handoff
      • NanoSoC Cast and First Triage
    • Spec to Tapeout Flow
    • Contracts and Ownership
    • Reading the SoC Spec
  • 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
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←The Integrator Role and Handoffs
  1. Topics
  2. SoC Design
  3. What SoC Integration Is
  4. The Integrator Role and Handoffs
  5. NanoSoC Cast and First Triage
On this page

    Part 1 of 14, lesson 3 of 12Part 1 of 14/What SoC Integration Is/Lesson 3 of 12All levels

    NanoSoC Cast and First Triage

    Who owns each NanoSoC block and table, and a worked triage of the mis-wired interrupt.

    Why it matters

    Abstract duties fix nothing until they have names. The DMA interrupt fires at its own block, the controller never sees it, both blocks pass their own tests, and the fix turns out to be one wire plus one new test. Walking that triage once, against the named owners below, gives a pattern for every misconnection in the course.

    The core idea

    The cast is small enough to hold in one table. The CPU, its cache and the async AXI bridge belong to the CPU owner. The interconnect, the APB bridge and slot decoder, and the APB clock-domain bridge belong to the integrator directly: the fabric is integration, not a block. The DMA and the stream bridge belong to their block owners, with the integrator owning the stream contract between them. The slow peripherals, UART, SPI and GPIO, belong to one peripheral owner. The interrupt controller belongs to the integrator, because its inputs are everyone else's outputs. The reset, clock and power controller belongs to the integrator for the same reason. The SRAM and ROM wrappers belong to the memory owner, with retention and repair shared with power and test. Software owns the drivers, the linker script, the boot image and the headers, all generated from integrator-owned tables.

    Owner

    Owns on NanoSoC

    Signs

    CPU owner

    nano_cpu, I-cache, nano_axi_cdc_m CPU side

    Core timing, cache behaviour

    Integrator

    nano_xbar, bridges, decoders, nano_intc, nano_rstpwr, maps, sequences

    Top wiring, tables, release order

    DMA owner

    nano_dma internals and bench

    Stream and register behaviour per map

    SBR owner

    nano_sbr read and write engines

    Memory-to-stream contract, error reporting

    Peripheral owner

    UART, SPI, GPIO

    Register behaviour, interrupt sources

    Memory owner

    SRAM and ROM wrappers, macros

    Latency, BIST and repair hooks, retention

    Software

    Drivers, linker script, boot image, headers

    Builds against the frozen tables

    Verification

    Chip-level proof

    Connectivity, boot, interrupt, DMA end-to-end

    PD

    Geometry, clock tree, power grid

    Closure against integrator-owned constraints

    Worked triage: the interrupt that never arrived

    The symptom: DMA STATUS reads DONE equals 1, the irq pin at the DMA is high, controller RAW bit 1 is 0, and RAW bit 6 is 1. The block owner confirms irq is irq_en anded with done-or-err, held as a level. The controller owner confirms PENDING equals RAW anded with ENABLE and the output follows. Both true, chip broken. The integrator forces each source in turn and watches RAW: forcing irq_dma lights bit 6, not bit 1. Diagnosis in one step: the wire lands on input 6, a reserved spare, instead of input 1. Fix the wire, tie unused inputs 6 and 7 to zero, and add the standing test: force each of the six real sources and expect exactly its bit, then force the spares and expect nothing.

    The wiring-table checker

    The script below is that standing test in miniature: the NanoSoC interrupt table as data, a check that every real source maps to a distinct input with spares 6 and 7 tied off, and a demonstration that it catches the exact miswire from the story. One table generates the RTL tie-offs, the software header and this test, which is the single-source rule applied to interrupts.

    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
    TABLE = {  # source: (input, priority); NanoSoC specification values
        "irq_pwr": (0, 0), "irq_dma": (1, 1), "irq_sbr": (2, 2),
        "irq_uart": (3, 3), "irq_spi": (4, 4), "irq_gpio": (5, 5)}
    SPARES = (6, 7)
    
    def check(table, wired):
        problems = []
        inputs = [wired[src] for src in table]
        if sorted(inputs) != sorted(table[src][0] for src in table):
            problems.append("wiring differs from the table")
        if len(set(inputs)) != len(inputs):
            problems.append("two sources share one input")
        if any(s in inputs for s in SPARES):
            problems.append("a real source lands on a spare input")
        return problems
    
    wired_ok = {src: inp for src, (inp, _) in TABLE.items()}
    assert check(TABLE, wired_ok) == []
    
    wired_bug = dict(wired_ok, irq_dma=6)  # the story: DMA on spare 6
    hits = check(TABLE, wired_bug)
    assert hits == ["wiring differs from the table",
                    "a real source lands on a spare input"], hits
    prio = sorted(TABLE.items(), key=lambda kv: kv[1][1])
    assert [s for s, _ in prio][0] == "irq_pwr"  # power first, lower number wins
    print("PASS: irq table distinct, spares free; DMA-on-6 miswire caught")

    What the review looks for

    • Every top-level wire appears in exactly one generated table, and the table version stamps the RTL, the header and the test.

    • Spare inputs are tied to zero in the RTL and flagged if ever used.

    • Triage starts by forcing the source and observing the sink, never by opening a passing block.

    Verify and debug

    Run the per-source force test on every build: six forces, six single-bit expectations, plus the spare check. When a new peripheral arrives, it takes the next free input, the table version bumps, and all three consumers regenerate. If RAW flickers for one cycle instead of holding, suspect the crossing rather than the wire: interrupt inputs must be levels held at least two peripheral-clock cycles, and a pulse shorter than that is missed no matter how correct the wiring is.

    Lost interrupt across a clock domain: a one-cycle pulse from the fast domain never seen by the slow one, missed once in thousands of jobs and passing every simulation. Levels held long, toggle handshakes and sticky-until-cleared status bits are the fixes; the crossing inventory from the handoff lesson says which inputs need them.

    If given the DMA-interrupt symptom on a whiteboard, narrate the split: confirm the source level, confirm the sink equation, force the source and read RAW. Name the wire before touching any RTL.

    Check yourself RAW bit 6 is 1 although nothing is wired to input 6. What do you check first?

    Whether a real source is miswired onto 6, as in this lesson's story; then whether the spare is actually tied to zero and whether isolation clamps it during power transitions.

    Related topics

    • Anatomy of a Handoff

    • Next: Spec to Tapeout Flow

    • NanoSoC Tour

    Previous

    8 / 289

    Next: Spec to Tapeout Flow

    Up next

    Up nextSpec to Tapeout Flow

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • What the Integrator Owns