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)
|
||||
{
|
||||
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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -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<m_N, _storage_N>::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()
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
typedef netlist_list_t<netlist_matrix_solver_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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
plinked_list<netlist_core_terminal_t> m_list_active;
|
||||
|
Loading…
Reference in New Issue
Block a user