summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2014-05-15 22:50:40 +0000
committer Couriersud <couriersud@users.noreply.github.com>2014-05-15 22:50:40 +0000
commitf3cf3a8e78a00abacbbb645332f12da18af9cda5 (patch)
treea7a6e4c42ab99a970fd638856e6f0e2bae8d520a /src/emu
parent3b5b4fd0eae0ab2f30cf9482aa33a7e41da7f747 (diff)
Preliminary support for LTE dynamic time-stepping based on Local truncation error. This enables the possibility to connect a capacitor between ground and a TTL output and get a e.g. 100 ns delay with a 1nF capacitor.
Added an example circuit (cdelay.c) Changed the log device to support nano-second granularity. LTE is not yet enabled due to it's ugly test-state.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/netlist/analog/nld_solver.c67
-rw-r--r--src/emu/netlist/analog/nld_solver.h6
-rw-r--r--src/emu/netlist/devices/nld_log.c2
-rw-r--r--src/emu/netlist/devices/nld_system.c4
-rw-r--r--src/emu/netlist/nl_base.c4
-rw-r--r--src/emu/netlist/nl_base.h7
6 files changed, 70 insertions, 20 deletions
diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c
index 7ede33a2664..4c1cf33fcc8 100644
--- a/src/emu/netlist/analog/nld_solver.c
+++ b/src/emu/netlist/analog/nld_solver.c
@@ -106,9 +106,28 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLI
}
}
-ATTR_HOT void netlist_matrix_solver_t::update_inputs()
+ATTR_HOT double netlist_matrix_solver_t::update_inputs(const double hn)
{
+ double m_xx = 0.0001;
+#if NEW_LTE
+ for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ {
+ netlist_net_t *n = (*p)->m_proxied_net;
+ double DD_n = (n->m_cur_Analog - n->m_last_Analog) / hn;
+ double DD2 = (DD_n - n->m_DD_n_m_1) / (hn + n->m_h_n_m_1);
+ n->m_DD_n_m_1 = DD_n;
+ n->m_h_n_m_1 = hn;
+ double xx;
+ if (fabs(DD2) > 1e-100)
+ xx=sqrt(1.0e-3/fabs(0.5*DD2));
+ else
+ xx=0.0001;
+ if (xx<m_xx) m_xx = xx;
+ }
+ if (m_xx < 2e-9) m_xx = 2e-9;
+ //printf("%20s %f us\n", name().cstr(), m_xx * 1000000.0);
+#endif
#if NEW_INPUT
// avoid recursive calls. Inputs are updated outside this call
for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
@@ -133,7 +152,7 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs()
(*p)->net().m_last_Analog = (*p)->net().m_cur_Analog;
}
#endif
-
+ return m_xx;
}
@@ -159,8 +178,14 @@ ATTR_HOT void netlist_matrix_solver_t::schedule()
if (!m_Q_sync.net().is_queued())
m_Q_sync.net().push_to_queue(m_params.m_nt_sync_delay);
#else
- if (solve())
- update_inputs();
+#if NEW_LTE
+ double xx = solve();
+ if (xx<10e-6)
+ if (!m_Q_sync.net().is_queued())
+ m_Q_sync.net().push_to_queue(netlist_time::from_double(xx));
+#else
+ solve();
+#endif
#endif
}
@@ -178,8 +203,14 @@ ATTR_COLD void netlist_matrix_solver_t::reset()
ATTR_COLD void netlist_matrix_solver_t::update()
{
- if (solve())
- update_inputs();
+#if NEW_LTE
+ double xx = solve();
+ if (xx<10e-6)
+ if (!m_Q_sync.net().is_queued())
+ m_Q_sync.net().push_to_queue(netlist_time::from_double(xx));
+#else
+ solve();
+#endif
}
@@ -190,7 +221,7 @@ ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta)
m_steps[k]->step_time(dd);
}
-ATTR_HOT bool netlist_matrix_solver_t::solve()
+ATTR_HOT double netlist_matrix_solver_t::solve()
{
netlist_time now = owner().netlist().time();
@@ -198,7 +229,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
// We are already up to date. Avoid oscillations.
if (delta < netlist_time::from_nsec(1))
- return true;
+ return 1.0;
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
@@ -223,7 +254,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
{
owner().netlist().warning("NEWTON_LOOPS exceeded ... reschedule");
m_Q_sync.net().push_to_queue(m_params.m_nt_sync_delay);
- return false;
+ return 1.0;
}
}
else
@@ -231,7 +262,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
while (solve_non_dynamic() > m_params.m_gs_loops)
owner().netlist().warning("Non-Dynamic Solve iterations exceeded .. Consider increasing RESCHED_LOOPS");
}
- return true;
+ return update_inputs(delta.as_double());
}
// ----------------------------------------------------------------------------------------
@@ -770,25 +801,33 @@ NETLIB_UPDATE(solver)
this_resched[i] = m_mat_solvers[i]->solve();
}
#else
+ // FIXME: parameter
+ double m_xx = m_inc.as_double() * 100;
for (int i = 0; i < t_cnt; i++)
{
if (m_mat_solvers[i]->is_timestep())
- if (m_mat_solvers[i]->solve())
- m_mat_solvers[i]->update_inputs();
+ {
+ double xx = m_mat_solvers[i]->solve();
+ if (m_xx > xx)
+ m_xx = xx;
+ }
}
#endif
/* step circuit */
if (!m_Q_step.net().is_queued())
+#if NEW_LTE
+ m_Q_step.net().push_to_queue(netlist_time::from_double(m_xx));
+#else
m_Q_step.net().push_to_queue(m_inc);
+#endif
}
ATTR_COLD void NETLIB_NAME(solver)::solve_all()
{
for (int i = 0; i < m_mat_solvers.count(); i++)
//m_mat_solvers[i]->m_Q_sync.net().push_to_queue(m_mat_solvers[i]->m_params.m_nt_sync_delay);
- if (m_mat_solvers[i]->solve())
- m_mat_solvers[i]->update_inputs();
+ m_mat_solvers[i]->solve();
}
diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h
index 5d592cbd0f5..12e1863f475 100644
--- a/src/emu/netlist/analog/nld_solver.h
+++ b/src/emu/netlist/analog/nld_solver.h
@@ -9,8 +9,6 @@
#include "../nl_setup.h"
#include "../nl_base.h"
-#define NEW_INPUT (1)
-
// ----------------------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------------------
@@ -51,9 +49,9 @@ public:
ATTR_HOT virtual int solve_non_dynamic() = 0;
ATTR_HOT virtual void step(const netlist_time delta);
- ATTR_HOT bool solve();
+ ATTR_HOT double solve();
- ATTR_HOT void update_inputs();
+ ATTR_HOT double update_inputs(const double hn);
ATTR_HOT void update_dynamic();
ATTR_HOT void schedule();
diff --git a/src/emu/netlist/devices/nld_log.c b/src/emu/netlist/devices/nld_log.c
index b98076e26cb..608e01a3a87 100644
--- a/src/emu/netlist/devices/nld_log.c
+++ b/src/emu/netlist/devices/nld_log.c
@@ -22,7 +22,7 @@ NETLIB_RESET(log)
NETLIB_UPDATE(log)
{
- fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I));
+ fprintf(m_file, "%20.9e %e\n", netlist().time().as_double(), INPANALOG(m_I));
}
NETLIB_NAME(log)::~NETLIB_NAME(log)()
diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c
index 962261458c7..b49e1392ffb 100644
--- a/src/emu/netlist/devices/nld_system.c
+++ b/src/emu/netlist/devices/nld_system.c
@@ -91,7 +91,9 @@ ATTR_HOT ATTR_ALIGN void nld_d_to_a_proxy::update()
{
double R = INPLOGIC(m_I) ? m_family_desc->m_R_high : m_family_desc->m_R_low;
double V = INPLOGIC(m_I) ? m_family_desc->m_high_V : m_family_desc->m_low_V;
- //printf("%f %f\n", R, V);
+#if NEW_LTE
+ m_R.update_dev();
+#endif
OUTANALOG(m_Q, V);
m_R.set_R(R);
}
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index b274bde868b..8170ced7771 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -473,6 +473,10 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil
, m_time(netlist_time::zero)
, m_active(0)
, m_in_queue(2)
+#if NEW_LTE
+ , m_DD_n_m_1(0.0)
+ , m_h_n_m_1(1e-6)
+#endif
{
m_last_Q = 0;
m_new_Q = 0;
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index cd820bf1c27..baacd515331 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -157,6 +157,9 @@
#include "pstring.h"
#include "pstate.h"
+#define NEW_INPUT (1)
+#define NEW_LTE (0)
+
// ----------------------------------------------------------------------------------------
// Type definitions
// ----------------------------------------------------------------------------------------
@@ -651,6 +654,10 @@ public:
double m_last_Analog;
double m_cur_Analog;
double m_new_Analog;
+#if NEW_LTE
+ double m_DD_n_m_1;
+ double m_h_n_m_1;
+#endif
};