Skip to content
LIBRARY
Analog.Semiconductors.NPN.md

Analog.Semiconductors.NPN ​

NPN bipolar junction transistor, Ebers-Moll, translated from MSL.

Transport currents through the two junctions, with the Gbe/Gbc leakage shunts:

Terminal currents, with qbk = 1 - V_BC*Vak the Early factor:

Diffusion capacitances follow the transport currents; depletion capacitances use C_j0 * powlin(V/phi, M), linear above zero bias. MSL sums each pair into cbe/cbc; this model keeps them separate.

Temperature ​

With use_temperature_dependency = true:

The exponent is continued along its tangent outside [EMin, EMax]. With the flag false the thermal voltage is the fixed Vt parameter. XTB defaults to zero, so the betas do not drift unless asked.

Phic/Phie and the zero-bias depletion capacitances are not temperature-scaled, as in MSL. SPICE scales both.

Structural parameters ​

At their defaults these reproduce MSL exactly. use_Early is the one to watch: MSL applies the Early effect unconditionally, so true is the MSL-matching value.

parameterdefaultMSL
use_heat_portfalseConditionalHeatPort(useHeatPort = useTemperatureDependency)
use_temperature_dependencyfalseuseTemperatureDependency = false
use_Earlytrueno flag; qbk = 1 - vbc*Vak always applied
use_advanced_continuationfalseno flag; powlin() continues at zero bias

use_Early = false sets qbk = 1. use_advanced_continuation = true starts the depletion-capacitance continuation at Phi - Z instead of zero bias; only then do Z_C/Z_E enter the equations.

Divergences from MSL ​

Extra here: Z_C/Z_E with use_advanced_continuation; use_Early; use_heat_port separate from use_temperature_dependency (MSL ties them, so set both true to match).

Missing here: IC/UIC — Dyad states carry their own initial values; useSubstrate — Dyad has no conditional connectors, so s is always present. Tie s to ground for MSL's useSubstrate = false.

Every other parameter matches MSL in name and default.

Connectors ​

  • b base, c collector, e emitter, s substrate

  • port heat port, active when use_heat_port = true

Reference ​

Modelica.Electrical.Analog.Semiconductors.NPN, Modelica Standard Library, after Vlach & Singhal, Computer Methods for Circuit Analysis and Design (1983).

Usage ​

ElectricalComponents.Analog.Semiconductors.NPN(Bf=50.0, Br=0.1, Is=1.0e-16, Vak=0.02, Vt=0.02585, Phic=0.8, Phie=0.8, Z_C=0.1, Z_E=0.1, Tauf=0.12e-9, Taur=5.0e-9, Cjc=0.5e-12, Cje=0.4e-12, Ccs=1.0e-12, Mc=0.333, Me=0.4, Gbc=1.0e-15, Gbe=1.0e-15, NF=1.0, NR=1.0, Tnom=300.15, T=293.15, XTI=3.0, XTB=0.0, EG=1.11, EMin=-100.0, EMax=40.0, Cjc_Z=Cjc / (1 - (Phic - Z_C) / Phic) ^ Mc, Cje_Z=Cje / (1 - (Phie - Z_E) / Phie) ^ Me, dCjc_Z=Cjc * Mc * (1 - (Phic - Z_C) / Phic) ^ (-Mc - 1) / Phic, dCje_Z=Cje * Me * (1 - (Phie - Z_E) / Phie) ^ (-Me - 1) / Phie)

Parameters: ​

NameDescriptionUnitsDefault value
use_heat_portCouple to port; when false the device sits at the fixed temperature T and port must be left unconnected–false
use_temperature_dependencyScale Bf, Br, Is and the thermal voltage with temperature, MSL useTemperatureDependency–false
use_EarlyModel the Early effect (collector-base voltage modulation of the base width). MSL always applies it–true
use_advanced_continuationStart the junction-capacitance continuation at phi - Z instead of at zero bias–false
BfForward beta–50.0
BrReverse beta–0.1
IsSaturation current at TnomA1.0e-16
VakInverse Early voltage1/V0.02
VtThermal voltage, used when use_temperature_dependency = falseV0.02585
PhicCollector junction scaling factorV0.8
PhieEmitter junction scaling factorV0.8
Z_CCollector junction offset; no MSL counterpartV0.1
Z_EEmitter junction offset; no MSL counterpartV0.1
TaufForward transit times0.12e-9
TaurReverse transit times5.0e-9
CjcCollector-junction capacitance coefficientF0.5e-12
CjeEmitter-junction capacitance coefficientF0.4e-12
CcsCollector-substrate capacitanceF1.0e-12
McCollector junction exponent–0.333
MeEmitter junction exponent–0.4
GbcBase-collector leakage conductance, shunting the collector junctionS1.0e-15
GbeBase-emitter leakage conductance, shunting the emitter junctionS1.0e-15
NFForward ideality exponent–1.0
NRReverse ideality exponent–1.0
TnomParameter measurement temperature (SPICE Tnom)K300.15
TFixed device temperature, used when use_heat_port = false (SPICE TEMP)K293.15
XTITemperature exponent for the saturation current (SPICE XTI)–3.0
XTBForward and reverse beta temperature exponent (SPICE XTB); zero disables beta drift–0.0
EGEnergy gap governing the saturation-current temperature drift (SPICE EG)V1.11
EMinLower exponent bound; below this the exponential is continued along its tangent–-100.0
EMaxUpper exponent bound; above this the exponential is continued along its tangent–40.0

Connectors ​

  • b - This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)

  • c - This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)

  • e - This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)

  • s - This connector represents an electrical pin with voltage and current as the potential and flow variables, respectively. (Pin)

  • port - This connector represents a thermal port with temperature and heat flow as the potential and flow variables, respectively. (HeatPort)

Variables ​

NameDescriptionUnits
T_devDevice temperatureK
vt_tThermal voltage at the device temperatureV
Is_tSaturation current at the device temperatureA
Bf_tForward beta at the device temperature–
Br_tReverse beta at the device temperature–
hexpBandgap exponent for the saturation-current temperature drift–
htempexpClamped exponential of hexp–
V_BEBase-emitter voltageV
V_BCBase-collector voltageV
e_DEClamped exp(V_BE/(NF*vt_t))–
e_DCClamped exp(V_BC/(NR*vt_t))–
ICCForward transport currentA
IECReverse transport currentA
C_jCCollector depletion (junction) capacitanceF
C_jEEmitter depletion (junction) capacitanceF
C_DCCollector diffusion capacitanceF
C_DEEmitter diffusion capacitanceF
I_subSubstrate currentA
V_subSubstrate potentialV
V_CSCollector-substrate voltageV
qbkInverse relative majority-carrier base charge, i.e. the Early factor–
LossPowerPower dissipated in the deviceW

Behavior ​

Source ​

dyad
"""
NPN bipolar junction transistor, Ebers-Moll, translated from MSL.

Transport currents through the two junctions, with the `Gbe`/`Gbc` leakage shunts:
```math
I_{CC} = I_s \left( e^{V_{BE}/(N_F V_T)} - 1 \right) + V_{BE} G_{be}, \quad
I_{EC} = I_s \left( e^{V_{BC}/(N_R V_T)} - 1 \right) + V_{BC} G_{bc}
```
Terminal currents, with `qbk = 1 - V_BC*Vak` the Early factor:
```math
i_c = (I_{CC} - I_{EC})\, qbk - \frac{I_{EC}}{B_r}
      - (C_{jC} + C_{DC}) \dot V_{BC} - I_{sub}
```
```math
i_b = \frac{I_{EC}}{B_r} + \frac{I_{CC}}{B_f}
      + (C_{jC} + C_{DC}) \dot V_{BC} + (C_{jE} + C_{DE}) \dot V_{BE}, \qquad
i_e = -i_c - i_b - I_{sub}
```
Diffusion capacitances follow the transport currents; depletion capacitances use
`C_j0 * powlin(V/phi, M)`, linear above zero bias. MSL sums each pair into `cbe`/`cbc`;
this model keeps them separate.

## Temperature

With `use_temperature_dependency = true`:
```math
v_t = \frac{kT}{q}, \quad
I_s(T) = I_s \left(\frac{T}{T_{nom}}\right)^{XTI}
  e^{\frac{E_g}{v_t}\left(\frac{T}{T_{nom}} - 1\right)}, \quad
B_{f,r}(T) = B_{f,r} \left(\frac{T}{T_{nom}}\right)^{XTB}
```
The exponent is continued along its tangent outside `[EMin, EMax]`. With the flag false
the thermal voltage is the fixed `Vt` parameter. `XTB` defaults to zero, so the betas do
not drift unless asked.

`Phic`/`Phie` and the zero-bias depletion capacitances are **not** temperature-scaled,
as in MSL. SPICE scales both.

## Structural parameters

**At their defaults these reproduce MSL exactly.** `use_Early` is the one to watch:
MSL applies the Early effect unconditionally, so `true` is the MSL-matching value.

| parameter | default | MSL |
|---|---|---|
| `use_heat_port` | `false` | `ConditionalHeatPort(useHeatPort = useTemperatureDependency)` |
| `use_temperature_dependency` | `false` | `useTemperatureDependency = false` |
| `use_Early` | `true` | no flag; `qbk = 1 - vbc*Vak` always applied |
| `use_advanced_continuation` | `false` | no flag; `powlin()` continues at zero bias |

`use_Early = false` sets `qbk = 1`. `use_advanced_continuation = true` starts the
depletion-capacitance continuation at `Phi - Z` instead of zero bias; only then do
`Z_C`/`Z_E` enter the equations.

## Divergences from MSL

Extra here: `Z_C`/`Z_E` with `use_advanced_continuation`; `use_Early`; `use_heat_port`
separate from `use_temperature_dependency` (MSL ties them, so set both true to match).

Missing here: `IC`/`UIC` — Dyad states carry their own `initial` values; `useSubstrate` —
Dyad has no conditional connectors, so `s` is always present. Tie `s` to ground for
MSL's `useSubstrate = false`.

Every other parameter matches MSL in name and default.

## Connectors

  * `b` base, `c` collector, `e` emitter, `s` substrate
  * `port` heat port, active when `use_heat_port = true`

## Reference

`Modelica.Electrical.Analog.Semiconductors.NPN`, Modelica Standard Library, after
Vlach & Singhal, *Computer Methods for Circuit Analysis and Design* (1983).
"""
component NPN
  "Base pin"
  b = Pin() {"Dyad": {"placement": {"icon": {"x1": -50, "y1": 450, "x2": 50, "y2": 550}}}}
  "Collector pin"
  c = Pin() {"Dyad": {"placement": {"icon": {"x1": 450, "y1": -50, "x2": 550, "y2": 50}}}}
  "Emitter pin"
  e = Pin() {"Dyad": {"placement": {"icon": {"x1": 450, "y1": 950, "x2": 550, "y2": 1050}}}}
  "Substrate pin"
  s = Pin() {"Dyad": {"placement": {"icon": {"x1": 950, "y1": 450, "x2": 1050, "y2": 550}}}}
  "Heat port for thermal-electric simulation"
  port = HeatPort() {"Dyad": {"placement": {"icon": {"x1": -50, "y1": 750, "x2": 50, "y2": 850}}}}
  "Couple to `port`; when false the device sits at the fixed temperature `T` and `port` must be left unconnected"
  structural parameter use_heat_port::Boolean = false
  "Scale `Bf`, `Br`, `Is` and the thermal voltage with temperature, MSL `useTemperatureDependency`"
  structural parameter use_temperature_dependency::Boolean = false
  "Model the Early effect (collector-base voltage modulation of the base width). MSL always applies it"
  structural parameter use_Early::Boolean = true
  "Start the junction-capacitance continuation at `phi - Z` instead of at zero bias"
  structural parameter use_advanced_continuation::Boolean = false
  "Forward beta"
  parameter Bf::Real = 50.0
  "Reverse beta"
  parameter Br::Real = 0.1
  "Saturation current at `Tnom`"
  parameter Is::Current = 1.0e-16
  "Inverse Early voltage"
  parameter Vak::InversePotential = 0.02
  "Thermal voltage, used when `use_temperature_dependency = false`"
  parameter Vt::Voltage = 0.02585
  "Collector junction scaling factor"
  parameter Phic::Voltage = 0.8
  "Emitter junction scaling factor"
  parameter Phie::Voltage = 0.8
  "Collector junction offset; no MSL counterpart"
  parameter Z_C::Voltage = 0.1
  "Emitter junction offset; no MSL counterpart"
  parameter Z_E::Voltage = 0.1
  "Forward transit time"
  parameter Tauf::Time = 0.12e-9
  "Reverse transit time"
  parameter Taur::Time = 5.0e-9
  "Collector-junction capacitance coefficient"
  parameter Cjc::Capacitance = 0.5e-12
  "Emitter-junction capacitance coefficient"
  parameter Cje::Capacitance = 0.4e-12
  "Collector-substrate capacitance"
  parameter Ccs::Capacitance = 1.0e-12
  "Collector junction exponent"
  parameter Mc::Real = 0.333
  "Emitter junction exponent"
  parameter Me::Real = 0.4
  "Base-collector leakage conductance, shunting the collector junction"
  parameter Gbc::Conductance = 1.0e-15
  "Base-emitter leakage conductance, shunting the emitter junction"
  parameter Gbe::Conductance = 1.0e-15
  "Forward ideality exponent"
  parameter NF::Real = 1.0
  "Reverse ideality exponent"
  parameter NR::Real = 1.0
  "Parameter measurement temperature (SPICE Tnom)"
  parameter Tnom::Temperature = 300.15
  "Fixed device temperature, used when `use_heat_port = false` (SPICE `TEMP`)"
  parameter T::Temperature = 293.15
  "Temperature exponent for the saturation current (SPICE XTI)"
  parameter XTI::Real = 3.0
  "Forward and reverse beta temperature exponent (SPICE XTB); zero disables beta drift"
  parameter XTB::Real = 0.0
  "Energy gap governing the saturation-current temperature drift (SPICE EG)"
  parameter EG::Voltage = 1.11
  "Lower exponent bound; below this the exponential is continued along its tangent"
  parameter EMin::Real = -100.0
  "Upper exponent bound; above this the exponential is continued along its tangent"
  parameter EMax::Real = 40.0
  "Collector-junction capacitance at the advanced continuation point `Phic - Z_C`"
  final parameter Cjc_Z::Capacitance = Cjc / (1 - (Phic - Z_C) / Phic) ^ Mc
  "Emitter-junction capacitance at the advanced continuation point `Phie - Z_E`"
  final parameter Cje_Z::Capacitance = Cje / (1 - (Phie - Z_E) / Phie) ^ Me
  "Slope of the collector-junction capacitance at the advanced continuation point"
  final parameter dCjc_Z::Real(units = "F/V") = Cjc * Mc * (1 - (Phic - Z_C) / Phic) ^ (-Mc - 1) / Phic
  "Slope of the emitter-junction capacitance at the advanced continuation point"
  final parameter dCje_Z::Real(units = "F/V") = Cje * Me * (1 - (Phie - Z_E) / Phie) ^ (-Me - 1) / Phie
  "Device temperature"
  variable T_dev::Temperature
  "Thermal voltage at the device temperature"
  variable vt_t::Voltage
  "Saturation current at the device temperature"
  variable Is_t::Current
  "Forward beta at the device temperature"
  variable Bf_t::Real
  "Reverse beta at the device temperature"
  variable Br_t::Real
  "Bandgap exponent for the saturation-current temperature drift"
  variable hexp::Real
  "Clamped exponential of `hexp`"
  variable htempexp::Real
  "Base-emitter voltage"
  variable V_BE::Voltage
  "Base-collector voltage"
  variable V_BC::Voltage
  "Clamped `exp(V_BE/(NF*vt_t))`"
  variable e_DE::Real
  "Clamped `exp(V_BC/(NR*vt_t))`"
  variable e_DC::Real
  "Forward transport current"
  variable ICC::Current
  "Reverse transport current"
  variable IEC::Current
  "Collector depletion (junction) capacitance"
  variable C_jC::Capacitance
  "Emitter depletion (junction) capacitance"
  variable C_jE::Capacitance
  "Collector diffusion capacitance"
  variable C_DC::Capacitance
  "Emitter diffusion capacitance"
  variable C_DE::Capacitance
  "Substrate current"
  variable I_sub::Current
  "Substrate potential"
  variable V_sub::Voltage
  "Collector-substrate voltage"
  variable V_CS::Voltage
  "Inverse relative majority-carrier base charge, i.e. the Early factor"
  variable qbk::Real
  "Power dissipated in the device"
  variable LossPower::Power
relations
  assert(T_dev > 0.0, "NPN: device temperature must be positive")
  if use_heat_port
    T_dev = port.T
    port.Q_flow = -LossPower
  else
    T_dev = T
    port.T = T
    port.Q_flow = 0
  end
  "Junction voltages"
  V_BE = b.v - e.v
  V_BC = b.v - c.v
  """
  Temperature dependence, following SPICE. The saturation current scales as
  `(T/T_{nom})^{XTI} \\exp\\left(\\frac{E_g}{vt_t}\\left(\\frac{T}{T_{nom}} - 1\\right)\\right)`,
  which is the model-card form `(T/T_{nom})^{XTI} \\exp\\left(\\frac{E_g q}{k}
  \\left(\\frac{1}{T_{nom}} - \\frac{1}{T}\\right)\\right)`, and both betas scale
  as `(T/T_{nom})^{XTB}`.  At `T_dev = Tnom` every factor is exactly one, so the
  temperature model is inert at the default temperature.
  """
  if use_temperature_dependency
    vt_t = 8.617333262145179e-5 * T_dev
    Is_t = Is * (T_dev / Tnom) ^ XTI * htempexp
    Bf_t = Bf * (T_dev / Tnom) ^ XTB
    Br_t = Br * (T_dev / Tnom) ^ XTB
  else
    vt_t = Vt
    Is_t = Is
    Bf_t = Bf
    Br_t = Br
  end
  hexp = (T_dev / Tnom - 1) * EG / vt_t
  htempexp = ifelse(hexp < EMin, exp(EMin) * (1 + hexp - EMin), ifelse(hexp > EMax, exp(EMax) * (1 + hexp - EMax), exp(max(min(hexp, EMax), EMin))))
  """
  Junction exponentials, continued along their tangent outside
  `[EMin, EMax]`. Unclamped, `exp(V_BE/vt_t)` reaches 1e20 by `V_BE = 1.2 V` and
  overflows outright not far above, which Newton finds during initialization
  long before the circuit is anywhere near that bias.
  """
  e_DE = ifelse(V_BE / (NF * vt_t) < EMin, exp(EMin) * (1 + V_BE / (NF * vt_t) - EMin), ifelse(V_BE / (NF * vt_t) > EMax, exp(EMax) * (1 + V_BE / (NF * vt_t) - EMax), exp(max(min(V_BE / (NF * vt_t), EMax), EMin))))
  e_DC = ifelse(V_BC / (NR * vt_t) < EMin, exp(EMin) * (1 + V_BC / (NR * vt_t) - EMin), ifelse(V_BC / (NR * vt_t) > EMax, exp(EMax) * (1 + V_BC / (NR * vt_t) - EMax), exp(max(min(V_BC / (NR * vt_t), EMax), EMin))))
  "Ebers-Moll transport currents"
  ICC = Is_t * (e_DE - 1) + V_BE * Gbe
  IEC = Is_t * (e_DC - 1) + V_BC * Gbc
  """
  Depletion capacitances. The base of the power is floored at the value it
  takes where the branch is selected — `Z/phi` for the advanced continuation,
  `1` for the simple one — so it is a no-op wherever the branch is actually
  taken. Without it the *untaken* branch of the `ifelse` still evaluates, and a
  negative base to a fractional power raises a domain error: at the ordinary
  forward bias `V_BE = 1.0` with `Phie = 0.8` the base is `-0.25`.
  """
  if use_advanced_continuation
    C_jC = ifelse(V_BC > Phic - Z_C, dCjc_Z * (V_BC - (Phic - Z_C)) + Cjc_Z, Cjc / max(1 - V_BC / Phic, Z_C / Phic) ^ Mc)
    C_jE = ifelse(V_BE > Phie - Z_E, dCje_Z * (V_BE - (Phie - Z_E)) + Cje_Z, Cje / max(1 - V_BE / Phie, Z_E / Phie) ^ Me)
  else
    C_jC = ifelse(V_BC / Phic > 0, Cjc * (1 + Mc * V_BC / Phic), Cjc / max(1 - V_BC / Phic, 1.0) ^ Mc)
    C_jE = ifelse(V_BE / Phie > 0, Cje * (1 + Me * V_BE / Phie), Cje / max(1 - V_BE / Phie, 1.0) ^ Me)
  end
  "Diffusion capacitances"
  C_DE = Tauf * (Is_t / (NF * vt_t)) * e_DE
  C_DC = Taur * (Is_t / (NR * vt_t)) * e_DC
  "Collector-substrate capacitive coupling"
  V_sub = s.v
  V_CS = c.v - V_sub
  I_sub = -Ccs * der(V_CS)
  s.i = I_sub
  "Early factor: the collector-base voltage modulates the effective base width"
  if use_Early
    qbk = 1 - V_BC * Vak
  else
    qbk = 1
  end
  "Terminal currents"
  c.i = (ICC - IEC) * qbk - IEC / Br_t - (C_jC + C_DC) * der(V_BC) - I_sub
  b.i = IEC / Br_t + ICC / Bf_t + (C_jC + C_DC) * der(V_BC) + (C_jE + C_DE) * der(V_BE)
  e.i = -c.i - b.i - I_sub
  "Resistive dissipation: both junctions plus the transport current. Capacitive storage is not sent to the heat port"
  LossPower = V_BC * IEC / Br_t + V_BE * ICC / Bf_t + (ICC - IEC) * qbk * (c.v - e.v)
metadata {
  "Dyad": {
    "labels": [{"label": "$(instance)", "x": 500, "y": 1200, "rot": 0}],
    "icons": {"default": "dyad://ElectricalComponents/NPN.svg"}
  }
}
end
Flattened Source
dyad
"""
NPN bipolar junction transistor, Ebers-Moll, translated from MSL.

Transport currents through the two junctions, with the `Gbe`/`Gbc` leakage shunts:
```math
I_{CC} = I_s \left( e^{V_{BE}/(N_F V_T)} - 1 \right) + V_{BE} G_{be}, \quad
I_{EC} = I_s \left( e^{V_{BC}/(N_R V_T)} - 1 \right) + V_{BC} G_{bc}
```
Terminal currents, with `qbk = 1 - V_BC*Vak` the Early factor:
```math
i_c = (I_{CC} - I_{EC})\, qbk - \frac{I_{EC}}{B_r}
      - (C_{jC} + C_{DC}) \dot V_{BC} - I_{sub}
```
```math
i_b = \frac{I_{EC}}{B_r} + \frac{I_{CC}}{B_f}
      + (C_{jC} + C_{DC}) \dot V_{BC} + (C_{jE} + C_{DE}) \dot V_{BE}, \qquad
i_e = -i_c - i_b - I_{sub}
```
Diffusion capacitances follow the transport currents; depletion capacitances use
`C_j0 * powlin(V/phi, M)`, linear above zero bias. MSL sums each pair into `cbe`/`cbc`;
this model keeps them separate.

## Temperature

With `use_temperature_dependency = true`:
```math
v_t = \frac{kT}{q}, \quad
I_s(T) = I_s \left(\frac{T}{T_{nom}}\right)^{XTI}
  e^{\frac{E_g}{v_t}\left(\frac{T}{T_{nom}} - 1\right)}, \quad
B_{f,r}(T) = B_{f,r} \left(\frac{T}{T_{nom}}\right)^{XTB}
```
The exponent is continued along its tangent outside `[EMin, EMax]`. With the flag false
the thermal voltage is the fixed `Vt` parameter. `XTB` defaults to zero, so the betas do
not drift unless asked.

`Phic`/`Phie` and the zero-bias depletion capacitances are **not** temperature-scaled,
as in MSL. SPICE scales both.

## Structural parameters

**At their defaults these reproduce MSL exactly.** `use_Early` is the one to watch:
MSL applies the Early effect unconditionally, so `true` is the MSL-matching value.

| parameter | default | MSL |
|---|---|---|
| `use_heat_port` | `false` | `ConditionalHeatPort(useHeatPort = useTemperatureDependency)` |
| `use_temperature_dependency` | `false` | `useTemperatureDependency = false` |
| `use_Early` | `true` | no flag; `qbk = 1 - vbc*Vak` always applied |
| `use_advanced_continuation` | `false` | no flag; `powlin()` continues at zero bias |

`use_Early = false` sets `qbk = 1`. `use_advanced_continuation = true` starts the
depletion-capacitance continuation at `Phi - Z` instead of zero bias; only then do
`Z_C`/`Z_E` enter the equations.

## Divergences from MSL

Extra here: `Z_C`/`Z_E` with `use_advanced_continuation`; `use_Early`; `use_heat_port`
separate from `use_temperature_dependency` (MSL ties them, so set both true to match).

Missing here: `IC`/`UIC` — Dyad states carry their own `initial` values; `useSubstrate` —
Dyad has no conditional connectors, so `s` is always present. Tie `s` to ground for
MSL's `useSubstrate = false`.

Every other parameter matches MSL in name and default.

## Connectors

  * `b` base, `c` collector, `e` emitter, `s` substrate
  * `port` heat port, active when `use_heat_port = true`

## Reference

`Modelica.Electrical.Analog.Semiconductors.NPN`, Modelica Standard Library, after
Vlach & Singhal, *Computer Methods for Circuit Analysis and Design* (1983).
"""
component NPN
  "Base pin"
  b = Pin() {"Dyad": {"placement": {"icon": {"x1": -50, "y1": 450, "x2": 50, "y2": 550}}}}
  "Collector pin"
  c = Pin() {"Dyad": {"placement": {"icon": {"x1": 450, "y1": -50, "x2": 550, "y2": 50}}}}
  "Emitter pin"
  e = Pin() {"Dyad": {"placement": {"icon": {"x1": 450, "y1": 950, "x2": 550, "y2": 1050}}}}
  "Substrate pin"
  s = Pin() {"Dyad": {"placement": {"icon": {"x1": 950, "y1": 450, "x2": 1050, "y2": 550}}}}
  "Heat port for thermal-electric simulation"
  port = HeatPort() {"Dyad": {"placement": {"icon": {"x1": -50, "y1": 750, "x2": 50, "y2": 850}}}}
  "Couple to `port`; when false the device sits at the fixed temperature `T` and `port` must be left unconnected"
  structural parameter use_heat_port::Boolean = false
  "Scale `Bf`, `Br`, `Is` and the thermal voltage with temperature, MSL `useTemperatureDependency`"
  structural parameter use_temperature_dependency::Boolean = false
  "Model the Early effect (collector-base voltage modulation of the base width). MSL always applies it"
  structural parameter use_Early::Boolean = true
  "Start the junction-capacitance continuation at `phi - Z` instead of at zero bias"
  structural parameter use_advanced_continuation::Boolean = false
  "Forward beta"
  parameter Bf::Real = 50.0
  "Reverse beta"
  parameter Br::Real = 0.1
  "Saturation current at `Tnom`"
  parameter Is::Current = 1.0e-16
  "Inverse Early voltage"
  parameter Vak::InversePotential = 0.02
  "Thermal voltage, used when `use_temperature_dependency = false`"
  parameter Vt::Voltage = 0.02585
  "Collector junction scaling factor"
  parameter Phic::Voltage = 0.8
  "Emitter junction scaling factor"
  parameter Phie::Voltage = 0.8
  "Collector junction offset; no MSL counterpart"
  parameter Z_C::Voltage = 0.1
  "Emitter junction offset; no MSL counterpart"
  parameter Z_E::Voltage = 0.1
  "Forward transit time"
  parameter Tauf::Time = 0.12e-9
  "Reverse transit time"
  parameter Taur::Time = 5.0e-9
  "Collector-junction capacitance coefficient"
  parameter Cjc::Capacitance = 0.5e-12
  "Emitter-junction capacitance coefficient"
  parameter Cje::Capacitance = 0.4e-12
  "Collector-substrate capacitance"
  parameter Ccs::Capacitance = 1.0e-12
  "Collector junction exponent"
  parameter Mc::Real = 0.333
  "Emitter junction exponent"
  parameter Me::Real = 0.4
  "Base-collector leakage conductance, shunting the collector junction"
  parameter Gbc::Conductance = 1.0e-15
  "Base-emitter leakage conductance, shunting the emitter junction"
  parameter Gbe::Conductance = 1.0e-15
  "Forward ideality exponent"
  parameter NF::Real = 1.0
  "Reverse ideality exponent"
  parameter NR::Real = 1.0
  "Parameter measurement temperature (SPICE Tnom)"
  parameter Tnom::Temperature = 300.15
  "Fixed device temperature, used when `use_heat_port = false` (SPICE `TEMP`)"
  parameter T::Temperature = 293.15
  "Temperature exponent for the saturation current (SPICE XTI)"
  parameter XTI::Real = 3.0
  "Forward and reverse beta temperature exponent (SPICE XTB); zero disables beta drift"
  parameter XTB::Real = 0.0
  "Energy gap governing the saturation-current temperature drift (SPICE EG)"
  parameter EG::Voltage = 1.11
  "Lower exponent bound; below this the exponential is continued along its tangent"
  parameter EMin::Real = -100.0
  "Upper exponent bound; above this the exponential is continued along its tangent"
  parameter EMax::Real = 40.0
  "Collector-junction capacitance at the advanced continuation point `Phic - Z_C`"
  final parameter Cjc_Z::Capacitance = Cjc / (1 - (Phic - Z_C) / Phic) ^ Mc
  "Emitter-junction capacitance at the advanced continuation point `Phie - Z_E`"
  final parameter Cje_Z::Capacitance = Cje / (1 - (Phie - Z_E) / Phie) ^ Me
  "Slope of the collector-junction capacitance at the advanced continuation point"
  final parameter dCjc_Z::Real(units = "F/V") = Cjc * Mc * (1 - (Phic - Z_C) / Phic) ^ (-Mc - 1) / Phic
  "Slope of the emitter-junction capacitance at the advanced continuation point"
  final parameter dCje_Z::Real(units = "F/V") = Cje * Me * (1 - (Phie - Z_E) / Phie) ^ (-Me - 1) / Phie
  "Device temperature"
  variable T_dev::Temperature
  "Thermal voltage at the device temperature"
  variable vt_t::Voltage
  "Saturation current at the device temperature"
  variable Is_t::Current
  "Forward beta at the device temperature"
  variable Bf_t::Real
  "Reverse beta at the device temperature"
  variable Br_t::Real
  "Bandgap exponent for the saturation-current temperature drift"
  variable hexp::Real
  "Clamped exponential of `hexp`"
  variable htempexp::Real
  "Base-emitter voltage"
  variable V_BE::Voltage
  "Base-collector voltage"
  variable V_BC::Voltage
  "Clamped `exp(V_BE/(NF*vt_t))`"
  variable e_DE::Real
  "Clamped `exp(V_BC/(NR*vt_t))`"
  variable e_DC::Real
  "Forward transport current"
  variable ICC::Current
  "Reverse transport current"
  variable IEC::Current
  "Collector depletion (junction) capacitance"
  variable C_jC::Capacitance
  "Emitter depletion (junction) capacitance"
  variable C_jE::Capacitance
  "Collector diffusion capacitance"
  variable C_DC::Capacitance
  "Emitter diffusion capacitance"
  variable C_DE::Capacitance
  "Substrate current"
  variable I_sub::Current
  "Substrate potential"
  variable V_sub::Voltage
  "Collector-substrate voltage"
  variable V_CS::Voltage
  "Inverse relative majority-carrier base charge, i.e. the Early factor"
  variable qbk::Real
  "Power dissipated in the device"
  variable LossPower::Power
relations
  assert(T_dev > 0.0, "NPN: device temperature must be positive")
  if use_heat_port
    T_dev = port.T
    port.Q_flow = -LossPower
  else
    T_dev = T
    port.T = T
    port.Q_flow = 0
  end
  "Junction voltages"
  V_BE = b.v - e.v
  V_BC = b.v - c.v
  """
  Temperature dependence, following SPICE. The saturation current scales as
  `(T/T_{nom})^{XTI} \\exp\\left(\\frac{E_g}{vt_t}\\left(\\frac{T}{T_{nom}} - 1\\right)\\right)`,
  which is the model-card form `(T/T_{nom})^{XTI} \\exp\\left(\\frac{E_g q}{k}
  \\left(\\frac{1}{T_{nom}} - \\frac{1}{T}\\right)\\right)`, and both betas scale
  as `(T/T_{nom})^{XTB}`.  At `T_dev = Tnom` every factor is exactly one, so the
  temperature model is inert at the default temperature.
  """
  if use_temperature_dependency
    vt_t = 8.617333262145179e-5 * T_dev
    Is_t = Is * (T_dev / Tnom) ^ XTI * htempexp
    Bf_t = Bf * (T_dev / Tnom) ^ XTB
    Br_t = Br * (T_dev / Tnom) ^ XTB
  else
    vt_t = Vt
    Is_t = Is
    Bf_t = Bf
    Br_t = Br
  end
  hexp = (T_dev / Tnom - 1) * EG / vt_t
  htempexp = ifelse(hexp < EMin, exp(EMin) * (1 + hexp - EMin), ifelse(hexp > EMax, exp(EMax) * (1 + hexp - EMax), exp(max(min(hexp, EMax), EMin))))
  """
  Junction exponentials, continued along their tangent outside
  `[EMin, EMax]`. Unclamped, `exp(V_BE/vt_t)` reaches 1e20 by `V_BE = 1.2 V` and
  overflows outright not far above, which Newton finds during initialization
  long before the circuit is anywhere near that bias.
  """
  e_DE = ifelse(V_BE / (NF * vt_t) < EMin, exp(EMin) * (1 + V_BE / (NF * vt_t) - EMin), ifelse(V_BE / (NF * vt_t) > EMax, exp(EMax) * (1 + V_BE / (NF * vt_t) - EMax), exp(max(min(V_BE / (NF * vt_t), EMax), EMin))))
  e_DC = ifelse(V_BC / (NR * vt_t) < EMin, exp(EMin) * (1 + V_BC / (NR * vt_t) - EMin), ifelse(V_BC / (NR * vt_t) > EMax, exp(EMax) * (1 + V_BC / (NR * vt_t) - EMax), exp(max(min(V_BC / (NR * vt_t), EMax), EMin))))
  "Ebers-Moll transport currents"
  ICC = Is_t * (e_DE - 1) + V_BE * Gbe
  IEC = Is_t * (e_DC - 1) + V_BC * Gbc
  """
  Depletion capacitances. The base of the power is floored at the value it
  takes where the branch is selected — `Z/phi` for the advanced continuation,
  `1` for the simple one — so it is a no-op wherever the branch is actually
  taken. Without it the *untaken* branch of the `ifelse` still evaluates, and a
  negative base to a fractional power raises a domain error: at the ordinary
  forward bias `V_BE = 1.0` with `Phie = 0.8` the base is `-0.25`.
  """
  if use_advanced_continuation
    C_jC = ifelse(V_BC > Phic - Z_C, dCjc_Z * (V_BC - (Phic - Z_C)) + Cjc_Z, Cjc / max(1 - V_BC / Phic, Z_C / Phic) ^ Mc)
    C_jE = ifelse(V_BE > Phie - Z_E, dCje_Z * (V_BE - (Phie - Z_E)) + Cje_Z, Cje / max(1 - V_BE / Phie, Z_E / Phie) ^ Me)
  else
    C_jC = ifelse(V_BC / Phic > 0, Cjc * (1 + Mc * V_BC / Phic), Cjc / max(1 - V_BC / Phic, 1.0) ^ Mc)
    C_jE = ifelse(V_BE / Phie > 0, Cje * (1 + Me * V_BE / Phie), Cje / max(1 - V_BE / Phie, 1.0) ^ Me)
  end
  "Diffusion capacitances"
  C_DE = Tauf * (Is_t / (NF * vt_t)) * e_DE
  C_DC = Taur * (Is_t / (NR * vt_t)) * e_DC
  "Collector-substrate capacitive coupling"
  V_sub = s.v
  V_CS = c.v - V_sub
  I_sub = -Ccs * der(V_CS)
  s.i = I_sub
  "Early factor: the collector-base voltage modulates the effective base width"
  if use_Early
    qbk = 1 - V_BC * Vak
  else
    qbk = 1
  end
  "Terminal currents"
  c.i = (ICC - IEC) * qbk - IEC / Br_t - (C_jC + C_DC) * der(V_BC) - I_sub
  b.i = IEC / Br_t + ICC / Bf_t + (C_jC + C_DC) * der(V_BC) + (C_jE + C_DE) * der(V_BE)
  e.i = -c.i - b.i - I_sub
  "Resistive dissipation: both junctions plus the transport current. Capacitive storage is not sent to the heat port"
  LossPower = V_BC * IEC / Br_t + V_BE * ICC / Bf_t + (ICC - IEC) * qbk * (c.v - e.v)
metadata {
  "Dyad": {
    "labels": [{"label": "$(instance)", "x": 500, "y": 1200, "rot": 0}],
    "icons": {"default": "dyad://ElectricalComponents/NPN.svg"}
  }
}
end


Test Cases ​

No test cases defined.