From bcbd00db40543ed9bf3744be6c0270edd9834a40 Mon Sep 17 00:00:00 2001 From: Couriersud Date: Sun, 19 Jan 2014 13:16:25 +0000 Subject: [PATCH] Removed dead code and simplified matrix solvers. No Wn --- src/emu/netlist/analog/nld_bjt.c | 128 ---------- src/emu/netlist/analog/nld_bjt.h | 108 +-------- src/emu/netlist/analog/nld_fourterm.c | 5 +- src/emu/netlist/analog/nld_solver.c | 325 +++++++++++++------------- src/emu/netlist/analog/nld_solver.h | 63 ++--- src/emu/netlist/analog/nld_switches.c | 8 +- src/emu/netlist/analog/nld_twoterm.c | 14 +- src/emu/netlist/devices/net_lib.c | 7 +- src/emu/netlist/devices/nld_signal.h | 21 +- src/emu/netlist/nl_base.c | 21 +- src/emu/netlist/nl_config.h | 2 +- src/emu/netlist/nl_lists.h | 29 +-- 12 files changed, 217 insertions(+), 514 deletions(-) diff --git a/src/emu/netlist/analog/nld_bjt.c b/src/emu/netlist/analog/nld_bjt.c index fca0441701e..b6256f8079d 100644 --- a/src/emu/netlist/analog/nld_bjt.c +++ b/src/emu/netlist/analog/nld_bjt.c @@ -58,64 +58,6 @@ NETLIB_UPDATE(Q) // nld_QBJT_switch // ---------------------------------------------------------------------------------------- -#if USE_OLD_S -NETLIB_START(QBJT_switch) -{ - NETLIB_NAME(Q)::start(); - - register_sub(m_RB, "RB"); - register_sub(m_RC, "RC"); - register_input("BV", m_BV); - register_input("EV", m_EV); - - register_subalias("B", m_RB.m_P); - register_subalias("E", m_RB.m_N); - register_subalias("C", m_RC.m_P); - - connect(m_RB.m_N, m_RC.m_N); - connect(m_RB.m_P, m_BV); - connect(m_RB.m_N, m_EV); - - save(NAME(m_state_on)); - - m_RB.set(NETLIST_GMIN, 0.0, 0.0); - m_RC.set(NETLIST_GMIN, 0.0, 0.0); - - m_state_on = 0; - - { - double IS = m_model.model_value("IS", 1e-15); - double BF = m_model.model_value("BF", 100); - double NF = m_model.model_value("NF", 1); - //double VJE = m_model.dValue("VJE", 0.75); - - set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); - - double alpha = BF / (1.0 + BF); - - diode d(IS, NF); - - // Assume 5mA Collector current for switch operation - - m_V = d.V(0.005 / alpha); - - /* Base current is 0.005 / beta - * as a rough estimate, we just scale the conductance down */ - - m_gB = d.gI(0.005 / alpha) / BF; - - if (m_gB < NETLIST_GMIN) - m_gB = NETLIST_GMIN; - m_gC = BF * m_gB; // very rough estimate - //printf("%f %f \n", m_V, m_gB); - } - -} - -NETLIB_UPDATE_PARAM(QBJT_switch) -{ -} -#else NETLIB_START(QBJT_switch) { NETLIB_NAME(Q)::start(); @@ -175,77 +117,12 @@ NETLIB_UPDATE_PARAM(QBJT_switch) { } -#endif - // ---------------------------------------------------------------------------------------- // nld_Q - Ebers Moll // ---------------------------------------------------------------------------------------- -#define USE_OLD_B (0) - -#if USE_OLD_B -NETLIB_START(QBJT_EB) -{ - NETLIB_NAME(Q)::start(); - - register_terminal("B", m_D_BE.m_P); // Anode - register_terminal("E", m_D_BE.m_N); // Cathode - - register_terminal("_B1", m_D_BC.m_P); // Anode - register_terminal("C", m_D_BC.m_N); // Cathode - - register_terminal("_B2", m_I_BE.m_P); - register_terminal("_E2", m_I_BE.m_N); - - register_terminal("_B3", m_I_BC.m_P); - register_terminal("_C1", m_I_BC.m_N); - - connect(m_D_BE.m_P, m_D_BC.m_P); - connect(m_D_BE.m_P, m_I_BE.m_P); - connect(m_D_BE.m_P, m_I_BC.m_P); - - connect(m_D_BE.m_N, m_I_BE.m_N); - connect(m_D_BC.m_N, m_I_BC.m_N); - - m_gD_BE.save("m_D_BE", *this); - m_gD_BC.save("m_D_BC", *this); - - { - double IS = m_model.model_value("IS", 1e-15); - double BF = m_model.model_value("BF", 100); - double NF = m_model.model_value("NF", 1); - double BR = m_model.model_value("BR", 1); - double NR = m_model.model_value("NR", 1); - //double VJE = m_model.dValue("VJE", 0.75); - - set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP); - //printf("type %s\n", m_model.model_type().cstr()); - - m_alpha_f = BF / (1.0 + BF); - m_alpha_r = BR / (1.0 + BR); - - m_gD_BE.set_param(IS / m_alpha_f, NF); - m_gD_BC.set_param(IS / m_alpha_r, NR); - } -} - -NETLIB_UPDATE(QBJT_EB) -{ -#if !(USE_ALTERNATE_SCHEDULING) - netlist().solver()->schedule1(); -#else - if (!m_D_BE.m_P.net().isRailNet()) - m_D_BE.m_P.net().solve(); // Basis - else if (!m_D_BE.m_N.net().isRailNet()) - m_D_BE.m_N.net().solve(); // Emitter - else - m_D_BC.m_N.net().solve(); // Collector -#endif -} - -#else NETLIB_START(QBJT_EB) { NETLIB_NAME(Q)::start(); @@ -287,18 +164,13 @@ NETLIB_START(QBJT_EB) NETLIB_UPDATE(QBJT_EB) { -#if !(USE_ALTERNATE_SCHEDULING) - netlist().solver()->schedule1(); -#else if (!m_D_EB.m_P.net().isRailNet()) m_D_EB.m_P.net().solve(); // Basis else if (!m_D_EB.m_N.net().isRailNet()) m_D_EB.m_N.net().solve(); // Emitter else m_D_CB.m_N.net().solve(); // Collector -#endif } -#endif NETLIB_RESET(QBJT_EB) { diff --git a/src/emu/netlist/analog/nld_bjt.h b/src/emu/netlist/analog/nld_bjt.h index 38554acdf5e..6d4bb60967c 100644 --- a/src/emu/netlist/analog/nld_bjt.h +++ b/src/emu/netlist/analog/nld_bjt.h @@ -86,64 +86,6 @@ private: * E */ -#define USE_OLD_S (0) - -#if USE_OLD_S -class NETLIB_NAME(QBJT_switch) : public NETLIB_NAME(QBJT) -{ -public: - ATTR_COLD NETLIB_NAME(QBJT_switch)() - : NETLIB_NAME(QBJT)(BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { } - - - NETLIB_UPDATEI() - { - double vE = INPANALOG(m_EV); - double vB = INPANALOG(m_BV); - double m = (is_qtype( BJT_NPN) ? 1 : -1); - - int new_state = ((vB - vE) * m > m_V ) ? 1 : 0; - if (m_state_on ^ new_state) - { - double gb = m_gB; - double gc = m_gC; - double v = m_V * m; - if (!new_state ) - { - // not conducting - gb = NETLIST_GMIN; - v = 0; - gc = NETLIST_GMIN; - } - m_RB.set(gb, v, 0.0); - m_RC.set(gc, 0.0, 0.0); - m_state_on = new_state; - // Don't update m_RB - could cause an infinite loop - m_RB.update_dev(); - m_RC.update_dev(); - } - - } - - NETLIB_NAME(R) m_RB; - NETLIB_NAME(R) m_RC; - - netlist_analog_input_t m_BV; - netlist_analog_input_t m_EV; - -protected: - - ATTR_COLD virtual void start(); - ATTR_HOT void update_param(); - - double m_gB; // base conductance / switch on - double m_gC; // collector conductance / switch on - double m_V; // internal voltage source - UINT8 m_state_on; - -private: -}; -#else class NETLIB_NAME(QBJT_switch) : public NETLIB_NAME(QBJT) { public: @@ -207,60 +149,12 @@ protected: private: }; -#endif // ---------------------------------------------------------------------------------------- // nld_QBJT_EB // ---------------------------------------------------------------------------------------- -#define USE_OLD_B (0) -#if USE_OLD_B -class NETLIB_NAME(QBJT_EB) : public NETLIB_NAME(QBJT) -{ -public: - ATTR_COLD NETLIB_NAME(QBJT_EB)() - : NETLIB_NAME(QBJT)(BJT_EB), - m_D_BC(netlist_object_t::ANALOG), - m_D_BE(netlist_object_t::ANALOG), - m_I_BC(netlist_object_t::ANALOG), - m_I_BE(netlist_object_t::ANALOG) - { } - - NETLIB_UPDATE_TERMINALS() - { - m_gD_BE.update_diode(m_D_BE.deltaV()); - m_gD_BC.update_diode(m_D_BC.deltaV()); - - m_D_BE.set(m_gD_BE.G(), 0.0, m_gD_BE.Ieq()); - m_D_BC.set(m_gD_BC.G(), 0.0, m_gD_BC.Ieq()); - - m_I_BE.set(0.0, 0.0, - m_alpha_r * m_gD_BC.I()); - m_I_BC.set(0.0, 0.0, - m_alpha_f * m_gD_BE.I()); - } - -protected: - - ATTR_COLD virtual void start(); - ATTR_COLD virtual void reset(); - ATTR_HOT void update_param(); - ATTR_HOT ATTR_ALIGN void virtual update(); - - netlist_generic_diode m_gD_BC; - netlist_generic_diode m_gD_BE; - - nld_twoterm m_D_BC; - nld_twoterm m_D_BE; - - nld_twoterm m_I_BC; - nld_twoterm m_I_BE; - - double m_alpha_f; - double m_alpha_r; - -private: -}; -#else class NETLIB_NAME(QBJT_EB) : public NETLIB_NAME(QBJT) { public: @@ -312,5 +206,5 @@ protected: private: }; -#endif + #endif /* NLD_BJT_H_ */ diff --git a/src/emu/netlist/analog/nld_fourterm.c b/src/emu/netlist/analog/nld_fourterm.c index 38bd2089417..32376031396 100644 --- a/src/emu/netlist/analog/nld_fourterm.c +++ b/src/emu/netlist/analog/nld_fourterm.c @@ -59,14 +59,11 @@ NETLIB_UPDATE_PARAM(VCCS) NETLIB_UPDATE(VCCS) { /* only called if connected to a rail net ==> notify the solver to recalculate */ -#if !(USE_ALTERNATE_SCHEDULING) - netlist().solver()->schedule1(); -#else + /* Big FIXME ... */ m_IP.net().solve(); m_IN.net().solve(); m_OP.net().solve(); m_ON.net().solve(); -#endif } // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index 9b448a67713..6333da2f65d 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -140,13 +140,44 @@ ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta) m_steps[k]->step_time(dd); } +ATTR_HOT inline bool netlist_matrix_solver_t::solve() +{ + int resched_cnt = 0; + + netlist_time now = owner().netlist().time(); + netlist_time delta = now - m_last_step; + if (delta >= netlist_time::from_nsec(1)) // always update capacitors + { + NL_VERBOSE_OUT(("Step!\n")); + /* update all terminals for new time step */ + m_last_step = now; + step(delta); + } + + if (is_dynamic()) + { + int this_resched; + do + { + update_dynamic(); + this_resched = solve_non_dynamic(); + resched_cnt += this_resched; + } while (this_resched > 1 && resched_cnt < m_resched_loops); + } + else + { + resched_cnt = solve_non_dynamic(); + } + return (resched_cnt >= m_resched_loops); +} + // ---------------------------------------------------------------------------------------- // netlist_matrix_solver - Direct base // ---------------------------------------------------------------------------------------- template -ATTR_COLD int netlist_matrix_solver_directb_t::get_net_idx(netlist_net_t *net) +ATTR_COLD int netlist_matrix_solver_direct_t::get_net_idx(netlist_net_t *net) { for (int k = 0; k < N(); k++) if (m_nets[k] == net) @@ -155,7 +186,7 @@ ATTR_COLD int netlist_matrix_solver_directb_t::get_net_idx(netl } template -ATTR_COLD void netlist_matrix_solver_directb_t::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) +ATTR_COLD void netlist_matrix_solver_direct_t::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) { netlist_matrix_solver_t::setup(nets, owner); @@ -201,7 +232,9 @@ ATTR_COLD void netlist_matrix_solver_directb_t::setup(netlist_n } template -ATTR_HOT inline void netlist_matrix_solver_directb_t::build_LE(double (* RESTRICT m_A)[_storage_N], double (* RESTRICT m_RHS)) +ATTR_HOT inline void netlist_matrix_solver_direct_t::build_LE( + double (* RESTRICT A)[_storage_N], + double (* RESTRICT RHS)) { #if 0 @@ -223,22 +256,117 @@ ATTR_HOT inline void netlist_matrix_solver_directb_t::build_LE for (int i = 0; i < m_rail_start; i++) { terms_t &t = m_terms[i]; - m_RHS[t.net_this] += t.term->m_Idr; - m_A[t.net_this][t.net_this] += t.term->m_gt; + RHS[t.net_this] += t.term->m_Idr; + A[t.net_this][t.net_this] += t.term->m_gt; - m_A[t.net_this][t.net_other] += -t.term->m_go; + A[t.net_this][t.net_other] += -t.term->m_go; } for (int i = m_rail_start; i < m_term_num; i++) { terms_t &t = m_terms[i]; - m_RHS[t.net_this] += t.term->m_Idr; - m_A[t.net_this][t.net_this] += t.term->m_gt; + RHS[t.net_this] += t.term->m_Idr; + A[t.net_this][t.net_this] += t.term->m_gt; - m_RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().Q_Analog(); + RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().Q_Analog(); } #endif } +template +ATTR_HOT inline void netlist_matrix_solver_direct_t::gauss_LE( + double (* RESTRICT A)[_storage_N], + double (* RESTRICT RHS), + double (* RESTRICT x)) +{ + for (int i = 0; i < N(); i++) { + +#if 0 + /* Find the row with the largest first value */ + maxrow = i; + for (j=i+1;j ABS(a[i][maxrow])) + maxrow = j; + } + + /* Swap the maxrow and ith row */ + for (k=i;k= 0; j--) + { + double tmp = 0; + for (int k = j + 1; k < N(); k++) + tmp += A[j][k] * x[k]; + x[j] = (RHS[j] - tmp) / A[j][j]; + } + +} + +template +ATTR_HOT inline double netlist_matrix_solver_direct_t::delta_and_store( + double (* RESTRICT RHS), + double (* RESTRICT V)) +{ + double cerr = 0; + double cerr2 = 0; + for (int i = 0; i < this->N(); i++) + { + double e = (V[i] - this->m_nets[i]->m_cur.Analog); + double e2 = (RHS[i] - this->m_RHS[i]); + cerr += e * e; + cerr2 += e2 * e2; + this->m_nets[i]->m_cur.Analog = this->m_nets[i]->m_new.Analog = V[i]; + this->m_RHS[i] = RHS[i]; + } + return (cerr + cerr2*(100000.0 * 100000.0)) / this->N(); +} + +template +ATTR_HOT int netlist_matrix_solver_direct_t::solve_non_dynamic() +{ + double A[_storage_N][_storage_N] = { { 0.0 } }; + double RHS[_storage_N] = { 0.0 }; + double new_v[_storage_N] = { 0.0 }; + + this->build_LE(A, RHS); + + this->gauss_LE(A, RHS, new_v); + + if (this->is_dynamic()) + { + double err = delta_and_store(RHS, new_v); + + if (err > this->m_accuracy * this->m_accuracy) + { + return 2; + } + } + return 1; +} + + // ---------------------------------------------------------------------------------------- // netlist_matrix_solver - Direct1 // ---------------------------------------------------------------------------------------- @@ -246,12 +374,6 @@ ATTR_HOT inline void netlist_matrix_solver_directb_t::build_LE ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic() { #if 1 - ATTR_UNUSED netlist_net_t *last_resched_net = NULL; - - /* over-relaxation not really works on these matrices */ - //const double w = 1.0; //2.0 / (1.0 + sin(3.14159 / (m_nets.count()+1))); - //const double w1 = 1.0 - w; - //NL_VERBOSE_OUT(("%d %d\n", N(), 1); double gtot_t = 0.0; double RHS_t = 0.0; @@ -294,40 +416,6 @@ ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic() } -ATTR_HOT inline bool netlist_matrix_solver_direct1_t::solve() -{ - int resched_cnt = 0; - ATTR_UNUSED netlist_net_t *last_resched_net = NULL; - - if (USE_ALTERNATE_SCHEDULING) - { - netlist_time now = owner().netlist().time(); - netlist_time delta = now - m_last_step; - if (delta >= netlist_time::from_nsec(5)) // always update capacitors - { - NL_VERBOSE_OUT(("Step!\n")); - /* update all terminals for new time step */ - m_last_step = now; - step(delta); - } - } - - if (is_dynamic()) - { - int this_resched; - do - { - update_dynamic(); - this_resched = solve_non_dynamic(); - resched_cnt += this_resched; - } while (this_resched > 1 && resched_cnt < m_resched_loops); - } - else - { - resched_cnt = solve_non_dynamic(); - } - return (resched_cnt >= m_resched_loops); -} // ---------------------------------------------------------------------------------------- // netlist_matrix_solver - Direct2 @@ -335,74 +423,30 @@ ATTR_HOT inline bool netlist_matrix_solver_direct1_t::solve() ATTR_HOT int netlist_matrix_solver_direct2_t::solve_non_dynamic() { - double m_A[2][2] = { { 0.0 } }; - double m_RHS[2] = { 0.0 }; + double A[2][2] = { { 0.0 } }; + double RHS[2] = { 0.0 }; + + build_LE(A, RHS); - build_LE(m_A, m_RHS); //NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]); - const double a = m_A[0][0]; - const double b = m_A[0][1]; - const double c = m_A[1][0]; - const double d = m_A[1][1]; + const double a = A[0][0]; + const double b = A[0][1]; + const double c = A[1][0]; + const double d = A[1][1]; - const double new_val1 = a / (a*d - b*c) * (m_RHS[1] - c / a * m_RHS[0]); - const double new_val0 = (m_RHS[0] - b * new_val1) / a; + double new_val[2]; + new_val[1] = a / (a*d - b*c) * (RHS[1] - c / a * RHS[0]); + new_val[0] = (RHS[0] - b * new_val[1]) / a; - double e = (new_val0 - m_nets[0]->m_cur.Analog); - double cerr = e * e; - m_nets[0]->m_cur.Analog = m_nets[0]->m_new.Analog = new_val0; - - e = (new_val1 - m_nets[1]->m_cur.Analog); - cerr += e * e; - m_nets[1]->m_cur.Analog = m_nets[1]->m_new.Analog = new_val1; - - if (is_dynamic() && (cerr / N() > m_accuracy * m_accuracy)) + if (is_dynamic() && (delta_and_store(RHS, new_val) > m_accuracy * m_accuracy)) { return 2; } else return 1; - } - -ATTR_HOT inline bool netlist_matrix_solver_direct2_t::solve() -{ - int resched_cnt = 0; - ATTR_UNUSED netlist_net_t *last_resched_net = NULL; - - if (USE_ALTERNATE_SCHEDULING) - { - netlist_time now = owner().netlist().time(); - netlist_time delta = now - m_last_step; - if (delta >= netlist_time::from_nsec(5)) // always update capacitors - { - NL_VERBOSE_OUT(("Step!\n")); - /* update all terminals for new time step */ - m_last_step = now; - step(delta); - } - } - - if (is_dynamic()) - { - int this_resched; - do - { - update_dynamic(); - this_resched = solve_non_dynamic(); - resched_cnt += this_resched; - } while (this_resched > 1 && resched_cnt < m_resched_loops); - } - else - { - resched_cnt = solve_non_dynamic(); - } - return (resched_cnt >= m_resched_loops); -} - - // ---------------------------------------------------------------------------------------- // netlist_matrix_solver - Gauss - Seidel // ---------------------------------------------------------------------------------------- @@ -503,51 +547,6 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t::solve return resched_cnt; } - -template -ATTR_HOT inline bool netlist_matrix_solver_gauss_seidel_t< m_N, _storage_N>::solve() -{ - int resched_cnt = 0; - ATTR_UNUSED netlist_net_t *last_resched_net = NULL; - - m_resched = false; - - if (USE_ALTERNATE_SCHEDULING) - { - netlist_time now = owner().netlist().time(); - netlist_time delta = now - m_last_step; - if (delta >= netlist_time::from_nsec(5)) // always update capacitors - { - NL_VERBOSE_OUT(("Step!\n")); - /* update all terminals for new time step */ - m_last_step = now; - step(delta); - } - } - - if (is_dynamic()) - { - int this_resched; - do - { - update_dynamic(); - this_resched = solve_non_dynamic(); - resched_cnt += this_resched; - } while (this_resched > 1 && resched_cnt < m_resched_loops); - } - else - { - resched_cnt = solve_non_dynamic(); - } - if (resched_cnt >= m_resched_loops) - m_resched = true; - - //if (resched) - //NL_VERBOSE_OUT(("Resched on net %s first term %s\n", last_resched_net->name().cstr(), last_resched_net->m_terms[0]->name().cstr()); - - return m_resched; -} - // ---------------------------------------------------------------------------------------- // solver // ---------------------------------------------------------------------------------------- @@ -594,14 +593,14 @@ NETLIB_START(solver) register_output("Q_step", m_Q_step); //register_input("FB", m_feedback); - register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(10).as_double()); + register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(5).as_double()); m_nt_sync_delay = m_sync_delay.Value(); register_param("FREQ", m_freq, 48000.0); m_inc = netlist_time::from_hz(m_freq.Value()); //register_param("ACCURACY", m_accuracy, 1e-3); - register_param("ACCURACY", m_accuracy, 1e-6); + register_param("ACCURACY", m_accuracy, 1e-7); register_param("CONVERG", m_convergence, 0.3); register_param("RESCHED_LOOPS", m_resched_loops, 35); @@ -646,26 +645,15 @@ NETLIB_UPDATE(solver) { netlist_time now = netlist().time(); netlist_time delta = now - m_last_step; - bool do_full = (USE_ALTERNATE_SCHEDULING ? false : true); + bool do_full = false; bool global_resched = false; bool this_resched[100]; if (delta < m_inc) do_full = true; // we have been called between updates - //FIXME: make this a parameter - if (!USE_ALTERNATE_SCHEDULING && delta >= netlist_time::from_nsec(5)) // always update capacitors - { - NL_VERBOSE_OUT(("Step!\n")); - /* update all terminals for new time step */ - for (netlist_matrix_solver_t * const *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e)) - { - (*e)->step(delta); - } - } m_last_step = now; - #if HAS_OPENMP && USE_OPENMP int t_cnt = m_mat_solvers.count(); omp_set_num_threads(3); @@ -739,20 +727,25 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() ms = new netlist_matrix_solver_direct1_t(); break; case 2: - //ms = new netlist_matrix_solver_gauss_seidel_t<2,2>(); - // Below is only half as fast as gauss_seidel .... ms = new netlist_matrix_solver_direct2_t(); break; + /* FIXME: There is an issue (singularity during gaussian elemination + * with the direct solver - use gauss_seidel + */ case 3: + //ms = new netlist_matrix_solver_direct_t<3,3>(); ms = new netlist_matrix_solver_gauss_seidel_t<3,3>(); break; case 4: + //ms = new netlist_matrix_solver_direct_t<4,4>(); ms = new netlist_matrix_solver_gauss_seidel_t<4,4>(); break; case 5: + //ms = new netlist_matrix_solver_direct_t<5,5>(); ms = new netlist_matrix_solver_gauss_seidel_t<5,5>(); break; default: + //ms = new netlist_matrix_solver_direct_t<0,16>(); ms = new netlist_matrix_solver_gauss_seidel_t<0,16>(); break; } diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index 59bbd208c2c..18aab7e0b9c 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -36,10 +36,11 @@ public: ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner); // return true if a reschedule is needed ... - ATTR_HOT virtual bool solve() = 0; ATTR_HOT virtual int solve_non_dynamic() = 0; ATTR_HOT virtual void step(const netlist_time delta); + ATTR_HOT bool solve(); + ATTR_HOT void update_inputs(); ATTR_HOT void update_dynamic(); @@ -66,21 +67,30 @@ protected: }; template -class netlist_matrix_solver_directb_t: public netlist_matrix_solver_t +class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t { public: - netlist_matrix_solver_directb_t() : netlist_matrix_solver_t() {} + netlist_matrix_solver_direct_t() : netlist_matrix_solver_t() {} - virtual ~netlist_matrix_solver_directb_t() {} + virtual ~netlist_matrix_solver_direct_t() {} ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner); + ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); } + ATTR_HOT virtual int solve_non_dynamic(); ATTR_HOT inline const int N() const { return (m_N == 0) ? m_nets.count() : m_N; } - ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); } protected: - ATTR_HOT inline void build_LE(double (* RESTRICT m_A)[_storage_N], double (* RESTRICT m_RHS)); + ATTR_HOT inline void build_LE(double (* RESTRICT A)[_storage_N], double (* RESTRICT RHS)); + ATTR_HOT inline void gauss_LE(double (* RESTRICT A)[_storage_N], + double (* RESTRICT RHS), + double (* RESTRICT x)); + ATTR_HOT inline double delta_and_store( + double (* RESTRICT RHS), + double (* RESTRICT V)); + + double m_RHS[_storage_N]; // right hand side - contains currents private: @@ -101,68 +111,35 @@ class netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_t { public: - netlist_matrix_solver_gauss_seidel_t() : netlist_matrix_solver_t(), m_resched(false) {} + netlist_matrix_solver_gauss_seidel_t() : netlist_matrix_solver_t() {} virtual ~netlist_matrix_solver_gauss_seidel_t() {} ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) { - m_resched = true; netlist_matrix_solver_t::setup(nets, owner); } - // return true if a reschedule is needed ... - ATTR_HOT bool solve(); ATTR_HOT int solve_non_dynamic(); + ATTR_HOT inline const int N() const { if (m_N == 0) return m_nets.count(); else return m_N; } ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); } private: - bool m_resched; }; -class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_directb_t<1,1> +class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1> { public: - - netlist_matrix_solver_direct1_t() : netlist_matrix_solver_directb_t() {} - - virtual ~netlist_matrix_solver_direct1_t() {} - - ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) - { - netlist_matrix_solver_directb_t::setup(nets, owner); - } - - // return true if a reschedule is needed ... - ATTR_HOT bool solve(); ATTR_HOT int solve_non_dynamic(); - - //ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); } - private: }; -class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_directb_t<2,2> +class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2> { public: - - netlist_matrix_solver_direct2_t() : netlist_matrix_solver_directb_t() {} - - virtual ~netlist_matrix_solver_direct2_t() {} - - ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner) - { - netlist_matrix_solver_directb_t::setup(nets, owner); - } - - // return true if a reschedule is needed ... - ATTR_HOT bool solve(); ATTR_HOT int solve_non_dynamic(); - - //ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); } - private: }; diff --git a/src/emu/netlist/analog/nld_switches.c b/src/emu/netlist/analog/nld_switches.c index 245ff243d20..6df63373c09 100644 --- a/src/emu/netlist/analog/nld_switches.c +++ b/src/emu/netlist/analog/nld_switches.c @@ -49,9 +49,7 @@ NETLIB_UPDATE_PARAM(switch2) m_R[0].set_R(R_OFF); m_R[1].set_R(R_ON); } - if (USE_ALTERNATE_SCHEDULING) - { - m_R[0].update_dev(); - m_R[1].update_dev(); - } + + m_R[0].update_dev(); + m_R[1].update_dev(); } diff --git a/src/emu/netlist/analog/nld_twoterm.c b/src/emu/netlist/analog/nld_twoterm.c index 2187b67740f..53116802bea 100644 --- a/src/emu/netlist/analog/nld_twoterm.c +++ b/src/emu/netlist/analog/nld_twoterm.c @@ -29,15 +29,11 @@ NETLIB_RESET(twoterm) NETLIB_UPDATE(twoterm) { /* only called if connected to a rail net ==> notify the solver to recalculate */ -#if !(USE_ALTERNATE_SCHEDULING) - netlist().solver()->schedule1(); -#else /* we only need to call the non-rail terminal */ if (!m_P.net().isRailNet()) m_P.net().solve(); else m_N.net().solve(); -#endif } // ---------------------------------------------------------------------------------------- @@ -81,8 +77,7 @@ NETLIB_UPDATE_PARAM(R) { //printf("updating %s to %f\n", name().cstr(), m_R.Value()); set_R(m_R.Value()); - if (USE_ALTERNATE_SCHEDULING) - update_dev(); + update_dev(); } // ---------------------------------------------------------------------------------------- @@ -126,11 +121,8 @@ NETLIB_UPDATE_PARAM(POT) m_R1.set_R(MAX(m_R.Value() * v, NETLIST_GMIN)); m_R2.set_R(MAX(m_R.Value() * (1.0 - v), NETLIST_GMIN)); // force a schedule all - if (USE_ALTERNATE_SCHEDULING) - { - m_R1.update_dev(); - m_R2.update_dev(); - } + m_R1.update_dev(); + m_R2.update_dev(); } // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c index 9a184fc670d..6348ae5d2a1 100644 --- a/src/emu/netlist/devices/net_lib.c +++ b/src/emu/netlist/devices/net_lib.c @@ -199,10 +199,7 @@ NETLIB_UPDATE(nic7450) m_I3.activate(); UINT8 t1 = INPLOGIC(m_I0) & INPLOGIC(m_I1); UINT8 t2 = INPLOGIC(m_I2) & INPLOGIC(m_I3); -#if 0 - UINT8 t = (t1 | t2) ^ 1; - OUTLOGIC(m_Q, t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15)); -#else + const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) }; UINT8 res = 0; @@ -225,8 +222,6 @@ NETLIB_UPDATE(nic7450) } } OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000); - -#endif } diff --git a/src/emu/netlist/devices/nld_signal.h b/src/emu/netlist/devices/nld_signal.h index 3e151e93571..6232e68d8a1 100644 --- a/src/emu/netlist/devices/nld_signal.h +++ b/src/emu/netlist/devices/nld_signal.h @@ -153,26 +153,22 @@ public: INT32 m_active; }; -#if 1 template -class xx_net_signal_t: public netlist_device_t +class net_signal_2inp_t: public netlist_device_t { public: - xx_net_signal_t() + net_signal_2inp_t() : netlist_device_t(), m_active(1) { } ATTR_COLD void start() { - const char *sIN[2] = { "A", "B" }; - register_output("Q", m_Q); - for (int i=0; i < 2; i++) - { - register_input(sIN[i], m_i[i]); - } - save(NAME(m_active)); + register_input("A", m_i[0]); + register_input("B", m_i[1]); + + save(NAME(m_active)); } ATTR_COLD void reset() @@ -229,7 +225,6 @@ public: INT32 m_active; }; -#endif // The following did not improve performance #if 0 @@ -297,11 +292,11 @@ public: template -class net_signal_t<2, _check, _invert> : public xx_net_signal_t<_check, _invert> +class net_signal_t<2, _check, _invert> : public net_signal_2inp_t<_check, _invert> { public: net_signal_t() - : xx_net_signal_t<_check, _invert>() { } + : net_signal_2inp_t<_check, _invert>() { } }; diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index 441864b3d46..2f61848101b 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -286,13 +286,6 @@ ATTR_COLD void netlist_base_t::error(const char *format, ...) const // net_core_device_t // ---------------------------------------------------------------------------------------- -#if 0 -ATTR_COLD netlist_core_device_t::netlist_core_device_t() -: netlist_object_t(DEVICE, GENERIC), m_family_desc(NULL) -{ -} -#endif - ATTR_COLD netlist_core_device_t::netlist_core_device_t(const family_t afamily) : netlist_object_t(DEVICE, afamily), m_family_desc(NULL) { @@ -535,13 +528,20 @@ ATTR_HOT inline void netlist_net_t::update_devs() assert(this->isRailNet()); - const UINT32 masks[4] = { 1, 5, 3, 1 }; + static const UINT32 masks[4] = { 1, 5, 3, 1 }; + const UINT32 mask = masks[ (m_last.Q << 1) | m_new.Q ]; + m_cur = m_new; m_in_queue = 2; /* mark as taken ... */ - const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ]; - netlist_core_terminal_t *p = m_head; +#if 0 + do + { + update_dev(p, mask); + p = p->m_update_list_next; + } while (p != NULL); +#else switch (m_num_cons) { case 2: @@ -558,6 +558,7 @@ ATTR_HOT inline void netlist_net_t::update_devs() } while (p != NULL); break; } +#endif m_last = m_cur; } diff --git a/src/emu/netlist/nl_config.h b/src/emu/netlist/nl_config.h index 9702f62d06a..5136d5ae6b1 100644 --- a/src/emu/netlist/nl_config.h +++ b/src/emu/netlist/nl_config.h @@ -34,7 +34,7 @@ #define NETLIST_INTERNAL_RES (U64(1000000000)) //#define NETLIST_INTERNAL_RES (U64(1000000000000)) -#define USE_ALTERNATE_SCHEDULING (1) +//#define USE_ALTERNATE_SCHEDULING (1) #define NETLIST_CLOCK (NETLIST_INTERNAL_RES) diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h index 70f0569d0f4..a581b590f4c 100644 --- a/src/emu/netlist/nl_lists.h +++ b/src/emu/netlist/nl_lists.h @@ -165,26 +165,15 @@ public: ATTR_HOT ATTR_ALIGN void push(const entry_t &e) { -#if 0 - // less is more - if (is_empty() || (e.time() <= (m_end - 1)->time())) - { - *m_end++ = e; - inc_stat(m_prof_end); - } - else -#endif - { - entry_t * RESTRICT i = m_end++; - while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) ) - { - i--; - *(i+1) = *i; - inc_stat(m_prof_sortmove); - } - *i = e; - inc_stat(m_prof_sort); - } + entry_t * RESTRICT i = m_end++; + while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) ) + { + i--; + *(i+1) = *i; + inc_stat(m_prof_sortmove); + } + *i = e; + inc_stat(m_prof_sort); assert(m_end - m_list < _Size); }