diff options
Diffstat (limited to 'src/lib/netlist/devices/nld_schmitt.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_schmitt.cpp | 195 |
1 files changed, 93 insertions, 102 deletions
diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index f219d215520..a6134f3a953 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -5,127 +5,118 @@ * */ -#include "nld_schmitt.h" +#include "analog/nlid_twoterm.h" +#include "nl_base.h" +#include "nl_errstr.h" +#include "solver/nld_solver.h" -#include "netlist/analog/nlid_twoterm.h" -#include "netlist/nl_base.h" -#include "netlist/nl_errstr.h" -#include "netlist/solver/nld_solver.h" +namespace netlist::devices { -#include <cmath> + /* + * Over-simplified TTL Schmitt trigger model + * It's good enough to work for 74xx/74LSxx if it isn't abused too badly + * It would need major changes to support 4000 or 74HCxx behaviour + * The input is over-simplified - it's actually more like a resistor in series with a diode, and can only source current + * Similarly, high output can only source current and low output can only sink current + * Propagation delays are ignored + * + */ - -namespace netlist -{ - namespace devices + class schmitt_trigger_model_t { - - /* - * Over-simplified TTL Schmitt trigger model - * It's good enough to work for 74xx/74LSxx if it isn't abused too badly - * It would need major changes to support 4000 or 74HCxx behaviour - * The input is over-simplified - it's actually more like a resistor in series with a diode, and can only source current - * Similarly, high output can only source current and low output can only sink current - * Propagation delays are ignored - * - */ - - class schmitt_trigger_model_t : public param_model_t + public: + schmitt_trigger_model_t(param_model_t &model) + : m_VTP(model, "VTP") + , m_VTM(model, "VTM") + , m_VI(model, "VI") + , m_RI(model, "RI") + , m_VOH(model, "VOH") + , m_ROH(model, "ROH") + , m_VOL(model, "VOL") + , m_ROL(model, "ROL") + , m_TPLH(model, "TPLH") + , m_TPHL(model, "TPHL") { - public: - schmitt_trigger_model_t(device_t &device, const pstring &name, const pstring &val) - : param_model_t(device, name, val) - , m_VTP(*this, "VTP") - , m_VTM(*this, "VTM") - , m_VI(*this, "VI") - , m_RI(*this, "RI") - , m_VOH(*this, "VOH") - , m_ROH(*this, "ROH") - , m_VOL(*this, "VOL") - , m_ROL(*this, "ROL") - , m_TPLH(*this, "TPLH") - , m_TPHL(*this, "TPHL") - { - } + } - value_t m_VTP; - value_t m_VTM; - value_t m_VI; - value_t m_RI; - value_t m_VOH; - value_t m_ROH; - value_t m_VOL; - value_t m_ROL; - value_t m_TPLH; - value_t m_TPHL; - }; + param_model_t::value_t m_VTP; + param_model_t::value_t m_VTM; + param_model_t::value_t m_VI; + param_model_t::value_t m_RI; + param_model_t::value_t m_VOH; + param_model_t::value_t m_ROH; + param_model_t::value_t m_VOL; + param_model_t::value_t m_ROL; + param_model_t::value_t m_TPLH; + param_model_t::value_t m_TPHL; + }; - NETLIB_OBJECT(schmitt_trigger) + NETLIB_OBJECT(schmitt_trigger) + { + NETLIB_CONSTRUCTOR(schmitt_trigger) + , m_A(*this, "A", NETLIB_DELEGATE(input)) + , m_supply(*this) + , m_RVI(*this, "RVI") + , m_RVO(*this, "RVO") + , m_stmodel(*this, "STMODEL", "TTL_7414_GATE") + , m_modacc(m_stmodel) + , m_last_state(*this, "m_last_var", 1) { - NETLIB_CONSTRUCTOR(schmitt_trigger) - , m_A(*this, "A") - , m_GND(*this, "GND") - , m_RVI(*this, "RVI") - , m_RVO(*this, "RVO") - , m_model(*this, "MODEL", "TTL_7414_GATE") - , m_last_state(*this, "m_last_var", 1) - , m_is_timestep(false) - { - register_subalias("Q", m_RVO.m_P); + register_sub_alias("Q", "RVO.1"); - connect(m_A, m_RVI.m_P); - connect(m_GND, m_RVI.m_N); - connect(m_GND, m_RVO.m_N); - } + connect("A", "RVI.1"); + // FIXME: need a symbolic reference from connect as well + connect(m_supply.GND(), m_RVI().N()); + connect(m_supply.GND(), m_RVO().N()); + } - protected: - NETLIB_RESETI() - { - m_last_state = 1; - m_RVI.reset(); - m_RVO.reset(); - m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices(); - m_RVI.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_RI, m_model.m_VI, 0.0); - m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROL, m_model.m_VOL, 0.0); - } + protected: + NETLIB_RESETI() + { + m_last_state = 1; + m_RVI().reset(); + m_RVO().reset(); + m_RVI().set_G_V_I(plib::reciprocal(m_modacc.m_RI()), m_modacc.m_VI, nlconst::zero()); + m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero()); + } - NETLIB_UPDATEI() + private: + NETLIB_HANDLERI(input) + { + const auto va(m_A.Q_Analog() - m_supply.GND().Q_Analog()); + if (m_last_state) { - if (m_last_state) + if (va < m_modacc.m_VTM) { - if (m_A.Q_Analog() < m_model.m_VTM) + m_last_state = 0; + m_RVO().change_state([this]() { - m_last_state = 0; - if (m_is_timestep) - m_RVO.update(); - m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROH, m_model.m_VOH, 0.0); - m_RVO.solve_later(); - } + m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROH()), m_modacc.m_VOH, nlconst::zero()); + }); } - else + } + else + { + if (va > m_modacc.m_VTP) { - if (m_A.Q_Analog() > m_model.m_VTP) + m_last_state = 1; + m_RVO().change_state([this]() { - m_last_state = 1; - if (m_is_timestep) - m_RVO.update(); - m_RVO.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_ROL, m_model.m_VOL, 0.0); - m_RVO.solve_later(); - } + m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero()); + }); } } + } - private: - analog_input_t m_A; - analog_input_t m_GND; - analog::NETLIB_SUB(twoterm) m_RVI; - analog::NETLIB_SUB(twoterm) m_RVO; - schmitt_trigger_model_t m_model; - state_var<int> m_last_state; - bool m_is_timestep; - }; + analog_input_t m_A; + NETLIB_NAME(power_pins) m_supply; + NETLIB_SUB_NS(analog, two_terminal) m_RVI; + NETLIB_SUB_NS(analog, two_terminal) m_RVO; + param_model_t m_stmodel; + schmitt_trigger_model_t m_modacc; + state_var<int> m_last_state; + }; - NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "MODEL") + NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "STMODEL") - } // namespace devices -} // namespace netlist +} // namespace netlist::devices |