diff --git a/src/emu/netlist/analog/nld_bjt.c b/src/emu/netlist/analog/nld_bjt.c index c5feca26848..c3367cb4563 100644 --- a/src/emu/netlist/analog/nld_bjt.c +++ b/src/emu/netlist/analog/nld_bjt.c @@ -165,11 +165,11 @@ NETLIB_START(QBJT_EB) NETLIB_UPDATE(QBJT_EB) { if (!m_D_EB.m_P.net().isRailNet()) - m_D_EB.m_P.net().solve(); // Basis + m_D_EB.m_P.net().schedule_solve(); // Basis else if (!m_D_EB.m_N.net().isRailNet()) - m_D_EB.m_N.net().solve(); // Emitter + m_D_EB.m_N.net().schedule_solve(); // Emitter else - m_D_CB.m_N.net().solve(); // Collector + m_D_CB.m_N.net().schedule_solve(); // Collector } NETLIB_RESET(QBJT_EB) diff --git a/src/emu/netlist/analog/nld_bjt.h b/src/emu/netlist/analog/nld_bjt.h index 78306f80ad9..91e8508bd7e 100644 --- a/src/emu/netlist/analog/nld_bjt.h +++ b/src/emu/netlist/analog/nld_bjt.h @@ -115,6 +115,8 @@ public: } m_RB.set(gb, v, 0.0); m_RC.set(gc, 0.0, 0.0); + //m_RB.update_dev(); + //m_RC.update_dev(); m_state_on = new_state; } } @@ -122,11 +124,11 @@ public: ATTR_HOT ATTR_ALIGN void virtual update() { if (!m_RB.m_P.net().isRailNet()) - m_RB.m_P.net().solve(); // Basis + m_RB.m_P.net().schedule_solve(); // Basis else if (!m_RB.m_N.net().isRailNet()) - m_RB.m_N.net().solve(); // Emitter + m_RB.m_N.net().schedule_solve(); // Emitter else if (!m_RC.m_P.net().isRailNet()) - m_RB.m_P.net().solve(); // Collector + m_RC.m_P.net().schedule_solve(); // Collector } nld_twoterm m_RB; diff --git a/src/emu/netlist/analog/nld_fourterm.c b/src/emu/netlist/analog/nld_fourterm.c index 61579e50bfb..bcc99e9a6a4 100644 --- a/src/emu/netlist/analog/nld_fourterm.c +++ b/src/emu/netlist/analog/nld_fourterm.c @@ -63,13 +63,13 @@ NETLIB_UPDATE(VCCS) /* only called if connected to a rail net ==> notify the solver to recalculate */ /* Big FIXME ... */ if (!m_IP.net().isRailNet()) - m_IP.net().solve(); + m_IP.net().schedule_solve(); else if (!m_IN.net().isRailNet()) - m_IN.net().solve(); + m_IN.net().schedule_solve(); else if (!m_OP.net().isRailNet()) - m_OP.net().solve(); + m_OP.net().schedule_solve(); else if (!m_ON.net().isRailNet()) - m_ON.net().solve(); + m_ON.net().schedule_solve(); } // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index db925466a26..12e537c4729 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -114,24 +114,24 @@ ATTR_HOT void netlist_matrix_solver_t::update_dynamic() ATTR_HOT void netlist_matrix_solver_t::schedule() { - if (!solve()) - { - // NL_VERBOSE_OUT(("update_inputs\n"); - update_inputs(); - } - else - { - m_owner->netlist().warning("Matrix solver reschedule .. Consider increasing RESCHED_LOOPS"); - if (m_owner != NULL) - this->m_owner->schedule(); - } - //solve(); - // update_inputs(); +#if 0 + if (/*!m_scheduled &&*/ m_owner != NULL) + { + m_scheduled = true; + this->m_owner->schedule(); + } +#else + solve(); + update_inputs(); + + m_scheduled = false; +#endif } ATTR_COLD void netlist_matrix_solver_t::reset() { m_last_step = netlist_time::zero; + m_scheduled = true; } ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta) @@ -141,9 +141,8 @@ 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 void netlist_matrix_solver_t::solve() { - int resched_cnt = 0; netlist_time now = owner().netlist().time(); netlist_time delta = now - m_last_step; @@ -162,17 +161,16 @@ ATTR_HOT bool netlist_matrix_solver_t::solve() int this_resched; do { - update_dynamic(); - this_resched = solve_non_dynamic(); - resched_cnt += this_resched; - } while (this_resched > 1 && resched_cnt < m_params.m_resched_loops); + update_dynamic(); + while ((this_resched = solve_non_dynamic()) > m_params.m_resched_loops) + owner().netlist().warning("Dynamic Solve iterations exceeded .. Consider increasing RESCHED_LOOPS"); + } while (this_resched > 1); } else { - resched_cnt = solve_non_dynamic(); - //printf("resched_cnt %d %d\n", resched_cnt, m_resched_loops); + while (solve_non_dynamic() > m_params.m_resched_loops) + owner().netlist().warning("Non-Dynamic Solve iterations exceeded .. Consider increasing RESCHED_LOOPS"); } - return (resched_cnt >= m_params.m_resched_loops); } // ---------------------------------------------------------------------------------------- @@ -425,7 +423,7 @@ ATTR_HOT int netlist_matrix_solver_direct_t::solve_non_dynamic( ATTR_HOT int netlist_matrix_solver_direct1_t::solve_non_dynamic() { -#if 1 +#if 0 double gtot_t = 0.0; double RHS_t = 0.0; @@ -654,7 +652,8 @@ 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(5).as_double()); + register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(5).as_double()); + //register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_US(10).as_double()); m_nt_sync_delay = m_sync_delay.Value(); register_param("FREQ", m_freq, 48000.0); @@ -674,13 +673,13 @@ NETLIB_START(solver) connect(m_fb_sync, m_Q_sync); connect(m_fb_step, m_Q_step); - save(NAME(m_last_step)); + //save(NAME(m_last_step)); } NETLIB_RESET(solver) { - m_last_step = netlist_time::zero; + //m_last_step = netlist_time::zero; for (int i = 0; i < m_mat_solvers.count(); i++) m_mat_solvers[i]->reset(); } @@ -705,18 +704,8 @@ NETLIB_NAME(solver)::~NETLIB_NAME(solver)() NETLIB_UPDATE(solver) { - netlist_time now = netlist().time(); - netlist_time delta = now - m_last_step; - bool do_full = false; - bool global_resched = false; - bool this_resched[100]; int t_cnt = m_mat_solvers.count(); - if (delta < m_inc) - do_full = true; // we have been called between updates - - m_last_step = now; - #if HAS_OPENMP && USE_OPENMP if (m_parallel.Value()) { @@ -738,35 +727,17 @@ NETLIB_UPDATE(solver) this_resched[i] = m_mat_solvers[i]->solve(); } #else - for (int i = 0; i < t_cnt; i++) - { - if (do_full || (m_mat_solvers[i]->is_timestep())) - this_resched[i] = m_mat_solvers[i]->solve(); - } + for (int i = 0; i < t_cnt; i++) + { + if (m_mat_solvers[i]->is_timestep()) + m_mat_solvers[i]->solve(); + m_mat_solvers[i]->update_inputs(); + } #endif - for (int i = 0; i < t_cnt; i++) - { - if (do_full || m_mat_solvers[i]->is_timestep()) - { - global_resched = global_resched || this_resched[i]; - if (!this_resched[i]) - m_mat_solvers[i]->update_inputs(); - } - } - - if (global_resched) - { - netlist().warning("Gobal reschedule .. Consider increasing RESCHED_LOOPS"); - schedule(); - } - else - { - /* step circuit */ - if (!m_Q_step.net().is_queued()) - m_Q_step.net().push_to_queue(m_inc); - } - + /* step circuit */ + if (!m_Q_step.net().is_queued()) + m_Q_step.net().push_to_queue(m_inc); } ATTR_COLD void NETLIB_NAME(solver)::post_start() diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index ca8129bf207..0d4516fc810 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -38,7 +38,7 @@ public: typedef netlist_list_t list_t; typedef netlist_core_device_t::list_t dev_list_t; - netlist_matrix_solver_t() : m_owner(NULL) {} + netlist_matrix_solver_t() : m_scheduled(true), m_owner(NULL) {} virtual ~netlist_matrix_solver_t() {} ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner); @@ -47,7 +47,7 @@ public: ATTR_HOT virtual int solve_non_dynamic() = 0; ATTR_HOT virtual void step(const netlist_time delta); - ATTR_HOT bool solve(); + ATTR_HOT void solve(); ATTR_HOT void update_inputs(); ATTR_HOT void update_dynamic(); @@ -62,6 +62,8 @@ public: netlist_solver_parameters_t m_params; + bool m_scheduled; + protected: netlist_net_t::list_t m_nets; dev_list_t m_dynamic; @@ -175,7 +177,6 @@ NETLIB_DEVICE_WITH_PARAMS(solver, netlist_param_int_t m_parallel; netlist_time m_inc; - netlist_time m_last_step; netlist_time m_nt_sync_delay; netlist_matrix_solver_t::list_t m_mat_solvers; @@ -193,7 +194,9 @@ public: ATTR_HOT inline void NETLIB_NAME(solver)::schedule() { if (!m_Q_sync.net().is_queued()) - m_Q_sync.net().push_to_queue(m_nt_sync_delay); + { + m_Q_sync.net().push_to_queue(m_nt_sync_delay); + } } ATTR_HOT inline const NETLIB_NAME(solver) &netlist_matrix_solver_t::owner() const diff --git a/src/emu/netlist/analog/nld_twoterm.c b/src/emu/netlist/analog/nld_twoterm.c index fa06c784cdf..29ac825201b 100644 --- a/src/emu/netlist/analog/nld_twoterm.c +++ b/src/emu/netlist/analog/nld_twoterm.c @@ -59,9 +59,9 @@ NETLIB_UPDATE(twoterm) /* only called if connected to a rail net ==> notify the solver to recalculate */ /* we only need to call the non-rail terminal */ if (!m_P.net().isRailNet()) - m_P.net().solve(); + m_P.net().schedule_solve(); else - m_N.net().solve(); + m_N.net().schedule_solve(); } // ---------------------------------------------------------------------------------------- diff --git a/src/emu/netlist/analog/nld_twoterm.h b/src/emu/netlist/analog/nld_twoterm.h index d5a2bf7d6f4..1c50d081c76 100644 --- a/src/emu/netlist/analog/nld_twoterm.h +++ b/src/emu/netlist/analog/nld_twoterm.h @@ -115,7 +115,11 @@ class NETLIB_NAME(R_base) : public NETLIB_NAME(twoterm) public: ATTR_COLD NETLIB_NAME(R_base)() : NETLIB_NAME(twoterm)(RESISTOR) { } - inline void set_R(const double R) { set(1.0 / R, 0.0, 0.0); } + inline void set_R(const double R) + { + set(1.0 / R, 0.0, 0.0); + //update_dev(); + } protected: ATTR_COLD virtual void start(); diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index e1ee8165192..b06400d26ff 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -712,7 +712,7 @@ ATTR_HOT ATTR_ALIGN inline void netlist_net_t::update_devs() m_last_Analog = m_cur_Analog; } -ATTR_HOT void netlist_net_t::solve() +ATTR_HOT void netlist_net_t::schedule_solve() { if (m_solver != NULL) m_solver->schedule(); diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index 2ca53f13d49..0d3c0139ab1 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -623,7 +623,7 @@ public: netlist_matrix_solver_t *m_solver; netlist_core_terminal_t * RESTRICT m_railterminal; - ATTR_HOT void solve(); + ATTR_HOT void schedule_solve(); netlist_list_t m_core_terms; // save post-start m_list ... plinked_list m_list_active;