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. What Lives in the Fuse Array
On this page

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

    What Lives in the Fuse Array

    Trim, boot configuration, repair, keys and lifecycle: allocating the one-time array on NanoSoC.

    Why it matters

    This lesson has one job: decide which bits the chip can never change its mind about. Every field fused is a field no firmware bug can corrupt and no attacker can rewrite, but also a field no erratum can fix. The allocation below spends 256 illustrative fuse bits across six owners and leaves spares, because the only thing worse than a wasted fuse is a missing one discovered after tapeout.

    The core idea

    Six classes share the array. Analog trim carries the oscillator and regulator settings the PHY and PLL need before anything runs. Boot configuration selects options the ROM reads in its first steps, such as whether secure boot enforces or merely reports. Repair holds the row and column addresses for both SRAM banks, written by the tester after MBIST. Secrets hold the device key material the secure-boot topic authenticates against. Version holds the minimum image version, a thermometer-coded counter that only ever advances, which the secure-boot topic compares against. Lifecycle holds the device state, covered in the third lesson. All field sizes are NanoSoC teaching values: the classes and the ordering rules are the portable part, the bit counts illustrate one plausible packing.

    Field

    Bits

    Written by

    Read by

    Rule

    Oscillator and regulator trim

    64

    Tester at sort

    Analog via shadow registers

    Loaded before PLL lock; safe defaults until then

    Boot configuration

    16

    Tester or OEM

    ROM in its first steps

    Read-only after sampling; no silent default change

    SRAM repair, both banks

    64

    Tester after MBIST

    Wrapper repair pins at reset

    ECC of the repair field itself where provided

    Device secrets (64 bits is illustrative, not a recommended key size)

    64

    Secure facility

    Secure-boot engine only

    Never mapped to any bus; no software read path

    Minimum image version, thermometer-coded

    16

    OEM at provisioning, then authorised updates

    ROM during image authentication

    Bits only go from 0 to 1, so the minimum can rise and never fall

    Lifecycle state

    16

    Each life stage

    Security controller

    Monotonic: states advance, never retreat

    Spare

    16

    Reserved

    None yet

    Spent only by engineering order with a map revision

    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
    fields = [("trim", 64), ("bootcfg", 16), ("repair", 64), ("secrets", 64), ("minver", 16), ("lifecycle", 16), ("spare", 16)]
    total = sum(bits for _, bits in fields)
    assert total == 256, total
    ranges = {}
    offset = 0
    for name, bits in fields:
        ranges[name] = (offset, offset + bits - 1)
        print(f"{name}: bits [{offset}:{offset + bits - 1}]")
        offset += bits
    assert offset == 256
    used = total - dict(fields)["spare"]
    assert used == 240
    spans = sorted(ranges.values())
    for (lo1, hi1), (lo2, hi2) in zip(spans, spans[1:]):
        assert hi1 < lo2, "fields overlap"
    assert "minver" in ranges, "anti-rollback needs a fuse field"
    def min_version(field):
        return bin(field).count("1")
    def accept(manifest_version, field):
        return manifest_version >= min_version(field)
    field = 0b0000_0000_0111_1111
    assert min_version(field) == 7
    assert accept(7, field) and accept(8, field) and not accept(6, field)
    assert min_version(field | 1 << 7) == 8 and min_version(field & ~1) == 6, "a cleared bit would lower the minimum, which fuses cannot do"
    print("PASS: 256-bit array, 240 used, 16 spare, no overlaps, version field present")

    What the review looks for

    • Every fuse bit has exactly one owner, one writer and one reader; the table above is the review exhibit.

    • Secrets have no bus read path by construction, confirmed by a connectivity check, not by policy text.

    • Spare bits are reserved in the map with a spend procedure, not silently absorbed by neighbouring fields.

    Verify and debug

    Pack and unpack the allocation in the build: the script above is the seed of that check, extended with field-level read-back after the reset sequence. Blow one spare bit in a scratch model and confirm nothing changes; blow one trim bit and confirm only the trimmed block moves. A field that affects two blocks is misallocated.

    Register specification out of sync with the hardware: fuse shadow registers documented with yesterday's field map while the array moved on. Symptom: trim loads into the wrong block. Caught by generating shadow-register headers from the same fuse map the hardware uses. Fix: one machine-readable fuse map for RTL, headers and tester patterns.

    If asked what you would fuse versus store in flash, answer with the threat: fused bits survive firmware replacement and cannot be rewritten by compromised code. Trim, repair, keys and lifecycle qualify; values that must be able to change after provisioning, such as a mutable configuration, do not. Monotonic counters, such as the minimum image version, do.

    Check yourself Why do repair fuses belong in the same array as device secrets?

    They share the tester-time programming flow and the at-reset read-out engine, not a security level. Sharing the array saves a second macro; the security comes from access control on the shadow registers, which keeps secrets off any bus while repair values route to the wrappers.

    Related topics

    • Next: Read-Out Timing and Distribution

    • Secure Boot and Root of Trust

    Previous

    163 / 289

    Next: Read-Out Timing and Distribution

    Up next

    Up nextRead-Out Timing and Distribution

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Repair, Lifecycle and Locking