Analog.Semiconductors.Tests.NPNSwitching ​
Saturated switching test for NPN, with use_advanced_continuation = true.
A 10 MHz square wave drives the base through 1 kΩ, overdriving the device well into saturation each half-cycle (Bf * I_B = 12 mA against a 5 mA collector-limited current). This exercises the parts of the charge model the DC benches never move:
the diffusion capacitances
C_DE/C_DC— storage delay on the falling base drive is set byTaur, visible as the collector holding low after the base drive is removed;the depletion capacitances through
der(V_BE)/der(V_BC), swinging with the junctions on every edge;the advanced continuation branch of
C_jC/C_jE, which starts the linear continuation atphi - Zinstead of zero bias — the branch that carries the fractional-power domain guard, compiled and integrated here.
rc.v tracks the collector current: square-ish with rounded storage-delayed edges.
Because use_advanced_continuation = true is not an MSL setting, this test has no MSL cross-validation — only a snapshot. Every other BJT test runs on pure defaults, which do reproduce MSL.
Usage ​
ElectricalComponents.Analog.Semiconductors.Tests.NPNSwitching()
Behavior ​
Source ​
"""
Saturated switching test for NPN, with `use_advanced_continuation = true`.
A 10 MHz square wave drives the base through 1 kΩ, overdriving the device
well into saturation each half-cycle (`Bf * I_B` = 12 mA against a 5 mA
collector-limited current). This exercises the parts of the charge model the
DC benches never move:
* the diffusion capacitances `C_DE`/`C_DC` — storage delay on the falling
base drive is set by `Taur`, visible as the collector holding low after
the base drive is removed;
* the depletion capacitances through `der(V_BE)`/`der(V_BC)`, swinging with
the junctions on every edge;
* the **advanced continuation** branch of `C_jC`/`C_jE`, which starts the
linear continuation at `phi - Z` instead of zero bias — the branch that
carries the fractional-power domain guard, compiled and integrated here.
`rc.v` tracks the collector current: square-ish with rounded storage-delayed
edges.
Because `use_advanced_continuation = true` is not an MSL setting, this test has no MSL
cross-validation — only a snapshot. Every other BJT test runs on pure defaults, which do
reproduce MSL.
"""
test component NPNSwitching
"Supply rail level (5 V)"
supply_lvl = BlockComponents.Sources.Constant(k = 5) {
"Dyad": {"placement": {"diagram": {"x1": 20, "x2": 120, "y1": 220, "y2": 320}}}
}
"Collector supply"
supply = ElectricalComponents.Analog.Sources.VoltageSource() {
"Dyad": {"placement": {"diagram": {"x1": 155, "x2": 255, "y1": 335, "y2": 435}}}
}
"Base drive: 0 to 1 V square wave at 10 MHz"
bias_sig = BlockComponents.Sources.Square(amplitude = 0.5, offset = 0.5, frequency = 1e7) {
"Dyad": {"placement": {"diagram": {"x1": 150, "x2": 250, "y1": 120, "y2": 220}}}
}
"Base drive source"
bias = ElectricalComponents.Analog.Sources.VoltageSource() {
"Dyad": {"placement": {"diagram": {"x1": 285, "x2": 385, "y1": 235, "y2": 335}}}
}
"Base series resistance (1 kΩ); sets the overdrive"
rb = ElectricalComponents.Analog.Basic.Resistor(R = 1000) {
"Dyad": {"placement": {"diagram": {"x1": 415, "x2": 515, "y1": 130, "y2": 230}}}
}
"Collector load resistor (1 kΩ)"
rc = ElectricalComponents.Analog.Basic.Resistor(R = 1000) {
"Dyad": {"placement": {"diagram": {"x1": 285, "x2": 385, "y1": 20, "y2": 120}}}
}
"Transistor under test, advanced junction-capacitance continuation"
q = ElectricalComponents.Analog.Semiconductors.NPN(use_advanced_continuation = true) {
"Dyad": {"placement": {"diagram": {"x1": 545, "x2": 645, "y1": 130, "y2": 230}}}
}
"Ground reference"
ground = ElectricalComponents.Analog.Basic.Ground() {
"Dyad": {"placement": {"diagram": {"x1": 415, "x2": 515, "y1": 340, "y2": 440}}}
}
relations
"Drive starts high mid-square-wave; junctions discharged, collector at the rail"
initial q.V_BE = 0
initial q.V_CS = 5
connect(supply_lvl.y, supply.V) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 205, "y": 270}], "E": 2}], "path": {}}}
connect(bias_sig.y, bias.V) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 335, "y": 170}], "E": 2}], "path": {}}}
connect(supply.p, rc.p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 385}, {"x": 140, "y": 70}], "E": 2}],
"path": {}
}
}
connect(rc.n, q.c) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 595, "y": 70}], "E": 2}], "path": {}}}
connect(bias.p, rb.p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 270, "y": 285}, {"x": 270, "y": 180}], "E": 2}],
"path": {}
}
}
connect(rb.n, q.b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
connect(q.e, q.s, supply.n, bias.n, ground.g) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 595, "y": 245}, {"x": 660, "y": 245}, {"x": 660, "y": 180}],
"E": 2
},
{
"S": 2,
"M": [{"x": 670, "y": 180}, {"x": 670, "y": 490}, {"x": 270, "y": 490}],
"E": -1
},
{"S": -1, "M": [], "E": 3},
{"S": -1, "M": [{"x": 400, "y": 385}], "E": -2},
{"S": -2, "M": [], "E": 4},
{"S": -2, "M": [{"x": 465, "y": 285}], "E": 5}
],
"junctions": [{"x": 270, "y": 385}, {"x": 400, "y": 285}],
"path": {}
}
}
metadata {
"Dyad": {
"tests": {
"case1": {
"stop": 5e-7,
"abstol": 1e-10,
"reltol": 1e-8,
"rtol": {"q.V_BE": 0.00001, "rc.v": 0.00001},
"expect": {"signals": ["q.V_BE", "rc.v"]}
}
}
}
}
endFlattened Source
"""
Saturated switching test for NPN, with `use_advanced_continuation = true`.
A 10 MHz square wave drives the base through 1 kΩ, overdriving the device
well into saturation each half-cycle (`Bf * I_B` = 12 mA against a 5 mA
collector-limited current). This exercises the parts of the charge model the
DC benches never move:
* the diffusion capacitances `C_DE`/`C_DC` — storage delay on the falling
base drive is set by `Taur`, visible as the collector holding low after
the base drive is removed;
* the depletion capacitances through `der(V_BE)`/`der(V_BC)`, swinging with
the junctions on every edge;
* the **advanced continuation** branch of `C_jC`/`C_jE`, which starts the
linear continuation at `phi - Z` instead of zero bias — the branch that
carries the fractional-power domain guard, compiled and integrated here.
`rc.v` tracks the collector current: square-ish with rounded storage-delayed
edges.
Because `use_advanced_continuation = true` is not an MSL setting, this test has no MSL
cross-validation — only a snapshot. Every other BJT test runs on pure defaults, which do
reproduce MSL.
"""
test component NPNSwitching
"Supply rail level (5 V)"
supply_lvl = BlockComponents.Sources.Constant(k = 5) {
"Dyad": {"placement": {"diagram": {"x1": 20, "x2": 120, "y1": 220, "y2": 320}}}
}
"Collector supply"
supply = ElectricalComponents.Analog.Sources.VoltageSource() {
"Dyad": {"placement": {"diagram": {"x1": 155, "x2": 255, "y1": 335, "y2": 435}}}
}
"Base drive: 0 to 1 V square wave at 10 MHz"
bias_sig = BlockComponents.Sources.Square(amplitude = 0.5, offset = 0.5, frequency = 1e7) {
"Dyad": {"placement": {"diagram": {"x1": 150, "x2": 250, "y1": 120, "y2": 220}}}
}
"Base drive source"
bias = ElectricalComponents.Analog.Sources.VoltageSource() {
"Dyad": {"placement": {"diagram": {"x1": 285, "x2": 385, "y1": 235, "y2": 335}}}
}
"Base series resistance (1 kΩ); sets the overdrive"
rb = ElectricalComponents.Analog.Basic.Resistor(R = 1000) {
"Dyad": {"placement": {"diagram": {"x1": 415, "x2": 515, "y1": 130, "y2": 230}}}
}
"Collector load resistor (1 kΩ)"
rc = ElectricalComponents.Analog.Basic.Resistor(R = 1000) {
"Dyad": {"placement": {"diagram": {"x1": 285, "x2": 385, "y1": 20, "y2": 120}}}
}
"Transistor under test, advanced junction-capacitance continuation"
q = ElectricalComponents.Analog.Semiconductors.NPN(use_advanced_continuation = true) {
"Dyad": {"placement": {"diagram": {"x1": 545, "x2": 645, "y1": 130, "y2": 230}}}
}
"Ground reference"
ground = ElectricalComponents.Analog.Basic.Ground() {
"Dyad": {"placement": {"diagram": {"x1": 415, "x2": 515, "y1": 340, "y2": 440}}}
}
relations
"Drive starts high mid-square-wave; junctions discharged, collector at the rail"
initial q.V_BE = 0
initial q.V_CS = 5
connect(supply_lvl.y, supply.V) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 205, "y": 270}], "E": 2}], "path": {}}}
connect(bias_sig.y, bias.V) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 335, "y": 170}], "E": 2}], "path": {}}}
connect(supply.p, rc.p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 140, "y": 385}, {"x": 140, "y": 70}], "E": 2}],
"path": {}
}
}
connect(rc.n, q.c) {"Dyad": {"edges": [{"S": 1, "M": [{"x": 595, "y": 70}], "E": 2}], "path": {}}}
connect(bias.p, rb.p) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 270, "y": 285}, {"x": 270, "y": 180}], "E": 2}],
"path": {}
}
}
connect(rb.n, q.b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
connect(q.e, q.s, supply.n, bias.n, ground.g) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 595, "y": 245}, {"x": 660, "y": 245}, {"x": 660, "y": 180}],
"E": 2
},
{
"S": 2,
"M": [{"x": 670, "y": 180}, {"x": 670, "y": 490}, {"x": 270, "y": 490}],
"E": -1
},
{"S": -1, "M": [], "E": 3},
{"S": -1, "M": [{"x": 400, "y": 385}], "E": -2},
{"S": -2, "M": [], "E": 4},
{"S": -2, "M": [{"x": 465, "y": 285}], "E": 5}
],
"junctions": [{"x": 270, "y": 385}, {"x": 400, "y": 285}],
"path": {}
}
}
metadata {
"Dyad": {
"tests": {
"case1": {
"stop": 5e-7,
"abstol": 1e-10,
"reltol": 1e-8,
"rtol": {"q.V_BE": 0.00001, "rc.v": 0.00001},
"expect": {"signals": ["q.V_BE", "rc.v"]}
}
}
}
}
endTest Cases ​
Test Case case1 ​
pltplt