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
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC19
    • Capstone Brief
      • Requirements, Deliverables and Data
      • Planted Bug Symptoms and Grading
    • Stage 1: Memory Map and Interconnect
    • Stage 2: Clocks, Resets, Power
    • Stage 3: Interrupts and Boot
    • Stage 4: Verification and Signoff
    • Solutions
Loading lesson

←Capstone Brief
  1. Topics
  2. SoC Design
  3. Capstone: Integrate NanoSoC
  4. Capstone Brief
  5. Planted Bug Symptoms and Grading
On this page

    Part 14 of 14, lesson 2 of 19Part 14 of 14/Capstone: Integrate NanoSoC/Lesson 2 of 19All levels

    Planted Bug Symptoms and Grading

    Ten observed integration symptoms and an evidence rubric; causes and worked injections follow the checks in Solutions.

    Why it matters

    A lab without known symptoms teaches touring, not integrating. Ten real integration failures are injected into the clean lab data, one at a time. You receive only the observable symptom here; infer the failing boundary from the evidence and write your own hypothesis before opening the separate Solutions lesson. Your grade is the fraction you catch with checkers, not with eyes.

    Goal, inputs and steps

    • Goal: classify the ten symptoms, identify the evidence you would collect, and use the rubric weights.

    • Inputs: the symptom table below; the clean behaviour of the DMA, SBR, clocks, resets, power and interrupt map from earlier stages.

    • Steps: for each symptom write a hypothesis and the checker or trace that would distinguish it; read Solutions only after the checks.

    Bug

    Symptom

    Stage

    Symptom 1

    SBR CTRL write flips DMA data bit 0

    1

    Symptom 2

    CPU stalls at 0x0000_0000, no RVALID

    2

    Symptom 3

    DMA irq high, INTC RAW bit 1 is 0, bit 6 is 1

    3

    Symptom 4

    Only CTRL reads right; STATUS, LEN, KEY take PSLVERR and a COUNT read silently returns STATUS

    1

    Symptom 5

    Missed interrupt once in thousands of jobs

    2

    Symptom 6

    Spurious irq_cpu in SLEEP; sleep/wake loop

    2

    Symptom 7

    SBR STATUS.ERR on first beat from SRAM1

    3

    Symptom 8

    ERR with COUNT 32, or SBR stuck BUSY

    3

    Symptom 9

    Stale KEY; irq never drops; IRQ_EN cleared

    3

    Symptom 10

    After CLK_EN = 0 the first access to the idle DMA hangs the bus; only reset recovers

    2

    Two related observations are not numbered bugs. Placing the SBR source and destination in the same SRAM bank changes the stream rate (stage 1). And the SBR register slot is non-secure, so the secure-partition question remains open in NanoSoC v1 (stage 3 and the readiness review). Record both as evidence to investigate, not as answer keys.

    The checker

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    MAP = [
        ("BOOTROM", 0x00000000, 0x4000),
        ("SRAM0", 0x20000000, 0x10000),
        ("SRAM1", 0x20010000, 0x10000),
        ("DMA", 0x40000000, 0x1000),
        ("SBR", 0x40001000, 0x1000),
        ("UART", 0x40002000, 0x1000),
        ("SPI", 0x40003000, 0x1000),
        ("GPIO", 0x40004000, 0x1000),
        ("INTC", 0x40005000, 0x1000),
        ("RSTPWR", 0x40006000, 0x1000),
    ]
    SECURE_ONLY = {"SRAM1", "RSTPWR"}
    SLOTS = ["DMA", "SBR", "UART", "SPI", "GPIO", "INTC", "RSTPWR"]
    T_CPU, T_SYS, T_PER = 1e9 / 192e6, 1e9 / 96e6, 1e9 / 24e6
    def end_of(base, size):
        return base + size - 1
    def overlaps(entries=MAP):
        bad = []
        xs = sorted(entries, key=lambda e: e[1])
        for a, b in zip(xs, xs[1:]):
            if b[1] < a[1] + a[2]:
                bad.append((a[0], b[0]))
        return bad
    def misaligned(entries=MAP):
        return [n for n, b, s in entries if b % s != 0]
    def decode(addr, slots=SLOTS):
        if addr >> 14 == 0:
            return "BOOTROM"
        if addr >> 16 == 0x2000:
            return "SRAM0"
        if addr >> 16 == 0x2001:
            return "SRAM1"
        if addr >> 16 == 0x4000:
            slot = (addr >> 12) & 0xF
            return slots[slot] if slot < 7 else "H3"
        if addr < 0x20000000:
            return "H1"
        if addr < 0x40000000:
            return "H2"
        return "H4"
    def response(addr, secure, slots=SLOTS):
        t = decode(addr, slots)
        if t in ("H1", "H2", "H4"):
            return "DECERR"
        if t == "H3":
            return "SLVERR"
        if t in SECURE_ONLY and not secure:
            return "SLVERR"
        return "OK"
    def sustained(peak, beats):
        return peak * beats / (beats + 1)
    
    # ---- this lesson starts here ----
    
    bugs = {1: "stage1", 2: "stage2", 3: "stage3", 4: "stage1", 5: "stage2",
            6: "stage2", 7: "stage3", 8: "stage3", 9: "stage3", 10: "stage2"}
    def covered(b):
        return {s: sum(1 for v in b.values() if v == s) for s in ["stage1", "stage2", "stage3"]}
    EXPECT = {"stage1": 2, "stage2": 4, "stage3": 4}
    assert sorted(bugs) == list(range(1, 11)) and covered(bugs) == EXPECT
    assert covered({**bugs, 4: "stage2"}) != EXPECT   # a mis-filed bug is visible
    assert decode(0x40000000) == "DMA" and decode(0x40001000) == "SBR"
    print("PASS: 10 planted bugs filed: stage1 2, stage2 4, stage3 4; stage 4 proves all ten")

    Expected output

    One PASS line with the per-stage catch counts. Stage 4 files no bug of its own: it runs the matrix that proves stages 1 to 3 caught all ten. The checker validates the exercise data; it does not reveal the solution key.

    What each failure means

    A count failure means a bug was filed under the wrong stage; the table above is the oracle. A decode failure means the engine's map disagrees with your bug-1 notes: slots 0 and 1 are the DMA and SBR windows, and both must decode clean.

    Hint ladder

    Choose one symptom, write two possible causes and identify the observation that would distinguish them. Preserve the clean requirement independently of the data being diagnosed. Compare your reasoning with Solutions only after you have completed the stage checks.

    Grading rubric (illustrative NanoSoC teaching values): 40 percent for checkers that catch their bugs on both good and injected-bad data, 25 percent for evidence-backed diagnoses quoting the exact register, signal or cycle count, 20 percent for the final manifest check passing, 10 percent for the waiver-ageing review with every waiver evidenced, 5 percent for the readiness statement and its stated leftovers. A stage scores only when its checker prints PASS on the clean data and flags the injected fault.

    Fixing a symptom in software and calling the bug caught. A workaround may change the observation without proving the integration boundary is correct; the rubric pays for the checker and trace evidence.

    Pick any two bugs and contrast their evidence: bug 1 is deterministic on the first SBR write, bug 5 needs thousands of jobs. An interviewer who hears that distinction knows you have debugged both kinds.

    Check yourself Before choosing a cause for a symptom, what should your investigation record?

    The required behaviour, the observed behaviour, at least two possible explanations and an observation that would distinguish those explanations.

    Related topics

    • Back: Requirements, Deliverables and Data

    • Stage 1: Memory Map and Interconnect

    • Hardware Debug: The Cost of a Bug by Stage

    Previous

    267 / 294

    Next: Stage 1: Memory Map and Interconnect

    Up next

    Up nextStage 1: Memory Map and Interconnect

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error