Simplified netlist code. It now always provides a stable solution instead of rescheduling the solver. [Couriersud]

This commit is contained in:
Couriersud 2014-04-16 21:52:30 +00:00
parent 77c9001d6f
commit 68d1d68e7f
9 changed files with 62 additions and 82 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------

View File

@ -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()

View File

@ -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

View File

@ -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();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------

View File

@ -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();

View File

@ -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();

View File

@ -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;