diff options
author | 2019-03-26 11:13:37 +1100 | |
---|---|---|
committer | 2019-03-26 11:13:37 +1100 | |
commit | 97b67170277437131adf6ed4d60139c172529e4f (patch) | |
tree | 7a5cbf608f191075f1612b1af15832c206a3fe2d /src/lib/netlist/analog/nld_bjt.cpp | |
parent | b380514764cf857469bae61c11143a19f79a74c5 (diff) |
(nw) Clean up the mess on master
This effectively reverts b380514764cf857469bae61c11143a19f79a74c5 and
c24473ddff715ecec2e258a6eb38960cf8c8e98e, restoring the state at
598cd5227223c3b04ca31f0dbc1981256d9ea3ff.
Before pushing, please check that what you're about to push is sane.
Check your local commit log and ensure there isn't anything out-of-place
before pushing to mainline. When things like this happen, it wastes
everyone's time. I really don't need this in a week when real work⢠is
busting my balls and I'm behind where I want to be with preparing for
MAME release.
Diffstat (limited to 'src/lib/netlist/analog/nld_bjt.cpp')
-rw-r--r-- | src/lib/netlist/analog/nld_bjt.cpp | 632 |
1 files changed, 330 insertions, 302 deletions
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index 6f4a2db86bf..aef920635fe 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -5,47 +5,49 @@ * */ -#include "../solver/nld_solver.h" +#include "netlist/solver/nld_solver.h" +#include "netlist/nl_setup.h" #include "nlid_twoterm.h" -#include "../nl_setup.h" + #include <cmath> namespace netlist { - namespace analog - { - -class diode +namespace analog { -public: - diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {} - diode(const nl_double Is, const nl_double n) - { - m_Is = Is; - m_VT = 0.0258 * n; - m_VT_inv = 1.0 / m_VT; - } - void set(const nl_double Is, const nl_double n) - { - m_Is = Is; - m_VT = 0.0258 * n; - m_VT_inv = 1.0 / m_VT; - } - nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; } - nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); } - nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x) - nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); } + using constants = plib::constants<nl_double>; -private: - nl_double m_Is; - nl_double m_VT; - nl_double m_VT_inv; -}; + class diode + { + public: + diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {} + diode(const nl_double Is, const nl_double n) + { + m_Is = Is; + m_VT = 0.0258 * n; + m_VT_inv = 1.0 / m_VT; + } + void set(const nl_double Is, const nl_double n) + { + m_Is = Is; + m_VT = 0.0258 * n; + m_VT_inv = 1.0 / m_VT; + } + nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; } + nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); } + nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x) + nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); } + + private: + nl_double m_Is; + nl_double m_VT; + nl_double m_VT_inv; + }; -// ----------------------------------------------------------------------------- -// nld_Q - Base classes -// ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + // nld_Q - Base classes + // ----------------------------------------------------------------------------- /*! Class representing the bjt model paramers. * @@ -73,7 +75,7 @@ private: * | | RBM | minimum base resistance at high currents | | RB | 10 | * | * | | RE | emitter resistance | | 0 | 1 | * | * | | RC | collector resistance | | 0 | 10 | * | - * | | CJE | B-E zero-bias depletion capacitance | F | 0 | 2pF | * | + * | Y | CJE | B-E zero-bias depletion capacitance | F | 0 | 2pF | * | * | | VJE | B-E built-in potential | V | 0.75 | 0.6 | | * | | MJE | B-E junction exponential factor | - | 0.33 | 0.33 | | * | | TF | ideal forward transit time | sec | 0 | 0.1ns | | @@ -81,7 +83,7 @@ private: * | | VTF | voltage describing VBC dependence of TF | V | infinite | | | * | | ITF | high-current parameter for effect on TF | A | 0 | | * | * | | PTF | excess phase at freq=1.0/(TF*2PI) Hz | deg | 0 | | | - * | | CJC | B-C zero-bias depletion capacitance | F | 0 | 2pF | * | + * | Y | CJC | B-C zero-bias depletion capacitance | F | 0 | 2pF | * | * | | VJC | B-C built-in potential | V | 0.75 | 0.5 | | * | | MJC | B-C junction exponential factor | - | 0.33 | 0.5 | | * | | XCJC | fraction of B-C depletion capacitance connected to internal base node | - | 1 | | | @@ -95,343 +97,369 @@ private: * | | KF | flicker-noise coefficient | - | 0 | | | * | | AF | flicker-noise exponent | - | 1 | | | * | | FC | coefficient for forward-bias depletion capacitance formula | - | 0.5 | | | - * | | TNOM | Parameter measurement temperature | C | 27 | 50 | | */ + * | | TNOM | Parameter measurement temperature | C | 27 | 50 | | + * */ class bjt_model_t : public param_model_t { public: bjt_model_t(device_t &device, const pstring &name, const pstring &val) : param_model_t(device, name, val) - , m_IS(*this, "IS") - , m_BF(*this, "BF") - , m_NF(*this, "NF") - , m_BR(*this, "BR") - , m_NR(*this, "NR") + , m_IS (*this, "IS") + , m_BF (*this, "BF") + , m_NF (*this, "NF") + , m_BR (*this, "BR") + , m_NR (*this, "NR") + , m_CJE(*this, "CJE") + , m_CJC(*this, "CJC") {} - value_t m_IS; //!< transport saturation current - value_t m_BF; //!< ideal maximum forward beta - value_t m_NF; //!< forward current emission coefficient - value_t m_BR; //!< ideal maximum reverse beta - value_t m_NR; //!< reverse current emission coefficient + value_t m_IS; //!< transport saturation current + value_t m_BF; //!< ideal maximum forward beta + value_t m_NF; //!< forward current emission coefficient + value_t m_BR; //!< ideal maximum reverse beta + value_t m_NR; //!< reverse current emission coefficient + value_t m_CJE; //!< B-E zero-bias depletion capacitance + value_t m_CJC; //!< B-C zero-bias depletion capacitance + }; // Have a common start for transistors -NETLIB_OBJECT(Q) -{ -public: - enum q_type { - BJT_NPN, - BJT_PNP + NETLIB_OBJECT(Q) + { + public: + enum q_type { + BJT_NPN, + BJT_PNP + }; + + NETLIB_CONSTRUCTOR(Q) + , m_model(*this, "MODEL", "NPN") + , m_qtype(BJT_NPN) + { + } + + NETLIB_IS_DYNAMIC(true) + + //NETLIB_RESETI(); + NETLIB_UPDATEI(); + + q_type qtype() const { return m_qtype; } + bool is_qtype(q_type atype) const { return m_qtype == atype; } + void set_qtype(q_type atype) { m_qtype = atype; } + protected: + + bjt_model_t m_model; + private: + q_type m_qtype; }; - NETLIB_CONSTRUCTOR(Q) - , m_model(*this, "MODEL", "NPN") - , m_qtype(BJT_NPN) + NETLIB_OBJECT_DERIVED(QBJT, Q) { - } - - NETLIB_IS_DYNAMIC(true) - - //NETLIB_RESETI(); - NETLIB_UPDATEI(); + public: + NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q) + { } - inline q_type qtype() const { return m_qtype; } - inline bool is_qtype(q_type atype) const { return m_qtype == atype; } - inline void set_qtype(q_type atype) { m_qtype = atype; } -protected: + protected: - bjt_model_t m_model; -private: - q_type m_qtype; -}; + private: + }; -NETLIB_OBJECT_DERIVED(QBJT, Q) -{ -public: - NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q) - { } -protected: -private: -}; + // ----------------------------------------------------------------------------- + // nld_QBJT_switch + // ----------------------------------------------------------------------------- + /* + * + - C + * B ----VVV----+ | + * | | + * Rb Rc + * Rb Rc + * Rb Rc + * | | + * +----+----+ + * | + * E + */ -// ----------------------------------------------------------------------------- -// nld_QBJT_switch -// ----------------------------------------------------------------------------- + NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT) + { + NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT) + , m_RB(*this, "m_RB", true) + , m_RC(*this, "m_RC", true) + , m_BC_dummy(*this, "m_BC", true) + , m_gB(1e-9) + , m_gC(1e-9) + , m_V(0.0) + , m_state_on(*this, "m_state_on", 0) + { + register_subalias("B", m_RB.m_P); + register_subalias("E", m_RB.m_N); + register_subalias("C", m_RC.m_P); + //register_term("_E1", m_RC.m_N); + + //register_term("_B1", m_BC_dummy.m_P); + //register_term("_C1", m_BC_dummy.m_N); + + connect(m_RB.m_N, m_RC.m_N); + + connect(m_RB.m_P, m_BC_dummy.m_P); + connect(m_RC.m_P, m_BC_dummy.m_N); + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + NETLIB_UPDATE_PARAMI(); + NETLIB_UPDATE_TERMINALSI(); + + private: + nld_twoterm m_RB; + nld_twoterm m_RC; + + // FIXME: this is needed so we have all terminals belong to one net list + + nld_twoterm m_BC_dummy; + + nl_double m_gB; // base conductance / switch on + nl_double m_gC; // collector conductance / switch on + nl_double m_V; // internal voltage source + state_var<unsigned> m_state_on; + + private: + }; + // ----------------------------------------------------------------------------- + // nld_QBJT_EB + // ----------------------------------------------------------------------------- -/* - * + - C - * B ----VVV----+ | - * | | - * Rb Rc - * Rb Rc - * Rb Rc - * | | - * +----+----+ - * | - * E - */ -NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT) -{ - NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT) - , m_RB(*this, "m_RB", true) - , m_RC(*this, "m_RC", true) - , m_BC_dummy(*this, "m_BC", true) - , m_gB(NETLIST_GMIN_DEFAULT) - , m_gC(NETLIST_GMIN_DEFAULT) - , m_V(0.0) - , m_state_on(*this, "m_state_on", 0) + NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT) { - register_subalias("B", m_RB.m_P); - register_subalias("E", m_RB.m_N); - register_subalias("C", m_RC.m_P); - //register_term("_E1", m_RC.m_N); + public: + NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT) + , m_gD_BC(*this, "m_D_BC") + , m_gD_BE(*this, "m_D_BE") + , m_D_CB(*this, "m_D_CB", true) + , m_D_EB(*this, "m_D_EB", true) + , m_D_EC(*this, "m_D_EC", true) + , m_alpha_f(0) + , m_alpha_r(0) + { + register_subalias("E", m_D_EB.m_P); // Cathode + register_subalias("B", m_D_EB.m_N); // Anode + + register_subalias("C", m_D_CB.m_P); // Cathode + + connect(m_D_EB.m_P, m_D_EC.m_P); + connect(m_D_EB.m_N, m_D_CB.m_N); + connect(m_D_CB.m_P, m_D_EC.m_N); + + if (m_model.m_CJE > 0.0) + { + create_and_register_subdevice("m_CJE", m_CJE); + connect("B", "m_CJE.1"); + connect("E", "m_CJE.2"); + } + if (m_model.m_CJC > 0.0) + { + create_and_register_subdevice("m_CJC", m_CJC); + connect("B", "m_CJC.1"); + connect("C", "m_CJC.2"); + } + } + + protected: + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + NETLIB_UPDATE_PARAMI(); + NETLIB_UPDATE_TERMINALSI(); + + private: + generic_diode<diode_e::BIPOLAR> m_gD_BC; + generic_diode<diode_e::BIPOLAR> m_gD_BE; + + nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic + nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie + nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0 + + nl_double m_alpha_f; + nl_double m_alpha_r; + + NETLIB_SUBXX(analog, C) m_CJE; + NETLIB_SUBXX(analog, C) m_CJC; + }; - //register_term("_B1", m_BC_dummy.m_P); - //register_term("_C1", m_BC_dummy.m_N); - connect(m_RB.m_N, m_RC.m_N); + // ---------------------------------------------------------------------------------------- + // nld_Q + // ---------------------------------------------------------------------------------------- - connect(m_RB.m_P, m_BC_dummy.m_P); - connect(m_RC.m_P, m_BC_dummy.m_N); + NETLIB_UPDATE(Q) + { + // netlist().solver()->schedule1(); } - NETLIB_RESETI(); - NETLIB_UPDATEI(); - NETLIB_UPDATE_PARAMI(); - NETLIB_UPDATE_TERMINALSI(); - - nld_twoterm m_RB; - nld_twoterm m_RC; - - // FIXME: this is needed so we have all terminals belong to one net list + // ---------------------------------------------------------------------------------------- + // nld_QBJT_switch + // ---------------------------------------------------------------------------------------- - nld_twoterm m_BC_dummy; - -protected: + NETLIB_RESET(QBJT_switch) + { + NETLIB_NAME(Q)::reset(); - nl_double m_gB; // base conductance / switch on - nl_double m_gC; // collector conductance / switch on - nl_double m_V; // internal voltage source - state_var<unsigned> m_state_on; + m_state_on = 0; -private: -}; + m_RB.set_G_V_I(exec().gmin(), 0.0, 0.0); + m_RC.set_G_V_I(exec().gmin(), 0.0, 0.0); -// ----------------------------------------------------------------------------- -// nld_QBJT_EB -// ----------------------------------------------------------------------------- + m_BC_dummy.set_G_V_I(exec().gmin() / 10.0, 0.0, 0.0); + } -NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT) -{ -public: - NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT) - , m_gD_BC(*this, "m_D_BC") - , m_gD_BE(*this, "m_D_BE") - , m_D_CB(*this, "m_D_CB", true) - , m_D_EB(*this, "m_D_EB", true) - , m_D_EC(*this, "m_D_EC", true) - , m_alpha_f(0) - , m_alpha_r(0) + NETLIB_UPDATE(QBJT_switch) { - register_subalias("E", m_D_EB.m_P); // Cathode - register_subalias("B", m_D_EB.m_N); // Anode - - register_subalias("C", m_D_CB.m_P); // Cathode - //register_term("_B1", m_D_CB.m_N); // Anode - - //register_term("_E1", m_D_EC.m_P); - //register_term("_C1", m_D_EC.m_N); - - connect(m_D_EB.m_P, m_D_EC.m_P); - connect(m_D_EB.m_N, m_D_CB.m_N); - connect(m_D_CB.m_P, m_D_EC.m_N); + if (!m_RB.m_P.net().isRailNet()) + m_RB.m_P.solve_now(); // Basis + else if (!m_RB.m_N.net().isRailNet()) + m_RB.m_N.solve_now(); // Emitter + else if (!m_RC.m_P.net().isRailNet()) + m_RC.m_P.solve_now(); // Collector } -protected: - - NETLIB_RESETI(); - NETLIB_UPDATEI(); - NETLIB_UPDATE_PARAMI(); - NETLIB_UPDATE_TERMINALSI(); - - generic_diode m_gD_BC; - generic_diode m_gD_BE; - -private: - nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic - nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie - nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0 - - nl_double m_alpha_f; - nl_double m_alpha_r; - -}; - - -// ---------------------------------------------------------------------------------------- -// nld_Q -// ---------------------------------------------------------------------------------------- - -NETLIB_UPDATE(Q) -{ -// netlist().solver()->schedule1(); -} - -// ---------------------------------------------------------------------------------------- -// nld_QBJT_switch -// ---------------------------------------------------------------------------------------- - - -NETLIB_RESET(QBJT_switch) -{ - NETLIB_NAME(Q)::reset(); - m_state_on = 0; - - m_RB.set(netlist().gmin(), 0.0, 0.0); - m_RC.set(netlist().gmin(), 0.0, 0.0); - - m_BC_dummy.set(netlist().gmin() / 10.0, 0.0, 0.0); - -} + NETLIB_UPDATE_PARAM(QBJT_switch) + { + nl_double IS = m_model.m_IS; + nl_double BF = m_model.m_BF; + nl_double NF = m_model.m_NF; + //nl_double VJE = m_model.dValue("VJE", 0.75); -NETLIB_UPDATE(QBJT_switch) -{ - if (!m_RB.m_P.net().isRailNet()) - m_RB.m_P.solve_now(); // Basis - else if (!m_RB.m_N.net().isRailNet()) - m_RB.m_N.solve_now(); // Emitter - else if (!m_RC.m_P.net().isRailNet()) - m_RC.m_P.solve_now(); // Collector -} + set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); + nl_double alpha = BF / (1.0 + BF); -NETLIB_UPDATE_PARAM(QBJT_switch) -{ - nl_double IS = m_model.m_IS; - nl_double BF = m_model.m_BF; - nl_double NF = m_model.m_NF; - //nl_double VJE = m_model.dValue("VJE", 0.75); + diode d(IS, NF); - set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); + // Assume 5mA Collector current for switch operation - nl_double alpha = BF / (1.0 + BF); + m_V = d.V(0.005 / alpha); - diode d(IS, NF); + /* Base current is 0.005 / beta + * as a rough estimate, we just scale the conductance down */ - // Assume 5mA Collector current for switch operation + m_gB = 1.0 / (m_V/(0.005 / BF)); - m_V = d.V(0.005 / alpha); + //m_gB = d.gI(0.005 / alpha); - /* Base current is 0.005 / beta - * as a rough estimate, we just scale the conductance down */ + if (m_gB < exec().gmin()) + m_gB = exec().gmin(); + m_gC = d.gI(0.005); // very rough estimate + } - m_gB = 1.0 / (m_V/(0.005 / BF)); + NETLIB_UPDATE_TERMINALS(QBJT_switch) + { + const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1); + + const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0; + if (m_state_on ^ new_state) + { + const nl_double gb = new_state ? m_gB : exec().gmin(); + const nl_double gc = new_state ? m_gC : exec().gmin(); + const nl_double v = new_state ? m_V * m : 0; + + m_RB.set_G_V_I(gb, v, 0.0); + m_RC.set_G_V_I(gc, 0.0, 0.0); + m_state_on = new_state; + } + } - //m_gB = d.gI(0.005 / alpha); - if (m_gB < netlist().gmin()) - m_gB = netlist().gmin(); - m_gC = d.gI(0.005); // very rough estimate -} + // ---------------------------------------------------------------------------------------- + // nld_Q - Ebers Moll + // ---------------------------------------------------------------------------------------- -NETLIB_UPDATE_TERMINALS(QBJT_switch) -{ - const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1); - const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0; - if (m_state_on ^ new_state) + NETLIB_UPDATE(QBJT_EB) { - const nl_double gb = new_state ? m_gB : netlist().gmin(); - const nl_double gc = new_state ? m_gC : netlist().gmin(); - const nl_double v = new_state ? m_V * m : 0; - - m_RB.set(gb, v, 0.0); - m_RC.set(gc, 0.0, 0.0); - m_state_on = new_state; + if (!m_D_EB.m_P.net().isRailNet()) + m_D_EB.m_P.solve_now(); // Basis + else if (!m_D_EB.m_N.net().isRailNet()) + m_D_EB.m_N.solve_now(); // Emitter + else + m_D_CB.m_N.solve_now(); // Collector } -} + NETLIB_RESET(QBJT_EB) + { + NETLIB_NAME(Q)::reset(); + if (m_CJE) + { + m_CJE->reset(); + m_CJE->m_C.setTo(m_model.m_CJE); + } + if (m_CJC) + { + m_CJC->reset(); + m_CJC->m_C.setTo(m_model.m_CJC); + } -// ---------------------------------------------------------------------------------------- -// nld_Q - Ebers Moll -// ---------------------------------------------------------------------------------------- + } + NETLIB_UPDATE_TERMINALS(QBJT_EB) + { + const nl_double polarity = (qtype() == BJT_NPN ? 1.0 : -1.0); + + m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity); + m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity); + + const nl_double gee = m_gD_BE.G(); + const nl_double gcc = m_gD_BC.G(); + const nl_double gec = m_alpha_r * gcc; + const nl_double gce = m_alpha_f * gee; + const nl_double sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I(); + const nl_double sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I(); + const nl_double Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity; + const nl_double Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity; + + m_D_EB.set_mat( gee, gec - gee, -Ie, + gce - gee, gee - gec, Ie); + m_D_CB.set_mat( gcc, gce - gcc, -Ic, + gec - gcc, gcc - gce, Ic); + m_D_EC.set_mat( 0, -gec, 0, + -gce, 0, 0); + } -NETLIB_UPDATE(QBJT_EB) -{ - if (!m_D_EB.m_P.net().isRailNet()) - m_D_EB.m_P.solve_now(); // Basis - else if (!m_D_EB.m_N.net().isRailNet()) - m_D_EB.m_N.solve_now(); // Emitter - else - m_D_CB.m_N.solve_now(); // Collector -} - -NETLIB_RESET(QBJT_EB) -{ - NETLIB_NAME(Q)::reset(); -} -NETLIB_UPDATE_TERMINALS(QBJT_EB) -{ - const nl_double polarity = (qtype() == BJT_NPN ? 1.0 : -1.0); - - m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity); - m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity); - - const nl_double gee = m_gD_BE.G(); - const nl_double gcc = m_gD_BC.G(); - const nl_double gec = m_alpha_r * gcc; - const nl_double gce = m_alpha_f * gee; - const nl_double sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I(); - const nl_double sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I(); - const nl_double Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity; - const nl_double Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity; - - m_D_EB.set_mat( gee, gec - gee, -Ie, - gce - gee, gee - gec, Ie); - m_D_CB.set_mat( gcc, gce - gcc, -Ic, - gec - gcc, gcc - gce, Ic); - m_D_EC.set_mat( 0, -gec, 0, - -gce, 0, 0); -} - - -NETLIB_UPDATE_PARAM(QBJT_EB) -{ - nl_double IS = m_model.m_IS; - nl_double BF = m_model.m_BF; - nl_double NF = m_model.m_NF; - nl_double BR = m_model.m_BR; - nl_double NR = m_model.m_NR; - //nl_double VJE = m_model.dValue("VJE", 0.75); + NETLIB_UPDATE_PARAM(QBJT_EB) + { + nl_double IS = m_model.m_IS; + nl_double BF = m_model.m_BF; + nl_double NF = m_model.m_NF; + nl_double BR = m_model.m_BR; + nl_double NR = m_model.m_NR; + //nl_double VJE = m_model.dValue("VJE", 0.75); - set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); + set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); - m_alpha_f = BF / (1.0 + BF); - m_alpha_r = BR / (1.0 + BR); + m_alpha_f = BF / (1.0 + BF); + m_alpha_r = BR / (1.0 + BR); - m_gD_BE.set_param(IS / m_alpha_f, NF, netlist().gmin()); - m_gD_BC.set_param(IS / m_alpha_r, NR, netlist().gmin()); -} + m_gD_BE.set_param(IS / m_alpha_f, NF, exec().gmin(), constants::T0()); + m_gD_BC.set_param(IS / m_alpha_r, NR, exec().gmin(), constants::T0()); + } - } //namespace analog +} // namespace analog - namespace devices { - NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB) - NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch) - } +namespace devices { + NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB, "QBJT_EB", "MODEL") + NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch, "QBJT_SW", "MODEL") +} // namespace devices } // namespace netlist |