diff --git a/nl_examples/congo_bongo.c b/nl_examples/congo_bongo.c index 030c4c48aa8..0415b6f0746 100644 --- a/nl_examples/congo_bongo.c +++ b/nl_examples/congo_bongo.c @@ -43,7 +43,7 @@ NETLIST_START(dummy) // .END PARAM(Solver.ACCURACY, 1e-8) - PARAM(Solver.NR_LOOPS, 9000) + PARAM(Solver.NR_LOOPS, 90) PARAM(Solver.SOR_FACTOR, 0.001) PARAM(Solver.GS_LOOPS, 1) PARAM(Solver.METHOD, "MAT_CR") diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 90cf78d6315..89f4cd017ae 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -408,7 +408,6 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, cons m_icount(0), m_old(netlist::netlist_time::zero()), m_netlist(nullptr), - m_setup(nullptr), m_setup_func(nullptr) { } @@ -418,7 +417,6 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, devi m_icount(0), m_old(netlist::netlist_time::zero()), m_netlist(nullptr), - m_setup(nullptr), m_setup_func(nullptr) { } @@ -442,7 +440,6 @@ void netlist_mame_device_t::device_start() //printf("clock is %d\n", clock()); m_netlist = global_alloc(netlist_mame_t(*this, "netlist")); - m_setup = global_alloc(netlist::setup_t(*m_netlist)); // register additional devices @@ -455,11 +452,11 @@ void netlist_mame_device_t::device_start() if( sdev != nullptr ) { LOG_DEV_CALLS(("Preparse subdevice %s/%s\n", d.name(), d.shortname())); - sdev->pre_parse_action(*m_setup); + sdev->pre_parse_action(setup()); } } - m_setup_func(*m_setup); + m_setup_func(setup()); /* let sub-devices tweak the netlist */ for (device_t &d : subdevices()) @@ -468,12 +465,11 @@ void netlist_mame_device_t::device_start() if( sdev != nullptr ) { LOG_DEV_CALLS(("Found subdevice %s/%s\n", d.name(), d.shortname())); - sdev->custom_netlist_additions(*m_setup); + sdev->custom_netlist_additions(setup()); } } - m_setup->start_devices(); - m_setup->resolve_inputs(); + netlist().start(); netlist().save(*this, m_rem, "m_rem"); netlist().save(*this, m_div, "m_div"); @@ -505,12 +501,8 @@ void netlist_mame_device_t::device_reset() void netlist_mame_device_t::device_stop() { LOG_DEV_CALLS(("device_stop\n")); - netlist().print_stats(); - netlist().stop(); - global_free(m_setup); - m_setup = nullptr; global_free(m_netlist); m_netlist = nullptr; } diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index 8466c39e070..b23003e9379 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -160,7 +160,7 @@ public: static void static_set_constructor(device_t &device, void (*setup_func)(netlist::setup_t &)); - ATTR_HOT inline netlist::setup_t &setup() { return *m_setup; } + ATTR_HOT inline netlist::setup_t &setup() { return m_netlist->setup(); } ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; } ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; } @@ -195,7 +195,6 @@ private: netlist::netlist_time m_old; netlist_mame_t * m_netlist; - netlist::setup_t * m_setup; void (*m_setup_func)(netlist::setup_t &); }; diff --git a/src/lib/netlist/analog/nld_fourterm.h b/src/lib/netlist/analog/nld_fourterm.h index 723eccf77f5..251f955edab 100644 --- a/src/lib/netlist/analog/nld_fourterm.h +++ b/src/lib/netlist/analog/nld_fourterm.h @@ -58,7 +58,7 @@ NETLIB_OBJECT(VCCS) public: NETLIB_CONSTRUCTOR(VCCS) , m_G(*this, "G", 1.0) - , m_RI(*this, "RI", NL_FCONST(1.0) / netlist().gmin()) + , m_RI(*this, "RI", 1e9) , m_OP(*this, "OP") , m_ON(*this, "ON") , m_IP(*this, "IP") diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index b2e5951e48a..4f324ea92bd 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -79,6 +79,8 @@ NETLIB_RESET(OPAMP) double RP = 0.5 / 3.1459 / CP / m_model.model_value("FPF"); double G = m_model.model_value("UGF") / m_model.model_value("FPF") / RP; + printf("Min Freq %s: %f\n", name().c_str(), 1.0 / (CP*RP / (G*RP))); + m_CP->m_C.setTo(CP); m_RP.set_R(RP); m_G1.m_G.setTo(G); diff --git a/src/lib/netlist/analog/nld_opamps.h b/src/lib/netlist/analog/nld_opamps.h index b695f497cb5..220984af0bc 100644 --- a/src/lib/netlist/analog/nld_opamps.h +++ b/src/lib/netlist/analog/nld_opamps.h @@ -99,7 +99,7 @@ NETLIB_OBJECT(OPAMP) private: - NETLIB_SUB(R) m_RP; + NETLIB_SUB(R_base) m_RP; NETLIB_SUB(VCCS) m_G1; NETLIB_SUBXX(C) m_CP; NETLIB_SUBXX(VCVS) m_EBUF; diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h index 697be6300aa..6c83e989e85 100644 --- a/src/lib/netlist/analog/nld_twoterm.h +++ b/src/lib/netlist/analog/nld_twoterm.h @@ -182,7 +182,7 @@ protected: NETLIB_OBJECT_DERIVED(R, R_base) { NETLIB_CONSTRUCTOR_DERIVED(R, R_base) - , m_R(*this, "R", 1.0 / netlist().gmin()) + , m_R(*this, "R", 1e9) { } @@ -193,6 +193,10 @@ protected: NETLIB_RESETI(); //NETLIB_UPDATEI() { } NETLIB_UPDATE_PARAMI(); + +private: + /* protect set_R ... it's a recipe to desaster when used to bypass the parameter */ + using NETLIB_NAME(R_base)::set_R; }; // ----------------------------------------------------------------------------- @@ -202,9 +206,9 @@ protected: NETLIB_OBJECT(POT) { NETLIB_CONSTRUCTOR(POT) - , m_R1(*this, "R1") - , m_R2(*this, "R2") - , m_R(*this, "R", 1.0 / netlist().gmin()) + , m_R1(*this, "_R1") + , m_R2(*this, "_R2") + , m_R(*this, "R", 10000) , m_Dial(*this, "DIAL", 0.5) , m_DialIsLog(*this, "DIALLOG", 0) { @@ -232,8 +236,8 @@ private: NETLIB_OBJECT(POT2) { NETLIB_CONSTRUCTOR(POT2) - , m_R1(*this, "R1") - , m_R(*this, "R", 1.0 / netlist().gmin()) + , m_R1(*this, "_R1") + , m_R(*this, "R", 10000) , m_Dial(*this, "DIAL", 0.5) , m_DialIsLog(*this, "DIALLOG", 0) , m_Reverse(*this, "REVERSE", 0) diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index a9d82b1e041..2936c692786 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -24,17 +24,25 @@ namespace netlist { } - NETLIB_RESETI() { } + NETLIB_RESETI(); NETLIB_UPDATEI(); public: NETLIB_SUB(vdd_vss) m_supply; - NETLIB_SUB(R) m_R; + NETLIB_SUB(R_base) m_R; analog_input_t m_control; param_double_t m_base_r; }; + NETLIB_RESET(CD4066_GATE) + { + // Start in off condition + // FIXME: is ROFF correct? + m_R.set_R(NL_FCONST(1.0) / netlist().gmin()); + + } + NETLIB_UPDATE(CD4066_GATE) { nl_double sup = (m_supply.vdd() - m_supply.vss()); diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp index 257ee0aac83..467786de3d1 100644 --- a/src/lib/netlist/devices/nld_4316.cpp +++ b/src/lib/netlist/devices/nld_4316.cpp @@ -16,24 +16,29 @@ namespace netlist { namespace devices { NETLIB_CONSTRUCTOR(CD4316_GATE) NETLIB_FAMILY("CD4XXX") , m_supply(*this, "PS") - , m_R(*this, "R") + , m_R(*this, "_R") , m_S(*this, "S") , m_E(*this, "E") , m_base_r(*this, "BASER", 45.0) { } - NETLIB_RESETI() { } + NETLIB_RESETI(); NETLIB_UPDATEI(); public: NETLIB_SUB(vdd_vss) m_supply; - NETLIB_SUB(R) m_R; + NETLIB_SUB(R_base) m_R; logic_input_t m_S, m_E; param_double_t m_base_r; }; + NETLIB_RESET(CD4316_GATE) + { + m_R.set_R(NL_FCONST(1.0) / netlist().gmin()); + } + NETLIB_UPDATE(CD4316_GATE) { m_R.update_dev(); diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp index 840dafeb5be..2ae1d0fcccc 100644 --- a/src/lib/netlist/devices/nld_ne555.cpp +++ b/src/lib/netlist/devices/nld_ne555.cpp @@ -44,10 +44,10 @@ namespace netlist NETLIB_RESETI(); protected: - NETLIB_SUB(R) m_R1; - NETLIB_SUB(R) m_R2; - NETLIB_SUB(R) m_R3; - NETLIB_SUB(R) m_RDIS; + NETLIB_SUB(R_base) m_R1; + NETLIB_SUB(R_base) m_R2; + NETLIB_SUB(R_base) m_R3; + NETLIB_SUB(R_base) m_RDIS; logic_input_t m_RESET; analog_input_t m_THRES; diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 836e744fc6a..16bc759ee94 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -91,6 +91,11 @@ namespace netlist // nld_res_sw // ----------------------------------------------------------------------------- + NETLIB_RESET(res_sw) + { + m_last_state = 0; + m_R.set_R(m_ROFF()); + } NETLIB_UPDATE(res_sw) { diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 89251264fa7..5850eadfd9d 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -386,7 +386,7 @@ namespace netlist { public: NETLIB_CONSTRUCTOR(res_sw) - , m_R(*this, "R") + , m_R(*this, "_R") , m_I(*this, "I") , m_RON(*this, "RON", 1.0) , m_ROFF(*this, "ROFF", 1.0E20) @@ -396,16 +396,12 @@ namespace netlist register_subalias("2", m_R.m_N); } - NETLIB_SUB(R) m_R; + NETLIB_SUB(R_base) m_R; logic_input_t m_I; param_double_t m_RON; param_double_t m_ROFF; - NETLIB_RESETI() - { - m_last_state = 0; - m_R.set_R(m_ROFF()); - } + NETLIB_RESETI(); //NETLIB_UPDATE_PARAMI(); NETLIB_UPDATEI(); diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 04d84897077..ba3f3db2c8a 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -243,19 +243,20 @@ netlist_t::netlist_t(const pstring &aname) , m_queue(*this) , m_mainclock(nullptr) , m_solver(nullptr) - , m_gnd(nullptr) , m_params(nullptr) , m_name(aname) - , m_setup(nullptr) , m_log(this) , m_lib(nullptr) { state().save_item(this, static_cast(m_queue), "m_queue"); state().save_item(this, m_time, "m_time"); + m_setup = new setup_t(*this); } netlist_t::~netlist_t() { + if (m_setup != nullptr) + delete m_setup; m_nets.clear(); m_devices.clear(); @@ -278,15 +279,15 @@ void netlist_t::register_dev(plib::owned_ptr dev) void netlist_t::start() { + setup().start_devices1(); + /* load the library ... */ /* make sure the solver and parameters are started first! */ for (auto & e : setup().m_device_factory) { - if ( setup().factory().is_class(e.second) - || setup().factory().is_class(e.second) - || setup().factory().is_class(e.second) + if ( setup().factory().is_class(e.second) || setup().factory().is_class(e.second)) { auto dev = plib::owned_ptr(e.second->Create(*this, e.first)); @@ -296,18 +297,14 @@ void netlist_t::start() log().debug("Searching for mainclock and solver ...\n"); - m_mainclock = get_single_device("mainclock"); m_solver = get_single_device("solver"); - m_gnd = get_single_device("gnd"); m_params = get_single_device("parameter"); /* create devices */ for (auto & e : setup().m_device_factory) { - if ( !setup().factory().is_class(e.second) - && !setup().factory().is_class(e.second) - && !setup().factory().is_class(e.second) + if ( !setup().factory().is_class(e.second) && !setup().factory().is_class(e.second)) { auto dev = plib::owned_ptr(e.second->Create(*this, e.first)); @@ -315,6 +312,9 @@ void netlist_t::start() } } + log().debug("Searching for mainclock\n"); + m_mainclock = get_single_device("mainclock"); + bool use_deactivate = (m_params->m_use_deactivate() ? true : false); for (auto &d : m_devices) @@ -333,16 +333,35 @@ void netlist_t::start() d->set_hint_deactivate(false); } - pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); - m_lib = plib::palloc(libpath); + /* resolve inputs */ + setup().resolve_inputs1(); + + log().verbose("initialize solver ...\n"); + + if (m_solver == nullptr) + { + for (auto &p : m_nets) + if (p->is_analog()) + log().fatal("No solver found for this net although analog elements are present\n"); + } + else + m_solver->post_start(); + + /* finally, set the pointers */ + + log().debug("Setting delegate pointers ...\n"); + for (auto &dev : m_devices) + dev->set_delegate_pointer(); } void netlist_t::stop() { + log().debug("Printing statistics ...\n"); + print_stats(); log().debug("Stopping solver device ...\n"); m_solver->stop(); } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index f2a7c4c81c6..00c14eef4af 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1166,11 +1166,10 @@ namespace netlist void start(); void stop(); - const detail::queue_t &queue() const { return m_queue; } - detail::queue_t &queue() { return m_queue; } const netlist_time time() const { return m_time; } devices::NETLIB_NAME(solver) *solver() const { return m_solver; } - devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; } + + /* never use this in constructors! */ nl_double gmin() const; void push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT; @@ -1181,7 +1180,6 @@ namespace netlist void rebuild_lists(); /* must be called after post_load ! */ - void set_setup(setup_t *asetup) { m_setup = asetup; } setup_t &setup() { return *m_setup; } void register_dev(plib::owned_ptr dev); @@ -1237,14 +1235,18 @@ namespace netlist plib::dynlib &lib() { return *m_lib; } - void print_stats() const; - std::vector> m_devices; /* sole use is to manage lifetime of net objects */ std::vector> m_nets; /* sole use is to manage lifetime of family objects */ std::vector>> m_family_cache; + const detail::queue_t &queue() const { return m_queue; } + detail::queue_t &queue() { return m_queue; } + + protected: + void print_stats() const; + private: plib::state_manager_t m_state; /* mostly rw */ @@ -1255,7 +1257,6 @@ namespace netlist devices::NETLIB_NAME(mainclock) * m_mainclock; devices::NETLIB_NAME(solver) * m_solver; - devices::NETLIB_NAME(gnd) * m_gnd; devices::NETLIB_NAME(netlistparams) *m_params; pstring m_name; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 925aeb3ba5a..9c4f895ec77 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -35,7 +35,6 @@ setup_t::setup_t(netlist_t &netlist) , m_proxy_cnt(0) , m_frontier_cnt(0) { - netlist.set_setup(this); initialize_factory(m_factory); NETLIST_NAME(base)(*this); } @@ -48,7 +47,6 @@ setup_t::~setup_t() m_terminals.clear(); m_param_values.clear(); - netlist().set_setup(nullptr); m_sources.clear(); pstring::resetmem(); @@ -703,10 +701,8 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t return ret; } -void setup_t::resolve_inputs() +void setup_t::resolve_inputs1() { - bool has_twoterms = false; - log().verbose("Resolving inputs ..."); /* Netlist can directly connect input to input. @@ -776,31 +772,13 @@ void setup_t::resolve_inputs() log().verbose("looking for two terms connected to rail nets ...\n"); for (auto & t : netlist().get_device_list()) { - has_twoterms = true; if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet()) log().warning("Found device {1} connected only to railterminals {2}/{3}\n", t->name(), t->m_N.net().name(), t->m_P.net().name()); } - - log().verbose("initialize solver ...\n"); - - if (netlist().solver() == nullptr) - { - if (has_twoterms) - log().fatal("No solver found for this net although analog elements are present\n"); - } - else - netlist().solver()->post_start(); - - /* finally, set the pointers */ - - log().debug("Initializing devices ...\n"); - for (auto &dev : netlist().m_devices) - dev->set_delegate_pointer(); - } -void setup_t::start_devices() +void setup_t::start_devices1() { pstring env = plib::util::environment("NL_LOGS"); @@ -817,8 +795,6 @@ void setup_t::start_devices() netlist().register_dev(std::move(nc)); } } - - netlist().start(); } plib::plog_base &setup_t::log() diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 66745504c74..42cc804e309 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -227,8 +227,8 @@ namespace netlist param_t *find_param(const pstring ¶m_in, bool required = true) const; - void start_devices(); - void resolve_inputs(); + void start_devices1(); + void resolve_inputs1(); /* handle namespace */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index f96fd423530..91f9fc7c1ae 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -128,19 +128,16 @@ class netlist_tool_t : public netlist::netlist_t public: netlist_tool_t(const pstring &aname) - : netlist::netlist_t(aname), m_setup(nullptr) + : netlist::netlist_t(aname) { } ~netlist_tool_t() { - if (m_setup != nullptr) - plib::pfree(m_setup); } void init() { - m_setup = plib::palloc(*this); } void read_netlist(const pstring &filename, const pstring &name, @@ -151,19 +148,18 @@ public: // read the netlist ... for (auto & d : defines) - m_setup->register_define(d); + setup().register_define(d); for (auto & r : roms) - m_setup->register_source(plib::make_unique_base(*m_setup, r)); + setup().register_source(plib::make_unique_base(setup(), r)); - m_setup->register_source(plib::make_unique_base(*m_setup, filename)); - m_setup->include(name); + setup().register_source(plib::make_unique_base(setup(), filename)); + setup().include(name); log_setup(logs); // start devices - m_setup->start_devices(); - m_setup->resolve_inputs(); + this->start(); // reset this->reset(); } @@ -174,19 +170,16 @@ public: for (auto & log : logs) { pstring name = "log_" + log; - /*netlist_device_t *nc = */ m_setup->register_dev("LOG", name); - m_setup->register_link(name + ".I", log); + /*netlist_device_t *nc = */ setup().register_dev("LOG", name); + setup().register_link(name + ".I", log); } } - netlist::setup_t &setup() { return *m_setup; } - protected: void vlog(const plib::plog_level &l, const pstring &ls) const override; private: - netlist::setup_t *m_setup; }; void netlist_tool_t::vlog(const plib::plog_level &l, const pstring &ls) const @@ -210,18 +203,12 @@ void usage(tool_options_t &opts) struct input_t { -#if 0 - input_t() - : m_param(nullptr), m_value(0.0) - { - } -#endif input_t(const netlist::setup_t &setup, const pstring &line) { char buf[400]; double t; int e = sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf, &m_value); - if ( e!= 3) + if (e != 3) throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line)); m_time = netlist::netlist_time::from_double(t); m_param = setup.find_param(buf, true); @@ -249,7 +236,6 @@ struct input_t netlist::netlist_time m_time; netlist::param_t *m_param; double m_value; - }; static std::vector read_input(const netlist::setup_t &setup, pstring fname) @@ -359,8 +345,7 @@ static void listdevices(tool_options_t &opts) nt.setup().include("dummy"); - nt.setup().start_devices(); - nt.setup().resolve_inputs(); + nt.start(); std::vector> devs;