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
      • Package Types at a Conceptual Level
      • Ball Assignment Rules
      • Pinout Review and Escape Routing
    • Power Delivery Through Package and Bumps
    • ESD and Latch-Up at the Top
    • Test and Debug Pins (extension)
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Package and Ballout
  1. Topics
  2. SoC Design
  3. Package, Pads and I/O
  4. Package and Ballout
  5. Ball Assignment Rules
On this page

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

    Ball Assignment Rules

    Assigning every NanoSoC pad to a ball: supplies first, signals by escape, quiet pins protected.

    Why it matters

    A ballout drawn by convenience, with signals in netlist order and supplies wherever they fit, gives the board an unroutable array and the supplies long detours. The NanoSoC ballout follows four rules in strict order, and this lesson applies them to all 31 pads of the 6 x 6 array: supplies first for short paths, fast signals where they escape cleanly, quiet pins guarded, and everything else in the space left over. Its job is the assignment; proving the board can route it is the next lesson.

    The core idea

    Rule one: supplies take the best balls. The four core supply pairs are spread one per quadrant of the array, each VDD ball beside its own VSS ball, on the ring of balls just inside the outer row where the logic they feed is closest. The two I/O pairs sit beside the outputs they feed. Rule two: fast signals take the outermost row or column, where they escape without vias, and within two balls of their I/O supply pair: the four SPI signals leave on the south and east edges beside pair 0. Rule three: quiet pins get quiet neighbours: the crystal balls sit in the north-west corner with one core ground and one I/O ground ball as guards and no fast signal near. Rule four: slow control fills what remains, with the sixteen GPIO groups matched to their I/O pairs. The array has 36 balls, 31 are assigned and 5 stay spare: the central 2 x 2 block, which a board could not escape anyway, and one edge ball.

    Ball assignment order for the NanoSoC teaching package: supplies first, fast signals second, quiet pins third, slow control last.
    Ball assignment order for the NanoSoC teaching package: supplies first, fast signals second, quiet pins third, slow control last.

    Row \ column

    1

    2

    3

    4

    5

    6

    A

    XTAL_IN

    XTAL_OUT

    RESET_N

    P8

    P9

    P10

    B

    P15

    VSS_CORE0

    VSS_IO1

    VDD_IO1

    VSS_CORE1

    P11

    C

    P13

    VDD_CORE0

    spare

    spare

    VDD_CORE1

    P12

    D

    P14

    VDD_CORE2

    spare

    spare

    VDD_CORE3

    P7

    E

    spare

    VSS_CORE2

    VSS_IO0

    VDD_IO0

    VSS_CORE3

    P5 (CS_N)

    F

    P0 (TX)

    P1 (RX)

    P2 (SCK)

    P3 (MOSI)

    P4 (MISO)

    P6

    The assignment checker

    The script below holds that array as data and checks it through one function: all 31 pads placed once and exactly 5 spare; one core pair in each quadrant with its VSS beside its VDD; each I/O pair adjacent; SPI pads on the outer ring and within 2 balls of their pair; every other output within 4; and the crystal with a core ground and an I/O ground beside it and no SPI pad within 3 balls. It then moves the SPI clock into the centre, and swaps the crystal guards for GPIO, and requires both to 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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    GRID = [
        ["XTAL_IN", "XTAL_OUT", "RESET_N", "GPIO8", "GPIO9", "GPIO10"],
        ["GPIO15", "VSS_CORE0", "VSS_IO1", "VDD_IO1", "VSS_CORE1", "GPIO11"],
        ["GPIO13", "VDD_CORE0", "NC", "NC", "VDD_CORE1", "GPIO12"],
        ["GPIO14", "VDD_CORE2", "NC", "NC", "VDD_CORE3", "GPIO7"],
        ["NC", "VSS_CORE2", "VSS_IO0", "VDD_IO0", "VSS_CORE3", "GPIO5"],
        ["GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO6"],
    ]
    SPI = ["GPIO2", "GPIO3", "GPIO4", "GPIO5"]            # fast signals: SCK, MOSI, MISO, CS_N
    
    def where(grid):
        return {n: (r, c) for r, row in enumerate(grid) for c, n in enumerate(row) if n != "NC"}
    
    def dist(a, b):
        return abs(a[0] - b[0]) + abs(a[1] - b[1])
    
    def check(grid):
        pos = where(grid)
        nc = sum(row.count("NC") for row in grid)
        assert len(pos) == 31 and nc == 5, (len(pos), nc)
        quadrants = set()
        for k in range(4):
            v, g = pos["VDD_CORE%d" % k], pos["VSS_CORE%d" % k]
            assert dist(v, g) == 1, "core pair %d is split" % k
            quadrants.add((v[0] >= 3, v[1] >= 3))
        assert len(quadrants) == 4, "core pairs are not one per quadrant"
        for k in range(2):
            assert dist(pos["VDD_IO%d" % k], pos["VSS_IO%d" % k]) == 1, "I/O pair split"
        for i in range(16):
            pad = "GPIO%d" % i
            pair = 0 if i < 8 else 1
            d = min(dist(pos[pad], pos["VDD_IO%d" % pair]), dist(pos[pad], pos["VSS_IO%d" % pair]))
            assert d <= (2 if pad in SPI else 4), (pad, "too far from its I/O pair", d)
        for pad in SPI:
            r, c = pos[pad]
            assert min(r, c, 5 - r, 5 - c) == 0, pad + " is not on the outer ring"
        xo = pos["XTAL_OUT"]
        near = [n for n, p in pos.items() if max(abs(p[0] - xo[0]), abs(p[1] - xo[1])) == 1]
        assert any(n.startswith("VSS_CORE") for n in near) and any(n.startswith("VSS_IO") for n in near), "crystal has no guards"
        for pad in SPI:
            assert dist(pos[pad], pos["XTAL_IN"]) >= 3 and dist(pos[pad], xo) >= 3
    
    check(GRID)
    moved = [row[:] for row in GRID]
    moved[5][2], moved[2][2] = "NC", "GPIO2"               # SCK moved to the centre of the array
    swapped = [row[:] for row in GRID]
    swapped[1][1], swapped[1][0] = "GPIO15", "VSS_CORE0"    # core ground moved away from the crystal
    for bad in (moved, swapped):
        try:
            check(bad)
            raise SystemExit("a bad assignment was accepted")
        except AssertionError:
            pass
    print("PASS: 31 balls placed once, 5 spare; core pair per quadrant; SPI on the outer ring near its pair; crystal guarded; two bad ballouts rejected")

    What the review looks for

    • Supplies placed before signals, with each pair's feed named.

    • Fast signals on the outer ring, quoted by coordinate, not by intent.

    • Quiet pins with named guards, and no fast neighbour within the stated distance.

    • The spare balls listed, so a later change knows what is free.

    Verify and debug

    Diff the ballout against the pin database and the board netlist together: a ball the board team moved without telling the chip team is the classic divergence, and the diff catches it in seconds. If a late change moves a fast signal inward, the escape lesson re-prices the vias before the move is accepted.

    A ball assignment fixed on one side only: two functions end up on one pin, or the chip's map differs from the board design. The symptom is a signal on the wrong ball or noise on the I/O; it is caught by a pin-mux check against the ballout and the board netlist plus a board-team review, and fixed by one pin database and supply pairs spread across the array.

    If asked to ball out a small chip live, narrate the rule order as you place: supplies, fast, quiet, rest. A strong answer is judged by the order of placement and the reasons, more than by the final coordinates.

    Check yourself A GPIO is swapped with the SPI clock to shorten a board trace. Why refuse?

    Because the swap moves a fast signal away from the outer ring or from its supply pair: the board saves one trace while the chip spends escape vias and the noise budget the pairing lesson closed. Ball moves are priced on both sides before acceptance.

    Related topics

    • Package Types at a Conceptual Level

    • Next: Pinout Review and Escape Routing

    • Physical Design: IO Placement and Bump Assignment

    Previous

    221 / 289

    Next: Pinout Review and Escape Routing

    Up next

    Up nextPinout Review and Escape Routing

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error