diff options
Diffstat (limited to 'src/emu/netlist/nl_base.c')
-rw-r--r-- | src/emu/netlist/nl_base.c | 535 |
1 files changed, 288 insertions, 247 deletions
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index b07e462f4f4..c63ddc61a00 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -5,43 +5,48 @@ * */ +#include <solver/nld_solver.h> #include <cstring> +#include <algorithm> +#include <cstdio> #include "plib/palloc.h" #include "nl_base.h" #include "devices/nld_system.h" -#include "analog/nld_solver.h" #include "nl_util.h" -const netlist_time netlist_time::zero = netlist_time::from_raw(0); +const netlist::netlist_time netlist::netlist_time::zero = netlist::netlist_time::from_raw(0); +namespace netlist +{ //============================================================ // Exceptions //============================================================ // emu_fatalerror is a generic fatal exception that provides an error string -nl_fatalerror::nl_fatalerror(const char *format, ...) +fatalerror_e::fatalerror_e(const char *format, ...) { va_list ap; va_start(ap, format); m_text = pstring(format).vprintf(ap); + fprintf(stderr, "%s\n", m_text.cstr()); va_end(ap); } -nl_fatalerror::nl_fatalerror(const char *format, va_list ap) +fatalerror_e::fatalerror_e(const char *format, va_list ap) { m_text = pstring(format).vprintf(ap); } // ---------------------------------------------------------------------------------------- -// netlist_logic_family_ttl_t +// logic_family_ttl_t // ---------------------------------------------------------------------------------------- -class netlist_logic_family_ttl_t : public netlist_logic_family_desc_t +class logic_family_ttl_t : public logic_family_desc_t { public: - netlist_logic_family_ttl_t() + logic_family_ttl_t() : logic_family_desc_t() { m_low_thresh_V = 0.8; m_high_thresh_V = 2.0; @@ -50,58 +55,92 @@ public: m_high_V = 4.0; m_R_low = 1.0; m_R_high = 130.0; + m_is_static = true; } - virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t &proxied) const + virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const { - return palloc(nld_d_to_a_proxy , proxied); + return palloc(devices::nld_d_to_a_proxy(proxied)); } }; //FIXME: set to proper values -class netlist_logic_family_cd4000_t : public netlist_logic_family_desc_t +class logic_family_cd4xxx_t : public logic_family_desc_t { public: - netlist_logic_family_cd4000_t() + logic_family_cd4xxx_t() : logic_family_desc_t() { m_low_thresh_V = 0.8; m_high_thresh_V = 2.0; // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_V = 0.1; - m_high_V = 4.0; - m_R_low = 1.0; - m_R_high = 130.0; + m_low_V = 0.05; + m_high_V = 4.95; + m_R_low = 10.0; + m_R_high = 10.0; + m_is_static = true; } - virtual nld_base_d_to_a_proxy *create_d_a_proxy(netlist_logic_output_t &proxied) const + virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const + { + return palloc(devices::nld_d_to_a_proxy(proxied)); + } +}; + +logic_family_desc_t *netlist_family_TTL = palloc(logic_family_ttl_t); +logic_family_desc_t *netlist_family_CD4XXX = palloc(logic_family_cd4xxx_t); + +class logic_family_std_proxy_t : public logic_family_desc_t +{ +public: + logic_family_std_proxy_t() { } + virtual devices::nld_base_d_to_a_proxy *create_d_a_proxy(logic_output_t *proxied) const { - return palloc(nld_d_to_a_proxy , proxied); + return palloc(devices::nld_d_to_a_proxy(proxied)); } }; -const netlist_logic_family_desc_t &netlist_family_TTL = netlist_logic_family_ttl_t(); -const netlist_logic_family_desc_t &netlist_family_CD4000 = netlist_logic_family_cd4000_t(); +logic_family_desc_t *logic_family_desc_t::from_model(const pstring &model) +{ + if (setup_t::model_value_str(model, "TYPE", "") == "TTL") + return netlist_family_TTL; + if (setup_t::model_value_str(model, "TYPE", "") == "CD4XXX") + return netlist_family_CD4XXX; + + logic_family_std_proxy_t *ret = palloc(logic_family_std_proxy_t); + + ret->m_low_thresh_V = setup_t::model_value(model, "IVL", 0.8); + ret->m_high_thresh_V = setup_t::model_value(model, "IVH", 2.0); + ret->m_low_V = setup_t::model_value(model, "OVL", 0.1); + ret->m_high_V = setup_t::model_value(model, "OVH", 4.0); + ret->m_R_low = setup_t::model_value(model, "ORL", 1.0); + ret->m_R_high = setup_t::model_value(model, "ORH", 130.0); + + return ret; +} + // ---------------------------------------------------------------------------------------- // netlist_queue_t // ---------------------------------------------------------------------------------------- -netlist_queue_t::netlist_queue_t(netlist_base_t &nl) - : netlist_timed_queue<netlist_net_t *, netlist_time, 512>() - , netlist_object_t(QUEUE, GENERIC) +queue_t::queue_t(netlist_t &nl) + : timed_queue<net_t *, netlist_time>(512) + , object_t(QUEUE, GENERIC) , pstate_callback_t() , m_qsize(0) + , m_times(512) + , m_names(512) { this->init_object(nl, "QUEUE"); } -void netlist_queue_t::register_state(pstate_manager_t &manager, const pstring &module) +void queue_t::register_state(pstate_manager_t &manager, const pstring &module) { NL_VERBOSE_OUT(("register_state\n")); manager.save_item(m_qsize, this, module + "." + "qsize"); - manager.save_item(m_times, this, module + "." + "times"); - manager.save_item(&(m_name[0][0]), this, module + "." + "names", sizeof(m_name)); + manager.save_item(&m_times[0], this, module + "." + "times", m_times.size()); + manager.save_item(&(m_names[0].m_buf[0]), this, module + "." + "names", m_names.size() * sizeof(names_t)); } -void netlist_queue_t::on_pre_save() +void queue_t::on_pre_save() { NL_VERBOSE_OUT(("on_pre_save\n")); m_qsize = this->count(); @@ -112,22 +151,22 @@ void netlist_queue_t::on_pre_save() pstring p = this->listptr()[i].object()->name(); int n = p.len(); n = std::min(63, n); - std::strncpy(&(m_name[i][0]), p, n); - m_name[i][n] = 0; + std::strncpy(m_names[i].m_buf, p, n); + m_names[i].m_buf[n] = 0; } } -void netlist_queue_t::on_post_load() +void queue_t::on_post_load() { this->clear(); NL_VERBOSE_OUT(("current time %f qsize %d\n", netlist().time().as_double(), m_qsize)); for (int i = 0; i < m_qsize; i++ ) { - netlist_net_t *n = netlist().find_net(&(m_name[i][0])); + net_t *n = netlist().find_net(m_names[i].m_buf); //NL_VERBOSE_OUT(("Got %s ==> %p\n", qtemp[i].m_name, n)); - //NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), qtemp[i].m_time.as_double())); - this->push(netlist_queue_t::entry_t(netlist_time::from_raw(m_times[i]), n)); + //NL_VERBOSE_OUT(("schedule time %f (%f)\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double())); + this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]), n)); } } @@ -135,24 +174,24 @@ void netlist_queue_t::on_post_load() // netlist_object_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_object_t::netlist_object_t(const type_t atype, const family_t afamily) +ATTR_COLD object_t::object_t(const type_t atype, const family_t afamily) : m_objtype(atype) , m_family(afamily) , m_netlist(NULL) {} -ATTR_COLD netlist_object_t::~netlist_object_t() +ATTR_COLD object_t::~object_t() { } -ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring &aname) +ATTR_COLD void object_t::init_object(netlist_t &nl, const pstring &aname) { m_netlist = &nl; m_name = aname; save_register(); } -ATTR_COLD const pstring &netlist_object_t::name() const +ATTR_COLD const pstring &object_t::name() const { if (m_name == "") netlist().error("object not initialized"); @@ -163,38 +202,38 @@ ATTR_COLD const pstring &netlist_object_t::name() const // netlist_owned_object_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_owned_object_t::netlist_owned_object_t(const type_t atype, +ATTR_COLD device_object_t::device_object_t(const type_t atype, const family_t afamily) -: netlist_object_t(atype, afamily) -, m_netdev(NULL) +: object_t(atype, afamily) +, m_device(NULL) { } -ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev, +ATTR_COLD void device_object_t::init_object(core_device_t &dev, const pstring &aname) { - netlist_object_t::init_object(dev.netlist(), aname); - m_netdev = &dev; + object_t::init_object(dev.netlist(), aname); + m_device = &dev; } // ---------------------------------------------------------------------------------------- // netlist_base_t // ---------------------------------------------------------------------------------------- -netlist_base_t::netlist_base_t() - : netlist_object_t(NETLIST, GENERIC), pstate_manager_t(), +netlist_t::netlist_t() + : object_t(NETLIST, GENERIC), pstate_manager_t(), m_stop(netlist_time::zero), m_time(netlist_time::zero), + m_use_deactivate(0), m_queue(*this), m_mainclock(NULL), m_solver(NULL), m_gnd(NULL), - m_use_deactivate(0), m_setup(NULL) { } -netlist_base_t::~netlist_base_t() +netlist_t::~netlist_t() { for (std::size_t i=0; i < m_nets.size(); i++) { @@ -211,28 +250,28 @@ netlist_base_t::~netlist_base_t() pstring::resetmem(); } -ATTR_COLD void netlist_base_t::save_register() +ATTR_COLD void netlist_t::save_register() { save(static_cast<pstate_callback_t &>(m_queue), "m_queue"); save(NLNAME(m_time)); - netlist_object_t::save_register(); + object_t::save_register(); } -ATTR_HOT nl_double netlist_base_t::gmin() const +ATTR_HOT nl_double netlist_t::gmin() const { return solver()->gmin(); } -ATTR_COLD void netlist_base_t::start() +ATTR_COLD void netlist_t::start() { /* find the main clock and solver ... */ NL_VERBOSE_OUT(("Searching for mainclock and solver ...\n")); - m_mainclock = get_single_device<NETLIB_NAME(mainclock)>("mainclock"); - m_solver = get_single_device<NETLIB_NAME(solver)>("solver"); - m_gnd = get_single_device<NETLIB_NAME(gnd)>("gnd"); - m_params = get_single_device<NETLIB_NAME(netlistparams)>("parameter"); + m_mainclock = get_single_device<devices:: NETLIB_NAME(mainclock)>("mainclock"); + m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver"); + m_gnd = get_single_device<devices::NETLIB_NAME(gnd)>("gnd"); + m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); /* make sure the solver and parameters are started first! */ @@ -249,14 +288,14 @@ ATTR_COLD void netlist_base_t::start() NL_VERBOSE_OUT(("Initializing devices ...\n")); for (std::size_t i = 0; i < m_devices.size(); i++) { - netlist_device_t *dev = m_devices[i]; + device_t *dev = m_devices[i]; if (dev != m_solver && dev != m_params) dev->start_dev(); } } -ATTR_COLD void netlist_base_t::stop() +ATTR_COLD void netlist_t::stop() { /* find the main clock and solver ... */ @@ -269,7 +308,7 @@ ATTR_COLD void netlist_base_t::stop() } } -ATTR_COLD netlist_net_t *netlist_base_t::find_net(const pstring &name) +ATTR_COLD net_t *netlist_t::find_net(const pstring &name) { for (std::size_t i = 0; i < m_nets.size(); i++) { @@ -279,14 +318,15 @@ ATTR_COLD netlist_net_t *netlist_base_t::find_net(const pstring &name) return NULL; } -ATTR_COLD void netlist_base_t::rebuild_lists() +ATTR_COLD void netlist_t::rebuild_lists() { + //printf("Rebuild Lists\n"); for (std::size_t i = 0; i < m_nets.size(); i++) m_nets[i]->rebuild_list(); } -ATTR_COLD void netlist_base_t::reset() +ATTR_COLD void netlist_t::reset() { m_time = netlist_time::zero; m_queue.clear(); @@ -320,7 +360,7 @@ ATTR_COLD void netlist_base_t::reset() } -ATTR_HOT void netlist_base_t::process_queue(const netlist_time &delta) +ATTR_HOT void netlist_t::process_queue(const netlist_time &delta) { m_stop = m_time + delta; @@ -328,7 +368,7 @@ ATTR_HOT void netlist_base_t::process_queue(const netlist_time &delta) { while ( (m_time < m_stop) && (m_queue.is_not_empty())) { - const netlist_queue_t::entry_t e = *m_queue.pop(); + const queue_t::entry_t e = *m_queue.pop(); m_time = e.exec_time(); e.object()->update_devs(); @@ -338,7 +378,7 @@ ATTR_HOT void netlist_base_t::process_queue(const netlist_time &delta) m_time = m_stop; } else { - netlist_logic_net_t &mc_net = m_mainclock->m_Q.net().as_logic(); + logic_net_t &mc_net = m_mainclock->m_Q.net().as_logic(); const netlist_time inc = m_mainclock->m_inc; netlist_time mc_time = mc_net.time(); @@ -350,17 +390,17 @@ ATTR_HOT void netlist_base_t::process_queue(const netlist_time &delta) { m_time = mc_time; mc_time += inc; - NETLIB_NAME(mainclock)::mc_update(mc_net); + devices::NETLIB_NAME(mainclock)::mc_update(mc_net); } - const netlist_queue_t::entry_t e = *m_queue.pop(); + const queue_t::entry_t e = *m_queue.pop(); m_time = e.exec_time(); e.object()->update_devs(); } else { m_time = mc_time; mc_time += inc; - NETLIB_NAME(mainclock)::mc_update(mc_net); + devices::NETLIB_NAME(mainclock)::mc_update(mc_net); } add_to_stat(m_perf_out_processed, 1); @@ -369,7 +409,7 @@ ATTR_HOT void netlist_base_t::process_queue(const netlist_time &delta) } } -ATTR_COLD void netlist_base_t::error(const char *format, ...) const +ATTR_COLD void netlist_t::error(const char *format, ...) const { va_list ap; va_start(ap, format); @@ -377,7 +417,7 @@ ATTR_COLD void netlist_base_t::error(const char *format, ...) const va_end(ap); } -ATTR_COLD void netlist_base_t::warning(const char *format, ...) const +ATTR_COLD void netlist_t::warning(const char *format, ...) const { va_list ap; va_start(ap, format); @@ -385,7 +425,7 @@ ATTR_COLD void netlist_base_t::warning(const char *format, ...) const va_end(ap); } -ATTR_COLD void netlist_base_t::log(const char *format, ...) const +ATTR_COLD void netlist_t::log(const char *format, ...) const { va_list ap; va_start(ap, format); @@ -404,8 +444,8 @@ ATTR_COLD void netlist_base_t::log(const char *format, ...) const // net_core_device_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_core_device_t::netlist_core_device_t(const family_t afamily) -: netlist_object_t(DEVICE, afamily), netlist_logic_family_t() +ATTR_COLD core_device_t::core_device_t(const family_t afamily) +: object_t(DEVICE, afamily), logic_family_t() #if (NL_KEEP_STATISTICS) , stat_total_time(0) , stat_update_count(0) @@ -414,27 +454,28 @@ ATTR_COLD netlist_core_device_t::netlist_core_device_t(const family_t afamily) { } -ATTR_COLD void netlist_core_device_t::init(netlist_base_t &anetlist, const pstring &name) +ATTR_COLD void core_device_t::init(netlist_t &anetlist, const pstring &name) { - set_logic_family(this->default_logic_family()); + if (logic_family() == NULL) + set_logic_family(this->default_logic_family()); init_object(anetlist, name); -#if USE_PMFDELEGATES - void (netlist_core_device_t::* pFunc)() = &netlist_core_device_t::update; -#if NO_USE_PMFCONVERSION - static_update = pFunc; -#else - static_update = reinterpret_cast<net_update_delegate>((this->*pFunc)); -#endif +#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) + void (core_device_t::* pFunc)() = &core_device_t::update; + m_static_update = pFunc; +#elif (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) + void (core_device_t::* pFunc)() = &core_device_t::update; + m_static_update = reinterpret_cast<net_update_delegate>((this->*pFunc)); +#elif (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL) + m_static_update = pmfp::get_mfp<net_update_delegate>(&core_device_t::update, this); #endif - } -ATTR_COLD netlist_core_device_t::~netlist_core_device_t() +ATTR_COLD core_device_t::~core_device_t() { } -ATTR_COLD void netlist_core_device_t::start_dev() +ATTR_COLD void core_device_t::start_dev() { #if (NL_KEEP_STATISTICS) netlist().m_started_devices.add(this, false); @@ -442,16 +483,16 @@ ATTR_COLD void netlist_core_device_t::start_dev() start(); } -ATTR_COLD void netlist_core_device_t::stop_dev() +ATTR_COLD void core_device_t::stop_dev() { #if (NL_KEEP_STATISTICS) #endif stop(); } -ATTR_HOT netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(netlist_logic_input_t &inp) +ATTR_HOT netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp) { - if (inp.state() != netlist_logic_t::STATE_INP_PASSIVE) + if (inp.state() != logic_t::STATE_INP_PASSIVE) return inp.Q(); else { @@ -467,35 +508,35 @@ ATTR_HOT netlist_sig_t netlist_core_device_t::INPLOGIC_PASSIVE(netlist_logic_inp // netlist_device_t // ---------------------------------------------------------------------------------------- -netlist_device_t::netlist_device_t() - : netlist_core_device_t(GENERIC), +device_t::device_t() + : core_device_t(GENERIC), m_terminals(20) { } -netlist_device_t::netlist_device_t(const family_t afamily) - : netlist_core_device_t(afamily), +device_t::device_t(const family_t afamily) + : core_device_t(afamily), m_terminals(20) { } -netlist_device_t::~netlist_device_t() +device_t::~device_t() { //NL_VERBOSE_OUT(("~net_device_t\n"); } -ATTR_COLD netlist_setup_t &netlist_device_t::setup() +ATTR_COLD setup_t &device_t::setup() { return netlist().setup(); } -ATTR_COLD void netlist_device_t::init(netlist_base_t &anetlist, const pstring &name) +ATTR_COLD void device_t::init(netlist_t &anetlist, const pstring &name) { - netlist_core_device_t::init(anetlist, name); + core_device_t::init(anetlist, name); } -ATTR_COLD void netlist_device_t::register_sub(const pstring &name, netlist_device_t &dev) +ATTR_COLD void device_t::register_sub(const pstring &name, device_t &dev) { dev.init(netlist(), this->name() + "." + name); // subdevices always first inherit the logic family of the parent @@ -503,60 +544,80 @@ ATTR_COLD void netlist_device_t::register_sub(const pstring &name, netlist_devic dev.start_dev(); } -ATTR_COLD void netlist_device_t::register_subalias(const pstring &name, netlist_core_terminal_t &term) +ATTR_COLD void device_t::register_subalias(const pstring &name, core_terminal_t &term) { pstring alias = this->name() + "." + name; // everything already fully qualified setup().register_alias_nofqn(alias, term.name()); - if (term.isType(netlist_terminal_t::INPUT) || term.isType(netlist_terminal_t::TERMINAL)) + if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL)) m_terminals.add(alias); } -ATTR_COLD void netlist_device_t::register_terminal(const pstring &name, netlist_terminal_t &port) +ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &aliased) +{ + pstring alias = this->name() + "." + name; + pstring aliased_fqn = this->name() + "." + aliased; + + // everything already fully qualified + setup().register_alias_nofqn(alias, aliased_fqn); + + // FIXME: make this working again + //if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL)) + // m_terminals.add(name); +} + +ATTR_COLD void device_t::register_terminal(const pstring &name, terminal_t &port) { setup().register_object(*this, name, port); - if (port.isType(netlist_terminal_t::INPUT) || port.isType(netlist_terminal_t::TERMINAL)) + if (port.isType(terminal_t::INPUT) || port.isType(terminal_t::TERMINAL)) m_terminals.add(port.name()); } -ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_logic_output_t &port) +ATTR_COLD void device_t::register_output(const pstring &name, logic_output_t &port) { port.set_logic_family(this->logic_family()); setup().register_object(*this, name, port); } -ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_analog_output_t &port) +ATTR_COLD void device_t::register_output(const pstring &name, analog_output_t &port) { - //port.set_logic_family(this->logic_family()); setup().register_object(*this, name, port); } -ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_logic_input_t &inp) +ATTR_COLD void device_t::register_input(const pstring &name, logic_input_t &inp) { inp.set_logic_family(this->logic_family()); setup().register_object(*this, name, inp); m_terminals.add(inp.name()); } -ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_analog_input_t &inp) +ATTR_COLD void device_t::register_input(const pstring &name, analog_input_t &inp) { - //inp.set_logic_family(this->logic_family()); setup().register_object(*this, name, inp); m_terminals.add(inp.name()); } -ATTR_COLD void netlist_device_t::connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2) +ATTR_COLD void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2) +{ + setup().register_link_fqn(t1.name(), t2.name()); +} + +ATTR_COLD void device_t::connect_late(const pstring &t1, const pstring &t2) +{ + setup().register_link_fqn(name() + "." + t1, name() + "." + t2); +} + +ATTR_COLD void device_t::connect_direct(core_terminal_t &t1, core_terminal_t &t2) { - /* FIXME: These should really first be collected like NET_C connects */ if (!setup().connect(t1, t2)) netlist().error("Error connecting %s to %s\n", t1.name().cstr(), t2.name().cstr()); } template <class C, class T> -ATTR_COLD void netlist_device_t::register_param(const pstring &sname, C ¶m, const T initialVal) +ATTR_COLD void device_t::register_param(const pstring &sname, C ¶m, const T initialVal) { pstring fullname = this->name() + "." + sname; param.init_object(*this, fullname); @@ -564,21 +625,21 @@ ATTR_COLD void netlist_device_t::register_param(const pstring &sname, C ¶m, setup().register_object(*this, fullname, param); } -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_double_t ¶m, const double initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_double_t ¶m, const float initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_int_t ¶m, const int initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_logic_t ¶m, const int initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_str_t ¶m, const char * const initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_str_t ¶m, const pstring &initialVal); -template ATTR_COLD void netlist_device_t::register_param(const pstring &sname, netlist_param_model_t ¶m, const char * const initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_double_t ¶m, const double initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_double_t ¶m, const float initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_int_t ¶m, const int initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_logic_t ¶m, const int initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_str_t ¶m, const char * const initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_str_t ¶m, const pstring &initialVal); +template ATTR_COLD void device_t::register_param(const pstring &sname, param_model_t ¶m, const char * const initialVal); // ---------------------------------------------------------------------------------------- // netlist_net_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_net_t::netlist_net_t(const family_t afamily) - : netlist_object_t(NET, afamily) +ATTR_COLD net_t::net_t(const family_t afamily) + : object_t(NET, afamily) , m_new_Q(0) , m_cur_Q (0) , m_railterminal(NULL) @@ -589,27 +650,28 @@ ATTR_COLD netlist_net_t::netlist_net_t(const family_t afamily) { } -ATTR_COLD netlist_net_t::~netlist_net_t() +ATTR_COLD net_t::~net_t() { if (isInitialized()) netlist().remove_save_items(this); } -ATTR_COLD void netlist_net_t::init_object(netlist_base_t &nl, const pstring &aname) +ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname) { - netlist_object_t::init_object(nl, aname); + object_t::init_object(nl, aname); nl.m_nets.add(this); } -ATTR_HOT void netlist_net_t::inc_active(netlist_core_terminal_t &term) +ATTR_HOT void net_t::inc_active(core_terminal_t &term) { m_active++; m_list_active.insert(term); + nl_assert(m_active <= num_cons()); if (m_active == 1) { if (netlist().use_deactivate()) { - railterminal().netdev().inc_active(); + railterminal().device().inc_active(); //m_cur_Q = m_new_Q; } if (m_in_queue == 0) @@ -630,31 +692,39 @@ ATTR_HOT void netlist_net_t::inc_active(netlist_core_terminal_t &term) } } -ATTR_HOT void netlist_net_t::dec_active(netlist_core_terminal_t &term) +ATTR_HOT void net_t::dec_active(core_terminal_t &term) { m_active--; + nl_assert(m_active >= 0); m_list_active.remove(term); if (m_active == 0 && netlist().use_deactivate()) - railterminal().netdev().dec_active(); + railterminal().device().dec_active(); } -ATTR_COLD void netlist_net_t::register_railterminal(netlist_core_terminal_t &mr) +ATTR_COLD void net_t::register_railterminal(core_terminal_t &mr) { nl_assert(m_railterminal == NULL); m_railterminal = &mr; } -ATTR_COLD void netlist_net_t::rebuild_list() +ATTR_COLD void net_t::rebuild_list() { /* rebuild m_list */ + unsigned cnt = 0; m_list_active.clear(); for (std::size_t i=0; i < m_core_terms.size(); i++) - if (m_core_terms[i]->state() != netlist_logic_t::STATE_INP_PASSIVE) + if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE) + { m_list_active.add(*m_core_terms[i]); + cnt++; + } + //if (cnt != m_active) + //printf("ARgh %s ==> %d != %d\n", name().cstr(), cnt, m_active); + m_active = cnt; } -ATTR_COLD void netlist_net_t::save_register() +ATTR_COLD void net_t::save_register() { save(NLNAME(m_time)); save(NLNAME(m_active)); @@ -662,19 +732,19 @@ ATTR_COLD void netlist_net_t::save_register() save(NLNAME(m_cur_Analog)); save(NLNAME(m_cur_Q)); save(NLNAME(m_new_Q)); - netlist_object_t::save_register(); + object_t::save_register(); } -ATTR_HOT inline void netlist_core_terminal_t::update_dev(const UINT32 mask) +ATTR_HOT /* inline */ void core_terminal_t::update_dev(const UINT32 mask) { inc_stat(netdev().stat_call_count); if ((state() & mask) != 0) { - netdev().update_dev(); + device().update_dev(); } } -ATTR_HOT inline void netlist_net_t::update_devs() +ATTR_HOT /* inline */ void net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); @@ -684,17 +754,39 @@ ATTR_HOT inline void netlist_net_t::update_devs() m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; +#if 0 + core_terminal_t * t[256]; + core_terminal_t *p = m_list_active.first(); + int cnt = 0; + while (p != NULL) + { + if ((p->state() & mask) != 0) + t[cnt++] = p; + p = m_list_active.next(p); + } - netlist_core_terminal_t *p = m_list_active.first(); + for (int i=0; i<cnt; i++) + t[i]->netdev().update_dev(); + core_terminal_t *p = m_list_active.first(); while (p != NULL) { p->update_dev(mask); p = m_list_active.next(p); } + +#else + core_terminal_t *p = m_list_active.first(); + + while (p != NULL) + { + p->update_dev(mask); + p = p->m_next; + } +#endif } -ATTR_COLD void netlist_net_t::reset() +ATTR_COLD void net_t::reset() { m_time = netlist_time::zero; m_active = 0; @@ -714,31 +806,32 @@ ATTR_COLD void netlist_net_t::reset() m_core_terms[i]->do_reset(); for (std::size_t i=0; i < m_core_terms.size(); i++) - if (m_core_terms[i]->state() != netlist_logic_t::STATE_INP_PASSIVE) + if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE) m_active++; } -ATTR_COLD void netlist_net_t::register_con(netlist_core_terminal_t &terminal) +ATTR_COLD void net_t::register_con(core_terminal_t &terminal) { terminal.set_net(*this); m_core_terms.add(&terminal); - if (terminal.state() != netlist_logic_t::STATE_INP_PASSIVE) + if (terminal.state() != logic_t::STATE_INP_PASSIVE) m_active++; } -ATTR_COLD void netlist_net_t::move_connections(netlist_net_t *dest_net) +ATTR_COLD void net_t::move_connections(net_t *dest_net) { for (std::size_t i = 0; i < m_core_terms.size(); i++) { - netlist_core_terminal_t *p = m_core_terms[i]; + core_terminal_t *p = m_core_terms[i]; dest_net->register_con(*p); } - m_core_terms.clear(); // FIXME: othernet needs to be free'd from memory + m_core_terms.clear(); + m_active = 0; } -ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet) +ATTR_COLD void net_t::merge_net(net_t *othernet) { NL_VERBOSE_OUT(("merging nets ...\n")); if (othernet == NULL) @@ -769,47 +862,47 @@ ATTR_COLD void netlist_net_t::merge_net(netlist_net_t *othernet) // netlist_logic_net_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_logic_net_t::netlist_logic_net_t() - : netlist_net_t(LOGIC) +ATTR_COLD logic_net_t::logic_net_t() + : net_t(LOGIC) { } -ATTR_COLD void netlist_logic_net_t::reset() +ATTR_COLD void logic_net_t::reset() { - netlist_net_t::reset(); + net_t::reset(); } -ATTR_COLD void netlist_logic_net_t::save_register() +ATTR_COLD void logic_net_t::save_register() { - netlist_net_t::save_register(); + net_t::save_register(); } // ---------------------------------------------------------------------------------------- // netlist_analog_net_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_analog_net_t::netlist_analog_net_t() - : netlist_net_t(ANALOG) +ATTR_COLD analog_net_t::analog_net_t() + : net_t(ANALOG) , m_DD_n_m_1(0.0) , m_h_n_m_1(1e-6) , m_solver(NULL) { } -ATTR_COLD void netlist_analog_net_t::reset() +ATTR_COLD void analog_net_t::reset() { - netlist_net_t::reset(); + net_t::reset(); } -ATTR_COLD void netlist_analog_net_t::save_register() +ATTR_COLD void analog_net_t::save_register() { save(NLNAME(m_DD_n_m_1)); save(NLNAME(m_h_n_m_1)); - netlist_net_t::save_register(); + net_t::save_register(); } -ATTR_COLD bool netlist_analog_net_t::already_processed(list_t *groups, int cur_group) +ATTR_COLD bool analog_net_t::already_processed(list_t *groups, int cur_group) { if (isRailNet()) return true; @@ -821,7 +914,7 @@ ATTR_COLD bool netlist_analog_net_t::already_processed(list_t *groups, int cur_g return false; } -ATTR_COLD void netlist_analog_net_t::process_net(list_t *groups, int &cur_group) +ATTR_COLD void analog_net_t::process_net(list_t *groups, int &cur_group) { if (num_cons() == 0) return; @@ -830,13 +923,13 @@ ATTR_COLD void netlist_analog_net_t::process_net(list_t *groups, int &cur_group) groups[cur_group].add(this); for (std::size_t i = 0; i < m_core_terms.size(); i++) { - netlist_core_terminal_t *p = m_core_terms[i]; + core_terminal_t *p = m_core_terms[i]; //SOLVER_VERBOSE_OUT(("terminal %s\n", p->name().cstr())); - if (p->isType(netlist_terminal_t::TERMINAL)) + if (p->isType(terminal_t::TERMINAL)) { //SOLVER_VERBOSE_OUT(("isterminal\n")); - netlist_terminal_t *pt = static_cast<netlist_terminal_t *>(p); - netlist_analog_net_t *other_net = &pt->m_otherterm->net().as_analog(); + terminal_t *pt = static_cast<terminal_t *>(p); + analog_net_t *other_net = &pt->m_otherterm->net().as_analog(); if (!other_net->already_processed(groups, cur_group)) other_net->process_net(groups, cur_group); } @@ -848,15 +941,15 @@ ATTR_COLD void netlist_analog_net_t::process_net(list_t *groups, int &cur_group) // netlist_core_terminal_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_core_terminal_t::netlist_core_terminal_t(const type_t atype, const family_t afamily) -: netlist_owned_object_t(atype, afamily) -, plinkedlist_element_t<netlist_core_terminal_t>() +ATTR_COLD core_terminal_t::core_terminal_t(const type_t atype, const family_t afamily) +: device_object_t(atype, afamily) +, plinkedlist_element_t<core_terminal_t>() , m_net(NULL) , m_state(STATE_NONEX) { } -ATTR_COLD void netlist_core_terminal_t::set_net(netlist_net_t &anet) +ATTR_COLD void core_terminal_t::set_net(net_t &anet) { m_net = &anet; } @@ -865,8 +958,8 @@ ATTR_COLD void netlist_core_terminal_t::set_net(netlist_net_t &anet) // netlist_terminal_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_terminal_t::netlist_terminal_t() -: netlist_core_terminal_t(TERMINAL, ANALOG) +ATTR_COLD terminal_t::terminal_t() +: core_terminal_t(TERMINAL, ANALOG) , m_Idr1(NULL) , m_go1(NULL) , m_gt1(NULL) @@ -874,21 +967,21 @@ ATTR_COLD netlist_terminal_t::netlist_terminal_t() { } -ATTR_HOT void netlist_terminal_t::schedule_solve() +ATTR_HOT void terminal_t::schedule_solve() { // FIXME: Remove this after we found a way to remove *ALL* twoterms connected to railnets only. if (net().as_analog().solver() != NULL) net().as_analog().solver()->update_forced(); } -ATTR_HOT void netlist_terminal_t::schedule_after(const netlist_time &after) +ATTR_HOT void terminal_t::schedule_after(const netlist_time &after) { // FIXME: Remove this after we found a way to remove *ALL* twoterms connected to railnets only. if (net().as_analog().solver() != NULL) net().as_analog().solver()->update_after(after); } -ATTR_COLD void netlist_terminal_t::reset() +ATTR_COLD void terminal_t::reset() { set_state(STATE_INP_ACTIVE); set_ptr(m_Idr1, 0.0); @@ -896,12 +989,12 @@ ATTR_COLD void netlist_terminal_t::reset() set_ptr(m_gt1, netlist().gmin()); } -ATTR_COLD void netlist_terminal_t::save_register() +ATTR_COLD void terminal_t::save_register() { save(NLNAME(m_Idr1)); save(NLNAME(m_go1)); save(NLNAME(m_gt1)); - netlist_core_terminal_t::save_register(); + core_terminal_t::save_register(); } @@ -917,21 +1010,21 @@ ATTR_COLD void netlist_terminal_t::save_register() // netlist_logic_output_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_logic_output_t::netlist_logic_output_t() - : netlist_logic_t(OUTPUT) +ATTR_COLD logic_output_t::logic_output_t() + : logic_t(OUTPUT) { set_state(STATE_OUT); this->set_net(m_my_net); } -ATTR_COLD void netlist_logic_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) +ATTR_COLD void logic_output_t::init_object(core_device_t &dev, const pstring &aname) { - netlist_core_terminal_t::init_object(dev, aname); + core_terminal_t::init_object(dev, aname); net().init_object(dev.netlist(), aname + ".net"); net().register_railterminal(*this); } -ATTR_COLD void netlist_logic_output_t::initial(const netlist_sig_t val) +ATTR_COLD void logic_output_t::initial(const netlist_sig_t val) { net().as_logic().initial(val); } @@ -941,68 +1034,38 @@ ATTR_COLD void netlist_logic_output_t::initial(const netlist_sig_t val) // netlist_analog_output_t // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_analog_output_t::netlist_analog_output_t() +ATTR_COLD analog_output_t::analog_output_t() : netlist_analog_t(OUTPUT), m_proxied_net(NULL) { this->set_net(m_my_net); set_state(STATE_OUT); - net().as_analog().m_cur_Analog = 0.98; + net().as_analog().m_cur_Analog = NL_FCONST(0.99); } -ATTR_COLD void netlist_analog_output_t::init_object(netlist_core_device_t &dev, const pstring &aname) +ATTR_COLD void analog_output_t::init_object(core_device_t &dev, const pstring &aname) { - netlist_core_terminal_t::init_object(dev, aname); + core_terminal_t::init_object(dev, aname); net().init_object(dev.netlist(), aname + ".net"); net().register_railterminal(*this); } -ATTR_COLD void netlist_analog_output_t::initial(const nl_double val) +ATTR_COLD void analog_output_t::initial(const nl_double val) { - // FIXME: Really necessary? - net().as_analog().m_cur_Analog = val * NL_FCONST(0.99); + net().as_analog().m_cur_Analog = val; } // ---------------------------------------------------------------------------------------- // netlist_param_t & friends // ---------------------------------------------------------------------------------------- -ATTR_COLD netlist_param_t::netlist_param_t(const param_type_t atype) - : netlist_owned_object_t(PARAM, ANALOG) +ATTR_COLD param_t::param_t(const param_type_t atype) + : device_object_t(PARAM, ANALOG) , m_param_type(atype) { } -ATTR_COLD netlist_param_double_t::netlist_param_double_t() - : netlist_param_t(DOUBLE) - , m_param(0.0) -{ -} - -ATTR_COLD netlist_param_int_t::netlist_param_int_t() - : netlist_param_t(INTEGER) - , m_param(0) -{ -} - -ATTR_COLD netlist_param_logic_t::netlist_param_logic_t() - : netlist_param_int_t() -{ -} - -ATTR_COLD netlist_param_str_t::netlist_param_str_t() - : netlist_param_t(STRING) - , m_param("") -{ -} - -ATTR_COLD netlist_param_model_t::netlist_param_model_t() - : netlist_param_t(MODEL) - , m_param("") -{ -} - -ATTR_COLD const pstring netlist_param_model_t::model_type() const +ATTR_COLD const pstring param_model_t::model_type() const { pstring tmp = this->Value(); // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon) @@ -1015,48 +1078,25 @@ ATTR_COLD const pstring netlist_param_model_t::model_type() const } -ATTR_COLD nl_double netlist_param_model_t::model_value(const pstring &entity, const nl_double defval) const +ATTR_COLD const pstring param_model_t::model_value_str(const pstring &entity, const pstring defval) const { - pstring tmp = this->Value(); - // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon) - int p = tmp.ucase().find(entity.ucase() + "="); - if (p>=0) - { - int pblank = tmp.find(" ", p); - if (pblank < 0) pblank = tmp.len() + 1; - tmp = tmp.substr(p, pblank - p); - int pequal = tmp.find("=", 0); - if (pequal < 0) - netlist().error("parameter %s misformat in model %s temp %s\n", entity.cstr(), Value().cstr(), tmp.cstr()); - tmp = tmp.substr(pequal+1); - nl_double factor = NL_FCONST(1.0); - switch (*(tmp.right(1).cstr())) - { - case 'm': factor = 1e-3; break; - case 'u': factor = 1e-6; break; - case 'n': factor = 1e-9; break; - case 'p': factor = 1e-12; break; - case 'f': factor = 1e-15; break; - case 'a': factor = 1e-18; break; + return setup_t::model_value_str(this->Value(), entity, defval); +} - } - if (factor != NL_FCONST(1.0)) - tmp = tmp.left(tmp.len() - 1); - return tmp.as_double() * factor; - } - else - { - netlist().log("Entity %s not found in model %s\n", entity.cstr(), tmp.cstr()); - return defval; - } +ATTR_COLD nl_double param_model_t::model_value(const pstring &entity, const nl_double defval) const +{ + return setup_t::model_value(this->Value(), entity, defval); } +} // namespace + +NETLIB_NAMESPACE_DEVICES_START() // ---------------------------------------------------------------------------------------- // mainclock // ---------------------------------------------------------------------------------------- -ATTR_HOT inline void NETLIB_NAME(mainclock)::mc_update(netlist_logic_net_t &net) +ATTR_HOT /* inline */ void NETLIB_NAME(mainclock)::mc_update(logic_net_t &net) { net.toggle_new_Q(); net.update_devs(); @@ -1082,9 +1122,10 @@ NETLIB_UPDATE_PARAM(mainclock) NETLIB_UPDATE(mainclock) { - netlist_logic_net_t &net = m_Q.net().as_logic(); + logic_net_t &net = m_Q.net().as_logic(); // this is only called during setup ... net.toggle_new_Q(); net.set_time(netlist().time() + m_inc); } +NETLIB_NAMESPACE_DEVICES_END() |