The dominant discharge events, handling and assembly, hit a chip with every supply off. A path that works only when the chip is powered is a path that fails in the state where most discharges actually arrive. NanoSoC has more states than it first appears: the I/O rail and the core rail, and within the core a switchable domain that may be off. This lesson walks the path in each of them.
A discharge entering a GPIO pad flows first through the pad's diode pair to the I/O rails, then must reach ground through the rail clamps and on to the board ground balls, crossing between the I/O ground and the core ground through the on-die diode pair if that is the shorter way. The review traces this in words before trusting any diagram: pad, pad diode, rail, rail clamp, ground, ground link, ground ball, each step named and each step present. The trace is then walked in four states. UNPOWERED: every rail floats, which is where handling discharges arrive. RUN and IDLE: everything is powered. SLEEP: the always-on domain is powered and PD_SW is off.
Two rules follow. In UNPOWERED and SLEEP the path must use clamps that need no supply voltage to trigger, the transient-triggered rail clamps of the I/O library, because there is no supply to bias a supply-triggered clamp. And in SLEEP the path must never rely on the switched PD_SW rail: the header switch is open, so that rail is connected only through a high-impedance device, not removed. The always-on rails and their clamps complete the path. This is why the checklist names the clamps per rail and why the always-on supply is never allowed to depend on the sleeping domain.
State | I/O rail | Core rail | PD_SW | What the path may use |
|---|---|---|---|---|
UNPOWERED | floating | floating | off | Diodes and transient-triggered clamps only. |
RUN | on | on | on | Any clamp. |
IDLE | on | on | on (CPU clock gated) | Any clamp. |
SLEEP | on | on | off | Clamps on the I/O and always-on rails; nothing on PD_SW. |
The script below holds the path as a list of elements, each with the rail it sits on, whether it needs a supply voltage to trigger, and whether it sits on the switched rail. It checks every element in every state. It then runs the same check on two bad designs: a supply-triggered rail clamp, which fails in UNPOWERED, and a clamp placed on the PD_SW rail, which fails in SLEEP.
STATES = {"UNPOWERED": {"vdd_io": False, "vdd_core": False, "pd_sw": False},
"RUN": {"vdd_io": True, "vdd_core": True, "pd_sw": True},
"IDLE": {"vdd_io": True, "vdd_core": True, "pd_sw": True},
"SLEEP": {"vdd_io": True, "vdd_core": True, "pd_sw": False}}
# element: (name, rail it sits on, needs a supply to trigger, sits on the switched rail)
PATH = [("pad_diode_pair", "vdd_io", False, False),
("io_rail_clamp", "vdd_io", False, False),
("ground_link_diodes", "vdd_io", False, False),
("core_rail_clamp", "vdd_core", False, False)]
def check(path):
for state, live in STATES.items():
for name, rail, needs_supply, on_sw in path:
if needs_supply:
assert live[rail], (state, name, "needs a supply that is off")
if on_sw:
assert live["pd_sw"], (state, name, "depends on the switched rail")
return len(STATES) * len(path)
assert check(PATH) == 16
supply_triggered = [PATH[0], ("io_rail_clamp", "vdd_io", True, False)] + PATH[2:]
on_switched_rail = PATH[:3] + [("core_rail_clamp", "vdd_core", False, True)]
for bad in (supply_triggered, on_switched_rail):
try:
check(bad)
raise SystemExit("a path with a dead end was accepted")
except AssertionError:
pass
print("PASS: the discharge path holds in UNPOWERED, RUN, IDLE and SLEEP; a supply-triggered clamp and a PD_SW clamp are rejected")The pad-to-ground trace written per state, UNPOWERED first, not assumed from one diagram.
Clamps stated to be transient-triggered where no supply is present, and none placed on the switchable rail.
No path step that depends on a switch being closed or a rail being up.
The clamp location stated: on the die, in the pad cells or ring cells, never on the package.
Rail clamps between the rails sit on the die, either inside the pad cells or as separate clamp cells in the ring or the core, depending on the I/O library; the integrator specifies their presence per rail pair and the review confirms it. A rail added late, such as a new analog supply or a split core rail, needs its clamp row before it needs its decoupling, because the discharge does not wait for the power-integrity sign-off. Walk the trace against the schematic in all four states and keep the four walks with the review minutes; a new power state added later re-opens all of them.
Because with the header switch open that rail is connected only through a high-impedance device, so it offers no low-impedance route to ground; a surge sent that way finds its own path, through logic. The path must use rails that stay connected to powered clamps.