mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
netlist: Document alternative approach to CD4016. (nw)
The CD4016 is an analog switch IC. Document an experimental approach to implement the analog switch as a 3 terminal element which is completely being dealt with as part as the linear system. The intention was to improve convergence when the switch is in a feedback loop. One example are two-opamp tridiagonal wave generators. Unfortunately the approach did not work out and in addition was performing far worse than the net-separating original code. Also updated comment in nld_generic_models.h.
This commit is contained in:
parent
5cd3a44607
commit
1af4b9f870
@ -14,7 +14,9 @@
|
||||
//
|
||||
// Set to 0 to use a linearized diode model in the range exceeding
|
||||
// maximum dissipation. The intention is to have a faster
|
||||
// convergence but this yet not really is observable
|
||||
// convergence. On selected circuits (LM3900 trapezoidal) this is
|
||||
// observable and has a 10% impact.
|
||||
// FIXME: More research needed
|
||||
//
|
||||
|
||||
#define USE_TEXTBOOK_DIODE (1)
|
||||
|
@ -11,6 +11,20 @@
|
||||
#include "netlist/solver/nld_solver.h"
|
||||
#include "nlid_system.h"
|
||||
|
||||
// This is an experimental approach to implement the analog switch.
|
||||
// This will make the switch a 3 terminal element which is completely
|
||||
// being dealt with as part as the linear system.
|
||||
//
|
||||
// The intention was to improve convergence when the switch is in a feedback
|
||||
// loop. One example are two-opamp tridiagonal wave generators.
|
||||
// Unfortunately the approach did not work out and in addition was performing
|
||||
// far worse than the net-separating original code.
|
||||
//
|
||||
// FIXME: The transfer function needs review
|
||||
//
|
||||
|
||||
#define USE_DYNAMIC_APPROACH (0)
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
@ -27,56 +41,110 @@ namespace netlist
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
// Start in off condition
|
||||
// FIXME: is ROFF correct?
|
||||
m_R.set_R(plib::reciprocal(exec().gmin()));
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
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.update();
|
||||
m_R.set_R(R);
|
||||
m_R.solve_later();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nld_power_pins m_supply;
|
||||
analog::NETLIB_SUB(R_base) m_R;
|
||||
|
||||
analog_input_t m_control;
|
||||
param_fp_t m_base_r;
|
||||
state_var<bool> m_last;
|
||||
};
|
||||
|
||||
NETLIB_RESET(CD4066_GATE)
|
||||
|
||||
NETLIB_OBJECT(CD4066_GATE_DYNAMIC)
|
||||
{
|
||||
// Start in off condition
|
||||
// FIXME: is ROFF correct?
|
||||
m_R.set_R(plib::reciprocal(exec().gmin()));
|
||||
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(CD4066_GATE)
|
||||
{
|
||||
nl_fptype sup = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog());
|
||||
nl_fptype low = nlconst::magic(0.45) * sup;
|
||||
nl_fptype high = nlconst::magic(0.55) * sup;
|
||||
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();
|
||||
bool new_state(false);
|
||||
|
||||
if (in < low)
|
||||
NETLIB_CONSTRUCTOR(CD4066_GATE_DYNAMIC)
|
||||
NETLIB_FAMILY("CD4XXX")
|
||||
, m_supply(*this, "VDD", "VSS")
|
||||
, m_R(*this, "R", true)
|
||||
, m_DUM1(*this, "_DUM1", true)
|
||||
, m_DUM2(*this, "_DUM2", true)
|
||||
, m_base_r(*this, "BASER", nlconst::magic(270.0))
|
||||
, m_last(*this, "m_last", false)
|
||||
{
|
||||
R = plib::reciprocal(exec().gmin());
|
||||
}
|
||||
else if (in > high)
|
||||
{
|
||||
R = rON;
|
||||
new_state = true;
|
||||
}
|
||||
//printf("%s %f %f %g\n", name().c_str(), sup, in, R);
|
||||
if (R > nlconst::zero() && (m_last != new_state))
|
||||
{
|
||||
m_last = new_state;
|
||||
m_R.update();
|
||||
m_R.set_R(R);
|
||||
m_R.solve_later();
|
||||
}
|
||||
}
|
||||
register_subalias("CTL", m_DUM1.m_P); // Cathode
|
||||
|
||||
connect(m_DUM1.m_P, m_DUM2.m_P);
|
||||
connect(m_DUM1.m_N, m_R.m_P);
|
||||
connect(m_DUM2.m_N, m_R.m_N);
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
// Start in off condition
|
||||
// FIXME: is ROFF correct?
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_TERMINALSI()
|
||||
{
|
||||
nl_fptype sup = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog());
|
||||
nl_fptype in = m_DUM1.m_P.net().Q_Analog() - m_supply.GND().Q_Analog();
|
||||
nl_fptype rON = m_base_r() * nlconst::magic(5.0) / sup;
|
||||
nl_fptype R = std::exp(-(in / sup - 0.55) * 25.0) + rON;
|
||||
nl_fptype G = plib::reciprocal(R);
|
||||
// dI/dVin = (VR1-VR2)*(1.0/sup*b) * exp((Vin/sup-a) * b)
|
||||
const auto dfdz = 25.0/(R*sup) * m_R.deltaV();
|
||||
const auto Ieq = dfdz * in;
|
||||
m_R.set_mat( G, -G, 0.0,
|
||||
-G, G, 0.0);
|
||||
//VIN VR1
|
||||
m_DUM1.set_mat( 0.0, 0.0, 0.0, // IIN
|
||||
dfdz, 0.0, Ieq); // IR1
|
||||
m_DUM2.set_mat( 0.0, 0.0, 0.0, // IIN
|
||||
-dfdz, 0.0, -Ieq); // IR2
|
||||
}
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
|
||||
private:
|
||||
nld_power_pins m_supply;
|
||||
analog::nld_twoterm m_R;
|
||||
analog::nld_twoterm m_DUM1;
|
||||
analog::nld_twoterm m_DUM2;
|
||||
param_fp_t m_base_r;
|
||||
state_var<bool> m_last;
|
||||
};
|
||||
|
||||
#if !USE_DYNAMIC_APPROACH
|
||||
NETLIB_DEVICE_IMPL(CD4066_GATE, "CD4066_GATE", "")
|
||||
|
||||
#else
|
||||
NETLIB_DEVICE_IMPL_ALIAS(CD4066_GATE, CD4066_GATE_DYNAMIC, "CD4066_GATE", "")
|
||||
#endif
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
Loading…
Reference in New Issue
Block a user