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
    • I/O Ring and Pad Types
    • Pad Count and Simultaneous Switching
    • Package and Ballout
    • Power Delivery Through Package and Bumps
    • ESD and Latch-Up at the Top
    • Test and Debug Pins (extension)
      • Dedicated Versus Shared Pins
      • Strap, Boot-Mode and Test Pins
      • JTAG and Safe Defaults at Reset
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Test and Debug Pins (extension)
  1. Topics
  2. SoC Design
  3. Package, Pads and I/O
  4. Test and Debug Pins (extension)
  5. Strap, Boot-Mode and Test Pins
On this page

    Part 11 of 14, lesson 17 of 18Part 11 of 14/Package, Pads and I/O/Lesson 17 of 18All levels

    Strap, Boot-Mode and Test Pins

    Sampling board-level intent safely: pulls, sample timing, and a strap sampler that really captures.

    Extension topic. NanoSoC v1 has no JTAG pins, no TEST_MODE pin and no BOOT_MODE pins: it boots from the SPI flash and has no debug port. Everything in this topic describes an optional test and boot port that could be added, so that its cost in pads, balls, risk and reset behaviour can be priced. The seven pins below are a teaching extension, not part of the NanoSoC the rest of the course describes.

    Why it matters

    How does a pin become a configuration bit without firmware? BOOT_MODE would tell the ROM where the image lives, TEST_MODE would tell the chip whether to enter scan, and both must be decided while the reset controller still holds everything else, from pins that may float, bounce or arrive late. Get the sampling wrong and the chip boots from the wrong device or wakes in test mode on a customer's board. A sampler that looks safe because its default is safe can also be a sampler that never captures anything, and the script below shows how.

    The core idea

    Three rules make straps safe. First, defined pulls: BOOT_MODE[1:0] and TEST_MODE carry pull-downs (the same pulls the GPIO pads have at reset), so an open pin selects the default and mission mode, never test mode and never an exotic boot. Second, sample timing: the straps are sampled once, inside the oscillator-ready wait of the cold-boot sequence, which is 1024 cycles (42.667 µs) after the power-on reset releases. By then the supplies are valid, the pull has settled and the synchroniser has been running for a thousand cycles; sampling earlier reads a rising rail, and sampling later risks reading a pin that firmware or the board has already driven. Third, synchronise the sample: the strap crosses from the pad into the 24 MHz always-on clock through two flops, because a strap that changes at the sample edge is exactly the metastability the synchroniser lessons teach against.

    The sampler's own reset matters as much as its timing. If the flops were held in reset until the peripheral reset releases, which comes after the oscillator-ready point, a sample pulse during the oscillator-ready wait would be ignored and the module would return its reset value whatever the board does. So the sampler resets with the power-on reset only, free-runs its synchroniser, captures at the pulse and then holds the value until the next power-on reset. A pad reset therefore does not resample the straps. The table below is the extension's contract with the board.

    BOOT_MODE[1:0]

    Meaning

    Board

    Notes

    00

    SPI image source

    Open (pull-downs)

    Default; this is NanoSoC's boot flow.

    01

    Reserved

    n/a

    No other image source exists; the ROM treats every reserved value as 00.

    10

    Reserved

    n/a

    As above.

    11

    Reserved

    n/a

    As above.

    The strap sampler

    The module below is the teaching sampler: two-flop synchroniser into the always-on clock, a sample enable pulsed once at the oscillator-ready point, and a done flag so that a second pulse is ignored. It resets with the power-on reset only.

    nano_strap_sample.sv
    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
    // Extension, not NanoSoC v1: strap sampler with a two-flop synchroniser.
    // Samples once when sample_en pulses (oscillator-ready point); holds until por_n.
    module nano_strap_sample (
      input  logic clk_per,   // always-on 24 MHz clock
      input  logic por_n,     // power-on reset only: a pad reset must not resample
      input  logic strap_in,  // from the pad receiver
      input  logic sample_en, // one-cycle pulse at the oscillator-ready point
      output logic strap_q    // sampled strap value
    );
      logic sync_a, sync_b, done;
    
      always_ff @(posedge clk_per or negedge por_n) begin
        if (!por_n) begin
          sync_a  <= 1'b0;
          sync_b  <= 1'b0;
          strap_q <= 1'b0; // safe default (the pull-down value)
          done    <= 1'b0;
        end else begin
          sync_a <= strap_in;
          sync_b <= sync_a;
          if (sample_en && !done) begin
            strap_q <= sync_b;
            done    <= 1'b1;
          end
        end
      end
    endmodule

    The sampler model and strap checker

    The script below models the same logic cycle by cycle in two versions. In the first the flops reset with the power-on reset only, as above. In the second they are held in reset until after the sample pulse, the mistake described earlier. The board drives the strap high from cycle 100. The first version must capture a 1; the second returns 0 whatever the board does, which the script requires, so a sampler that looks safe but cannot capture is caught. Then a strap table is checked by one function: every strap needs a pull, the default must select SPI, and no boot mode may select test; bad tables with a test-mode default and a missing pull must be rejected.

    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
    def run(strap, rst_release, sample_cycle, cycles=1100):
        a = b = q = 0
        done = False
        for t in range(cycles):
            if t < rst_release:                         # flops held in reset
                a = b = q = 0
                done = False
                continue
            sample = (t == sample_cycle)
            take = sample and not done
            q, b, a = (b if take else q), a, strap(t)   # nonblocking update order
            done = done or take
        return q
    
    board = lambda t: 1 if t >= 100 else 0              # a board that drives the strap high from cycle 100
    assert run(board, rst_release=0, sample_cycle=1024) == 1        # reset with por_n only: captures
    assert run(board, rst_release=1026, sample_cycle=1024) == 0     # reset held past the pulse: never captures
    assert run(lambda t: 0, rst_release=0, sample_cycle=1024) == 0  # an open pin (pull-down) reads 0
    late = lambda t: 1 if t >= 1030 else 0
    assert run(late, rst_release=0, sample_cycle=1024) == 0         # a strap driven after the window is ignored
    
    def check(modes, default, pulls):
        for pin, pull in pulls.items():
            assert pull in ("down", "up"), pin + " has no defined pull"
        assert modes[default] == "SPI", "the default does not select SPI"
        assert all("TEST" not in m for m in modes.values()), "a boot mode selects test"
        return True
    
    MODES = {"00": "SPI", "01": "SPI", "10": "SPI", "11": "SPI"}    # reserved values fall back to SPI
    PULLS = {"BOOT0": "down", "BOOT1": "down", "TEST_MODE": "down"}
    assert check(MODES, "00", PULLS)
    for bad in (({**MODES, "00": "TEST"}, "00", PULLS), (MODES, "00", {**PULLS, "TEST_MODE": "none"})):
        try:
            check(*bad)
            raise SystemExit("a bad strap table was accepted")
        except AssertionError:
            pass
    print("PASS: sampler captures a driven strap, an open pin reads 0, a late strap is ignored; the held-in-reset sampler never captures; bad strap tables rejected")

    What the review looks for

    • The strap table with pulls, default and reserved handling, signed with the board team.

    • The sample point named on the cold-boot sequence, inside the oscillator-ready wait.

    • The sampler's reset source named (power-on reset only) and the synchroniser shown between pad and consumer.

    • A simulation in which a strap driven high is actually captured, not only one where the default is read.

    Verify and debug

    Verify sampling with a slow-ramp simulation: sweep the supply rise and the strap drive across corners and confirm the sampled value equals the pulled value whenever the board leaves the pin open, and equals the driven value whenever it drives. On the bench, a strap suspect is confirmed by forcing the pin both ways and watching the boot source change; a pin that changes nothing is unsampled or overridden downstream.

    Boot strap pins that float or are sampled before they are valid, so the chip boots from the wrong device, or a test pin left floating so that a chip sits in scan or shifts at random. The repairs are the three rules above: defined pulls, a sample inside the oscillator-ready wait, and a synchroniser. A related trap is the sampler that never captures at all, which the model above catches.

    If asked when straps are sampled, answer with the two boundaries: after the rails are valid and the pull has settled, before firmware or the board can drive the pin. Then add the synchroniser and the sampler's reset source without prompting; that is the detail that shows you have debugged one.

    Check yourself Firmware drives a shared GPIO high just after reset release. Why must strap sampling already be over?

    Because the sampling window closes at reset release: a later driver fights the pull and rewrites what the sampler would see. The strap is valid only inside its window; after it, the pin belongs to its mission function.

    Related topics

    • Dedicated Versus Shared Pins

    • Next: JTAG and Safe Defaults at Reset

    Previous

    230 / 289

    Next: JTAG and Safe Defaults at Reset

    Up next

    Up nextJTAG and Safe Defaults at Reset

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error