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
      • Running Boot Code Against RTL
      • Bench Checkpoints and the ROM Self-Test
      • Cost, Speed and What to Log
    • Performance Verification
    • Gate-Level and Power-Aware Simulation
    • Emulation and FPGA Prototyping
    • Bring-Up Readiness
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Firmware Co-Simulation
  1. Topics
  2. SoC Design
  3. Top-Level Verification and Bring-up
  4. Firmware Co-Simulation
  5. Bench Checkpoints and the ROM Self-Test
On this page

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

    Bench Checkpoints and the ROM Self-Test

    The banner, bench-side stage checkpoints and the DMA self-test: how a hung boot names its stage.

    Why it matters

    A boot that hangs with no output is a twelve-millisecond haystack. Checkpoints turn it into a numbered stage: the last event the bench saw is the last thing that worked, and the next stage in the table is the suspect. Its one job is the checkpoint plan: where each event is observed, what the self-test covers, and how to read a silent hang.

    The core idea

    The shipped ROM prints exactly one thing: the 16-character banner NanoSoC boot ok with its newline. Every other checkpoint is a bench-side monitor event, a timestamp on a bus or pin observation that costs the ROM nothing: the RST_CAUSE read (the first access to the clk_per segment, which decides whether the cold-boot stack clear runs at all), the first UART DATA write, the first DMA register access, SPI chip-select falling, and the first fetch at 0x2000_0000. The banner is the one stage that is also visible on a pin, 1,386.667 us at 115,384.6 baud, 11.0 percent of the whole boot and the second largest share. The self-test and loader events that follow are bus and pin observations too. Then the DMA self-test of boot step 13: five reads proving reset values are zero, seven writes loading KEY, LEN of 64, CTRL 0x3 and the SBR addresses, the 72-cycle job, the interrupt latency at 135.4 ns, and the read-back of all 64 words against the checksum. Then the SPI load of 8,192 bytes plus the 4-byte command (8,196 bytes at 6 Mb/s), the checksum over 2,048 words, and the jump.

    The self-test earns its place by touching every driver contract the later software depends on: the CTRL mirror that demands 0x3 not 0x1, the W1C clear of both DONE and ERR, the two LEN registers written from one variable, and the NS bit cleared in the same CTRL write so the SBR may write the secure-only SRAM1. A self-test that passes with the wrong KEY or a mismatched LEN is worse than none, because it certifies the driver order it should be checking; the checksum comparison is what makes it a test rather than a printout.

    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
    # Boot-stage audit from NanoSoC teaching values: recompute the 12.581 ms total
    # and each stage share, so a slow boot names its stage.
    T_PER_NS, T_SYS_NS, T_CPU_NS = 1e9 / 24e6, 1e9 / 96e6, 1e9 / 192e6
    stages = {
        "oscillator 1024 clk_per": 1024 * T_PER_NS,
        "pll lock 260 clk_per": 260 * T_PER_NS,
        "releases + first fetch": (2 + 2) * T_PER_NS + (18 + 8) * T_SYS_NS
                                   + (2 + 24) * T_CPU_NS,
        "stack clear 1024 writes": 1024 * T_SYS_NS,
        "rst_cause read": 281.25,
        "uart init 3x281.25ns": 3 * 281.25,
        "banner 160 bits/115384.6": 160 / 115384.6 * 1e9,
        "dma self-test": 625 + 875 + 72 * T_SYS_NS + 135.4 + 6000,
        "spi load (8192+4) B at 6Mb/s": (8192 + 4) * 8 / 6e6 * 1e9,
        "checksum 2048 reads": 2048 * 18 * T_CPU_NS,
    }
    total_us = sum(stages.values()) / 1000
    for name, ns in stages.items():
        print(f"{name}: {ns / 1000:.3f} us ({ns / sum(stages.values()) * 100:.1f}%)")
    assert abs(total_us - 12580.917) < 1.0, total_us
    assert stages["spi load (8192+4) B at 6Mb/s"] / sum(stages.values()) > 0.86
    # the check can fail: checkpoints printed by the ROM would add 64 characters of 86.67 us each
    extra_us = 64 * 10 / 115384.6 * 1e6
    assert abs(extra_us - 5546.7) < 0.1 and abs(total_us + extra_us - 12580.917) > 5000
    print("PASS: boot totals 12.581 ms, SPI load dominates at 86.9%; ROM prints would add 5.55 ms")

    What the review looks for

    • Every boot stage has a bench monitor event with an expected time, so the last event seen always names the failing stage; the ROM is not asked to print anything beyond the banner.

    • The self-test compares data, not just status bits: the 64-word read-back against the XOR checksum.

    • The banner text and length are asserted byte for byte — 16 characters including the newline — as the first UART proof.

    Verify and debug

    Read the monitor log backwards from the hang: the missing event is the diagnosis. No UART DATA write means reset, clocks or the early ROM stages; a write but no banner on the pin means UART init or clocks; banner without self-test done means the DMA contract — check LEN agreement and the NS bit first; self-test done without prompt means the loader or the checksum. A self-test that fails only with certain keys reruns with the all-ones and walking-one keys before anyone suspects the fabric.

    DMA error swallowed: an error response the driver never checks, so the test reports success over corrupt data. The self-test answers it with the checksum and with STATUS.ERR asserted as a failure, never ignored — error injection during the self-test proves the check is awake.

    Checkpoints written into the ROM in simulation only: a model of the boot that prints a character per stage runs 64 characters (5.55 ms, 44 percent) longer than the ROM that is built, so every timeline compared against it is wrong, and the lab finds the silicon prints nothing. Keep stage checkpoints on the bench. Whether the real ROM should drive a GPIO code per step is a readiness decision, priced in the debug-access lesson of the bring-up topic.

    If asked where boot time goes, answer SPI load 86.9 percent and banner 11.0 percent, then say what follows: speed up boot by shrinking the image and the banner, never by skipping the self-test. If asked how the ROM reports its stage, answer that it prints only the banner and the bench watches the buses and pins.

    Check yourself The log shows the banner but no self-test completion, and the DMA STATUS reads ERR. Which LEN is suspect and why?

    The SBR LEN is shorter than the DMA LEN (planted bug 8, case A): the SBR's last beat arrives before the DMA's LEN-th word, so the DMA ends the job early and sets ERR, with COUNT equal to the SBR LEN. If instead the DMA LEN were the shorter one, the DMA would report DONE and the SBR would stay BUSY with no ERR. The driver rule is one n_words variable written to both, and COUNT compared with the SBR LEN after DONE.

    Related topics

    • Running Boot Code Against RTL

    • Next: Cost, Speed and What to Log

    • Memories and Boot: The NanoSoC Boot Flow in Time

    • Bring-up: Boot ROM Execution and Firmware Stage Handoff

    Previous

    200 / 289

    Next: Cost, Speed and What to Log

    Up next

    Up nextCost, Speed and What to Log

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error