mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
netlist: prepare road towards trapezoidal integration.
* This is a long term transition goal. Documented in source (see NL_USE_BACKWARD_EULER).
This commit is contained in:
parent
65a2745af0
commit
5d0786a449
@ -131,7 +131,7 @@ namespace analog
|
||||
nl_fptype m_gmin;
|
||||
};
|
||||
|
||||
#if 1
|
||||
#if (NL_USE_BACKWARD_EULER)
|
||||
// Constant model for constant capacitor model
|
||||
// Backward Euler
|
||||
// "Circuit simulation", page 274
|
||||
@ -166,7 +166,7 @@ namespace analog
|
||||
struct generic_capacitor_const
|
||||
{
|
||||
public:
|
||||
generic_capacitor_const(device_t &dev, const pstring &name)
|
||||
generic_capacitor_const(core_device_t &dev, const pstring &name)
|
||||
: m_gmin(nlconst::zero())
|
||||
, m_vn(0)
|
||||
, m_in(0)
|
||||
@ -195,6 +195,10 @@ namespace analog
|
||||
m_trn = h;
|
||||
return { G + m_gmin, -Ieq };
|
||||
}
|
||||
void restore_state() noexcept
|
||||
{
|
||||
// this one has no state
|
||||
}
|
||||
void setparams(nl_fptype gmin) noexcept { m_gmin = gmin; }
|
||||
private:
|
||||
nl_fptype m_gmin;
|
||||
|
@ -83,6 +83,7 @@ namespace netlist
|
||||
, m_ff(*this, "m_ff", false)
|
||||
, m_last_reset(*this, "m_last_reset", false)
|
||||
, m_overshoot(*this, "m_overshoot", 0.0)
|
||||
, m_undershoot(*this, "m_undershoot", 0.0)
|
||||
, m_ovlimit(0.0)
|
||||
{
|
||||
register_subalias("GND", m_R3.N()); // Pin 1
|
||||
@ -138,10 +139,13 @@ namespace netlist
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto delta = m_THRES() + m_overshoot - vthresh;
|
||||
const bool bthresh = (delta > 0.0);
|
||||
#if (NL_USE_BACKWARD_EULER)
|
||||
const bool bthresh = (m_THRES() + m_overshoot > vthresh);
|
||||
const bool btrig = (m_TRIG() - m_overshoot > vtrig);
|
||||
|
||||
#else
|
||||
const bool bthresh = (m_THRES() + m_overshoot > vthresh);
|
||||
const bool btrig = (m_TRIG() - m_undershoot > vtrig);
|
||||
#endif
|
||||
if (!btrig)
|
||||
m_ff = true;
|
||||
else if (bthresh)
|
||||
@ -154,7 +158,11 @@ namespace netlist
|
||||
|
||||
if (m_last_out && !out)
|
||||
{
|
||||
m_overshoot += ((m_THRES() - vthresh)) * 2;
|
||||
#if (NL_USE_BACKWARD_EULER)
|
||||
m_overshoot += ((m_THRES() - vthresh)) * 2.0;
|
||||
#else
|
||||
m_overshoot += ((m_THRES() - vthresh));
|
||||
#endif
|
||||
m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), ovlimit);
|
||||
//if (this->name() == "IC6_2")
|
||||
// printf("%f %s %f %f %f\n", exec().time().as_double(), this->name().c_str(), m_overshoot(), m_R2.P()(), m_THRES());
|
||||
@ -166,8 +174,13 @@ namespace netlist
|
||||
}
|
||||
else if (!m_last_out && out)
|
||||
{
|
||||
m_overshoot += (vtrig - m_TRIG()) * 2;
|
||||
#if (NL_USE_BACKWARD_EULER)
|
||||
m_overshoot += (vtrig - m_TRIG()) * 2.0;
|
||||
m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), ovlimit);
|
||||
#else
|
||||
m_undershoot += (vtrig - m_TRIG());
|
||||
m_undershoot = plib::clamp(m_undershoot(), nlconst::zero(), ovlimit);
|
||||
#endif
|
||||
m_RDIS.change_state([this]()
|
||||
{
|
||||
m_RDIS.set_R(nlconst::magic(R_OFF));
|
||||
@ -193,6 +206,7 @@ namespace netlist
|
||||
state_var<bool> m_ff;
|
||||
state_var<bool> m_last_reset;
|
||||
state_var<nl_fptype> m_overshoot;
|
||||
state_var<nl_fptype> m_undershoot;
|
||||
nl_fptype m_ovlimit;
|
||||
|
||||
nl_fptype clamp_hl(const nl_fptype v, const nl_fptype a, const nl_fptype b) noexcept
|
||||
|
@ -28,14 +28,9 @@ NETLIST_EXTERNAL(loc_lib)
|
||||
|
||||
NETLIST_START(ex2N6027)
|
||||
|
||||
/* This is a circuit pushing the solvers to the limits
|
||||
* 50,000 maximum NR loops.
|
||||
*/
|
||||
SOLVER(Solver, 48000)
|
||||
PARAM(Solver.ACCURACY, 1e-5)
|
||||
PARAM(Solver.DYNAMIC_TS, 1)
|
||||
PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-9)
|
||||
PARAM(Solver.NR_LOOPS, 50000)
|
||||
PARAM(Solver.METHOD, "MAT_CR")
|
||||
|
||||
LOCAL_SOURCE(loc_lib)
|
||||
|
@ -97,6 +97,20 @@
|
||||
#define NL_USE_COPY_INSTEAD_OF_REFERENCE (0)
|
||||
#endif
|
||||
|
||||
/// \brief Use backward Euler integration
|
||||
///
|
||||
/// This will use backward Euler instead of trapezoidal integration.
|
||||
///
|
||||
/// FIXME: Longterm this will become a runtime setting. Only the capacitor model
|
||||
/// currently has a trapezoidal version and there is no support currently for
|
||||
/// variable capacitors.
|
||||
/// The change will have impact on timings since trapezoidal improves timing
|
||||
/// accuracy.
|
||||
|
||||
#ifndef NL_USE_BACKWARD_EULER
|
||||
#define NL_USE_BACKWARD_EULER (1)
|
||||
#endif
|
||||
|
||||
/// \brief Use the truthtable implementation of 7448 instead of the coded device
|
||||
///
|
||||
/// FIXME: Using truthtable is a lot slower than the explicit device
|
||||
|
@ -532,7 +532,7 @@ namespace solver
|
||||
if (dynamic_device_count() != 0)
|
||||
{
|
||||
step(timestep_type::FORWARD, delta);
|
||||
auto resched = solve_nr_base();
|
||||
const auto resched = solve_nr_base();
|
||||
|
||||
if (resched)
|
||||
return newton_loops_exceeded(delta);
|
||||
|
Loading…
Reference in New Issue
Block a user