mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
Simplified netlist code. It now always provides a stable solution instead of rescheduling the solver. [Couriersud]
This commit is contained in:
parent
77c9001d6f
commit
68d1d68e7f
@ -165,11 +165,11 @@ NETLIB_START(QBJT_EB)
|
|||||||
NETLIB_UPDATE(QBJT_EB)
|
NETLIB_UPDATE(QBJT_EB)
|
||||||
{
|
{
|
||||||
if (!m_D_EB.m_P.net().isRailNet())
|
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())
|
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
|
else
|
||||||
m_D_CB.m_N.net().solve(); // Collector
|
m_D_CB.m_N.net().schedule_solve(); // Collector
|
||||||
}
|
}
|
||||||
|
|
||||||
NETLIB_RESET(QBJT_EB)
|
NETLIB_RESET(QBJT_EB)
|
||||||
|
@ -115,6 +115,8 @@ public:
|
|||||||
}
|
}
|
||||||
m_RB.set(gb, v, 0.0);
|
m_RB.set(gb, v, 0.0);
|
||||||
m_RC.set(gc, 0.0, 0.0);
|
m_RC.set(gc, 0.0, 0.0);
|
||||||
|
//m_RB.update_dev();
|
||||||
|
//m_RC.update_dev();
|
||||||
m_state_on = new_state;
|
m_state_on = new_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,11 +124,11 @@ public:
|
|||||||
ATTR_HOT ATTR_ALIGN void virtual update()
|
ATTR_HOT ATTR_ALIGN void virtual update()
|
||||||
{
|
{
|
||||||
if (!m_RB.m_P.net().isRailNet())
|
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())
|
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())
|
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;
|
nld_twoterm m_RB;
|
||||||
|
@ -63,13 +63,13 @@ NETLIB_UPDATE(VCCS)
|
|||||||
/* only called if connected to a rail net ==> notify the solver to recalculate */
|
/* only called if connected to a rail net ==> notify the solver to recalculate */
|
||||||
/* Big FIXME ... */
|
/* Big FIXME ... */
|
||||||
if (!m_IP.net().isRailNet())
|
if (!m_IP.net().isRailNet())
|
||||||
m_IP.net().solve();
|
m_IP.net().schedule_solve();
|
||||||
else if (!m_IN.net().isRailNet())
|
else if (!m_IN.net().isRailNet())
|
||||||
m_IN.net().solve();
|
m_IN.net().schedule_solve();
|
||||||
else if (!m_OP.net().isRailNet())
|
else if (!m_OP.net().isRailNet())
|
||||||
m_OP.net().solve();
|
m_OP.net().schedule_solve();
|
||||||
else if (!m_ON.net().isRailNet())
|
else if (!m_ON.net().isRailNet())
|
||||||
m_ON.net().solve();
|
m_ON.net().schedule_solve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
@ -114,24 +114,24 @@ ATTR_HOT void netlist_matrix_solver_t::update_dynamic()
|
|||||||
|
|
||||||
ATTR_HOT void netlist_matrix_solver_t::schedule()
|
ATTR_HOT void netlist_matrix_solver_t::schedule()
|
||||||
{
|
{
|
||||||
if (!solve())
|
#if 0
|
||||||
|
if (/*!m_scheduled &&*/ m_owner != NULL)
|
||||||
{
|
{
|
||||||
// NL_VERBOSE_OUT(("update_inputs\n");
|
m_scheduled = true;
|
||||||
update_inputs();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_owner->netlist().warning("Matrix solver reschedule .. Consider increasing RESCHED_LOOPS");
|
|
||||||
if (m_owner != NULL)
|
|
||||||
this->m_owner->schedule();
|
this->m_owner->schedule();
|
||||||
}
|
}
|
||||||
//solve();
|
#else
|
||||||
// update_inputs();
|
solve();
|
||||||
|
update_inputs();
|
||||||
|
|
||||||
|
m_scheduled = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_COLD void netlist_matrix_solver_t::reset()
|
ATTR_COLD void netlist_matrix_solver_t::reset()
|
||||||
{
|
{
|
||||||
m_last_step = netlist_time::zero;
|
m_last_step = netlist_time::zero;
|
||||||
|
m_scheduled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta)
|
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);
|
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 now = owner().netlist().time();
|
||||||
netlist_time delta = now - m_last_step;
|
netlist_time delta = now - m_last_step;
|
||||||
@ -163,16 +162,15 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
update_dynamic();
|
update_dynamic();
|
||||||
this_resched = solve_non_dynamic();
|
while ((this_resched = solve_non_dynamic()) > m_params.m_resched_loops)
|
||||||
resched_cnt += this_resched;
|
owner().netlist().warning("Dynamic Solve iterations exceeded .. Consider increasing RESCHED_LOOPS");
|
||||||
} while (this_resched > 1 && resched_cnt < m_params.m_resched_loops);
|
} while (this_resched > 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resched_cnt = solve_non_dynamic();
|
while (solve_non_dynamic() > m_params.m_resched_loops)
|
||||||
//printf("resched_cnt %d %d\n", resched_cnt, 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<m_N, _storage_N>::solve_non_dynamic(
|
|||||||
|
|
||||||
ATTR_HOT int netlist_matrix_solver_direct1_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 gtot_t = 0.0;
|
||||||
double RHS_t = 0.0;
|
double RHS_t = 0.0;
|
||||||
@ -655,6 +653,7 @@ NETLIB_START(solver)
|
|||||||
//register_input("FB", m_feedback);
|
//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();
|
m_nt_sync_delay = m_sync_delay.Value();
|
||||||
|
|
||||||
register_param("FREQ", m_freq, 48000.0);
|
register_param("FREQ", m_freq, 48000.0);
|
||||||
@ -674,13 +673,13 @@ NETLIB_START(solver)
|
|||||||
connect(m_fb_sync, m_Q_sync);
|
connect(m_fb_sync, m_Q_sync);
|
||||||
connect(m_fb_step, m_Q_step);
|
connect(m_fb_step, m_Q_step);
|
||||||
|
|
||||||
save(NAME(m_last_step));
|
//save(NAME(m_last_step));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NETLIB_RESET(solver)
|
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++)
|
for (int i = 0; i < m_mat_solvers.count(); i++)
|
||||||
m_mat_solvers[i]->reset();
|
m_mat_solvers[i]->reset();
|
||||||
}
|
}
|
||||||
@ -705,18 +704,8 @@ NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
|
|||||||
|
|
||||||
NETLIB_UPDATE(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();
|
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 HAS_OPENMP && USE_OPENMP
|
||||||
if (m_parallel.Value())
|
if (m_parallel.Value())
|
||||||
{
|
{
|
||||||
@ -740,33 +729,15 @@ NETLIB_UPDATE(solver)
|
|||||||
#else
|
#else
|
||||||
for (int i = 0; i < t_cnt; i++)
|
for (int i = 0; i < t_cnt; i++)
|
||||||
{
|
{
|
||||||
if (do_full || (m_mat_solvers[i]->is_timestep()))
|
if (m_mat_solvers[i]->is_timestep())
|
||||||
this_resched[i] = m_mat_solvers[i]->solve();
|
m_mat_solvers[i]->solve();
|
||||||
|
m_mat_solvers[i]->update_inputs();
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/* step circuit */
|
||||||
if (!m_Q_step.net().is_queued())
|
if (!m_Q_step.net().is_queued())
|
||||||
m_Q_step.net().push_to_queue(m_inc);
|
m_Q_step.net().push_to_queue(m_inc);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_COLD void NETLIB_NAME(solver)::post_start()
|
ATTR_COLD void NETLIB_NAME(solver)::post_start()
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
|
typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
|
||||||
typedef netlist_core_device_t::list_t dev_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() {}
|
virtual ~netlist_matrix_solver_t() {}
|
||||||
|
|
||||||
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
|
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 int solve_non_dynamic() = 0;
|
||||||
ATTR_HOT virtual void step(const netlist_time delta);
|
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_inputs();
|
||||||
ATTR_HOT void update_dynamic();
|
ATTR_HOT void update_dynamic();
|
||||||
@ -62,6 +62,8 @@ public:
|
|||||||
|
|
||||||
netlist_solver_parameters_t m_params;
|
netlist_solver_parameters_t m_params;
|
||||||
|
|
||||||
|
bool m_scheduled;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
netlist_net_t::list_t m_nets;
|
netlist_net_t::list_t m_nets;
|
||||||
dev_list_t m_dynamic;
|
dev_list_t m_dynamic;
|
||||||
@ -175,7 +177,6 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
|
|||||||
netlist_param_int_t m_parallel;
|
netlist_param_int_t m_parallel;
|
||||||
|
|
||||||
netlist_time m_inc;
|
netlist_time m_inc;
|
||||||
netlist_time m_last_step;
|
|
||||||
netlist_time m_nt_sync_delay;
|
netlist_time m_nt_sync_delay;
|
||||||
|
|
||||||
netlist_matrix_solver_t::list_t m_mat_solvers;
|
netlist_matrix_solver_t::list_t m_mat_solvers;
|
||||||
@ -193,7 +194,9 @@ public:
|
|||||||
ATTR_HOT inline void NETLIB_NAME(solver)::schedule()
|
ATTR_HOT inline void NETLIB_NAME(solver)::schedule()
|
||||||
{
|
{
|
||||||
if (!m_Q_sync.net().is_queued())
|
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
|
ATTR_HOT inline const NETLIB_NAME(solver) &netlist_matrix_solver_t::owner() const
|
||||||
|
@ -59,9 +59,9 @@ NETLIB_UPDATE(twoterm)
|
|||||||
/* only called if connected to a rail net ==> notify the solver to recalculate */
|
/* only called if connected to a rail net ==> notify the solver to recalculate */
|
||||||
/* we only need to call the non-rail terminal */
|
/* we only need to call the non-rail terminal */
|
||||||
if (!m_P.net().isRailNet())
|
if (!m_P.net().isRailNet())
|
||||||
m_P.net().solve();
|
m_P.net().schedule_solve();
|
||||||
else
|
else
|
||||||
m_N.net().solve();
|
m_N.net().schedule_solve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
@ -115,7 +115,11 @@ class NETLIB_NAME(R_base) : public NETLIB_NAME(twoterm)
|
|||||||
public:
|
public:
|
||||||
ATTR_COLD NETLIB_NAME(R_base)() : NETLIB_NAME(twoterm)(RESISTOR) { }
|
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:
|
protected:
|
||||||
ATTR_COLD virtual void start();
|
ATTR_COLD virtual void start();
|
||||||
|
@ -712,7 +712,7 @@ ATTR_HOT ATTR_ALIGN inline void netlist_net_t::update_devs()
|
|||||||
m_last_Analog = m_cur_Analog;
|
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)
|
if (m_solver != NULL)
|
||||||
m_solver->schedule();
|
m_solver->schedule();
|
||||||
|
@ -623,7 +623,7 @@ public:
|
|||||||
netlist_matrix_solver_t *m_solver;
|
netlist_matrix_solver_t *m_solver;
|
||||||
netlist_core_terminal_t * RESTRICT m_railterminal;
|
netlist_core_terminal_t * RESTRICT m_railterminal;
|
||||||
|
|
||||||
ATTR_HOT void solve();
|
ATTR_HOT void schedule_solve();
|
||||||
|
|
||||||
netlist_list_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
|
netlist_list_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||||
plinked_list<netlist_core_terminal_t> m_list_active;
|
plinked_list<netlist_core_terminal_t> m_list_active;
|
||||||
|
Loading…
Reference in New Issue
Block a user