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

View File

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

View File

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

View File

@ -114,24 +114,24 @@ ATTR_HOT void netlist_matrix_solver_t::update_dynamic()
ATTR_HOT void netlist_matrix_solver_t::schedule()
{
if (!solve())
#if 0
if (/*!m_scheduled &&*/ m_owner != NULL)
{
// NL_VERBOSE_OUT(("update_inputs\n");
update_inputs();
}
else
{
m_owner->netlist().warning("Matrix solver reschedule .. Consider increasing RESCHED_LOOPS");
if (m_owner != NULL)
m_scheduled = true;
this->m_owner->schedule();
}
//solve();
// update_inputs();
#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;
@ -163,16 +162,15 @@ ATTR_HOT bool netlist_matrix_solver_t::solve()
do
{
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
} while (this_resched > 1 && resched_cnt < m_params.m_resched_loops);
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;
@ -655,6 +653,7 @@ NETLIB_START(solver)
//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_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())
{
@ -740,33 +729,15 @@ NETLIB_UPDATE(solver)
#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();
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);
}
}
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_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);
}
}
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 */
/* 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();
}
// ----------------------------------------------------------------------------------------

View File

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

View File

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

View File

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