@vessel-dsp/compiler 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -2
- package/dist/bake.d.ts +38 -0
- package/dist/bake.d.ts.map +1 -0
- package/dist/bake.js +101 -0
- package/dist/bake.js.map +1 -0
- package/dist/bbd-clock.d.ts +171 -0
- package/dist/bbd-clock.d.ts.map +1 -0
- package/dist/bbd-clock.js +1750 -0
- package/dist/bbd-clock.js.map +1 -0
- package/dist/block-row.d.ts +51 -0
- package/dist/block-row.d.ts.map +1 -0
- package/dist/block-row.js +17 -0
- package/dist/block-row.js.map +1 -0
- package/dist/bypass.d.ts +3 -0
- package/dist/bypass.d.ts.map +1 -0
- package/dist/bypass.js +228 -0
- package/dist/bypass.js.map +1 -0
- package/dist/compile.d.ts +24 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +348 -0
- package/dist/compile.js.map +1 -0
- package/dist/converter-scale.d.ts +14 -0
- package/dist/converter-scale.d.ts.map +1 -0
- package/dist/converter-scale.js +133 -0
- package/dist/converter-scale.js.map +1 -0
- package/dist/couple.d.ts +28 -0
- package/dist/couple.d.ts.map +1 -0
- package/dist/couple.js +567 -0
- package/dist/couple.js.map +1 -0
- package/dist/dangling-active-terminal.d.ts +47 -0
- package/dist/dangling-active-terminal.d.ts.map +1 -0
- package/dist/dangling-active-terminal.js +542 -0
- package/dist/dangling-active-terminal.js.map +1 -0
- package/dist/declared-program.d.ts +23 -0
- package/dist/declared-program.d.ts.map +1 -0
- package/dist/declared-program.js +387 -0
- package/dist/declared-program.js.map +1 -0
- package/dist/denomination.d.ts +48 -0
- package/dist/denomination.d.ts.map +1 -0
- package/dist/denomination.js +27 -0
- package/dist/denomination.js.map +1 -0
- package/dist/device-laws.d.ts +237 -0
- package/dist/device-laws.d.ts.map +1 -0
- package/dist/device-laws.js +3513 -0
- package/dist/device-laws.js.map +1 -0
- package/dist/diagnostics.d.ts +13 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +19 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit.d.ts +8 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +43 -0
- package/dist/emit.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/firmware-class.d.ts +69 -0
- package/dist/firmware-class.d.ts.map +1 -0
- package/dist/firmware-class.js +20 -0
- package/dist/firmware-class.js.map +1 -0
- package/dist/fixtures/circuits.d.ts +1742 -0
- package/dist/fixtures/circuits.d.ts.map +1 -0
- package/dist/fixtures/circuits.js +13896 -0
- package/dist/fixtures/circuits.js.map +1 -0
- package/dist/fixtures/expected.d.ts +261 -0
- package/dist/fixtures/expected.d.ts.map +1 -0
- package/dist/fixtures/expected.js +315 -0
- package/dist/fixtures/expected.js.map +1 -0
- package/dist/fixtures/index.d.ts +4 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +8 -0
- package/dist/fixtures/index.js.map +1 -0
- package/dist/fixtures/registry.d.ts +52 -0
- package/dist/fixtures/registry.d.ts.map +1 -0
- package/dist/fixtures/registry.js +341 -0
- package/dist/fixtures/registry.js.map +1 -0
- package/dist/generic-tube-fit.d.ts +12 -0
- package/dist/generic-tube-fit.d.ts.map +1 -0
- package/dist/generic-tube-fit.js +45 -0
- package/dist/generic-tube-fit.js.map +1 -0
- package/dist/grounded-clock-supply.d.ts +13 -0
- package/dist/grounded-clock-supply.d.ts.map +1 -0
- package/dist/grounded-clock-supply.js +45 -0
- package/dist/grounded-clock-supply.js.map +1 -0
- package/dist/identify.d.ts +50 -0
- package/dist/identify.d.ts.map +1 -0
- package/dist/identify.js +319 -0
- package/dist/identify.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/inert-controls.d.ts +15 -0
- package/dist/inert-controls.d.ts.map +1 -0
- package/dist/inert-controls.js +266 -0
- package/dist/inert-controls.js.map +1 -0
- package/dist/latch-seed.d.ts +53 -0
- package/dist/latch-seed.d.ts.map +1 -0
- package/dist/latch-seed.js +257 -0
- package/dist/latch-seed.js.map +1 -0
- package/dist/link.d.ts +7 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +270 -0
- package/dist/link.js.map +1 -0
- package/dist/lower.d.ts +79 -0
- package/dist/lower.d.ts.map +1 -0
- package/dist/lower.js +1855 -0
- package/dist/lower.js.map +1 -0
- package/dist/netlist.d.ts +79 -0
- package/dist/netlist.d.ts.map +1 -0
- package/dist/netlist.js +4746 -0
- package/dist/netlist.js.map +1 -0
- package/dist/non-executable-clock-drivers.d.ts +8 -0
- package/dist/non-executable-clock-drivers.d.ts.map +1 -0
- package/dist/non-executable-clock-drivers.js +33 -0
- package/dist/non-executable-clock-drivers.js.map +1 -0
- package/dist/open-category.d.ts +98 -0
- package/dist/open-category.d.ts.map +1 -0
- package/dist/open-category.js +111 -0
- package/dist/open-category.js.map +1 -0
- package/dist/over-driven-node.d.ts +33 -0
- package/dist/over-driven-node.d.ts.map +1 -0
- package/dist/over-driven-node.js +188 -0
- package/dist/over-driven-node.js.map +1 -0
- package/dist/part-catalog.d.ts +15 -0
- package/dist/part-catalog.d.ts.map +1 -0
- package/dist/part-catalog.js +6712 -0
- package/dist/part-catalog.js.map +1 -0
- package/dist/part-number.d.ts +32 -0
- package/dist/part-number.d.ts.map +1 -0
- package/dist/part-number.js +80 -0
- package/dist/part-number.js.map +1 -0
- package/dist/partition.d.ts +7 -0
- package/dist/partition.d.ts.map +1 -0
- package/dist/partition.js +242 -0
- package/dist/partition.js.map +1 -0
- package/dist/port-full-scale.d.ts +70 -0
- package/dist/port-full-scale.d.ts.map +1 -0
- package/dist/port-full-scale.js +235 -0
- package/dist/port-full-scale.js.map +1 -0
- package/dist/pot-orientation.d.ts +114 -0
- package/dist/pot-orientation.d.ts.map +1 -0
- package/dist/pot-orientation.js +551 -0
- package/dist/pot-orientation.js.map +1 -0
- package/dist/power-domain-control.d.ts +40 -0
- package/dist/power-domain-control.d.ts.map +1 -0
- package/dist/power-domain-control.js +142 -0
- package/dist/power-domain-control.js.map +1 -0
- package/dist/proxy-declaration.d.ts +121 -0
- package/dist/proxy-declaration.d.ts.map +1 -0
- package/dist/proxy-declaration.js +50 -0
- package/dist/proxy-declaration.js.map +1 -0
- package/dist/registry.d.ts +323 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +192 -0
- package/dist/registry.js.map +1 -0
- package/dist/sparse-schedule.d.ts +65 -0
- package/dist/sparse-schedule.d.ts.map +1 -0
- package/dist/sparse-schedule.js +421 -0
- package/dist/sparse-schedule.js.map +1 -0
- package/dist/speaker-load.d.ts +38 -0
- package/dist/speaker-load.d.ts.map +1 -0
- package/dist/speaker-load.js +97 -0
- package/dist/speaker-load.js.map +1 -0
- package/dist/stage-coverage.d.ts +21 -0
- package/dist/stage-coverage.d.ts.map +1 -0
- package/dist/stage-coverage.js +124 -0
- package/dist/stage-coverage.js.map +1 -0
- package/dist/stamp-partition.d.ts +314 -0
- package/dist/stamp-partition.d.ts.map +1 -0
- package/dist/stamp-partition.js +472 -0
- package/dist/stamp-partition.js.map +1 -0
- package/dist/supply-reference.d.ts +19 -0
- package/dist/supply-reference.d.ts.map +1 -0
- package/dist/supply-reference.js +66 -0
- package/dist/supply-reference.js.map +1 -0
- package/dist/supply-short.d.ts +32 -0
- package/dist/supply-short.d.ts.map +1 -0
- package/dist/supply-short.js +118 -0
- package/dist/supply-short.js.map +1 -0
- package/dist/supply-stamps.d.ts +51 -0
- package/dist/supply-stamps.d.ts.map +1 -0
- package/dist/supply-stamps.js +363 -0
- package/dist/supply-stamps.js.map +1 -0
- package/dist/terminal-role.d.ts +109 -0
- package/dist/terminal-role.d.ts.map +1 -0
- package/dist/terminal-role.js +46 -0
- package/dist/terminal-role.js.map +1 -0
- package/dist/terminal-roles.d.ts +59 -0
- package/dist/terminal-roles.d.ts.map +1 -0
- package/dist/terminal-roles.js +92 -0
- package/dist/terminal-roles.js.map +1 -0
- package/dist/transformer.d.ts +181 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +476 -0
- package/dist/transformer.js.map +1 -0
- package/dist/types.d.ts +3157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/unbounded-operating-point.d.ts +35 -0
- package/dist/unbounded-operating-point.d.ts.map +1 -0
- package/dist/unbounded-operating-point.js +181 -0
- package/dist/unbounded-operating-point.js.map +1 -0
- package/dist/unexecuted-region.d.ts +3 -0
- package/dist/unexecuted-region.d.ts.map +1 -0
- package/dist/unexecuted-region.js +122 -0
- package/dist/unexecuted-region.js.map +1 -0
- package/dist/unimplemented-control-role.d.ts +3 -0
- package/dist/unimplemented-control-role.d.ts.map +1 -0
- package/dist/unimplemented-control-role.js +61 -0
- package/dist/unimplemented-control-role.js.map +1 -0
- package/dist/unreachable-output.d.ts +3 -0
- package/dist/unreachable-output.d.ts.map +1 -0
- package/dist/unreachable-output.js +97 -0
- package/dist/unreachable-output.js.map +1 -0
- package/dist/unreadable-terminal-role.d.ts +67 -0
- package/dist/unreadable-terminal-role.d.ts.map +1 -0
- package/dist/unreadable-terminal-role.js +409 -0
- package/dist/unreadable-terminal-role.js.map +1 -0
- package/dist/unverified-pinout.d.ts +27 -0
- package/dist/unverified-pinout.d.ts.map +1 -0
- package/dist/unverified-pinout.js +121 -0
- package/dist/unverified-pinout.js.map +1 -0
- package/package.json +75 -5
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
// Compile-time stamp partitioning for MNA blocks.
|
|
2
|
+
//
|
|
3
|
+
// Classifies stamps into linear vs nonlinear (port rows), control-dependent vs
|
|
4
|
+
// constant, and dynamic/reactive state. Precomputed at compile time and emitted on
|
|
5
|
+
// the program as data, avoiding runtime re-classification or dynamic row allocations.
|
|
6
|
+
import { atLeast, perBlock } from "./denomination.js";
|
|
7
|
+
/**
|
|
8
|
+
* Which fields of each stamp kind hold a node id.
|
|
9
|
+
*
|
|
10
|
+
* One table rather than a switch per consumer. `remapStampNodes` used to restate this as 150
|
|
11
|
+
* lines of `{ ...stamp, anode: row(stamp.anode), cathode: row(stamp.cathode) }`, and
|
|
12
|
+
* `stampTerminals` in `sparse-schedule.ts` restates a near-copy of it again for a different
|
|
13
|
+
* purpose. That is the same fact written twice, and the documented failure mode of getting it
|
|
14
|
+
* wrong is severe: a stamp kind missing a case kept its authored node ids while every other
|
|
15
|
+
* stamp in the block moved to row indices, which is an element quietly wired to the wrong
|
|
16
|
+
* nodes that still renders.
|
|
17
|
+
*
|
|
18
|
+
* `satisfies` checks this harder than the switch did. The mapped type requires **every** stamp
|
|
19
|
+
* kind to appear -- a new kind is a compile error here -- and requires each listed name to be
|
|
20
|
+
* an actual key of that kind's own variant, so a typo or a field moved during a refactor fails
|
|
21
|
+
* to build rather than silently renumbering nothing.
|
|
22
|
+
*/
|
|
23
|
+
export const STAMP_SHAPES = {
|
|
24
|
+
conductance: { nodes: ["a", "b"], aux: 0, ports: "none", newton: false },
|
|
25
|
+
"controlled-conductance": {
|
|
26
|
+
nodes: ["a", "b"],
|
|
27
|
+
aux: 0,
|
|
28
|
+
ports: "none",
|
|
29
|
+
newton: false,
|
|
30
|
+
control: true,
|
|
31
|
+
},
|
|
32
|
+
"controlled-resistance": {
|
|
33
|
+
nodes: ["a", "b"],
|
|
34
|
+
aux: 0,
|
|
35
|
+
ports: "none",
|
|
36
|
+
newton: false,
|
|
37
|
+
control: true,
|
|
38
|
+
},
|
|
39
|
+
capacitor: {
|
|
40
|
+
nodes: ["a", "b"],
|
|
41
|
+
aux: 0,
|
|
42
|
+
ports: "none",
|
|
43
|
+
newton: false,
|
|
44
|
+
dynamic: true,
|
|
45
|
+
},
|
|
46
|
+
inductor: {
|
|
47
|
+
nodes: ["a", "b"],
|
|
48
|
+
aux: 0,
|
|
49
|
+
ports: "none",
|
|
50
|
+
newton: false,
|
|
51
|
+
dynamic: true,
|
|
52
|
+
},
|
|
53
|
+
switch: {
|
|
54
|
+
nodes: ["a", "b"],
|
|
55
|
+
aux: 0,
|
|
56
|
+
ports: "none",
|
|
57
|
+
newton: false,
|
|
58
|
+
control: true,
|
|
59
|
+
},
|
|
60
|
+
selector: {
|
|
61
|
+
nodes: ["common", "throwNode"],
|
|
62
|
+
aux: 0,
|
|
63
|
+
ports: "none",
|
|
64
|
+
newton: false,
|
|
65
|
+
control: true,
|
|
66
|
+
},
|
|
67
|
+
// A sine EMF is time-varying and linear: it differs between samples and is a constant
|
|
68
|
+
// within the system being solved at each one, exactly as the input source is.
|
|
69
|
+
"dc-source": {
|
|
70
|
+
nodes: ["positive", "negative"],
|
|
71
|
+
aux: 1,
|
|
72
|
+
ports: "none",
|
|
73
|
+
newton: false,
|
|
74
|
+
},
|
|
75
|
+
"ac-source": {
|
|
76
|
+
nodes: ["positive", "negative"],
|
|
77
|
+
aux: 1,
|
|
78
|
+
ports: "none",
|
|
79
|
+
newton: false,
|
|
80
|
+
},
|
|
81
|
+
"input-source": { nodes: ["node"], aux: 1, ports: "none", newton: false },
|
|
82
|
+
// A `coupled` port's write-back, same shape as `dc-source`: a same-sample source term,
|
|
83
|
+
// not a curve. The macro core it reads from is a delay line, which needs no Newton loop
|
|
84
|
+
// of its own either -- see couple.ts's header for why that stays true for this build.
|
|
85
|
+
"macro-audio-source": {
|
|
86
|
+
nodes: ["node"],
|
|
87
|
+
aux: 1,
|
|
88
|
+
ports: "none",
|
|
89
|
+
newton: false,
|
|
90
|
+
},
|
|
91
|
+
"logic-divider": {
|
|
92
|
+
nodes: ["clockNode", "qNode", "gndNode"],
|
|
93
|
+
aux: 1,
|
|
94
|
+
ports: "none",
|
|
95
|
+
newton: false,
|
|
96
|
+
dynamic: true,
|
|
97
|
+
},
|
|
98
|
+
// A VCCS is linear within a sample: transconductance couples the controlling input pair
|
|
99
|
+
// (inP, inN) to the output pair (outP, outN) across the Jacobian matrix.
|
|
100
|
+
vccs: {
|
|
101
|
+
nodes: ["outP", "outN", "inP", "inN"],
|
|
102
|
+
aux: 0,
|
|
103
|
+
ports: "none",
|
|
104
|
+
newton: false,
|
|
105
|
+
},
|
|
106
|
+
transformer: {
|
|
107
|
+
nodes: ["primaryPlus", "primaryMinus", "secondaryPlus", "secondaryMinus"],
|
|
108
|
+
aux: 1,
|
|
109
|
+
ports: "nodes-and-aux",
|
|
110
|
+
newton: false,
|
|
111
|
+
},
|
|
112
|
+
// A tank is stateful but not non-linear: within one sample it is a fixed conductance and a
|
|
113
|
+
// fixed Thevenin source. Its memory advances once per sample, after the solve. It still
|
|
114
|
+
// declares port rows, which is why `ports` and `newton` are separate facts here.
|
|
115
|
+
"spring-reverb": {
|
|
116
|
+
nodes: ["inputPlus", "inputMinus", "outputPlus", "outputMinus"],
|
|
117
|
+
aux: 1,
|
|
118
|
+
ports: "nodes",
|
|
119
|
+
newton: false,
|
|
120
|
+
dynamic: true,
|
|
121
|
+
},
|
|
122
|
+
// Rails make an op-amp saturate, which is the mode switch Newton is for. Without them it is
|
|
123
|
+
// a plain high-gain VCVS and the row stays linear.
|
|
124
|
+
"ideal-opamp": {
|
|
125
|
+
nodes: ["plus", "minus", "output"],
|
|
126
|
+
aux: 1,
|
|
127
|
+
ports: "railed-opamp",
|
|
128
|
+
newton: "railed-opamp",
|
|
129
|
+
},
|
|
130
|
+
diode: { nodes: ["anode", "cathode"], aux: 0, ports: "nodes", newton: true },
|
|
131
|
+
"tube-diode": {
|
|
132
|
+
nodes: ["plate", "cathode"],
|
|
133
|
+
aux: 0,
|
|
134
|
+
ports: "nodes",
|
|
135
|
+
newton: true,
|
|
136
|
+
},
|
|
137
|
+
bjt: {
|
|
138
|
+
nodes: ["base", "collector", "emitter"],
|
|
139
|
+
aux: 0,
|
|
140
|
+
ports: "nodes",
|
|
141
|
+
newton: true,
|
|
142
|
+
},
|
|
143
|
+
fet: {
|
|
144
|
+
nodes: ["gate", "drain", "source"],
|
|
145
|
+
aux: 0,
|
|
146
|
+
ports: "nodes",
|
|
147
|
+
newton: true,
|
|
148
|
+
},
|
|
149
|
+
triode: {
|
|
150
|
+
nodes: ["grid", "cathode", "plate"],
|
|
151
|
+
aux: 0,
|
|
152
|
+
ports: "nodes",
|
|
153
|
+
newton: true,
|
|
154
|
+
},
|
|
155
|
+
pentode: {
|
|
156
|
+
nodes: ["grid", "cathode", "plate", "screen"],
|
|
157
|
+
aux: 0,
|
|
158
|
+
ports: "nodes",
|
|
159
|
+
newton: true,
|
|
160
|
+
},
|
|
161
|
+
ota: {
|
|
162
|
+
nodes: ["plus", "minus", "bias", "output", "vee"],
|
|
163
|
+
aux: 0,
|
|
164
|
+
ports: "nodes",
|
|
165
|
+
newton: true,
|
|
166
|
+
},
|
|
167
|
+
optocoupler: {
|
|
168
|
+
nodes: ["ldrA", "ldrB", "ledAnode", "ledCathode"],
|
|
169
|
+
aux: 0,
|
|
170
|
+
ports: "nodes",
|
|
171
|
+
newton: true,
|
|
172
|
+
},
|
|
173
|
+
"analog-switch": {
|
|
174
|
+
nodes: ["a", "b", "control"],
|
|
175
|
+
aux: 0,
|
|
176
|
+
ports: "nodes",
|
|
177
|
+
newton: true,
|
|
178
|
+
},
|
|
179
|
+
compandor: {
|
|
180
|
+
nodes: ["rectIn", "rectCap", "cellIn", "sumNode", "vref"],
|
|
181
|
+
aux: 0,
|
|
182
|
+
ports: "nodes",
|
|
183
|
+
newton: true,
|
|
184
|
+
dynamic: true,
|
|
185
|
+
},
|
|
186
|
+
// Owns three consecutive auxiliary rows, which its matrix square covers but its port rows
|
|
187
|
+
// deliberately do not.
|
|
188
|
+
"clock-driver": {
|
|
189
|
+
nodes: ["cp1", "cp2", "vgg", "vdd", "ox1", "gnd"],
|
|
190
|
+
aux: 3,
|
|
191
|
+
ports: "nodes",
|
|
192
|
+
newton: true,
|
|
193
|
+
},
|
|
194
|
+
comparator: {
|
|
195
|
+
nodes: ["plus", "minus", "output", "vee"],
|
|
196
|
+
aux: 0,
|
|
197
|
+
ports: "nodes",
|
|
198
|
+
newton: true,
|
|
199
|
+
},
|
|
200
|
+
"linear-vca": {
|
|
201
|
+
nodes: ["plus", "minus", "output", "control"],
|
|
202
|
+
aux: 0,
|
|
203
|
+
ports: "nodes",
|
|
204
|
+
newton: true,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
/** The shape entry for a stamp, with the table's per-kind literal types widened away. */
|
|
208
|
+
export function stampShape(stamp) {
|
|
209
|
+
return STAMP_SHAPES[stamp.kind];
|
|
210
|
+
}
|
|
211
|
+
/** Read a named node field off a stamp. */
|
|
212
|
+
export function stampNodeValue(stamp, field) {
|
|
213
|
+
return stamp[field];
|
|
214
|
+
}
|
|
215
|
+
/** The auxiliary rows a stamp owns, as absolute row indices. */
|
|
216
|
+
export function stampAuxRows(stamp, nodeCount) {
|
|
217
|
+
const shape = stampShape(stamp);
|
|
218
|
+
if (shape.aux === 0)
|
|
219
|
+
return [];
|
|
220
|
+
const base = nodeCount + (stamp.sourceIndex ?? 0);
|
|
221
|
+
return Array.from({ length: shape.aux }, (_, offset) => base + offset);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Rewrite a stamp's node fields through `row`.
|
|
225
|
+
*
|
|
226
|
+
* The spread reassigns keys the stamp already carries, so their position in the object is
|
|
227
|
+
* unchanged -- which matters because a lowered stamp is serialised into the emitted program
|
|
228
|
+
* and key order is part of those bytes.
|
|
229
|
+
*/
|
|
230
|
+
export function remapStampNodes(stamp, row) {
|
|
231
|
+
const remapped = { ...stamp };
|
|
232
|
+
for (const field of stampShape(stamp).nodes) {
|
|
233
|
+
remapped[field] = row(stampNodeValue(stamp, field));
|
|
234
|
+
}
|
|
235
|
+
return remapped;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Does this stamp have to be re-evaluated inside a Newton loop?
|
|
239
|
+
*
|
|
240
|
+
* **The stamp-level twin of `partition.ts`'s `lawNeedsNewton`, and deliberately a second fact
|
|
241
|
+
* rather than a reuse of the first.** A law and its stamps are not the same list -- a jack's
|
|
242
|
+
* `port-engage` law lowers to a plain `conductance`, an `ac-source` law lowers to two stamps,
|
|
243
|
+
* an `open` law lowers to none -- and what a solver has to do is decided by what is in the
|
|
244
|
+
* block, not by what was in the document. `Block.linear` is read by the runtime to choose
|
|
245
|
+
* between one pass and an iteration cap, so it has to describe the stamps it will evaluate.
|
|
246
|
+
*
|
|
247
|
+
* The two mistakes are not symmetric, which is why the table has to be exhaustive. Calling a
|
|
248
|
+
* linear stamp nonlinear costs a few iterations; calling a nonlinear stamp linear makes
|
|
249
|
+
* `iterate` run one pass, evaluate the curve once from a zero start, and emit that as a solved
|
|
250
|
+
* answer -- no held sample, no telemetry, no diagnostic.
|
|
251
|
+
*/
|
|
252
|
+
export function stampNeedsNewton(stamp) {
|
|
253
|
+
const { newton } = stampShape(stamp);
|
|
254
|
+
if (newton === "railed-opamp") {
|
|
255
|
+
return stamp.railHigh !== null;
|
|
256
|
+
}
|
|
257
|
+
return newton;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Which runtime control moves a stamp's value, or `null` when it is constant.
|
|
261
|
+
*
|
|
262
|
+
* Read off the shape table's `control` flag. A stamp missing that flag would silently make a
|
|
263
|
+
* block look `controlFree`, and step 4's whole promise is that such a block's matrix is
|
|
264
|
+
* constant -- so the omission would be a factorisation frozen against a knob that still moves.
|
|
265
|
+
*/
|
|
266
|
+
export function stampControl(stamp) {
|
|
267
|
+
return stampShape(stamp).control === true
|
|
268
|
+
? (stamp.control ?? null)
|
|
269
|
+
: null;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Which rows a stamp's device law actually writes into the Jacobian / RHS, or `null` when the
|
|
273
|
+
* stamp writes none.
|
|
274
|
+
*
|
|
275
|
+
* Read off the shape table's `ports`, which is a **separate fact from `newton`** and not a
|
|
276
|
+
* synonym for it. `transformer` and `spring-reverb` are both linear within a sample yet
|
|
277
|
+
* declare port rows, so deriving this from `stampNeedsNewton` would drop them.
|
|
278
|
+
*
|
|
279
|
+
* The returned order is not significant: `computeStampPartition` feeds these into a `Set` and
|
|
280
|
+
* sorts it.
|
|
281
|
+
*/
|
|
282
|
+
export function stampPortRows(stamp, nodeCount) {
|
|
283
|
+
const shape = stampShape(stamp);
|
|
284
|
+
if (shape.ports === "none")
|
|
285
|
+
return null;
|
|
286
|
+
if (shape.ports === "railed-opamp" &&
|
|
287
|
+
stamp.railHigh === null) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const rows = shape.nodes.map((field) => stampNodeValue(stamp, field));
|
|
291
|
+
return shape.ports === "nodes"
|
|
292
|
+
? rows
|
|
293
|
+
: [...rows, ...stampAuxRows(stamp, nodeCount)];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Whether a stamp carries dynamic/reactive state (e.g. companion state across time steps).
|
|
297
|
+
*/
|
|
298
|
+
export function stampIsDynamic(stamp) {
|
|
299
|
+
return stampShape(stamp).dynamic === true;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Compute the complete stamp partition for an MNA block.
|
|
303
|
+
*/
|
|
304
|
+
export function computeStampPartition(stamps, nodeCount) {
|
|
305
|
+
const ports = new Set();
|
|
306
|
+
const linearStampIndices = [];
|
|
307
|
+
const nonlinearStampIndices = [];
|
|
308
|
+
const constantStampIndices = [];
|
|
309
|
+
const controlStampIndices = [];
|
|
310
|
+
const dynamicStampIndices = [];
|
|
311
|
+
for (let index = 0; index < stamps.length; index += 1) {
|
|
312
|
+
const stamp = stamps[index];
|
|
313
|
+
const rows = stampPortRows(stamp, nodeCount);
|
|
314
|
+
const isLinear = rows === null;
|
|
315
|
+
if (isLinear) {
|
|
316
|
+
linearStampIndices.push(index);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
nonlinearStampIndices.push(index);
|
|
320
|
+
for (const row of rows) {
|
|
321
|
+
if (row !== 0) {
|
|
322
|
+
ports.add(row);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const isControl = stampControl(stamp) !== null;
|
|
327
|
+
if (isControl) {
|
|
328
|
+
controlStampIndices.push(index);
|
|
329
|
+
}
|
|
330
|
+
const isDynamic = stampIsDynamic(stamp);
|
|
331
|
+
if (isDynamic) {
|
|
332
|
+
dynamicStampIndices.push(index);
|
|
333
|
+
}
|
|
334
|
+
const isSignalSource = stamp.kind === "input-source" ||
|
|
335
|
+
stamp.kind === "macro-audio-source" ||
|
|
336
|
+
stamp.kind === "ac-source";
|
|
337
|
+
if (isLinear && !isControl && !isDynamic && !isSignalSource) {
|
|
338
|
+
constantStampIndices.push(index);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Auxiliary rows owned by sources whose non-ground terminals are all in `ports` have no
|
|
342
|
+
// off-diagonal coupling into the linear interior `L`. Leaving such an aux row in `L` creates an
|
|
343
|
+
// all-zero row in `M_lin[L][L]` when source resistance is zero, making `M_lin[L][L]` singular
|
|
344
|
+
// and dropping the source excitation. Promoting the aux row to `ports` couples it directly to
|
|
345
|
+
// the port equations.
|
|
346
|
+
for (const stamp of stamps) {
|
|
347
|
+
const auxRows = stampAuxRows(stamp, nodeCount);
|
|
348
|
+
if (auxRows.length === 0)
|
|
349
|
+
continue;
|
|
350
|
+
const nodes = stampShape(stamp).nodes.map((f) => stampNodeValue(stamp, f));
|
|
351
|
+
const nonGroundNodes = nodes.filter((n) => n !== 0);
|
|
352
|
+
if (nonGroundNodes.length > 0 &&
|
|
353
|
+
nonGroundNodes.every((n) => ports.has(n))) {
|
|
354
|
+
for (const aux of auxRows) {
|
|
355
|
+
ports.add(aux);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
portRows: [...ports].sort((a, b) => a - b),
|
|
361
|
+
linearStampIndices,
|
|
362
|
+
nonlinearStampIndices,
|
|
363
|
+
constantStampIndices,
|
|
364
|
+
controlStampIndices,
|
|
365
|
+
dynamicStampIndices,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Thresholds for solving a block by eliminating its linear interior and iterating only the
|
|
370
|
+
* nonlinear port rows (the runtime's Schur-complement path).
|
|
371
|
+
*
|
|
372
|
+
* All three must hold, and they are a cost model rather than a correctness rule -- eliminating
|
|
373
|
+
* a block that fails them is still a correct solve, just a slower one. The ratio says the
|
|
374
|
+
* interior is worth removing at all, the floor keeps the extra bookkeeping off small blocks,
|
|
375
|
+
* and the cubic saving estimates the dense-factorisation work actually avoided.
|
|
376
|
+
*/
|
|
377
|
+
const ELIMINATE_MIN_UNKNOWN_RATIO = 2.4;
|
|
378
|
+
const ELIMINATE_MIN_UNKNOWNS = 12;
|
|
379
|
+
/**
|
|
380
|
+
* **Per BLOCK, and typed so it cannot be compared against a per-packet figure.** A prediction
|
|
381
|
+
* stated in these units was measured in packet units on 2026-09-11 and the resulting null was
|
|
382
|
+
* meaningless -- 84% of a block became 0.3% of a packet, and four independent checks passed it
|
|
383
|
+
* because each was correct at the level it was stated. The type now makes that comparison fail
|
|
384
|
+
* to compile rather than fail to be noticed.
|
|
385
|
+
*/
|
|
386
|
+
const ELIMINATE_MIN_ALGEBRAIC_SAVING = perBlock(5000);
|
|
387
|
+
/**
|
|
388
|
+
* Whether a block should carry the eliminated (Schur-complement) solve.
|
|
389
|
+
*
|
|
390
|
+
* Shared by `lower.ts`, which decides it when a region is first lowered, and `couple.ts`,
|
|
391
|
+
* which must re-decide it after adding a stamp. The two carried byte-identical copies of this
|
|
392
|
+
* predicate, so a threshold changed in one and not the other would have made a coupled block
|
|
393
|
+
* disagree with the same block uncoupled.
|
|
394
|
+
*/
|
|
395
|
+
export function shouldEliminate(unknowns, portRowCount, linear,
|
|
396
|
+
/**
|
|
397
|
+
* The document's `convergence-opt-in` flag. Where set, a nonlinear block with port rows is
|
|
398
|
+
* eliminated regardless of the cost rule -- it overrides the cost veto, but not the
|
|
399
|
+
* linear / zero-port guard above, which a portless or linear block cannot use elimination
|
|
400
|
+
* for at all.
|
|
401
|
+
*/
|
|
402
|
+
convergenceOptIn = false) {
|
|
403
|
+
if (linear || portRowCount === 0) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
if (convergenceOptIn) {
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
if (derivedAdmissionEnabled()) {
|
|
410
|
+
return derivedShouldEliminate(unknowns, portRowCount);
|
|
411
|
+
}
|
|
412
|
+
return (unknowns / portRowCount >= ELIMINATE_MIN_UNKNOWN_RATIO &&
|
|
413
|
+
unknowns >= ELIMINATE_MIN_UNKNOWNS &&
|
|
414
|
+
atLeast(perBlock(unknowns ** 3 - portRowCount ** 3), ELIMINATE_MIN_ALGEBRAIC_SAVING));
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* **The measured dense-versus-sparse penalty**, from the WASM console. First measured 2026-08-25
|
|
418
|
+
* on two matched-size pairs (`boss-ch-1`/`orange-gro100` at 85 unknowns, `boss-ce-5`/
|
|
419
|
+
* `mxr-carbon-copy` at ~100) and pinned at 1.9 with the caveat that it "should grow with size".
|
|
420
|
+
* The 2026-09-17 re-fit measured the on/off cost of the five large amps (72-119 unknowns) directly
|
|
421
|
+
* -- jcm800 1.41x, vox 1.85x, peavey 2.57x, sunn 2.57x, rockerverb 2.98x -- and fitting
|
|
422
|
+
* `R = C (p/n)^b` to those gives **C = 7.2, b = 1.98 (R^2 = 0.79)**. The constant was ~4x too low
|
|
423
|
+
* (the "grows with size" direction was right) but the exponent is **~2, not the 1.5** the
|
|
424
|
+
* sparse-cost hypothesis predicted: the phase-2 cost regression is a too-low constant, not a
|
|
425
|
+
* size-dependent exponent. **Measured, not chosen** — which is the whole point of using it here.
|
|
426
|
+
*/
|
|
427
|
+
const MEASURED_DENSIFICATION = 7.2;
|
|
428
|
+
/**
|
|
429
|
+
* The derived admission rule, behind `VESSEL_DERIVED_ELIMINATION=1`.
|
|
430
|
+
*
|
|
431
|
+
* **Cost goes as unknowns² × nonlinear count** — fitted across ten packets with WASM-measured cost,
|
|
432
|
+
* `R² = 0.674`. Elimination replaces an `n`-unknown iterated system with a `p`-unknown one, and its
|
|
433
|
+
* own factorisation is prepare-time for a linear interior. What it costs per sample is
|
|
434
|
+
* **densification**: the port system is dense where the original may have been sparse. So:
|
|
435
|
+
*
|
|
436
|
+
* ```
|
|
437
|
+
* admit when MEASURED_DENSIFICATION * p² < n² i.e. n/p > sqrt(7.2) = 2.68
|
|
438
|
+
* ```
|
|
439
|
+
*
|
|
440
|
+
* **No free constant.** `7.2` is the measured on/off of the two solve paths at 72-119 unknowns and
|
|
441
|
+
* the exponent is fitted (~2); neither was chosen to admit or reject any particular packet — which
|
|
442
|
+
* is the failure this replaces. Lowering `2.4` until it admitted the three packets whose saving had
|
|
443
|
+
* been predicted would have made the prediction and the admission one choice, and no later
|
|
444
|
+
* measurement could have separated them.
|
|
445
|
+
*
|
|
446
|
+
* **`ELIMINATE_MIN_UNKNOWNS` is still consulted and is still hand-set.** The model has **no term
|
|
447
|
+
* for fixed per-block overhead**, and without one the inequality admits every block with any
|
|
448
|
+
* interior — 241 of 241, which is not a predicate. The floor stands in for that missing term, and
|
|
449
|
+
* the sample straddling it (15 admitted blocks below, 31 above) is designed to retire it: if a
|
|
450
|
+
* 7-unknown block predicted at 84% delivers nothing, the overhead is the whole saving at that size
|
|
451
|
+
* and the crossover **is** the floor, derived rather than chosen.
|
|
452
|
+
*/
|
|
453
|
+
export function derivedShouldEliminate(unknowns, portRowCount) {
|
|
454
|
+
if (portRowCount === 0) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
return (MEASURED_DENSIFICATION * portRowCount ** 2 < unknowns ** 2 &&
|
|
458
|
+
unknowns >= ELIMINATE_MIN_UNKNOWNS);
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Off by default, and deliberately so: enabling it changes the compiled program of a large share of
|
|
462
|
+
* the corpus, which moves all seven gates at once and would not localise a failure. It is measured
|
|
463
|
+
* on a registered sample spanning the prediction range first — see
|
|
464
|
+
* `artifacts/docs/validation/2026-09-11-what-actually-drives-cpu-cost.md`.
|
|
465
|
+
*/
|
|
466
|
+
function derivedAdmissionEnabled() {
|
|
467
|
+
// Guarded like the runtime's limiter trace: the compiler also runs in the browser, where
|
|
468
|
+
// `process` does not exist. A measurement-only switch does not earn a CompileOptions field
|
|
469
|
+
// threaded through lower.ts and couple.ts, so it stays an environment read.
|
|
470
|
+
return typeof process !== "undefined" && process.env?.VESSEL_DERIVED_ELIMINATION === "1";
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=stamp-partition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamp-partition.js","sourceRoot":"","sources":["../src/stamp-partition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Block, Program } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Read from the lowered `dc-source` stamps rather than the declared `rail`/`battery` devices,
|
|
4
|
+
* for the same reason `over-driven-node.ts` reads stamps: lowering is what collapses a
|
|
5
|
+
* redundant pair of supply declarations into one source, and the stamps are what the runtime
|
|
6
|
+
* executes and the deck is emitted from.
|
|
7
|
+
*
|
|
8
|
+
* Zero-volt sources are ignored. A `0 V` source is a ground tie, not a supply, and counting it
|
|
9
|
+
* would make an unpowered circuit look powered.
|
|
10
|
+
*
|
|
11
|
+
* **`dual-rail` is not the same as `positive-ground`, and conflating them would be the whole
|
|
12
|
+
* bug.** `klon-centaur` (`+9`, `+18`, `-9`) and `earthquaker-devices-plumes` (`+9`, `-9`) each
|
|
13
|
+
* derive a negative rail from a charge pump inside an ordinary center-negative pedal, so their
|
|
14
|
+
* *external* supply is the same as every other pedal's. What matters for a shared supply is
|
|
15
|
+
* whether a positive rail exists at all, which is why the chain rule below is stated that way
|
|
16
|
+
* and not as "positive-ground versus everything".
|
|
17
|
+
*/
|
|
18
|
+
export declare function supplyReference(blocks: readonly Block[]): Program["supplyReference"];
|
|
19
|
+
//# sourceMappingURL=supply-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supply-reference.d.ts","sourceRoot":"","sources":["../src/supply-reference.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,GACtB,OAAO,CAAC,iBAAiB,CAAC,CA6B5B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Which terminal of its supply a circuit references to ground.
|
|
2
|
+
//
|
|
3
|
+
// A pedal's DC jack is center-negative or center-positive, and **that convention is not an
|
|
4
|
+
// electrical fact this pipeline can read or needs to**: MNA solves node voltages against a
|
|
5
|
+
// reference node, so once the source says which node is the supply and what sign it carries,
|
|
6
|
+
// how the barrel is wired is invisible to the solve. Nothing in the corpus declares barrel
|
|
7
|
+
// polarity, and nothing here reads it.
|
|
8
|
+
//
|
|
9
|
+
// What *is* electrical is the **sign of the supply relative to ground**. A germanium PNP fuzz
|
|
10
|
+
// references the battery's positive terminal to ground and runs a negative rail — measured over
|
|
11
|
+
// the corpus, five packets do: `dallas-arbiter-fuzz-face-ac128`,
|
|
12
|
+
// `dallas-rangemaster-original-treble-booster`, `sola-sound-mki-tone-bender`,
|
|
13
|
+
// `sola-sound-tone-bender-professional-mkii`, and `maestro-fz-1a` at **-1.5 V**. Get that sign
|
|
14
|
+
// wrong and the PNP stages never reach conduction, which is silence rather than a wrong tone.
|
|
15
|
+
//
|
|
16
|
+
// The reason a program carries this at all is that it is the one supply fact a *chain* needs:
|
|
17
|
+
// two pedals on one physical supply must agree about which terminal is ground, and a chain of
|
|
18
|
+
// programs is where that can be checked (`src/runtime/supply-ground.ts`). It is not a
|
|
19
|
+
// simulation input — each program is solved against its own declared rails either way.
|
|
20
|
+
/**
|
|
21
|
+
* Read from the lowered `dc-source` stamps rather than the declared `rail`/`battery` devices,
|
|
22
|
+
* for the same reason `over-driven-node.ts` reads stamps: lowering is what collapses a
|
|
23
|
+
* redundant pair of supply declarations into one source, and the stamps are what the runtime
|
|
24
|
+
* executes and the deck is emitted from.
|
|
25
|
+
*
|
|
26
|
+
* Zero-volt sources are ignored. A `0 V` source is a ground tie, not a supply, and counting it
|
|
27
|
+
* would make an unpowered circuit look powered.
|
|
28
|
+
*
|
|
29
|
+
* **`dual-rail` is not the same as `positive-ground`, and conflating them would be the whole
|
|
30
|
+
* bug.** `klon-centaur` (`+9`, `+18`, `-9`) and `earthquaker-devices-plumes` (`+9`, `-9`) each
|
|
31
|
+
* derive a negative rail from a charge pump inside an ordinary center-negative pedal, so their
|
|
32
|
+
* *external* supply is the same as every other pedal's. What matters for a shared supply is
|
|
33
|
+
* whether a positive rail exists at all, which is why the chain rule below is stated that way
|
|
34
|
+
* and not as "positive-ground versus everything".
|
|
35
|
+
*/
|
|
36
|
+
export function supplyReference(blocks) {
|
|
37
|
+
let positive = false;
|
|
38
|
+
let negative = false;
|
|
39
|
+
for (const block of blocks) {
|
|
40
|
+
if (block.kind !== "mna") {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
for (const stamp of block.stamps) {
|
|
44
|
+
if (stamp.kind !== "dc-source") {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (stamp.volts > 0) {
|
|
48
|
+
positive = true;
|
|
49
|
+
}
|
|
50
|
+
if (stamp.volts < 0) {
|
|
51
|
+
negative = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (positive && negative) {
|
|
56
|
+
return "dual-rail";
|
|
57
|
+
}
|
|
58
|
+
if (positive) {
|
|
59
|
+
return "negative-ground";
|
|
60
|
+
}
|
|
61
|
+
if (negative) {
|
|
62
|
+
return "positive-ground";
|
|
63
|
+
}
|
|
64
|
+
return "unpowered";
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=supply-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supply-reference.js","sourceRoot":"","sources":["../src/supply-reference.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,2FAA2F;AAC3F,2FAA2F;AAC3F,6FAA6F;AAC7F,2FAA2F;AAC3F,uCAAuC;AACvC,EAAE;AACF,8FAA8F;AAC9F,gGAAgG;AAChG,iEAAiE;AACjE,8EAA8E;AAC9E,+FAA+F;AAC/F,8FAA8F;AAC9F,EAAE;AACF,8FAA8F;AAC9F,8FAA8F;AAC9F,sFAAsF;AACtF,uFAAuF;AAIvF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC9B,MAAwB;IAExB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAChC,SAAS;YACV,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACrB,QAAQ,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACrB,QAAQ,GAAG,IAAI,CAAC;YACjB,CAAC;QACF,CAAC;IACF,CAAC;IACD,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAC1B,OAAO,WAAW,CAAC;IACpB,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,iBAAiB,CAAC;IAC1B,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,iBAAiB,CAAC;IAC1B,CAAC;IACD,OAAO,WAAW,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Netlist, SupplyShortWarning } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* A diode whose **anode sits on a supply node and whose cathode sits on ground** is forward
|
|
4
|
+
* biased by the whole supply. In a real circuit that is a dead short: the junction conducts
|
|
5
|
+
* until something fails.
|
|
6
|
+
*
|
|
7
|
+
* The runtime does not diverge on it, which is why this went unseen. `DIODE_VOLTAGE_LIMIT` caps
|
|
8
|
+
* the junction voltage at `0.9 V` before the current is computed, so instead of running away the
|
|
9
|
+
* diode settles at about **1 A** — and the supply is an ideal source, so it simply sinks that
|
|
10
|
+
* current and the pedal renders a plausible level. `ibanez-ts808` renders a gain of `0.506` with
|
|
11
|
+
* a 1 A short on its rail. The clamp is a convergence device that turned out to be hiding a
|
|
12
|
+
* circuit defect, which is the same shape as several other masks found the same day.
|
|
13
|
+
*
|
|
14
|
+
* **Directness is required, and it is what makes this precise.** The check asks that the anode
|
|
15
|
+
* be *on* a node a `voltage-source` or `rail` device terminates, and the cathode be ground
|
|
16
|
+
* itself. An indicator LED fed through a series resistor does not match, because its anode sits
|
|
17
|
+
* on the resistor's node rather than the supply's — so the common legitimate arrangement is
|
|
18
|
+
* excluded by construction rather than by a special case.
|
|
19
|
+
*
|
|
20
|
+
* Measured over the pedal corpus: **6 diodes across 6 packets** match structurally, of which the
|
|
21
|
+
* two that compile carry `1.074 A` each. The other four are in the unsupported population, so
|
|
22
|
+
* they are flagged the moment their packets compile.
|
|
23
|
+
*
|
|
24
|
+
* The warning states the structure and the polarity, and does **not** claim the source is wrong.
|
|
25
|
+
* A protection diode reversed in the source and a protection diode this pipeline has mis-read
|
|
26
|
+
* look identical from here; what makes it reportable is that either way the compiled circuit
|
|
27
|
+
* contains a short. Checked on `ibanez-ts808`: the source itself declares `anode` on the 9 V
|
|
28
|
+
* node and `cathode` on ground, so the role reading is not at fault there — but that is a
|
|
29
|
+
* per-packet finding rather than something this stage should assert.
|
|
30
|
+
*/
|
|
31
|
+
export declare function findSupplyShorts(netlist: Netlist): readonly SupplyShortWarning[];
|
|
32
|
+
//# sourceMappingURL=supply-short.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supply-short.d.ts","sourceRoot":"","sources":["../src/supply-short.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAU,OAAO,EAAU,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAM3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAC/B,OAAO,EAAE,OAAO,GACd,SAAS,kBAAkB,EAAE,CAuD/B"}
|