diff options
Diffstat (limited to 'src/lib/netlist/analog/nld_bjt.cpp')
-rw-r--r-- | src/lib/netlist/analog/nld_bjt.cpp | 255 |
1 files changed, 248 insertions, 7 deletions
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index 0acd0887e74..e40fbfa366d 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -6,13 +6,16 @@ */ #include "solver/nld_solver.h" -#include "analog/nld_bjt.h" +#include "analog/nlid_twoterm.h" #include "nl_setup.h" +#include <cmath> + namespace netlist { namespace analog { + class diode { public: @@ -40,6 +43,240 @@ private: nl_double m_VT_inv; }; +// ----------------------------------------------------------------------------- +// nld_Q - Base classes +// ----------------------------------------------------------------------------- + + /*! Class representing the bjt model paramers. + * + * This is the model representation of the bjt model. Typically, SPICE uses + * the following parameters. A "Y" in the first column indicates that the + * parameter is actually used in netlist. + * + * | NL? | name | parameter | units | default | example | area | + * |:---:|------|-----------------------------------------------------------------------|-------|---------:|----------------:|:----:| + * | Y | IS | transport saturation current | A | 1E-016 | 1E-015 | * | + * | Y | BF | ideal maximum forward beta | - | 100 | 100 | | + * | Y | NF | forward current emission coefficient | - | 1 | 1 | | + * | | VAF | forward Early voltage | V | infinite | 200 | | + * | | IKF | corner for forward beta high current roll-off | A | infinite | 0.01 | * | + * | | ISE | B-E leakage saturation current | A | 0 | 0.0000000000001 | * | + * | | NE | B-E leakage emission coefficient | - | 1.5 | 2 | | + * | Y | BR | ideal maximum reverse beta | - | 1 | 0.1 | | + * | Y | NR | reverse current emission coefficient | - | 1 | 1 | | + * | | VAR | reverse Early voltage | V | infinite | 200 | | + * | | IKR | corner for reverse beta high current roll-off | A | infinite | 0.01 | * | + * | | ISC | leakage saturation current | A | 0 | 8 | | + * | | NC | leakage emission coefficient | - | 2 | 1.5 | | + * | | RB | zero bias base resistance | | 0 | 100 | * | + * | | IRB | current where base resistance falls halfway to its min value | A | infinte | 0.1 | * | + * | | 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 | * | + * | | 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 | | + * | | XTF | coefficient for bias dependence of TF | - | 0 | | | + * | | 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 | * | + * | | 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 | | | + * | | TR | ideal reverse transit time | sec | 0 | 10ns | | + * | | CJS | zero-bias collector-substrate capacitance | F | 0 | 2pF | * | + * | | VJS | substrate junction built-in potential | V | 0.75 | | | + * | | MJS | substrate junction exponential factor | - | 0 | 0.5 | | + * | | XTB | forward and reverse beta temperature exponent | - | 0 | | | + * | | EG | energy gap for temperature effect on IS | eV | 1.11 | | | + * | | XTI | temperature exponent for effect on IS | - | 3 | | | + * | | 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 | | */ + + 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") + {} + + 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 + }; + + // Have a common start for transistors + +NETLIB_OBJECT(Q) +{ +public: + enum q_type { + BJT_NPN, + BJT_PNP + }; + + NETLIB_CONSTRUCTOR(Q) + , m_model(*this, "MODEL", "") + , m_qtype(BJT_NPN) + { + } + + NETLIB_IS_DYNAMIC(true) + + //NETLIB_RESETI(); + NETLIB_UPDATEI(); + + 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: + + bjt_model_t m_model; +private: + q_type m_qtype; +}; + +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 + */ + +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) + { + 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(); + + 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; + +protected: + + + 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 +// ----------------------------------------------------------------------------- + + +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) + { + 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); + } + +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; + +}; // ---------------------------------------------------------------------------------------- @@ -122,8 +359,6 @@ NETLIB_UPDATE_TERMINALS(QBJT_switch) m_RB.set(gb, v, 0.0); m_RC.set(gc, 0.0, 0.0); - //m_RB.update_dev(); - //m_RC.update_dev(); m_state_on = new_state; } } @@ -166,11 +401,11 @@ NETLIB_UPDATE_TERMINALS(QBJT_EB) 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); + gce - gee, gee - gec, Ie); m_D_CB.set_mat( gcc, gce - gcc, -Ic, - gec - gcc, gcc - gce, Ic); + gec - gcc, gcc - gce, Ic); m_D_EC.set_mat( 0, -gec, 0, - -gce, 0, 0); + -gce, 0, 0); } @@ -192,5 +427,11 @@ NETLIB_UPDATE_PARAM(QBJT_EB) m_gD_BC.set_param(IS / m_alpha_r, NR, netlist().gmin()); } - } //namespace devices + } //namespace analog + + namespace devices { + NETLIB_DEVICE_IMPL_NS(analog, QBJT_EB) + NETLIB_DEVICE_IMPL_NS(analog, QBJT_switch) + } + } // namespace netlist |