diff options
Diffstat (limited to 'src/lib/netlist/devices/nld_4066.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_4066.cpp | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index 96200688400..bd2a0a13196 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -1,76 +1,83 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Couriersud /* - * nld_4066.c + * nld_4066.cpp + * + * CD4066: Quad Bilateral Switch + * + * +--------------+ + * INOUTA |1 ++ 14| VDD + * OUTINA |2 13| CONTROLA + * OUTINB |3 12| CONTROLD + * INOUTB |4 4066 11| INOUTD + * CONTROLB |5 10| OUTIND + * CONTROLC |6 9| OUTINC + * VSS |7 8| INOUTC + * +--------------+ + * + * FIXME: These devices are slow (~125 ns). This is currently not reflected + * + * Naming conventions follow National semiconductor datasheet * */ -#include "nld_4066.h" +#include "analog/nlid_twoterm.h" +#include "solver/nld_solver.h" -#include "netlist/analog/nlid_twoterm.h" -#include "netlist/solver/nld_solver.h" -#include "nlid_system.h" -namespace netlist -{ - namespace devices - { +namespace netlist::devices { + NETLIB_OBJECT(CD4066_GATE) { - NETLIB_CONSTRUCTOR(CD4066_GATE) - NETLIB_FAMILY("CD4XXX") - , m_supply(*this, "VDD", "VSS", true) + NETLIB_CONSTRUCTOR_MODEL(CD4066_GATE, "CD4XXX") , m_R(*this, "R") - , m_control(*this, "CTL") - , m_base_r(*this, "BASER", 270.0) + , m_control(*this, "CTL", NETLIB_DELEGATE(control)) + , m_base_r(*this, "BASER", nlconst::magic(270.0)) + , m_last(*this, "m_last", false) + , m_supply(*this) { } - NETLIB_RESETI(); - NETLIB_UPDATEI(); + NETLIB_RESETI() + { + // Start in off condition + // FIXME: is ROFF correct? + m_R().set_R(plib::reciprocal(exec().gmin())); + } private: - nld_power_pins m_supply; - analog::NETLIB_SUB(R_base) m_R; + NETLIB_HANDLERI(control) + { + nl_fptype sup = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog()); + nl_fptype in = m_control() - m_supply.GND().Q_Analog(); + nl_fptype rON = m_base_r() * nlconst::magic(5.0) / sup; + nl_fptype R = -nlconst::one(); + nl_fptype low = nlconst::magic(0.45) * sup; + nl_fptype high = nlconst::magic(0.55) * sup; + bool new_state(false); + if (in < low) + { + R = plib::reciprocal(exec().gmin()); + } + else if (in > high) + { + R = rON; + new_state = true; + } + if (R > nlconst::zero() && (m_last != new_state)) + { + m_last = new_state; + m_R().change_state([this, &R]() -> void { this->m_R().set_R(R);}); + } + } + NETLIB_SUB_NS(analog, R_base) m_R; analog_input_t m_control; - param_double_t m_base_r; + param_fp_t m_base_r; + state_var<bool> m_last; + nld_power_pins m_supply; }; - NETLIB_RESET(CD4066_GATE) - { - // Start in off condition - // FIXME: is ROFF correct? - m_R.set_R(plib::constants<nl_double>::one() / exec().gmin()); - - } - - NETLIB_UPDATE(CD4066_GATE) - { - nl_double sup = (m_supply.VCC() - m_supply.GND()); - nl_double low = plib::constants<nl_double>::cast(0.45) * sup; - nl_double high = plib::constants<nl_double>::cast(0.55) * sup; - nl_double in = m_control() - m_supply.GND(); - nl_double rON = m_base_r() * plib::constants<nl_double>::cast(5.0) / sup; - nl_double R = -1.0; - - if (in < low) - { - R = plib::constants<nl_double>::one() / exec().gmin(); - } - else if (in > high) - { - R = rON; - } - if (R > plib::constants<nl_double>::zero()) - { - m_R.update(); - m_R.set_R(R); - m_R.solve_later(); - } - } - NETLIB_DEVICE_IMPL(CD4066_GATE, "CD4066_GATE", "") - } //namespace devices -} // namespace netlist +} // namespace netlist::devices |