On some devices a core rail that rises before its IO rail can forward-bias protection structures between the two; on any device a POR that releases on a rail at 80 percent of nominal can latch the wrong strap values into every pad. Both failures can be silent at power-up and, in the worst case, damaging or hard to reproduce afterwards. The order rules exist so that each consumer sees only settled supplies, and power-good is how the chip knows they have settled.
The order is a property of the chip's pad ring and datasheet, not a universal rule: some devices want the core rail first, others the IO rail first, and others allow any order with a limit on the voltage difference between rails during the ramp. The review therefore writes down the required order, the maximum allowed voltage difference between rails during the ramp, and the reason for each constraint. What is general is the gate: each power-good asserts after its rail stays inside tolerance for a debounce interval, and only after the last power-good does POR release into the cold-start timeline. No reset, no clock and no strap is sampled before that. The illustrative two-rail example below ramps IO first and core second. On NanoSoC the order has one step, the single 0.9 V rail, and POR release comes from the analogue POR cell in PD_AON; the waveform shows the two-rail case so the order can be read off the lanes. Every multi-rail number in this lesson is illustrative and kept consistent across the topic.
# not-run: illustrative two-rail order for teaching; NanoSoC itself has one 0.9 V rail
Rail order: VDD_IO (illustrative 1.8 V) first, then VDD_CORE (0.9 V, NanoSoC value).
Each rail: ramp, then 5 us debounce inside +/-5% (illustrative), then PGOOD.
POR releases only after ALL PGOODs assert; strap sampling follows POR release.
The order here is the example's, not a rule: the real order comes from the datasheet.How to read it: vdd_io rises first and pgood_io follows after its debounce; vdd_core rises second and pgood_core follows the same way; por_n releases only once both power-good lanes are high; rst_per_n, rst_sys_n and rst_cpu_n then release in that order, two, three and three slots apart. The lanes are not to scale: a slot is 40 ns of simulation, whereas the real gaps, the 42.667 µs oscillator wait and the 10.833 µs PLL lock between POR and rst_sys_n, are in the cold-start topic. The clk lane is a sampling clock only, not a NanoSoC clock, and each rail is drawn as a single step rather than a ramp. If any lane moves early, por_n first, the CPU reset before the fabric reset, or a reset before its power-good, the sequence is broken exactly where the lanes cross.
Signal | Where it comes from | What it means | Used by NanoSoC for |
|---|---|---|---|
por_n | Analogue POR cell in PD_AON, threshold on the 0.9 V supply | Supply is above its threshold; released at t = 0 of the cold-start timeline | Cold boot: starts the oscillator wait |
pgood (PWR_STATUS bit 1) | The switched PD_SW rail, after the power switch closes | PD_SW rail is usable | Wake: starts the 8-clock margin before PLL relock |
board PGOOD | PMIC output, external to the chip | A board rail is inside tolerance | Optional input that holds pad_rst_n low until all board rails are good |
Do not mix the three: por_n is the chip's own cold-boot gate, pgood is the on-chip switch's wake gate, and board PGOOD belongs to the board. The wave and script below are about the board signal.
# Power-good gating check: POR may release only after every rail is good.
# Thresholds illustrative; the NanoSoC single rail uses its POR the same way.
RAILS = {"vdd_io": {"pgood": True}, "vdd_core": {"pgood": True}}
por_release_ok = all(r["pgood"] for r in RAILS.values())
assert por_release_ok
RAILS["vdd_core"]["pgood"] = False
assert not all(r["pgood"] for r in RAILS.values())
# Debounce: rail must stay in tolerance for N consecutive samples (illustrative 5).
samples = [0.86, 0.88, 0.90, 0.91, 0.90, 0.89] # volts around 0.9 nominal
lo, hi, need = 0.855, 0.945, 5
run, pgood = 0, False
for v in samples:
run = run + 1 if lo <= v <= hi else 0
pgood = pgood or run >= need
assert pgood # last five samples all inside +/-5%
# A dip inside the window restarts the count: the same rail never reaches 5.
run, pgood = 0, False
for v in [0.86, 0.88, 0.80, 0.91, 0.90, 0.89]:
run = run + 1 if lo <= v <= hi else 0
pgood = pgood or run >= need
assert not pgood
print("PASS: POR gated on all PGOODs; 5-sample debounce inside +/-5%")The rail order is taken from the datasheet and written with a reason per constraint, including the maximum voltage difference between rails during the ramp, not just a list.
POR release is an AND of all power-goods plus debounce, shown in the waveform and in the check above.
No strap, trim or reset is sampled before POR release anywhere in the design.
Simulate the ramp with each rail delayed, sagged and shorted in turn: only the all-good case may release POR, and every other case must hold the chip in reset with the cause visible. On the bench, probe the rails against their power-goods during a slow ramp; a power-good that asserts below its threshold is a divider or reference fault, not a timing tweak.
The monitor threshold or its reference, not the ramp rate. Check the divider or reference trim first; if the threshold is analogue-trimmed, confirm the trim loaded before the monitor was armed.