Removed dead code and simplified matrix solvers. No Wn

This commit is contained in:
Couriersud 2014-01-19 13:16:25 +00:00
parent 61f3de3165
commit bcbd00db40
12 changed files with 217 additions and 514 deletions

View File

@ -58,64 +58,6 @@ NETLIB_UPDATE(Q)
// nld_QBJT_switch
// ----------------------------------------------------------------------------------------
#if USE_OLD_S
NETLIB_START(QBJT_switch)
{
NETLIB_NAME(Q)::start();
register_sub(m_RB, "RB");
register_sub(m_RC, "RC");
register_input("BV", m_BV);
register_input("EV", m_EV);
register_subalias("B", m_RB.m_P);
register_subalias("E", m_RB.m_N);
register_subalias("C", m_RC.m_P);
connect(m_RB.m_N, m_RC.m_N);
connect(m_RB.m_P, m_BV);
connect(m_RB.m_N, m_EV);
save(NAME(m_state_on));
m_RB.set(NETLIST_GMIN, 0.0, 0.0);
m_RC.set(NETLIST_GMIN, 0.0, 0.0);
m_state_on = 0;
{
double IS = m_model.model_value("IS", 1e-15);
double BF = m_model.model_value("BF", 100);
double NF = m_model.model_value("NF", 1);
//double VJE = m_model.dValue("VJE", 0.75);
set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
double alpha = BF / (1.0 + BF);
diode d(IS, NF);
// Assume 5mA Collector current for switch operation
m_V = d.V(0.005 / alpha);
/* Base current is 0.005 / beta
* as a rough estimate, we just scale the conductance down */
m_gB = d.gI(0.005 / alpha) / BF;
if (m_gB < NETLIST_GMIN)
m_gB = NETLIST_GMIN;
m_gC = BF * m_gB; // very rough estimate
//printf("%f %f \n", m_V, m_gB);
}
}
NETLIB_UPDATE_PARAM(QBJT_switch)
{
}
#else
NETLIB_START(QBJT_switch)
{
NETLIB_NAME(Q)::start();
@ -175,77 +117,12 @@ NETLIB_UPDATE_PARAM(QBJT_switch)
{
}
#endif
// ----------------------------------------------------------------------------------------
// nld_Q - Ebers Moll
// ----------------------------------------------------------------------------------------
#define USE_OLD_B (0)
#if USE_OLD_B
NETLIB_START(QBJT_EB)
{
NETLIB_NAME(Q)::start();
register_terminal("B", m_D_BE.m_P); // Anode
register_terminal("E", m_D_BE.m_N); // Cathode
register_terminal("_B1", m_D_BC.m_P); // Anode
register_terminal("C", m_D_BC.m_N); // Cathode
register_terminal("_B2", m_I_BE.m_P);
register_terminal("_E2", m_I_BE.m_N);
register_terminal("_B3", m_I_BC.m_P);
register_terminal("_C1", m_I_BC.m_N);
connect(m_D_BE.m_P, m_D_BC.m_P);
connect(m_D_BE.m_P, m_I_BE.m_P);
connect(m_D_BE.m_P, m_I_BC.m_P);
connect(m_D_BE.m_N, m_I_BE.m_N);
connect(m_D_BC.m_N, m_I_BC.m_N);
m_gD_BE.save("m_D_BE", *this);
m_gD_BC.save("m_D_BC", *this);
{
double IS = m_model.model_value("IS", 1e-15);
double BF = m_model.model_value("BF", 100);
double NF = m_model.model_value("NF", 1);
double BR = m_model.model_value("BR", 1);
double NR = m_model.model_value("NR", 1);
//double VJE = m_model.dValue("VJE", 0.75);
set_qtype((m_model.model_type() == "NPN") ? BJT_NPN : BJT_PNP);
//printf("type %s\n", m_model.model_type().cstr());
m_alpha_f = BF / (1.0 + BF);
m_alpha_r = BR / (1.0 + BR);
m_gD_BE.set_param(IS / m_alpha_f, NF);
m_gD_BC.set_param(IS / m_alpha_r, NR);
}
}
NETLIB_UPDATE(QBJT_EB)
{
#if !(USE_ALTERNATE_SCHEDULING)
netlist().solver()->schedule1();
#else
if (!m_D_BE.m_P.net().isRailNet())
m_D_BE.m_P.net().solve(); // Basis
else if (!m_D_BE.m_N.net().isRailNet())
m_D_BE.m_N.net().solve(); // Emitter
else
m_D_BC.m_N.net().solve(); // Collector
#endif
}
#else
NETLIB_START(QBJT_EB)
{
NETLIB_NAME(Q)::start();
@ -287,18 +164,13 @@ NETLIB_START(QBJT_EB)
NETLIB_UPDATE(QBJT_EB)
{
#if !(USE_ALTERNATE_SCHEDULING)
netlist().solver()->schedule1();
#else
if (!m_D_EB.m_P.net().isRailNet())
m_D_EB.m_P.net().solve(); // Basis
else if (!m_D_EB.m_N.net().isRailNet())
m_D_EB.m_N.net().solve(); // Emitter
else
m_D_CB.m_N.net().solve(); // Collector
#endif
}
#endif
NETLIB_RESET(QBJT_EB)
{

View File

@ -86,64 +86,6 @@ private:
* E
*/
#define USE_OLD_S (0)
#if USE_OLD_S
class NETLIB_NAME(QBJT_switch) : public NETLIB_NAME(QBJT)
{
public:
ATTR_COLD NETLIB_NAME(QBJT_switch)()
: NETLIB_NAME(QBJT)(BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { }
NETLIB_UPDATEI()
{
double vE = INPANALOG(m_EV);
double vB = INPANALOG(m_BV);
double m = (is_qtype( BJT_NPN) ? 1 : -1);
int new_state = ((vB - vE) * m > m_V ) ? 1 : 0;
if (m_state_on ^ new_state)
{
double gb = m_gB;
double gc = m_gC;
double v = m_V * m;
if (!new_state )
{
// not conducting
gb = NETLIST_GMIN;
v = 0;
gc = NETLIST_GMIN;
}
m_RB.set(gb, v, 0.0);
m_RC.set(gc, 0.0, 0.0);
m_state_on = new_state;
// Don't update m_RB - could cause an infinite loop
m_RB.update_dev();
m_RC.update_dev();
}
}
NETLIB_NAME(R) m_RB;
NETLIB_NAME(R) m_RC;
netlist_analog_input_t m_BV;
netlist_analog_input_t m_EV;
protected:
ATTR_COLD virtual void start();
ATTR_HOT void update_param();
double m_gB; // base conductance / switch on
double m_gC; // collector conductance / switch on
double m_V; // internal voltage source
UINT8 m_state_on;
private:
};
#else
class NETLIB_NAME(QBJT_switch) : public NETLIB_NAME(QBJT)
{
public:
@ -207,60 +149,12 @@ protected:
private:
};
#endif
// ----------------------------------------------------------------------------------------
// nld_QBJT_EB
// ----------------------------------------------------------------------------------------
#define USE_OLD_B (0)
#if USE_OLD_B
class NETLIB_NAME(QBJT_EB) : public NETLIB_NAME(QBJT)
{
public:
ATTR_COLD NETLIB_NAME(QBJT_EB)()
: NETLIB_NAME(QBJT)(BJT_EB),
m_D_BC(netlist_object_t::ANALOG),
m_D_BE(netlist_object_t::ANALOG),
m_I_BC(netlist_object_t::ANALOG),
m_I_BE(netlist_object_t::ANALOG)
{ }
NETLIB_UPDATE_TERMINALS()
{
m_gD_BE.update_diode(m_D_BE.deltaV());
m_gD_BC.update_diode(m_D_BC.deltaV());
m_D_BE.set(m_gD_BE.G(), 0.0, m_gD_BE.Ieq());
m_D_BC.set(m_gD_BC.G(), 0.0, m_gD_BC.Ieq());
m_I_BE.set(0.0, 0.0, - m_alpha_r * m_gD_BC.I());
m_I_BC.set(0.0, 0.0, - m_alpha_f * m_gD_BE.I());
}
protected:
ATTR_COLD virtual void start();
ATTR_COLD virtual void reset();
ATTR_HOT void update_param();
ATTR_HOT ATTR_ALIGN void virtual update();
netlist_generic_diode m_gD_BC;
netlist_generic_diode m_gD_BE;
nld_twoterm m_D_BC;
nld_twoterm m_D_BE;
nld_twoterm m_I_BC;
nld_twoterm m_I_BE;
double m_alpha_f;
double m_alpha_r;
private:
};
#else
class NETLIB_NAME(QBJT_EB) : public NETLIB_NAME(QBJT)
{
public:
@ -312,5 +206,5 @@ protected:
private:
};
#endif
#endif /* NLD_BJT_H_ */

View File

@ -59,14 +59,11 @@ NETLIB_UPDATE_PARAM(VCCS)
NETLIB_UPDATE(VCCS)
{
/* only called if connected to a rail net ==> notify the solver to recalculate */
#if !(USE_ALTERNATE_SCHEDULING)
netlist().solver()->schedule1();
#else
/* Big FIXME ... */
m_IP.net().solve();
m_IN.net().solve();
m_OP.net().solve();
m_ON.net().solve();
#endif
}
// ----------------------------------------------------------------------------------------

View File

@ -140,13 +140,44 @@ ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
m_steps[k]->step_time(dd);
}
ATTR_HOT inline bool netlist_matrix_solver_t::solve()
{
int resched_cnt = 0;
netlist_time now = owner().netlist().time();
netlist_time delta = now - m_last_step;
if (delta >= netlist_time::from_nsec(1)) // always update capacitors
{
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
step(delta);
}
if (is_dynamic())
{
int this_resched;
do
{
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
} while (this_resched > 1 && resched_cnt < m_resched_loops);
}
else
{
resched_cnt = solve_non_dynamic();
}
return (resched_cnt >= m_resched_loops);
}
// ----------------------------------------------------------------------------------------
// netlist_matrix_solver - Direct base
// ----------------------------------------------------------------------------------------
template <int m_N, int _storage_N>
ATTR_COLD int netlist_matrix_solver_directb_t<m_N, _storage_N>::get_net_idx(netlist_net_t *net)
ATTR_COLD int netlist_matrix_solver_direct_t<m_N, _storage_N>::get_net_idx(netlist_net_t *net)
{
for (int k = 0; k < N(); k++)
if (m_nets[k] == net)
@ -155,7 +186,7 @@ ATTR_COLD int netlist_matrix_solver_directb_t<m_N, _storage_N>::get_net_idx(netl
}
template <int m_N, int _storage_N>
ATTR_COLD void netlist_matrix_solver_directb_t<m_N, _storage_N>::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
ATTR_COLD void netlist_matrix_solver_direct_t<m_N, _storage_N>::setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
{
netlist_matrix_solver_t::setup(nets, owner);
@ -201,7 +232,9 @@ ATTR_COLD void netlist_matrix_solver_directb_t<m_N, _storage_N>::setup(netlist_n
}
template <int m_N, int _storage_N>
ATTR_HOT inline void netlist_matrix_solver_directb_t<m_N, _storage_N>::build_LE(double (* RESTRICT m_A)[_storage_N], double (* RESTRICT m_RHS))
ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::build_LE(
double (* RESTRICT A)[_storage_N],
double (* RESTRICT RHS))
{
#if 0
@ -223,22 +256,117 @@ ATTR_HOT inline void netlist_matrix_solver_directb_t<m_N, _storage_N>::build_LE
for (int i = 0; i < m_rail_start; i++)
{
terms_t &t = m_terms[i];
m_RHS[t.net_this] += t.term->m_Idr;
m_A[t.net_this][t.net_this] += t.term->m_gt;
RHS[t.net_this] += t.term->m_Idr;
A[t.net_this][t.net_this] += t.term->m_gt;
m_A[t.net_this][t.net_other] += -t.term->m_go;
A[t.net_this][t.net_other] += -t.term->m_go;
}
for (int i = m_rail_start; i < m_term_num; i++)
{
terms_t &t = m_terms[i];
m_RHS[t.net_this] += t.term->m_Idr;
m_A[t.net_this][t.net_this] += t.term->m_gt;
RHS[t.net_this] += t.term->m_Idr;
A[t.net_this][t.net_this] += t.term->m_gt;
m_RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().Q_Analog();
RHS[t.net_this] += t.term->m_go * t.term->m_otherterm->net().Q_Analog();
}
#endif
}
template <int m_N, int _storage_N>
ATTR_HOT inline void netlist_matrix_solver_direct_t<m_N, _storage_N>::gauss_LE(
double (* RESTRICT A)[_storage_N],
double (* RESTRICT RHS),
double (* RESTRICT x))
{
for (int i = 0; i < N(); i++) {
#if 0
/* Find the row with the largest first value */
maxrow = i;
for (j=i+1;j<n;j++) {
if (ABS(a[i][j]) > ABS(a[i][maxrow]))
maxrow = j;
}
/* Swap the maxrow and ith row */
for (k=i;k<n+1;k++) {
tmp = a[k][i];
a[k][i] = a[k][maxrow];
a[k][maxrow] = tmp;
}
#endif
/* Singular matrix? */
double f = A[i][i];
//if (fabs(A[i][i]) < 1e-20) printf("Singular!");
f = 1.0 / f;
/* Eliminate column i from row j */
for (int j = i + 1; j < N(); j++)
{
double f1 = A[j][i] * f;
for (int k = i; k < N(); k++)
{
A[j][k] -= A[i][k] * f1;
}
RHS[j] -= RHS[i] * f1;
}
}
/* back substitution */
for (int j = N() - 1; j >= 0; j--)
{
double tmp = 0;
for (int k = j + 1; k < N(); k++)
tmp += A[j][k] * x[k];
x[j] = (RHS[j] - tmp) / A[j][j];
}
}
template <int m_N, int _storage_N>
ATTR_HOT inline double netlist_matrix_solver_direct_t<m_N, _storage_N>::delta_and_store(
double (* RESTRICT RHS),
double (* RESTRICT V))
{
double cerr = 0;
double cerr2 = 0;
for (int i = 0; i < this->N(); i++)
{
double e = (V[i] - this->m_nets[i]->m_cur.Analog);
double e2 = (RHS[i] - this->m_RHS[i]);
cerr += e * e;
cerr2 += e2 * e2;
this->m_nets[i]->m_cur.Analog = this->m_nets[i]->m_new.Analog = V[i];
this->m_RHS[i] = RHS[i];
}
return (cerr + cerr2*(100000.0 * 100000.0)) / this->N();
}
template <int m_N, int _storage_N>
ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic()
{
double A[_storage_N][_storage_N] = { { 0.0 } };
double RHS[_storage_N] = { 0.0 };
double new_v[_storage_N] = { 0.0 };
this->build_LE(A, RHS);
this->gauss_LE(A, RHS, new_v);
if (this->is_dynamic())
{
double err = delta_and_store(RHS, new_v);
if (err > this->m_accuracy * this->m_accuracy)
{
return 2;
}
}
return 1;
}
// ----------------------------------------------------------------------------------------
// netlist_matrix_solver - Direct1
// ----------------------------------------------------------------------------------------
@ -246,12 +374,6 @@ ATTR_HOT inline void netlist_matrix_solver_directb_t<m_N, _storage_N>::build_LE
ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic()
{
#if 1
ATTR_UNUSED netlist_net_t *last_resched_net = NULL;
/* over-relaxation not really works on these matrices */
//const double w = 1.0; //2.0 / (1.0 + sin(3.14159 / (m_nets.count()+1)));
//const double w1 = 1.0 - w;
//NL_VERBOSE_OUT(("%d %d\n", N(), 1);
double gtot_t = 0.0;
double RHS_t = 0.0;
@ -294,40 +416,6 @@ ATTR_HOT inline int netlist_matrix_solver_direct1_t::solve_non_dynamic()
}
ATTR_HOT inline bool netlist_matrix_solver_direct1_t::solve()
{
int resched_cnt = 0;
ATTR_UNUSED netlist_net_t *last_resched_net = NULL;
if (USE_ALTERNATE_SCHEDULING)
{
netlist_time now = owner().netlist().time();
netlist_time delta = now - m_last_step;
if (delta >= netlist_time::from_nsec(5)) // always update capacitors
{
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
step(delta);
}
}
if (is_dynamic())
{
int this_resched;
do
{
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
} while (this_resched > 1 && resched_cnt < m_resched_loops);
}
else
{
resched_cnt = solve_non_dynamic();
}
return (resched_cnt >= m_resched_loops);
}
// ----------------------------------------------------------------------------------------
// netlist_matrix_solver - Direct2
@ -335,74 +423,30 @@ ATTR_HOT inline bool netlist_matrix_solver_direct1_t::solve()
ATTR_HOT int netlist_matrix_solver_direct2_t::solve_non_dynamic()
{
double m_A[2][2] = { { 0.0 } };
double m_RHS[2] = { 0.0 };
double A[2][2] = { { 0.0 } };
double RHS[2] = { 0.0 };
build_LE(A, RHS);
build_LE(m_A, m_RHS);
//NL_VERBOSE_OUT(("%f %f\n", new_val, m_RHS[0] / m_A[0][0]);
const double a = m_A[0][0];
const double b = m_A[0][1];
const double c = m_A[1][0];
const double d = m_A[1][1];
const double a = A[0][0];
const double b = A[0][1];
const double c = A[1][0];
const double d = A[1][1];
const double new_val1 = a / (a*d - b*c) * (m_RHS[1] - c / a * m_RHS[0]);
const double new_val0 = (m_RHS[0] - b * new_val1) / a;
double new_val[2];
new_val[1] = a / (a*d - b*c) * (RHS[1] - c / a * RHS[0]);
new_val[0] = (RHS[0] - b * new_val[1]) / a;
double e = (new_val0 - m_nets[0]->m_cur.Analog);
double cerr = e * e;
m_nets[0]->m_cur.Analog = m_nets[0]->m_new.Analog = new_val0;
e = (new_val1 - m_nets[1]->m_cur.Analog);
cerr += e * e;
m_nets[1]->m_cur.Analog = m_nets[1]->m_new.Analog = new_val1;
if (is_dynamic() && (cerr / N() > m_accuracy * m_accuracy))
if (is_dynamic() && (delta_and_store(RHS, new_val) > m_accuracy * m_accuracy))
{
return 2;
}
else
return 1;
}
ATTR_HOT inline bool netlist_matrix_solver_direct2_t::solve()
{
int resched_cnt = 0;
ATTR_UNUSED netlist_net_t *last_resched_net = NULL;
if (USE_ALTERNATE_SCHEDULING)
{
netlist_time now = owner().netlist().time();
netlist_time delta = now - m_last_step;
if (delta >= netlist_time::from_nsec(5)) // always update capacitors
{
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
step(delta);
}
}
if (is_dynamic())
{
int this_resched;
do
{
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
} while (this_resched > 1 && resched_cnt < m_resched_loops);
}
else
{
resched_cnt = solve_non_dynamic();
}
return (resched_cnt >= m_resched_loops);
}
// ----------------------------------------------------------------------------------------
// netlist_matrix_solver - Gauss - Seidel
// ----------------------------------------------------------------------------------------
@ -503,51 +547,6 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::solve
return resched_cnt;
}
template <int m_N, int _storage_N>
ATTR_HOT inline bool netlist_matrix_solver_gauss_seidel_t< m_N, _storage_N>::solve()
{
int resched_cnt = 0;
ATTR_UNUSED netlist_net_t *last_resched_net = NULL;
m_resched = false;
if (USE_ALTERNATE_SCHEDULING)
{
netlist_time now = owner().netlist().time();
netlist_time delta = now - m_last_step;
if (delta >= netlist_time::from_nsec(5)) // always update capacitors
{
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
step(delta);
}
}
if (is_dynamic())
{
int this_resched;
do
{
update_dynamic();
this_resched = solve_non_dynamic();
resched_cnt += this_resched;
} while (this_resched > 1 && resched_cnt < m_resched_loops);
}
else
{
resched_cnt = solve_non_dynamic();
}
if (resched_cnt >= m_resched_loops)
m_resched = true;
//if (resched)
//NL_VERBOSE_OUT(("Resched on net %s first term %s\n", last_resched_net->name().cstr(), last_resched_net->m_terms[0]->name().cstr());
return m_resched;
}
// ----------------------------------------------------------------------------------------
// solver
// ----------------------------------------------------------------------------------------
@ -594,14 +593,14 @@ 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(10).as_double());
register_param("SYNC_DELAY", m_sync_delay, NLTIME_FROM_NS(5).as_double());
m_nt_sync_delay = m_sync_delay.Value();
register_param("FREQ", m_freq, 48000.0);
m_inc = netlist_time::from_hz(m_freq.Value());
//register_param("ACCURACY", m_accuracy, 1e-3);
register_param("ACCURACY", m_accuracy, 1e-6);
register_param("ACCURACY", m_accuracy, 1e-7);
register_param("CONVERG", m_convergence, 0.3);
register_param("RESCHED_LOOPS", m_resched_loops, 35);
@ -646,26 +645,15 @@ NETLIB_UPDATE(solver)
{
netlist_time now = netlist().time();
netlist_time delta = now - m_last_step;
bool do_full = (USE_ALTERNATE_SCHEDULING ? false : true);
bool do_full = false;
bool global_resched = false;
bool this_resched[100];
if (delta < m_inc)
do_full = true; // we have been called between updates
//FIXME: make this a parameter
if (!USE_ALTERNATE_SCHEDULING && delta >= netlist_time::from_nsec(5)) // always update capacitors
{
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
for (netlist_matrix_solver_t * const *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
{
(*e)->step(delta);
}
}
m_last_step = now;
#if HAS_OPENMP && USE_OPENMP
int t_cnt = m_mat_solvers.count();
omp_set_num_threads(3);
@ -739,20 +727,25 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
ms = new netlist_matrix_solver_direct1_t();
break;
case 2:
//ms = new netlist_matrix_solver_gauss_seidel_t<2,2>();
// Below is only half as fast as gauss_seidel ....
ms = new netlist_matrix_solver_direct2_t();
break;
/* FIXME: There is an issue (singularity during gaussian elemination
* with the direct solver - use gauss_seidel
*/
case 3:
//ms = new netlist_matrix_solver_direct_t<3,3>();
ms = new netlist_matrix_solver_gauss_seidel_t<3,3>();
break;
case 4:
//ms = new netlist_matrix_solver_direct_t<4,4>();
ms = new netlist_matrix_solver_gauss_seidel_t<4,4>();
break;
case 5:
//ms = new netlist_matrix_solver_direct_t<5,5>();
ms = new netlist_matrix_solver_gauss_seidel_t<5,5>();
break;
default:
//ms = new netlist_matrix_solver_direct_t<0,16>();
ms = new netlist_matrix_solver_gauss_seidel_t<0,16>();
break;
}

View File

@ -36,10 +36,11 @@ public:
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
// return true if a reschedule is needed ...
ATTR_HOT virtual bool solve() = 0;
ATTR_HOT virtual int solve_non_dynamic() = 0;
ATTR_HOT virtual void step(const netlist_time delta);
ATTR_HOT bool solve();
ATTR_HOT void update_inputs();
ATTR_HOT void update_dynamic();
@ -66,21 +67,30 @@ protected:
};
template <int m_N, int _storage_N>
class netlist_matrix_solver_directb_t: public netlist_matrix_solver_t
class netlist_matrix_solver_direct_t: public netlist_matrix_solver_t
{
public:
netlist_matrix_solver_directb_t() : netlist_matrix_solver_t() {}
netlist_matrix_solver_direct_t() : netlist_matrix_solver_t() {}
virtual ~netlist_matrix_solver_directb_t() {}
virtual ~netlist_matrix_solver_direct_t() {}
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner);
ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
ATTR_HOT virtual int solve_non_dynamic();
ATTR_HOT inline const int N() const { return (m_N == 0) ? m_nets.count() : m_N; }
ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
protected:
ATTR_HOT inline void build_LE(double (* RESTRICT m_A)[_storage_N], double (* RESTRICT m_RHS));
ATTR_HOT inline void build_LE(double (* RESTRICT A)[_storage_N], double (* RESTRICT RHS));
ATTR_HOT inline void gauss_LE(double (* RESTRICT A)[_storage_N],
double (* RESTRICT RHS),
double (* RESTRICT x));
ATTR_HOT inline double delta_and_store(
double (* RESTRICT RHS),
double (* RESTRICT V));
double m_RHS[_storage_N]; // right hand side - contains currents
private:
@ -101,68 +111,35 @@ class netlist_matrix_solver_gauss_seidel_t: public netlist_matrix_solver_t
{
public:
netlist_matrix_solver_gauss_seidel_t() : netlist_matrix_solver_t(), m_resched(false) {}
netlist_matrix_solver_gauss_seidel_t() : netlist_matrix_solver_t() {}
virtual ~netlist_matrix_solver_gauss_seidel_t() {}
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
{
m_resched = true;
netlist_matrix_solver_t::setup(nets, owner);
}
// return true if a reschedule is needed ...
ATTR_HOT bool solve();
ATTR_HOT int solve_non_dynamic();
ATTR_HOT inline const int N() const { if (m_N == 0) return m_nets.count(); else return m_N; }
ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
private:
bool m_resched;
};
class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_directb_t<1,1>
class netlist_matrix_solver_direct1_t: public netlist_matrix_solver_direct_t<1,1>
{
public:
netlist_matrix_solver_direct1_t() : netlist_matrix_solver_directb_t() {}
virtual ~netlist_matrix_solver_direct1_t() {}
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
{
netlist_matrix_solver_directb_t::setup(nets, owner);
}
// return true if a reschedule is needed ...
ATTR_HOT bool solve();
ATTR_HOT int solve_non_dynamic();
//ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
private:
};
class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_directb_t<2,2>
class netlist_matrix_solver_direct2_t: public netlist_matrix_solver_direct_t<2,2>
{
public:
netlist_matrix_solver_direct2_t() : netlist_matrix_solver_directb_t() {}
virtual ~netlist_matrix_solver_direct2_t() {}
ATTR_COLD virtual void setup(netlist_net_t::list_t &nets, NETLIB_NAME(solver) &owner)
{
netlist_matrix_solver_directb_t::setup(nets, owner);
}
// return true if a reschedule is needed ...
ATTR_HOT bool solve();
ATTR_HOT int solve_non_dynamic();
//ATTR_COLD virtual void reset() { netlist_matrix_solver_t::reset(); }
private:
};

View File

@ -49,9 +49,7 @@ NETLIB_UPDATE_PARAM(switch2)
m_R[0].set_R(R_OFF);
m_R[1].set_R(R_ON);
}
if (USE_ALTERNATE_SCHEDULING)
{
m_R[0].update_dev();
m_R[1].update_dev();
}
m_R[0].update_dev();
m_R[1].update_dev();
}

View File

@ -29,15 +29,11 @@ NETLIB_RESET(twoterm)
NETLIB_UPDATE(twoterm)
{
/* only called if connected to a rail net ==> notify the solver to recalculate */
#if !(USE_ALTERNATE_SCHEDULING)
netlist().solver()->schedule1();
#else
/* we only need to call the non-rail terminal */
if (!m_P.net().isRailNet())
m_P.net().solve();
else
m_N.net().solve();
#endif
}
// ----------------------------------------------------------------------------------------
@ -81,8 +77,7 @@ NETLIB_UPDATE_PARAM(R)
{
//printf("updating %s to %f\n", name().cstr(), m_R.Value());
set_R(m_R.Value());
if (USE_ALTERNATE_SCHEDULING)
update_dev();
update_dev();
}
// ----------------------------------------------------------------------------------------
@ -126,11 +121,8 @@ NETLIB_UPDATE_PARAM(POT)
m_R1.set_R(MAX(m_R.Value() * v, NETLIST_GMIN));
m_R2.set_R(MAX(m_R.Value() * (1.0 - v), NETLIST_GMIN));
// force a schedule all
if (USE_ALTERNATE_SCHEDULING)
{
m_R1.update_dev();
m_R2.update_dev();
}
m_R1.update_dev();
m_R2.update_dev();
}
// ----------------------------------------------------------------------------------------

View File

@ -199,10 +199,7 @@ NETLIB_UPDATE(nic7450)
m_I3.activate();
UINT8 t1 = INPLOGIC(m_I0) & INPLOGIC(m_I1);
UINT8 t2 = INPLOGIC(m_I2) & INPLOGIC(m_I3);
#if 0
UINT8 t = (t1 | t2) ^ 1;
OUTLOGIC(m_Q, t, t ? NLTIME_FROM_NS(22) : NLTIME_FROM_NS(15));
#else
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
UINT8 res = 0;
@ -225,8 +222,6 @@ NETLIB_UPDATE(nic7450)
}
}
OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
#endif
}

View File

@ -153,26 +153,22 @@ public:
INT32 m_active;
};
#if 1
template <int _check, int _invert>
class xx_net_signal_t: public netlist_device_t
class net_signal_2inp_t: public netlist_device_t
{
public:
xx_net_signal_t()
net_signal_2inp_t()
: netlist_device_t(), m_active(1)
{
}
ATTR_COLD void start()
{
const char *sIN[2] = { "A", "B" };
register_output("Q", m_Q);
for (int i=0; i < 2; i++)
{
register_input(sIN[i], m_i[i]);
}
save(NAME(m_active));
register_input("A", m_i[0]);
register_input("B", m_i[1]);
save(NAME(m_active));
}
ATTR_COLD void reset()
@ -229,7 +225,6 @@ public:
INT32 m_active;
};
#endif
// The following did not improve performance
#if 0
@ -297,11 +292,11 @@ public:
template <int _check, int _invert>
class net_signal_t<2, _check, _invert> : public xx_net_signal_t<_check, _invert>
class net_signal_t<2, _check, _invert> : public net_signal_2inp_t<_check, _invert>
{
public:
net_signal_t()
: xx_net_signal_t<_check, _invert>() { }
: net_signal_2inp_t<_check, _invert>() { }
};

View File

@ -286,13 +286,6 @@ ATTR_COLD void netlist_base_t::error(const char *format, ...) const
// net_core_device_t
// ----------------------------------------------------------------------------------------
#if 0
ATTR_COLD netlist_core_device_t::netlist_core_device_t()
: netlist_object_t(DEVICE, GENERIC), m_family_desc(NULL)
{
}
#endif
ATTR_COLD netlist_core_device_t::netlist_core_device_t(const family_t afamily)
: netlist_object_t(DEVICE, afamily), m_family_desc(NULL)
{
@ -535,13 +528,20 @@ ATTR_HOT inline void netlist_net_t::update_devs()
assert(this->isRailNet());
const UINT32 masks[4] = { 1, 5, 3, 1 };
static const UINT32 masks[4] = { 1, 5, 3, 1 };
const UINT32 mask = masks[ (m_last.Q << 1) | m_new.Q ];
m_cur = m_new;
m_in_queue = 2; /* mark as taken ... */
const UINT32 mask = masks[ (m_last.Q << 1) | m_cur.Q ];
netlist_core_terminal_t *p = m_head;
#if 0
do
{
update_dev(p, mask);
p = p->m_update_list_next;
} while (p != NULL);
#else
switch (m_num_cons)
{
case 2:
@ -558,6 +558,7 @@ ATTR_HOT inline void netlist_net_t::update_devs()
} while (p != NULL);
break;
}
#endif
m_last = m_cur;
}

View File

@ -34,7 +34,7 @@
#define NETLIST_INTERNAL_RES (U64(1000000000))
//#define NETLIST_INTERNAL_RES (U64(1000000000000))
#define USE_ALTERNATE_SCHEDULING (1)
//#define USE_ALTERNATE_SCHEDULING (1)
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)

View File

@ -165,26 +165,15 @@ public:
ATTR_HOT ATTR_ALIGN void push(const entry_t &e)
{
#if 0
// less is more
if (is_empty() || (e.time() <= (m_end - 1)->time()))
{
*m_end++ = e;
inc_stat(m_prof_end);
}
else
#endif
{
entry_t * RESTRICT i = m_end++;
while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) )
{
i--;
*(i+1) = *i;
inc_stat(m_prof_sortmove);
}
*i = e;
inc_stat(m_prof_sort);
}
entry_t * RESTRICT i = m_end++;
while ((i > &m_list[0]) && (e.time() > (i - 1)->time()) )
{
i--;
*(i+1) = *i;
inc_stat(m_prof_sortmove);
}
*i = e;
inc_stat(m_prof_sort);
assert(m_end - m_list < _Size);
}