summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2014-12-31 14:51:20 +0100
committer couriersud <couriersud@arcor.de>2014-12-31 14:51:20 +0100
commite198be8555f69608c13d2d44a50517bde8ebf73c (patch)
treeec9fec0f643e6e264e0854723b69a888ee3d728c
parentf563f3bbf2be759d612fe4f8c982faa35f2351c5 (diff)
Netlist update. Most prominent one is a "frontier" element which on a
low to high impedance node will - no other connections provided - let the system create two matrices.
-rw-r--r--src/emu/netlist/analog/nld_ms_direct.h25
-rw-r--r--src/emu/netlist/analog/nld_ms_gauss_seidel.h19
-rw-r--r--src/emu/netlist/analog/nld_opamps.c2
-rw-r--r--src/emu/netlist/analog/nld_solver.c14
-rw-r--r--src/emu/netlist/analog/nld_solver.h18
-rw-r--r--src/emu/netlist/devices/net_lib.c1
-rw-r--r--src/emu/netlist/devices/nld_4020.c3
-rw-r--r--src/emu/netlist/devices/nld_cmos.h6
-rw-r--r--src/emu/netlist/devices/nld_system.h40
-rw-r--r--src/emu/netlist/nl_base.h1
10 files changed, 109 insertions, 20 deletions
diff --git a/src/emu/netlist/analog/nld_ms_direct.h b/src/emu/netlist/analog/nld_ms_direct.h
index e067a476989..ed1215ec293 100644
--- a/src/emu/netlist/analog/nld_ms_direct.h
+++ b/src/emu/netlist/analog/nld_ms_direct.h
@@ -14,6 +14,7 @@ class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t
public:
netlist_matrix_solver_direct_t(const netlist_solver_parameters_t &params, int size);
+ netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t &params, int size);
virtual ~netlist_matrix_solver_direct_t();
@@ -186,13 +187,17 @@ ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::vsetup(netlist_a
* Sorting as a general matrix pre-conditioning is mentioned in
* literature but I have found no articles about Gauss Seidel.
*
+ * For Gaussian Elimination however increasing order is better suited.
+ * FIXME: Even better would be to sort on elements right of the matrix diagonal.
+ *
*/
+ int sort_order = (type() == GAUSS_SEIDEL ? 1 : -1);
for (int k = 0; k < N() / 2; k++)
for (int i = 0; i < N() - 1; i++)
{
- if (m_terms[i]->m_railstart < m_terms[i+1]->m_railstart)
+ if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0)
{
std::swap(m_terms[i],m_terms[i+1]);
m_nets.swap(i, i+1);
@@ -443,7 +448,7 @@ ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_
template <int m_N, int _storage_N>
netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const netlist_solver_parameters_t &params, int size)
-: netlist_matrix_solver_t(params)
+: netlist_matrix_solver_t(GAUSSIAN_ELIMINATION, params)
, m_dim(size)
, m_lp_fact(0)
{
@@ -458,6 +463,22 @@ netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(
m_row_ops[N()] = vector_ops_t::create_ops(N());
}
+template <int m_N, int _storage_N>
+netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(const eSolverType type, const netlist_solver_parameters_t &params, int size)
+: netlist_matrix_solver_t(type, params)
+, m_dim(size)
+, m_lp_fact(0)
+{
+ m_terms = new terms_t *[N()];
+ m_rails_temp = new terms_t[N()];
+
+ for (int k = 0; k < N(); k++)
+ {
+ m_terms[k] = new terms_t;
+ m_row_ops[k] = vector_ops_t::create_ops(k);
+ }
+ m_row_ops[N()] = vector_ops_t::create_ops(N());
+}
#endif /* NLD_MS_DIRECT_H_ */
diff --git a/src/emu/netlist/analog/nld_ms_gauss_seidel.h b/src/emu/netlist/analog/nld_ms_gauss_seidel.h
index 270aaf227a3..e09bf33cfb2 100644
--- a/src/emu/netlist/analog/nld_ms_gauss_seidel.h
+++ b/src/emu/netlist/analog/nld_ms_gauss_seidel.h
@@ -17,7 +17,7 @@ class ATTR_ALIGNED(64) netlist_matrix_solver_gauss_seidel_t: public netlist_matr
public:
netlist_matrix_solver_gauss_seidel_t(const netlist_solver_parameters_t &params, int size)
- : netlist_matrix_solver_direct_t<m_N, _storage_N>(params, size)
+ : netlist_matrix_solver_direct_t<m_N, _storage_N>(netlist_matrix_solver_t::GAUSS_SEIDEL, params, size)
, m_lp_fact(0)
, m_gs_fail(0)
, m_gs_total(0)
@@ -45,20 +45,21 @@ private:
template <int m_N, int _storage_N>
void netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::log_stats()
{
-#if 0
- if (this->m_calculations == 0)
+#if 1
+ if (this->m_stat_calculations == 0)
return;
printf("==============================================\n");
printf("Solver %s\n", this->name().cstr());
printf(" ==> %d nets\n", this->N()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
printf(" has %s elements\n", this->is_dynamic() ? "dynamic" : "no dynamic");
printf(" has %s elements\n", this->is_timestep() ? "timestep" : "no timestep");
+ printf(" %6.3f average newton raphson loops\n", (double) this->m_stat_newton_raphson / (double) this->m_stat_vsolver_calls);
printf(" %10d invocations (%6d Hz) %10d gs fails (%6.2f%%) %6.3f average\n",
- this->m_calculations,
- this->m_calculations * 10 / (int) (this->netlist().time().as_double() * 10.0),
+ this->m_stat_calculations,
+ this->m_stat_calculations * 10 / (int) (this->netlist().time().as_double() * 10.0),
this->m_gs_fail,
- 100.0 * (double) this->m_gs_fail / (double) this->m_calculations,
- (double) this->m_gs_total / (double) this->m_calculations);
+ 100.0 * (double) this->m_gs_fail / (double) this->m_stat_calculations,
+ (double) this->m_gs_total / (double) this->m_stat_calculations);
#endif
}
@@ -292,7 +293,7 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolv
//if (fabs(gabs_t - fabs(gtot_t)) > 1e-20)
// printf("%d %e abs: %f tot: %f\n",k, gabs_t / gtot_t -1.0, gabs_t, gtot_t);
- gabs_t *= 0.5; // avoid rounding issues
+ gabs_t *= 0.95; // avoid rounding issues
if (!USE_GABS || gabs_t <= gtot_t)
{
w[k] = ws / gtot_t;
@@ -336,7 +337,7 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolv
this->m_nets[k]->m_cur_Analog = new_V[k];
this->m_gs_total += resched_cnt;
- this->m_calculations++;
+ this->m_stat_calculations++;
if (resched)
{
diff --git a/src/emu/netlist/analog/nld_opamps.c b/src/emu/netlist/analog/nld_opamps.c
index 6ee4f8e3640..32d2457e71f 100644
--- a/src/emu/netlist/analog/nld_opamps.c
+++ b/src/emu/netlist/analog/nld_opamps.c
@@ -31,7 +31,7 @@ NETLIST_START(opamp_lm3900)
NET_C(R1.2, R2.2, G1.ON)
VCVS(G1)
PARAM(G1.G, 10000000)
- //PARAM(G1.RI, 100)
+ //PARAM(G1.RI, 1)
PARAM(G1.RO, RES_K(8))
NETLIST_END()
diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c
index 653a621b6e0..bef3dcbcd77 100644
--- a/src/emu/netlist/analog/nld_solver.c
+++ b/src/emu/netlist/analog/nld_solver.c
@@ -36,7 +36,7 @@
#include "../nl_lists.h"
#if HAS_OPENMP
-#include <omp.h>
+#include "omp.h"
#endif
vector_ops_t *vector_ops_t::create_ops(const int size)
@@ -99,8 +99,13 @@ ATTR_COLD void terms_t::set_pointers()
// netlist_matrix_solver
// ----------------------------------------------------------------------------------------
-ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t(const netlist_solver_parameters_t &params)
-: m_calculations(0), m_params(params), m_cur_ts(0)
+ATTR_COLD netlist_matrix_solver_t::netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t &params)
+: m_stat_calculations(0),
+ m_stat_newton_raphson(0),
+ m_stat_vsolver_calls(0),
+ m_params(params),
+ m_cur_ts(0),
+ m_type(type)
{
}
@@ -254,6 +259,7 @@ ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta)
template<class C >
void netlist_matrix_solver_t::solve_base(C *p)
{
+ m_stat_vsolver_calls++;
if (is_dynamic())
{
int this_resched;
@@ -266,6 +272,7 @@ void netlist_matrix_solver_t::solve_base(C *p)
newton_loops++;
} while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
+ m_stat_newton_raphson += newton_loops;
// reschedule ....
if (this_resched > 1 && !m_Q_sync.net().is_queued())
{
@@ -285,6 +292,7 @@ ATTR_HOT double netlist_matrix_solver_t::solve()
netlist_time delta = now - m_last_step;
// We are already up to date. Avoid oscillations.
+ // FIXME: Make this a parameter!
if (delta < netlist_time::from_nsec(1))
return -1.0;
diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h
index a0f6ea470f9..8aa87025e53 100644
--- a/src/emu/netlist/analog/nld_solver.h
+++ b/src/emu/netlist/analog/nld_solver.h
@@ -14,7 +14,7 @@
#define USE_PIVOT_SEARCH (0)
#define VECTALT 1
-#define USE_GABS 0
+#define USE_GABS 1
#define USE_MATRIX_GS 0
// savings are eaten up by effort
#define USE_LINEAR_PREDICTION (0)
@@ -197,7 +197,13 @@ public:
typedef plinearlist_t<netlist_matrix_solver_t *> list_t;
typedef netlist_core_device_t::list_t dev_list_t;
- ATTR_COLD netlist_matrix_solver_t(const netlist_solver_parameters_t &params);
+ enum eSolverType
+ {
+ GAUSSIAN_ELIMINATION,
+ GAUSS_SEIDEL
+ };
+
+ ATTR_COLD netlist_matrix_solver_t(const eSolverType type, const netlist_solver_parameters_t &params);
ATTR_COLD virtual ~netlist_matrix_solver_t();
ATTR_COLD virtual void vsetup(netlist_analog_net_t::list_t &nets) = 0;
@@ -224,6 +230,8 @@ public:
ATTR_COLD int get_net_idx(netlist_net_t *net);
ATTR_COLD virtual void log_stats() {};
+ inline const eSolverType type() const { return m_type; }
+
protected:
ATTR_COLD void setup(netlist_analog_net_t::list_t &nets);
@@ -237,7 +245,10 @@ protected:
plinearlist_t<netlist_analog_net_t *> m_nets;
plinearlist_t<netlist_analog_output_t *> m_inps;
- int m_calculations;
+ int m_stat_calculations;
+ int m_stat_newton_raphson;
+ int m_stat_vsolver_calls;
+
const netlist_solver_parameters_t &m_params;
ATTR_HOT inline const double current_timestep() { return m_cur_ts; }
@@ -255,6 +266,7 @@ private:
ATTR_HOT void update_inputs();
+ const eSolverType m_type;
};
diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c
index 28e2809f777..b9d6686b964 100644
--- a/src/emu/netlist/devices/net_lib.c
+++ b/src/emu/netlist/devices/net_lib.c
@@ -91,6 +91,7 @@ void netlist_factory_t::initialize()
ENTRY(VCCS, VCCS, "-")
ENTRY(CCCS, CCCS, "-")
ENTRY(dummy_input, DUMMY_INPUT, "-")
+ ENTRY(frontier, FRONTIER, "+I,Q")
ENTRY(QBJT_EB, QBJT_EB, "model")
ENTRY(QBJT_switch, QBJT_SW, "model")
ENTRY(ttl_input, TTL_INPUT, "IN")
diff --git a/src/emu/netlist/devices/nld_4020.c b/src/emu/netlist/devices/nld_4020.c
index b9b5eb2f0c0..4a477efcff6 100644
--- a/src/emu/netlist/devices/nld_4020.c
+++ b/src/emu/netlist/devices/nld_4020.c
@@ -8,6 +8,7 @@
NETLIB_START(4020)
{
register_sub(sub, "sub");
+ register_sub(m_supply, "supply");
register_input("RESET", m_RESET);
register_subalias("IP", sub.m_IP);
@@ -42,7 +43,7 @@ NETLIB_START(4020_sub)
register_output("Q5", m_Q[4]);
register_output("Q6", m_Q[5]);
register_output("Q7", m_Q[6]);
- register_output("Q8", m_Q[8]);
+ register_output("Q8", m_Q[7]);
register_output("Q9", m_Q[8]);
register_output("Q10", m_Q[9]);
register_output("Q11", m_Q[10]);
diff --git a/src/emu/netlist/devices/nld_cmos.h b/src/emu/netlist/devices/nld_cmos.h
index 4d450c2003e..5be09d905cd 100644
--- a/src/emu/netlist/devices/nld_cmos.h
+++ b/src/emu/netlist/devices/nld_cmos.h
@@ -21,7 +21,11 @@ class nld_vdd_vss : public netlist_device_t
protected:
ATTR_HOT void update() {};
- ATTR_HOT void start() {};
+ ATTR_HOT void start()
+ {
+ register_input("VDD,", m_vdd);
+ register_input("VSS,", m_vss);
+ };
ATTR_HOT void reset() {};
public:
diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h
index f1397e4365a..47ca470d197 100644
--- a/src/emu/netlist/devices/nld_system.h
+++ b/src/emu/netlist/devices/nld_system.h
@@ -39,6 +39,11 @@
#define DUMMY_INPUT(_name) \
NET_REGISTER_DEV(dummy_input, _name)
+#define FRONTIER(_name, _IN, _OUT) \
+ NET_REGISTER_DEV(frontier, _name) \
+ NET_C(_IN, _name.I) \
+ NET_C(_OUT, _name.Q) \
+
// -----------------------------------------------------------------------------
// mainclock
// -----------------------------------------------------------------------------
@@ -147,6 +152,41 @@ private:
};
+// -----------------------------------------------------------------------------
+// nld_frontier
+// -----------------------------------------------------------------------------
+
+class NETLIB_NAME(frontier) : public netlist_device_t
+{
+public:
+ ATTR_COLD NETLIB_NAME(frontier)()
+ : netlist_device_t(DUMMY) { }
+
+ ATTR_COLD virtual ~NETLIB_NAME(frontier)() {}
+
+protected:
+
+ ATTR_COLD void start()
+ {
+ register_input("I", m_I);
+ register_output("Q", m_Q);
+ }
+
+ ATTR_COLD void reset()
+ {
+ }
+
+ ATTR_HOT ATTR_ALIGN void update()
+ {
+ OUTANALOG(m_Q, INPANALOG(m_I));
+ }
+
+private:
+ netlist_analog_input_t m_I;
+ netlist_analog_output_t m_Q;
+
+};
+
// -----------------------------------------------------------------------------
// netdev_a_to_d
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index 1a94734ed93..59803356a9c 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -337,6 +337,7 @@ public:
CAPACITOR, // Capacitor
DIODE, // Diode
DUMMY, // DUMMY device without function
+ FRONTIER, // Net frontier
BJT_EB, // BJT(Ebers-Moll)
BJT_SWITCH, // BJT(Switch)
VCVS, // Voltage controlled voltage source