summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_4066.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_4066.cpp')
-rw-r--r--src/lib/netlist/devices/nld_4066.cpp117
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