Made GMIN a solver parameter. All users now use this value.

This commit is contained in:
Couriersud 2014-03-04 13:02:33 +00:00
parent ad9f9424ef
commit 33719a2b2c
12 changed files with 148 additions and 65 deletions

View File

@ -77,10 +77,10 @@ NETLIB_START(QBJT_switch)
save(NAME(m_state_on));
m_RB.set(NETLIST_GMIN, 0.0, 0.0);
m_RC.set(NETLIST_GMIN, 0.0, 0.0);
m_RB.set(netlist().gmin(), 0.0, 0.0);
m_RC.set(netlist().gmin(), 0.0, 0.0);
m_BC_dummy.set(NETLIST_GMIN, 0.0, 0.0);
m_BC_dummy.set(netlist().gmin(), 0.0, 0.0);
m_state_on = 0;
@ -105,8 +105,8 @@ NETLIB_START(QBJT_switch)
m_gB = d.gI(0.005 / alpha);
if (m_gB < NETLIST_GMIN)
m_gB = NETLIST_GMIN;
if (m_gB < netlist().gmin())
m_gB = netlist().gmin();
m_gC = d.gI(0.005); // very rough estimate
//printf("%f %f \n", m_V, m_gB);
}
@ -157,8 +157,8 @@ NETLIB_START(QBJT_EB)
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);
m_gD_BE.set_param(IS / m_alpha_f, NF, netlist().gmin());
m_gD_BC.set_param(IS / m_alpha_r, NR, netlist().gmin());
}
}

View File

@ -94,7 +94,7 @@ public:
m_RB(netlist_object_t::ANALOG),
m_RC(netlist_object_t::ANALOG),
m_BC_dummy(netlist_object_t::ANALOG),
m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { }
m_gB(NETLIST_GMIN_DEFAULT), m_gC(NETLIST_GMIN_DEFAULT), m_V(0.0), m_state_on(0) { }
NETLIB_UPDATE_TERMINALS()
{
@ -109,9 +109,9 @@ public:
if (!new_state )
{
// not conducting
gb = NETLIST_GMIN;
gb = netlist().gmin();
v = 0;
gc = NETLIST_GMIN;
gc = netlist().gmin();
}
m_RB.set(gb, v, 0.0);
m_RC.set(gc, 0.0, 0.0);

View File

@ -14,7 +14,7 @@
NETLIB_START(VCCS)
{
register_param("G", m_G, 1.0);
register_param("RI", m_RI, 1.0 / NETLIST_GMIN);
register_param("RI", m_RI, 1.0 / netlist().gmin());
register_terminal("IP", m_IP);
register_terminal("IN", m_IN);

View File

@ -663,6 +663,7 @@ NETLIB_START(solver)
register_param("CONVERG", m_convergence, 0.3);
register_param("RESCHED_LOOPS", m_resched_loops, 35);
register_param("PARALLEL", m_parallel, 0);
register_param("GMIN", m_gmin, NETLIST_GMIN_DEFAULT);
// internal staff

View File

@ -170,6 +170,7 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_param_double_t m_sync_delay;
netlist_param_double_t m_accuracy;
netlist_param_double_t m_convergence;
netlist_param_double_t m_gmin;
netlist_param_int_t m_resched_loops;
netlist_param_int_t m_parallel;
@ -185,6 +186,8 @@ public:
ATTR_HOT inline void schedule();
ATTR_COLD void post_start();
ATTR_HOT inline double gmin() { return m_gmin.Value(); }
);
ATTR_HOT inline void NETLIB_NAME(solver)::schedule()

View File

@ -6,7 +6,7 @@
#include "nld_switches.h"
#include "netlist/nl_setup.h"
#define R_OFF (1.0 / NETLIST_GMIN)
#define R_OFF (1.0 / netlist().gmin())
#define R_ON 0.01
NETLIB_START(switch2)

View File

@ -6,6 +6,34 @@
#include "nld_twoterm.h"
#include "nld_solver.h"
// ----------------------------------------------------------------------------------------
// netlist_generic_diode
// ----------------------------------------------------------------------------------------
ATTR_COLD netlist_generic_diode::netlist_generic_diode()
{
m_Vd = 0.7;
}
ATTR_COLD void netlist_generic_diode::set_param(const double Is, const double n, double gmin)
{
m_Is = Is;
m_n = n;
m_gmin = gmin;
m_Vt = 0.0258 * m_n;
m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0));
m_VtInv = 1.0 / m_Vt;
}
ATTR_COLD void netlist_generic_diode::save(pstring name, netlist_object_t &parent)
{
parent.save(m_Vd, name + ".m_Vd");
parent.save(m_Id, name + ".m_Id");
parent.save(m_G, name + ".m_G");
}
// ----------------------------------------------------------------------------------------
// nld_twoterm
// ----------------------------------------------------------------------------------------
@ -49,7 +77,7 @@ NETLIB_START(R_base)
NETLIB_RESET(R_base)
{
NETLIB_NAME(twoterm)::reset();
set_R(1.0 / NETLIST_GMIN);
set_R(1.0 / netlist().gmin());
}
NETLIB_UPDATE(R_base)
@ -60,7 +88,7 @@ NETLIB_UPDATE(R_base)
NETLIB_START(R)
{
NETLIB_NAME(R_base)::start();
register_param("R", m_R, 1.0 / NETLIST_GMIN);
register_param("R", m_R, 1.0 / netlist().gmin());
}
NETLIB_RESET(R)
@ -98,7 +126,7 @@ NETLIB_START(POT)
connect(m_R2.m_P, m_R1.m_N);
register_param("R", m_R, 1.0 / NETLIST_GMIN);
register_param("R", m_R, 1.0 / netlist().gmin());
register_param("DIAL", m_Dial, 0.5);
register_param("DIALLOG", m_DialIsLog, 0);
@ -121,8 +149,8 @@ NETLIB_UPDATE_PARAM(POT)
double v = m_Dial.Value();
if (m_DialIsLog.Value())
v = (exp(v) - 1.0) / (exp(1.0) - 1.0);
m_R1.set_R(MAX(m_R.Value() * v, NETLIST_GMIN));
m_R2.set_R(MAX(m_R.Value() * (1.0 - v), NETLIST_GMIN));
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
m_R1.update_dev();
m_R2.update_dev();
@ -140,13 +168,13 @@ NETLIB_START(C)
register_param("C", m_C, 1e-6);
// set up the element
set(NETLIST_GMIN, 0.0, -5.0 / NETLIST_GMIN);
set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
//set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
}
NETLIB_RESET(C)
{
set(NETLIST_GMIN, 0.0, -5.0 / NETLIST_GMIN);
set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
//set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
}
@ -180,7 +208,7 @@ NETLIB_UPDATE_PARAM(D)
double Is = m_model.model_value("Is", 1e-15);
double n = m_model.model_value("N", 1);
m_D.set_param(Is, n);
m_D.set_param(Is, n, netlist().gmin());
}
NETLIB_UPDATE(D)

View File

@ -175,10 +175,7 @@ protected:
class netlist_generic_diode
{
public:
netlist_generic_diode()
{
m_Vd = 0.7;
}
ATTR_COLD netlist_generic_diode();
ATTR_HOT inline void update_diode(const double nVd)
{
@ -187,7 +184,7 @@ public:
if (nVd < -5.0 * m_Vt)
{
m_Vd = nVd;
m_G = NETLIST_GMIN;
m_G = m_gmin;
m_Id = - m_Is;
}
else if (nVd < m_Vcrit)
@ -196,7 +193,7 @@ public:
const double eVDVt = exp(m_Vd * m_VtInv);
m_Id = m_Is * (eVDVt - 1.0);
m_G = m_Is * m_VtInv * eVDVt + NETLIST_GMIN;
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
}
else
{
@ -210,22 +207,13 @@ public:
const double eVDVt = exp(m_Vd * m_VtInv);
m_Id = m_Is * (eVDVt - 1.0);
m_G = m_Is * m_VtInv * eVDVt + NETLIST_GMIN;
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
}
//printf("nVd %f m_Vd %f Vcrit %f\n", nVd, m_Vd, m_Vcrit);
}
void set_param(const double Is, const double n)
{
m_Is = Is;
m_n = n;
m_Vt = 0.0258 * m_n;
m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0));
m_VtInv = 1.0 / m_Vt;
}
ATTR_COLD void set_param(const double Is, const double n, double gmin);
ATTR_HOT inline double I() const { return m_Id; }
ATTR_HOT inline double G() const { return m_G; }
@ -234,12 +222,7 @@ public:
/* owning object must save those ... */
void save(pstring name, netlist_object_t &parent)
{
parent.save(m_Vd, name + ".m_Vd");
parent.save(m_Id, name + ".m_Id");
parent.save(m_G, name + ".m_G");
}
ATTR_COLD void save(pstring name, netlist_object_t &parent);
private:
double m_Vd;
@ -249,6 +232,7 @@ private:
double m_Vt;
double m_Is;
double m_n;
double m_gmin;
double m_VtInv;
double m_Vcrit;

View File

@ -38,7 +38,7 @@ NETLIB_UPDATE(4066)
if (in < low)
{
m_R.set_R(1.0 / NETLIST_GMIN);
m_R.set_R(1.0 / netlist().gmin());
m_R.update_dev();
}
else if (in > high)

View File

@ -155,6 +155,18 @@ netlist_base_t::~netlist_base_t()
pstring::resetmem();
}
ATTR_COLD void netlist_base_t::save_register()
{
save(NAME(m_queue.callback()));
save(NAME(m_time));
netlist_object_t::save_register();
}
ATTR_HOT const double netlist_base_t::gmin() const
{
return solver()->gmin();
}
ATTR_COLD void netlist_base_t::start()
{
/* find the main clock and solver ... */
@ -163,11 +175,17 @@ ATTR_COLD void netlist_base_t::start()
m_solver = get_single_device<NETLIB_NAME(solver)>("solver");
m_gnd = get_single_device<NETLIB_NAME(gnd)>("gnd");
/* make sure the solver is started first! */
if (m_solver != NULL)
m_solver->start_dev();
NL_VERBOSE_OUT(("Initializing devices ...\n"));
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
netlist_device_t *dev = entry->object();
dev->start_dev();
if (dev != m_solver)
dev->start_dev();
}
}
@ -504,6 +522,48 @@ ATTR_COLD netlist_net_t::~netlist_net_t()
netlist().remove_save_items(this);
}
ATTR_HOT void netlist_net_t::inc_active()
{
m_active++;
if (USE_DEACTIVE_DEVICE)
{
if (m_active == 1 && m_in_queue > 0)
{
m_last_Q = m_cur_Q;
m_last_Analog = m_cur_Analog; // FIXME: Needed here ?
railterminal().netdev().inc_active();
m_cur_Q = m_new_Q;
m_cur_Analog = m_new_Analog;
}
}
if (m_active == 1 && m_in_queue == 0)
{
if (m_time > netlist().time())
{
m_in_queue = 1; /* pending */
netlist().push_to_queue(this, m_time);
}
else
{
m_cur_Q = m_last_Q = m_new_Q;
m_cur_Analog = m_last_Analog = m_new_Analog; // FIXME: Needed here?
m_in_queue = 2;
}
}
}
ATTR_HOT void netlist_net_t::dec_active()
{
m_active--;
if (USE_DEACTIVE_DEVICE)
{
if (m_active == 0)
railterminal().netdev().dec_active();
}
}
ATTR_COLD void netlist_net_t::reset()
{
@ -668,8 +728,8 @@ ATTR_COLD netlist_core_terminal_t::netlist_core_terminal_t(const type_t atype, c
ATTR_COLD netlist_terminal_t::netlist_terminal_t()
: netlist_core_terminal_t(TERMINAL, ANALOG)
, m_Idr(0.0)
, m_go(NETLIST_GMIN)
, m_gt(NETLIST_GMIN)
, m_go(NETLIST_GMIN_DEFAULT)
, m_gt(NETLIST_GMIN_DEFAULT)
, m_otherterm(NULL)
{
}
@ -680,10 +740,19 @@ ATTR_COLD void netlist_terminal_t::reset()
//netlist_terminal_core_terminal_t::reset();
set_state(STATE_INP_ACTIVE);
m_Idr = 0.0;
m_go = NETLIST_GMIN;
m_gt = NETLIST_GMIN;
m_go = netlist().gmin();
m_gt = netlist().gmin();
}
ATTR_COLD void netlist_terminal_t::save_register()
{
save(NAME(m_Idr));
save(NAME(m_go));
save(NAME(m_gt));
netlist_core_terminal_t::save_register();
}
ATTR_COLD void netlist_core_terminal_t::set_net(netlist_net_t &anet)
{
m_net = &anet;

View File

@ -454,13 +454,7 @@ public:
netlist_terminal_t *m_otherterm;
protected:
ATTR_COLD virtual void save_register()
{
save(NAME(m_Idr));
save(NAME(m_go));
save(NAME(m_gt));
netlist_core_terminal_t::save_register();
}
ATTR_COLD virtual void save_register();
ATTR_COLD virtual void reset();
};
@ -574,10 +568,13 @@ public:
ATTR_HOT inline const netlist_core_terminal_t & RESTRICT railterminal() const { return *m_railterminal; }
/* Everything below is used by the logic subsystem */
#if 0
ATTR_HOT inline void inc_active();
ATTR_HOT inline void dec_active();
#else
ATTR_HOT void inc_active();
ATTR_HOT void dec_active();
#endif
ATTR_HOT inline const netlist_sig_t Q() const
{
assert(family() == LOGIC);
@ -922,6 +919,8 @@ public:
ATTR_HOT virtual void step_time(const double st) { }
ATTR_HOT virtual void update_terminals() { }
#if (NL_KEEP_STATISTICS)
/* stats */
osd_ticks_t total_time;
@ -1026,6 +1025,7 @@ public:
ATTR_HOT inline const netlist_time time() const { return m_time; }
ATTR_HOT inline NETLIB_NAME(solver) *solver() const { return m_solver; }
ATTR_HOT inline NETLIB_NAME(gnd) *gnd() const { return m_gnd; }
ATTR_HOT const double gmin() const;
ATTR_HOT inline void push_to_queue(netlist_net_t *out, const netlist_time attime)
{
@ -1105,12 +1105,7 @@ protected:
/* from netlist_object */
ATTR_COLD virtual void reset();
ATTR_COLD virtual void save_register()
{
save(NAME(m_queue.callback()));
save(NAME(m_time));
netlist_object_t::save_register();
}
ATTR_COLD virtual void save_register();
#if (NL_KEEP_STATISTICS)
// performance
@ -1213,6 +1208,7 @@ ATTR_HOT inline void netlist_net_t::push_to_queue(const netlist_time delay)
}
}
#if 0
ATTR_HOT inline void netlist_net_t::inc_active()
{
m_active++;
@ -1254,6 +1250,7 @@ ATTR_HOT inline void netlist_net_t::dec_active()
railterminal().netdev().dec_active();
}
}
#endif
ATTR_HOT inline const netlist_sig_t netlist_logic_input_t::Q() const
{
@ -1270,6 +1267,7 @@ ATTR_HOT inline const double netlist_analog_input_t::Q_Analog() const
return net().Q_Analog();
}
// ----------------------------------------------------------------------------------------
// net_dev class factory
// ----------------------------------------------------------------------------------------

View File

@ -36,7 +36,7 @@
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
#define NETLIST_GMIN (1e-9)
#define NETLIST_GMIN_DEFAULT (1e-9)
typedef UINT8 netlist_sig_t;