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
    • Memory Subsystem Integration
    • ECC and Error Handling
    • External Memory Controller Integration
    • Boot ROM and Boot Modes
    • eFuse and OTP
      • What Lives in the Fuse Array
      • Read-Out Timing and Distribution
      • Repair, Lifecycle and Locking
    • Secure Boot and Root of Trust
    • Security Architecture
  • 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

←eFuse and OTP
  1. Topics
  2. SoC Design
  3. Memories, Boot and Security
  4. eFuse and OTP
  5. Read-Out Timing and Distribution
On this page

    Part 8 of 14, lesson 14 of 21Part 8 of 14/Memories, Boot and Security/Lesson 14 of 21All levels

    Read-Out Timing and Distribution

    One sequenced read at reset: timing, shadow registers, and proving every consumer was served.

    Why it matters

    This lesson has one job: get every fuse value to its consumer before that consumer's first use. The array read is slow and sequenced, the PLL needs trim before lock, the wrappers need repair before the first test or access, and the ROM reads boot configuration in its opening steps. A consumer released before its fuse value arrives starts life on a safe default at best and on garbage at worst.

    The core idea

    Read-out runs inside the reset sequence, in one window: it starts when the oscillator is ready (cycle 1024 of clk_per) and runs during the PLL start-up and lock window (260 clk_per, 10.833 microseconds, which starts at cycle 1026). The fuse controller walks the array, shifts each field into its shadow register near the consumer, and raises a done flag that gates the downstream releases. Shadow registers are ordinary flops, so timing analysis treats them like any other path, and the array itself powers down after the read to save leakage. The shadow registers live in PD_AON, the always-on domain: SLEEP removes power from PD_SW, but the shadows keep their values and drive the repair pins of the SRAM wrappers across the domain boundary (always-on to switchable wires need no isolation clamp; the clamps cover the other direction). That is why the 14.073 microsecond wake sequence has no fuse re-read in it. If the shadows were in PD_SW, wake would have to re-read the array and the 14.073 microseconds would grow by the read time. The ordering constraint is absolute: trim before lock, repair before the SRAM wrappers leave reset, boot configuration and secrets before the CPU's first fetch, and the version field before the first authentication. With an illustrative 256-bit array read at 8 bits per peripheral clock, the whole read costs 32 clocks or about 1.333 microseconds and ends at cycle 1056, long before the PLL locks at cycle 1286, so it never extends the boot.

    The script uses the boot ledger's reset times in units of clk_per cycles: the oscillator is ready at cycle 1024, the PLL window ends with lock at cycle 1286, the system reset is released at about cycle 1292.5 (step 6) and the CPU reset at about cycle 1294.75 (step 7). It reads the array at three assumed widths and checks every consumer. The slowest case must fail.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    array_bits = 256
    osc_ready = 1024
    pll_lock = 1024 + 2 + 260
    rst_sys = pll_lock + 2 + 4.5
    rst_cpu = rst_sys + 2.25
    consumers = {"trim (before PLL lock)": pll_lock, "repair (before SRAM wrappers leave reset)": rst_sys, "boot config and secrets (before CPU fetch)": rst_cpu}
    def check(clocks_per_bit_group, bits_per_group):
        cycles = array_bits // bits_per_group * clocks_per_bit_group
        done = osc_ready + cycles
        late = [name for name, need in consumers.items() if done > need]
        return cycles, done, late
    cycles, done, late = check(1, 8)
    assert cycles == 32 and done == 1056 and not late, (cycles, done, late)
    assert abs(cycles / 24e6 * 1e6 - 1.333) < 0.002
    print(f"8 bits per clock: {cycles} cycles, done at cycle {done}, ends before lock at {pll_lock}")
    cycles, done, late = check(1, 1)
    assert cycles == 256 and not late
    print(f"1 bit per clock: {cycles} cycles, done at cycle {done}: still early enough")
    cycles, done, late = check(2, 1)
    assert cycles == 512 and late and "trim (before PLL lock)" in late, late
    print(f"1 bit per 2 clocks: {cycles} cycles, done at cycle {done}: LATE for {late}")
    print("PASS: the 32-cycle read beats every consumer; the 512-cycle read is caught missing the PLL lock")

    What the review looks for

    • The reset sequence diagram shows the fuse read with its start (oscillator ready), its end inside the PLL window, its done flag and every release the flag gates.

    • Each shadow register names its fuse field and its consumer; unconnected shadows are a review finding.

    • Safe defaults are documented per consumer for the window before read-out completes.

    Verify and debug

    Simulate reset with the fuse model delaying done past each consumer's release in turn and confirm the release waits: a consumer that starts early has its gate wired to the wrong flag. Then corrupt one shadow register after read-out and confirm only its consumer misbehaves, proving distribution fans out without cross-talk.

    Trim and fuse data loaded late: the PLL locks on untrimmed settings or the first memory access precedes repair. Symptom: wrong frequency at start or a failing first access that passes on retry. Caught by a boot-sequence simulation that models the fuse read. Fix: gate each release on the read-out done flag with safe defaults until then.

    If asked when fuses are read, answer with the sequence position: from oscillator ready, inside the PLL start-up and lock window, finished before lock and gated by a done flag. Then explain why the array powers down after (leakage, not secrecy) and why the shadows sit in the always-on domain (wake needs no re-read).

    Check yourself The fuse read takes 32 peripheral clocks. Why does it cost boot nothing?

    Because it runs inside the 260-clock PLL start-up and lock window that the reset sequence already pays: it starts at cycle 1024, ends at cycle 1056 and the PLL does not lock until cycle 1286. Work inside an existing wait is free; only work on the critical path costs.

    Related topics

    • What Lives in the Fuse Array

    • Next: Repair, Lifecycle and Locking

    Previous

    164 / 289

    Next: Repair, Lifecycle and Locking

    Up next

    Up nextRepair, Lifecycle and Locking

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error