summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--nl_examples/kidniki.c23
-rw-r--r--scripts/src/netlist.lua1
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp2
-rw-r--r--src/lib/netlist/devices/nld_system.cpp1
-rw-r--r--src/lib/netlist/nl_base.cpp3
-rw-r--r--src/lib/netlist/nl_base.h2
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h144
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h105
-rw-r--r--src/lib/netlist/solver/nld_ms_direct1.h22
-rw-r--r--src/lib/netlist/solver/nld_ms_gmres.h31
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp35
-rw-r--r--src/lib/netlist/solver/nld_solver.h130
-rw-r--r--src/mame/audio/irem.cpp5
13 files changed, 248 insertions, 256 deletions
diff --git a/nl_examples/kidniki.c b/nl_examples/kidniki.c
index b1d0a87317b..3b51e40328f 100644
--- a/nl_examples/kidniki.c
+++ b/nl_examples/kidniki.c
@@ -8,14 +8,18 @@
#define USE_FIXED_STV 1
NETLIST_START(dummy)
-#if (USE_FRONTIERS)
+#if (1 || USE_FRONTIERS)
SOLVER(Solver, 18000)
PARAM(Solver.ACCURACY, 1e-8)
PARAM(Solver.NR_LOOPS, 300)
PARAM(Solver.GS_LOOPS, 1)
PARAM(Solver.GS_THRESHOLD, 6)
//PARAM(Solver.ITERATIVE, "MAT")
+ //PARAM(Solver.ITERATIVE, "GMRES")
PARAM(Solver.ITERATIVE, "SOR")
+ PARAM(Solver.DYNAMIC_TS, 0)
+ PARAM(Solver.DYNAMIC_LTE, 5e-3)
+ PARAM(Solver.MIN_TIMESTEP, 10e-6)
PARAM(Solver.PARALLEL, 0)
PARAM(Solver.SOR_FACTOR, 1.00)
#else
@@ -46,14 +50,15 @@ NETLIST_START(dummy)
//ANALOG_INPUT(I_V0, 0)
ALIAS(I_V0.Q, GND)
#if 0
- ANALOG_INPUT(I_SD0, 0)
- ANALOG_INPUT(I_BD0, 0)
- ANALOG_INPUT(I_CH0, 0)
- ANALOG_INPUT(I_OH0, 0)
- ANALOG_INPUT(I_SOUNDIC0, 0)
- ANALOG_INPUT(I_OKI0, 0)
- ANALOG_INPUT(I_SOUND0, 0)
- ANALOG_INPUT(I_SINH0, 0)
+ TTL_INPUT(I_SD0, 0)
+ TTL_INPUT(I_BD0, 0)
+ TTL_INPUT(I_CH0, 0)
+ TTL_INPUT(I_OH0, 0)
+ TTL_INPUT(I_SOUNDIC0, 0)
+ ANALOG_INPUT(I_MSM2K0, 0)
+ ANALOG_INPUT(I_MSM3K0, 0)
+ TTL_INPUT(I_SOUND0, 0)
+ TTL_INPUT(I_SINH0, 0)
#else
TTL_INPUT(I_SD0, 1)
//CLOCK(I_SD0, 5)
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index 65b8ca29336..29bc8f0a7bb 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -73,6 +73,7 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/analog/nld_opamps.h",
MAME_DIR .. "src/lib/netlist/solver/nld_solver.cpp",
MAME_DIR .. "src/lib/netlist/solver/nld_solver.h",
+ MAME_DIR .. "src/lib/netlist/solver/nld_matrix_solver.h",
MAME_DIR .. "src/lib/netlist/solver/nld_ms_direct.h",
MAME_DIR .. "src/lib/netlist/solver/nld_ms_direct1.h",
MAME_DIR .. "src/lib/netlist/solver/nld_ms_direct2.h",
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index 7f7ab6f8660..82e774b4923 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -5,7 +5,7 @@
*
*/
-#include <solver/nld_solver.h>
+#include <solver/nld_matrix_solver.h>
#include "nld_mm5837.h"
#include "nl_setup.h"
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index dbf6926437d..e861bf05171 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -6,6 +6,7 @@
*/
#include <solver/nld_solver.h>
+#include <solver/nld_matrix_solver.h>
#include "nld_system.h"
NETLIB_NAMESPACE_DEVICES_START()
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 9ebb1378e5b..7afa0285ef8 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -5,7 +5,8 @@
*
*/
-#include <solver/nld_solver.h>
+#include <solver/nld_matrix_solver.h>
+
#include <cstring>
#include <algorithm>
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index e4374b75ad3..52a91704607 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -1062,7 +1062,7 @@ namespace netlist
ATTR_HOT nl_double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); }
- ATTR_HOT nl_double TERMANALOG(const terminal_t &term) const { return term.net().as_analog().Q_Analog(); }
+ ATTR_HOT nl_double TERMANALOG(const terminal_t &term) const { return term.net().Q_Analog(); }
ATTR_HOT void OUTANALOG(analog_output_t &out, const nl_double val)
{
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
new file mode 100644
index 00000000000..40896d431e5
--- /dev/null
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -0,0 +1,144 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * nld_matrix_solver.h
+ *
+ */
+
+#ifndef NLD_MATRIX_SOLVER_H_
+#define NLD_MATRIX_SOLVER_H_
+
+#include "solver/nld_solver.h"
+
+NETLIB_NAMESPACE_DEVICES_START()
+
+class terms_t
+{
+ P_PREVENT_COPYING(terms_t)
+
+ public:
+ ATTR_COLD terms_t() : m_railstart(0)
+ {}
+
+ ATTR_COLD void clear()
+ {
+ m_term.clear();
+ m_net_other.clear();
+ m_gt.clear();
+ m_go.clear();
+ m_Idr.clear();
+ m_other_curanalog.clear();
+ }
+
+ ATTR_COLD void add(terminal_t *term, int net_other, bool sorted);
+
+ inline unsigned count() { return m_term.size(); }
+
+ inline terminal_t **terms() { return m_term.data(); }
+ inline int *net_other() { return m_net_other.data(); }
+ inline nl_double *gt() { return m_gt.data(); }
+ inline nl_double *go() { return m_go.data(); }
+ inline nl_double *Idr() { return m_Idr.data(); }
+ inline nl_double **other_curanalog() { return m_other_curanalog.data(); }
+
+ ATTR_COLD void set_pointers();
+
+ unsigned m_railstart;
+
+ pvector_t<unsigned> m_nz; /* all non zero for multiplication */
+ pvector_t<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, includes RHS element */
+ pvector_t<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
+private:
+ pvector_t<terminal_t *> m_term;
+ pvector_t<int> m_net_other;
+ pvector_t<nl_double> m_go;
+ pvector_t<nl_double> m_gt;
+ pvector_t<nl_double> m_Idr;
+ pvector_t<nl_double *> m_other_curanalog;
+};
+
+class matrix_solver_t : public device_t
+{
+public:
+ typedef pvector_t<matrix_solver_t *> list_t;
+ typedef core_device_t::list_t dev_list_t;
+
+ enum eSolverType
+ {
+ GAUSSIAN_ELIMINATION,
+ GAUSS_SEIDEL
+ };
+
+ matrix_solver_t(const eSolverType type, const solver_parameters_t *params);
+ virtual ~matrix_solver_t();
+
+ void setup(analog_net_t::list_t &nets) { vsetup(nets); }
+
+ netlist_time solve_base();
+
+ netlist_time solve();
+
+ inline bool is_dynamic() const { return m_dynamic_devices.size() > 0; }
+ inline bool is_timestep() const { return m_step_devices.size() > 0; }
+
+ void update_forced();
+ void update_after(const netlist_time after)
+ {
+ m_Q_sync.net().reschedule_in_queue(after);
+ }
+
+ /* netdevice functions */
+ virtual void update() override;
+ virtual void start() override;
+ virtual void reset() override;
+
+ ATTR_COLD int get_net_idx(net_t *net);
+
+ eSolverType type() const { return m_type; }
+ plog_base<NL_DEBUG> &log() { return netlist().log(); }
+
+ virtual void log_stats();
+
+protected:
+
+ ATTR_COLD void setup_base(analog_net_t::list_t &nets);
+ void update_dynamic();
+
+ virtual void add_term(int net_idx, terminal_t *term) = 0;
+ virtual void vsetup(analog_net_t::list_t &nets) = 0;
+ virtual int vsolve_non_dynamic(const bool newton_raphson) = 0;
+ virtual netlist_time compute_next_timestep() = 0;
+
+ pvector_t<analog_net_t *> m_nets;
+ pvector_t<analog_output_t *> m_inps;
+
+ int m_stat_calculations;
+ int m_stat_newton_raphson;
+ int m_stat_vsolver_calls;
+ int m_iterative_fail;
+ int m_iterative_total;
+
+ const solver_parameters_t &m_params;
+
+ inline nl_double current_timestep() { return m_cur_ts; }
+private:
+
+ netlist_time m_last_step;
+ nl_double m_cur_ts;
+ dev_list_t m_step_devices;
+ dev_list_t m_dynamic_devices;
+
+ logic_input_t m_fb_sync;
+ logic_output_t m_Q_sync;
+
+ void step(const netlist_time &delta);
+
+ void update_inputs();
+
+ const eSolverType m_type;
+};
+
+
+NETLIB_NAMESPACE_DEVICES_END()
+
+#endif /* NLD_MS_DIRECT_H_ */
diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h
index 586b71a2bbe..5d0167f8758 100644
--- a/src/lib/netlist/solver/nld_ms_direct.h
+++ b/src/lib/netlist/solver/nld_ms_direct.h
@@ -39,32 +39,30 @@ public:
virtual void vsetup(analog_net_t::list_t &nets) override;
virtual void reset() override { matrix_solver_t::reset(); }
- inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
-
- virtual int vsolve_non_dynamic(const bool newton_raphson) override;
-
protected:
virtual void add_term(int net_idx, terminal_t *term) override;
-
+ virtual int vsolve_non_dynamic(const bool newton_raphson) override;
int solve_non_dynamic(const bool newton_raphson);
+
+ inline const unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
+
void build_LE_A();
void build_LE_RHS();
void LE_solve();
- void LE_back_subst(nl_double * RESTRICT x);
- /* Full LU back substitution, not used currently, in for future use */
+ template <typename T>
+ void LE_back_subst(T * RESTRICT x);
- void LE_back_subst_full(nl_double * RESTRICT x);
+ template <typename T>
+ T delta(const T * RESTRICT V);
- nl_double delta(const nl_double * RESTRICT V);
- void store(const nl_double * RESTRICT V);
+ template <typename T>
+ void store(const T * RESTRICT V);
- /* bring the whole system to the current time
- * Don't schedule a new calculation time. The recalculation has to be
- * triggered by the caller after the netlist element was changed.
- */
- virtual nl_double compute_next_timestep() override;
+ virtual netlist_time compute_next_timestep() override;
+ terms_t **m_terms;
+ terms_t *m_rails_temp;
#if (NL_USE_DYNAMIC_ALLOCATION)
template <typename T1, typename T2>
@@ -76,13 +74,11 @@ protected:
inline nl_ext_double &A(const T1 &r, const T2 &c) { return m_A[r][c]; }
template <typename T1>
inline nl_ext_double &RHS(const T1 &r) { return m_A[r][N()]; }
-
#endif
ATTR_ALIGN nl_double m_last_RHS[_storage_N]; // right hand side - contains currents
ATTR_ALIGN nl_double m_last_V[_storage_N];
- terms_t **m_terms;
- terms_t *m_rails_temp;
+
private:
static const unsigned m_pitch = (((_storage_N + 1) + 7) / 8) * 8;
@@ -94,6 +90,7 @@ private:
//ATTR_ALIGN nl_ext_double m_RHSx[_storage_N];
const unsigned m_dim;
+
};
// ----------------------------------------------------------------------------------------
@@ -115,7 +112,7 @@ matrix_solver_direct_t<m_N, _storage_N>::~matrix_solver_direct_t()
}
template <unsigned m_N, unsigned _storage_N>
-nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
+netlist_time matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
{
nl_double new_solver_timestep = m_params.m_max_timestep;
@@ -152,7 +149,7 @@ nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
}
//if (new_solver_timestep > 10.0 * hn)
// new_solver_timestep = 10.0 * hn;
- return new_solver_timestep;
+ return netlist_time::from_double(new_solver_timestep);
}
template <unsigned m_N, unsigned _storage_N>
@@ -284,9 +281,15 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
t->m_nz.push_back(other[i]);
}
}
+ /* Add RHS element */
+ if (!t->m_nzrd.contains(N()))
+ t->m_nzrd.push_back(N());
+
+ /* and sort */
psort_list(t->m_nzrd);
t->m_nz.push_back(k); // add diagonal
+
psort_list(t->m_nz);
}
@@ -437,7 +440,7 @@ void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
if (f1 != NL_FCONST(0.0))
{
nl_double * RESTRICT pi = &A(i,i+1);
- nl_double * RESTRICT pj = &A(j,i+1);
+ const nl_double * RESTRICT pj = &A(j,i+1);
#if 1
vec_add_mult_scalar(kN-i,pj,f1,pi);
#else
@@ -466,23 +469,18 @@ void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
{
const unsigned j = pb[jb];
const nl_double f1 = - A(j,i) * f;
-#if 0
- nl_double * RESTRICT pi = &m_A[i][i+1];
- nl_double * RESTRICT pj = &m_A[j][i+1];
- vec_add_mult_scalar(kN-i-1,pi,f1,pj);
-#else
for (unsigned k = 0; k < e; k++)
A(j,p[k]) += A(i,p[k]) * f1;
-#endif
- RHS(j) += RHS(i) * f1;
+ //RHS(j) += RHS(i) * f1;
}
}
}
}
template <unsigned m_N, unsigned _storage_N>
+template <typename T>
void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
- nl_double * RESTRICT x)
+ T * RESTRICT x)
{
const unsigned kN = N();
@@ -491,7 +489,7 @@ void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
{
for (int j = kN - 1; j >= 0; j--)
{
- nl_double tmp = 0;
+ T tmp = 0;
for (unsigned k = j+1; k < kN; k++)
tmp += A(j,k) * x[k];
x[j] = (RHS(j) - tmp) / A(j,j);
@@ -501,10 +499,10 @@ void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
{
for (int j = kN - 1; j >= 0; j--)
{
- nl_double tmp = 0;
+ T tmp = 0;
const unsigned *p = m_terms[j]->m_nzrd.data();
- const unsigned e = m_terms[j]->m_nzrd.size();
+ const unsigned e = m_terms[j]->m_nzrd.size() - 1; /* exclude RHS element */
for (unsigned k = 0; k < e; k++)
{
@@ -516,43 +514,11 @@ void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
}
}
-template <unsigned m_N, unsigned _storage_N>
-void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst_full(
- nl_double * RESTRICT x)
-{
- const unsigned kN = N();
-
- /* back substitution */
-
- // int ip;
- // ii=-1
-
- //for (int i=0; i < kN; i++)
- // x[i] = m_RHS[i];
-
- for (int i=0; i < kN; i++)
- {
- //ip=indx[i]; USE_PIVOT_SEARCH
- //sum=b[ip];
- //b[ip]=b[i];
- double sum=RHS(i);//x[i];
- for (int j=0; j < i; j++)
- sum -= A(i,j) * x[j];
- x[i]=sum;
- }
- for (int i=kN-1; i >= 0; i--)
- {
- double sum=x[i];
- for (int j = i+1; j < kN; j++)
- sum -= A(i,j)*x[j];
- x[i] = sum / A(i,i);
- }
-
-}
template <unsigned m_N, unsigned _storage_N>
-nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
- const nl_double * RESTRICT V)
+template <typename T>
+T matrix_solver_direct_t<m_N, _storage_N>::delta(
+ const T * RESTRICT V)
{
/* FIXME: Ideally we should also include currents (RHS) here. This would
* need a revaluation of the right hand side after voltages have been updated
@@ -560,15 +526,16 @@ nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
*/
const unsigned iN = this->N();
- nl_double cerr = 0;
+ T cerr = 0;
for (unsigned i = 0; i < iN; i++)
cerr = std::max(cerr, nl_math::abs(V[i] - this->m_nets[i]->m_cur_Analog));
return cerr;
}
template <unsigned m_N, unsigned _storage_N>
+template <typename T>
void matrix_solver_direct_t<m_N, _storage_N>::store(
- const nl_double * RESTRICT V)
+ const T * RESTRICT V)
{
for (unsigned i = 0, iN=N(); i < iN; i++)
{
diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h
index 909792a2787..ab19c92a4cb 100644
--- a/src/lib/netlist/solver/nld_ms_direct1.h
+++ b/src/lib/netlist/solver/nld_ms_direct1.h
@@ -30,25 +30,23 @@ public:
inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
{
- analog_net_t *net = m_nets[0];
this->build_LE_A();
this->build_LE_RHS();
//NL_VERBOSE_OUT(("{1} {2}\n", new_val, m_RHS[0] / m_A[0][0]);
- nl_double new_val = RHS(0) / A(0,0);
+ nl_double new_val[1] = { RHS(0) / A(0,0) };
- nl_double e = (new_val - net->Q_Analog());
- nl_double cerr = nl_math::abs(e);
-
- net->m_cur_Analog = new_val;
-
- if (is_dynamic() && (cerr > m_params.m_accuracy))
+ if (is_dynamic())
{
- return 2;
+ nl_double err = this->delta(new_val);
+ store(new_val);
+ if (err > m_params.m_accuracy )
+ return 2;
+ else
+ return 1;
}
- else
- return 1;
-
+ store(new_val);
+ return 1;
}
NETLIB_NAMESPACE_DEVICES_END()
diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h
index 483decbd05d..6ff0d43f421 100644
--- a/src/lib/netlist/solver/nld_ms_gmres.h
+++ b/src/lib/netlist/solver/nld_ms_gmres.h
@@ -58,7 +58,7 @@ public:
private:
- int solve_ilu_gmres(nl_double * RESTRICT x, nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy);
+ int solve_ilu_gmres(nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy);
pvector_t<int> m_term_cr[_storage_N];
@@ -157,6 +157,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton
const nl_double * const * RESTRICT other_cur_analog = this->m_terms[k]->other_curanalog();
l_V[k] = new_V[k] = this->m_nets[k]->m_cur_Analog;
+
for (unsigned i = 0; i < term_count; i++)
{
gtot_t = gtot_t + gt[i];
@@ -180,7 +181,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton
mat.ia[iN] = mat.nz_num;
const nl_double accuracy = this->m_params.m_accuracy;
-#if 1
+
int mr = _storage_N;
if (_storage_N > 3 )
mr = (int) sqrt(iN);
@@ -188,19 +189,12 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton
int iter = 4;
int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy);
int failed = mr * iter;
-#else
- int failed = 6;
- //int gsl = tt_ilu_cr(new_V, RHS, failed, accuracy);
- int gsl = tt_gs_cr(new_V, RHS, failed, accuracy);
-#endif
+
this->m_iterative_total += gsl;
this->m_stat_calculations++;
if (gsl>=failed)
{
- //for (int k = 0; k < iN; k++)
- // this->m_nets[k]->m_cur_Analog = new_V[k];
- // Fallback to direct solver ...
this->m_iterative_fail++;
return matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(newton_raphson);
}
@@ -226,17 +220,18 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton
}
}
-static inline void givens_mult( const nl_double c, const nl_double s, nl_double * RESTRICT g0, nl_double * RESTRICT g1 )
+template <typename T>
+inline void givens_mult( const T c, const T s, T & g0, T & g1 )
{
- const double tg0 = c * *g0 - s * *g1;
- const double tg1 = s * *g0 + c * *g1;
+ const T tg0 = c * g0 - s * g1;
+ const T tg1 = s * g0 + c * g1;
- *g0 = tg0;
- *g1 = tg1;
+ g0 = tg0;
+ g1 = tg1;
}
template <unsigned m_N, unsigned _storage_N>
-int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (nl_double * RESTRICT x, nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy)
+int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy)
{
/*-------------------------------------------------------------------------
* The code below was inspired by code published by John Burkardt under
@@ -342,7 +337,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (nl_double * RESTRIC
vec_scale(n, m_v[k1], NL_FCONST(1.0) / m_ht[k1][k]);
for (unsigned j = 0; j < k; j++)
- givens_mult(m_c[j], m_s[j], &m_ht[j][k], &m_ht[j+1][k]);
+ givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]);
mu = std::sqrt(std::pow(m_ht[k][k], 2) + std::pow(m_ht[k1][k], 2));
@@ -351,7 +346,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (nl_double * RESTRIC
m_ht[k][k] = m_c[k] * m_ht[k][k] - m_s[k] * m_ht[k1][k];
m_ht[k1][k] = 0.0;
- givens_mult(m_c[k], m_s[k], &m_g[k], &m_g[k1]);
+ givens_mult(m_c[k], m_s[k], m_g[k], m_g[k1]);
rho = std::abs(m_g[k1]);
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 39e4fdaacf2..5a7c8fecd40 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -31,7 +31,16 @@
#include <iostream>
#include <algorithm>
+//#include "nld_twoterm.h"
+#include "nl_lists.h"
+
+#if HAS_OPENMP
+#include "omp.h"
+#endif
+
#include "nld_solver.h"
+#include "nld_matrix_solver.h"
+
#if 1
#include "nld_ms_direct.h"
#else
@@ -42,12 +51,6 @@
#include "nld_ms_sor.h"
#include "nld_ms_sor_mat.h"
#include "nld_ms_gmres.h"
-//#include "nld_twoterm.h"
-#include "nl_lists.h"
-
-#if HAS_OPENMP
-#include "omp.h"
-#endif
NETLIB_NAMESPACE_DEVICES_START()
@@ -222,28 +225,28 @@ ATTR_COLD void matrix_solver_t::reset()
ATTR_COLD void matrix_solver_t::update()
{
- const nl_double new_timestep = solve();
+ const netlist_time new_timestep = solve();
- if (m_params.m_dynamic && is_timestep() && new_timestep > 0)
- m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(new_timestep));
+ if (m_params.m_dynamic && is_timestep() && new_timestep > netlist_time::zero)
+ m_Q_sync.net().reschedule_in_queue(new_timestep);
}
ATTR_COLD void matrix_solver_t::update_forced()
{
- ATTR_UNUSED const nl_double new_timestep = solve();
+ ATTR_UNUSED const netlist_time new_timestep = solve();
if (m_params.m_dynamic && is_timestep())
m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
}
-void matrix_solver_t::step(const netlist_time delta)
+void matrix_solver_t::step(const netlist_time &delta)
{
const nl_double dd = delta.as_double();
for (std::size_t k=0; k < m_step_devices.size(); k++)
m_step_devices[k]->step_time(dd);
}
-nl_double matrix_solver_t::solve_base()
+netlist_time matrix_solver_t::solve_base()
{
m_stat_vsolver_calls++;
if (is_dynamic())
@@ -273,7 +276,7 @@ nl_double matrix_solver_t::solve_base()
return this->compute_next_timestep();
}
-nl_double matrix_solver_t::solve()
+netlist_time matrix_solver_t::solve()
{
const netlist_time now = netlist().time();
const netlist_time delta = now - m_last_step;
@@ -281,7 +284,7 @@ nl_double matrix_solver_t::solve()
// We are already up to date. Avoid oscillations.
// FIXME: Make this a parameter!
if (delta < netlist_time::from_nsec(1)) // 20000
- return -1.0;
+ return netlist_time::from_nsec(0);
/* update all terminals for new time step */
m_last_step = now;
@@ -289,7 +292,7 @@ nl_double matrix_solver_t::solve()
step(delta);
- const nl_double next_time_step = solve_base();
+ const netlist_time next_time_step = solve_base();
update_inputs();
return next_time_step;
@@ -427,7 +430,7 @@ NETLIB_UPDATE(solver)
for (auto & solver : m_mat_solvers)
if (solver->is_timestep())
// Ignore return value
- ATTR_UNUSED const nl_double ts = solver->solve();
+ ATTR_UNUSED const netlist_time ts = solver->solve();
#endif
/* step circuit */
diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h
index 93d1e18be0e..6d08e0bbb73 100644
--- a/src/lib/netlist/solver/nld_solver.h
+++ b/src/lib/netlist/solver/nld_solver.h
@@ -48,133 +48,7 @@ struct solver_parameters_t
};
-class terms_t
-{
- P_PREVENT_COPYING(terms_t)
-
- public:
- ATTR_COLD terms_t() : m_railstart(0)
- {}
-
- ATTR_COLD void clear()
- {
- m_term.clear();
- m_net_other.clear();
- m_gt.clear();
- m_go.clear();
- m_Idr.clear();
- m_other_curanalog.clear();
- }
-
- ATTR_COLD void add(terminal_t *term, int net_other, bool sorted);
-
- inline unsigned count() { return m_term.size(); }
-
- inline terminal_t **terms() { return m_term.data(); }
- inline int *net_other() { return m_net_other.data(); }
- inline nl_double *gt() { return m_gt.data(); }
- inline nl_double *go() { return m_go.data(); }
- inline nl_double *Idr() { return m_Idr.data(); }
- inline nl_double **other_curanalog() { return m_other_curanalog.data(); }
-
- ATTR_COLD void set_pointers();
-
- unsigned m_railstart;
-
- pvector_t<unsigned> m_nz; /* all non zero for multiplication */
- pvector_t<unsigned> m_nzrd; /* non zero right of the diagonal for elimination */
- pvector_t<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
-private:
- pvector_t<terminal_t *> m_term;
- pvector_t<int> m_net_other;
- pvector_t<nl_double> m_go;
- pvector_t<nl_double> m_gt;
- pvector_t<nl_double> m_Idr;
- pvector_t<nl_double *> m_other_curanalog;
-};
-
-class matrix_solver_t : public device_t
-{
-public:
- typedef pvector_t<matrix_solver_t *> list_t;
- typedef core_device_t::list_t dev_list_t;
-
- enum eSolverType
- {
- GAUSSIAN_ELIMINATION,
- GAUSS_SEIDEL
- };
-
- ATTR_COLD matrix_solver_t(const eSolverType type, const solver_parameters_t *params);
- virtual ~matrix_solver_t();
-
- void setup(analog_net_t::list_t &nets) { vsetup(nets); }
-
- nl_double solve_base();
-
- nl_double solve();
-
- inline bool is_dynamic() const { return m_dynamic_devices.size() > 0; }
- inline bool is_timestep() const { return m_step_devices.size() > 0; }
-
- void update_forced();
- void update_after(const netlist_time after)
- {
- m_Q_sync.net().reschedule_in_queue(after);
- }
-
- /* netdevice functions */
- virtual void update() override;
- virtual void start() override;
- virtual void reset() override;
-
- ATTR_COLD int get_net_idx(net_t *net);
-
- eSolverType type() const { return m_type; }
- plog_base<NL_DEBUG> &log() { return netlist().log(); }
-
- virtual void log_stats();
-
-protected:
-
- ATTR_COLD void setup_base(analog_net_t::list_t &nets);
- void update_dynamic();
-
- virtual void add_term(int net_idx, terminal_t *term) = 0;
- virtual void vsetup(analog_net_t::list_t &nets) = 0;
- virtual int vsolve_non_dynamic(const bool newton_raphson) = 0;
- virtual nl_double compute_next_timestep() = 0;
-
- pvector_t<analog_net_t *> m_nets;
- pvector_t<analog_output_t *> m_inps;
-
- int m_stat_calculations;
- int m_stat_newton_raphson;
- int m_stat_vsolver_calls;
- int m_iterative_fail;
- int m_iterative_total;
-
- const solver_parameters_t &m_params;
-
- inline nl_double current_timestep() { return m_cur_ts; }
-private:
-
- netlist_time m_last_step;
- nl_double m_cur_ts;
- dev_list_t m_step_devices;
- dev_list_t m_dynamic_devices;
-
- logic_input_t m_fb_sync;
- logic_output_t m_Q_sync;
-
- void step(const netlist_time delta);
-
- void update_inputs();
-
- const eSolverType m_type;
-};
-
-
+class matrix_solver_t;
class NETLIB_NAME(solver) : public device_t
{
@@ -216,7 +90,7 @@ protected:
param_logic_t m_log_stats;
- matrix_solver_t::list_t m_mat_solvers;
+ pvector_t<matrix_solver_t *> m_mat_solvers;
private:
solver_parameters_t m_params;
diff --git a/src/mame/audio/irem.cpp b/src/mame/audio/irem.cpp
index 0d16b99e066..0a7469091fc 100644
--- a/src/mame/audio/irem.cpp
+++ b/src/mame/audio/irem.cpp
@@ -422,8 +422,11 @@ NETLIST_START(kidniki_interface)
PARAM(Solver.ITERATIVE, "SOR")
//PARAM(Solver.ITERATIVE, "MAT")
//PARAM(Solver.ITERATIVE, "GMRES")
- PARAM(Solver.PARALLEL, 1)
+ PARAM(Solver.PARALLEL, 0)
PARAM(Solver.SOR_FACTOR, 1.00)
+ PARAM(Solver.DYNAMIC_TS, 0)
+ PARAM(Solver.DYNAMIC_LTE, 5e-4)
+ PARAM(Solver.MIN_TIMESTEP, 20e-6)
#else
SOLVER(Solver, 12000)
PARAM(Solver.ACCURACY, 1e-8)