mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Made GMIN a solver parameter. All users now use this value.
This commit is contained in:
parent
ad9f9424ef
commit
33719a2b2c
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user