tests / archlinux:latest (push) Successful in 39s
tests / debian:12 (push) Successful in 1m17s
tests / fedora:latest (push) Successful in 1m8s
tests / ubuntu:24.04 (push) Successful in 1m23s
tests / ubuntu-latest · py3.11 (push) Successful in 1m25s
tests / ubuntu-latest · py3.13 (push) Successful in 1m5s
tests / NixOS (FHS wrapper from docs/NIXOS.md) (push) Skipped
Build PCM package / build (push) Successful in 11s
Multiple Thevenin supplies and prescribed-current loads on one net, solved in absolute volts with the Tellegen power balance verified per run; a source-sink pair table (effective copper resistance per supply x load pair plus an exactly-summing proportional-sharing loss attribution), in summary.txt and as its own figure. Bonded terminals short a package's contacts into one lug so the per-pin split becomes a solve outcome. Geometry dumps carry the terminal set (schema v8). The dialog gained a Classic/PDN mode selector and a full PDN editor: per-role supply/load tables built from the marker rectangles (or a config's terminal set, which never pins mode or net), with Component hints, per-terminal Layer scopes, Active checkboxes, comments, a per-net row filter, resizable tables and a scrolling, screen-sized dialog. Numbers accept SI suffixes (50m, 4.7k) everywhere. fill_res_config.json fully specifies a run (classic or PDN) with validation, comments, named side-by-side configs (the one called default auto-loads), Load/Save buttons with an editable file name, and saves that never drop anything drawn on the board. 347 tests, green on Python 3.13 and on the 3.9 macOS wheel stack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
155 lines
9.1 KiB
Markdown
155 lines
9.1 KiB
Markdown
PDN mode, a full configuration-file workflow and a reworked dialog -
|
|
all opt-in: classic runs behave exactly as in 1.3.0 (the analytic test
|
|
suite runs unchanged against the same solver paths).
|
|
|
|
PDN mode - multiple supplies and loads on one net:
|
|
|
|
- Instead of one driven terminal pair, a run can now model a power
|
|
rail: any number of supply points, each a Thevenin source with a
|
|
configurable output resistance (and optionally its own open-circuit
|
|
voltage), plus any number of loads, each drawing its own prescribed
|
|
current. The solve runs in absolute volts and reports the IR-drop
|
|
map, each supply's delivered current (the Thevenin split - an
|
|
outcome, not an input), and each load's mean and worst-case contact
|
|
voltage, alongside the usual per-layer dissipation, |J| maps and
|
|
per-via currents.
|
|
- The summary carries a source-sink pair table: for every supply x
|
|
load pair, the effective COPPER resistance between the two contacts
|
|
(operating-point independent, source R_out excluded; one extra
|
|
linear solve per terminal, deferred-corrected on the adaptive grid
|
|
too) plus the copper loss attributed to the pair by proportional
|
|
sharing - an attribution convention, but it sums exactly to the
|
|
total copper dissipation, never crosses a copper gap, and pairs
|
|
without a common copper path report "no path". The same table is
|
|
also rendered as a figure (5_source_sink_pairs.png) alongside the
|
|
field maps; terminals are keyed by their unique labels (no
|
|
positional tags), and both outputs note each terminal's component
|
|
hint and comment - the summary in the supplies/loads tables, the
|
|
figure in a terminals legend underneath.
|
|
- The consistency check generalizes: source power = copper loss +
|
|
output-resistance loss + load power (Tellegen), verified on every
|
|
run. Both the uniform-reference and the adaptive grid support PDN
|
|
mode; geometry dumps embed the terminal set (schema v8) and re-solve
|
|
offline via standalone.py with no extra flags. Older dumps load
|
|
unchanged.
|
|
|
|
The dialog editor - PDN runs need no JSON at all:
|
|
|
|
- The dialog gained a Mode selector: Classic (unchanged - and simply
|
|
called that; a "two-terminal" label would read like a 2-contact cap,
|
|
but classic terminals can bundle many contact parts) or PDN. In PDN
|
|
mode, rectangles on User.1 are supply terminals and rectangles on
|
|
User.2 are load terminals - the same marker layers as classic, but
|
|
each rectangle is its OWN terminal instead of being merged into one
|
|
V+/V- contact. Two editable tables - one for supplies, one for
|
|
loads, each titled with the marker layer its rectangles come from -
|
|
assign each load its current draw and each supply its output
|
|
resistance (plus an optional open-circuit voltage; empty = the
|
|
V-nominal field). PDN is selectable whenever both layers carry at
|
|
least one rectangle; otherwise the radio is disabled with the reason
|
|
shown, and a classic-mode failure (nothing selected, no marker pair)
|
|
no longer kills the launch when PDN rectangles exist - the dialog
|
|
opens in the mode that works.
|
|
- A text item placed inside a rectangle names the terminal; unnamed
|
|
rectangles get automatic names (S1../L1.., stable reading order).
|
|
- A read-only Component column identifies each row: the footprint
|
|
whose pad intersects the contact area (e.g. "U5"), or "near U5"
|
|
when nothing touches it. Purely spatial - it names where the
|
|
terminal sits, it plays no electrical role.
|
|
- Every terminal row picks its contacted copper in a Layer combo,
|
|
like the classic contact scopes: "All selected layers" (a
|
|
rectangle's natural bolted-lug scope) or one specific layer. The
|
|
choice is saved as the terminal-level "contact" key.
|
|
- Every row has an Active checkbox: unchecking it disregards the
|
|
terminal (no solve, value cells may stay blank) WITHOUT deleting it
|
|
- the row is saved as "active": false and can be re-enabled later.
|
|
A free-text Comment column is saved with each terminal ("comment"
|
|
key). Both are editable in config-backed setups too.
|
|
- The tables show only the rectangles that actually sit on the
|
|
selected net: switching the net swaps the visible set, the totals
|
|
line counts the hidden rows, and hidden rows take no part in the
|
|
run - not validated, not solved. Saving keeps them anyway: every
|
|
row lands in the config file, off-net ones as "active": false with
|
|
their values and comments intact, and config-backed runs apply the
|
|
same per-net filter so archived terminals are skipped, never fatal.
|
|
- The terminal tables are height-resizable: each sizes itself to its
|
|
rows, a drag handle between the two redistributes space, and
|
|
enlarging the dialog grows them. In PDN mode the dialog opens at
|
|
~60% of the screen height (capped at 85%/90% of the screen; the
|
|
KiCad window itself is not reachable through the IPC API, so the
|
|
screen is the reference). The whole form scrolls when it outgrows
|
|
the screen (the error line and the buttons always stay visible at
|
|
the bottom).
|
|
- Numbers understand SI suffixes: 50m = 0.05, 4.7k = 4700, 2M = 2e6
|
|
(case separates milli from mega). This works in every dialog number
|
|
field (R_out, V_oc, I draw, V nominal, test current, cell size,
|
|
thresholds), in the config file (any number may be a string:
|
|
"r_out_ohm": "50m"), and in the CLI's --current / --cell-um /
|
|
--v-nominal. The frequency field keeps its own grammar (142k, 1.5M -
|
|
a lone m means MHz there, as before).
|
|
|
|
Bonded terminals - a package's total current with a free per-pin split:
|
|
|
|
- A terminal (config key "bonded": true; in the editor, simply give
|
|
several rectangles the same name) shorts all its contacts into one
|
|
lug, the way a multi-pin package joins its pins with internal metal:
|
|
the TOTAL current stays prescribed, but which contact carries how
|
|
much becomes a solve outcome instead of the default per-cell area
|
|
share. Works for loads and supplies (a bonded supply is an
|
|
equipotential lug with its whole output resistance in series), on
|
|
both grids, and the reported per-part currents are the computed
|
|
boundary fluxes. A bonded load may even span disconnected copper
|
|
sheets - the bond is the connection.
|
|
|
|
Configuration file - the run, fully specified next to the board:
|
|
|
|
- A JSON config next to the board file can specify a complete run:
|
|
every dialog field, the classic terminals by board reference
|
|
(skipping the selection / marker-rectangle step), the select
|
|
physics constants that previously required editing config.py
|
|
(resistivity, copper thickness, via plating), the marker layer
|
|
names - or the whole PDN terminal set. Precedence is simple:
|
|
config.py defaults < config file < dialog edits; the file pre-fills
|
|
the dialog, what the dialog shows is what runs.
|
|
- Terminals are written by board reference: "U7" (all pads of a
|
|
footprint on the net), "U7.3" (one pad), "rect:NAME" (a rectangle
|
|
named by a text item placed inside it - searched on User.3, User.1
|
|
and User.2, so names must be unique across the marker layers),
|
|
explicit rectangles or nearest-via coordinates.
|
|
- Configs can be kept side by side as "fill_res_config.<name>.json":
|
|
the config named "default" loads automatically (plain
|
|
"fill_res_config.json" is its legacy spelling, and a board-specific
|
|
"<stem>.fill_res_config.json" wins over both), and the Load
|
|
config... button in the dialog pulls in any other config for this
|
|
run - the dialog re-opens seeded entirely from the picked file.
|
|
Save config... asks for the target file name each time (pre-filled
|
|
with the loaded config; ".json" appended when omitted), so writing
|
|
back and branching a variant are both one click; a name outside the
|
|
auto-load set prints a Load-config reminder.
|
|
- Save config... works in both modes: classic saves write the run
|
|
parameters and contact scopes, PDN saves write the whole terminal
|
|
set - named rectangles as live "rect:NAME" references (they follow
|
|
the rectangle wherever it moves), unnamed ones as frozen rect_mm
|
|
coordinates, so label your rectangles if the layout is still
|
|
moving. Full-line // comments and "_"-prefixed keys are allowed;
|
|
invalid files stop the run with the offending key path instead of
|
|
silently running defaults; unknown keys warn (typo guard).
|
|
- A config never pins anything. Its mode is only the STARTING mode
|
|
(a classic-mode file may carry a terminals section and vice versa),
|
|
the net stays switchable, values / layer scopes / active flags /
|
|
comments are editable per run and written back on save (part
|
|
references are preserved verbatim; part-level contacts keep winning
|
|
over the terminal scope), and a classic save over a PDN config
|
|
keeps the whole terminals section - it just flips the starting
|
|
mode. A broken terminal reference disables PDN mode with the reason
|
|
shown instead of killing the launch.
|
|
- A config-backed set is open-ended: any marker rectangle the file
|
|
does not reference yet appears as a NEW terminal row (a note under
|
|
the tables counts them) and Save config... appends it to the file.
|
|
A rectangle named after an existing rect:NAME terminal instead
|
|
joins that terminal as another contact part at resolve time. A
|
|
label colliding with an unrelated terminal name is skipped with a
|
|
note; colliding auto names are renumbered.
|
|
- standalone.py gained --config (run-parameter defaults under the
|
|
explicit flags) and --v-nominal.
|