diff options
Diffstat (limited to 'src/lib/netlist/nl_base.cpp')
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 239 |
1 files changed, 111 insertions, 128 deletions
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 80acf9847a3..4374ef2212d 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -6,6 +6,7 @@ */ #include <cstring> +#include <cmath> #include "solver/nld_matrix_solver.h" #include "solver/nld_solver.h" @@ -25,7 +26,7 @@ namespace netlist namespace detail { #if (USE_MEMPOOL) -static plib::mempool pool(65536, 8); +static plib::mempool pool(6553600, 64); void * object_t::operator new (size_t size) { @@ -135,24 +136,6 @@ const logic_family_desc_t *family_CD4XXX() return &obj; } -class logic_family_std_proxy_t : public logic_family_desc_t -{ -public: - logic_family_std_proxy_t() { } - virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, - const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override; -}; - -plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_t &anetlist, - const pstring &name, logic_output_t *proxied) const -{ - return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); -} -plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const -{ - return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); -} // ---------------------------------------------------------------------------------------- // queue_t @@ -199,10 +182,10 @@ void detail::queue_t::on_post_load() netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { - detail::net_t *n = netlist().find_net(m_names[i].m_buf); + detail::net_t *n = netlist().find_net(pstring(m_names[i].m_buf, pstring::UTF8)); //log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n)); //log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double())); - this->push(n, netlist_time::from_raw(m_times[i])); + this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n)); } } @@ -234,24 +217,22 @@ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &anam { } -detail::device_object_t::type_t detail::device_object_t::type() const +detail::terminal_type detail::core_terminal_t::type() const { if (dynamic_cast<const terminal_t *>(this) != nullptr) - return type_t::TERMINAL; - else if (dynamic_cast<const param_t *>(this) != nullptr) - return param_t::PARAM; + return terminal_type::TERMINAL; else if (dynamic_cast<const logic_input_t *>(this) != nullptr) - return param_t::INPUT; + return terminal_type::INPUT; else if (dynamic_cast<const logic_output_t *>(this) != nullptr) - return param_t::OUTPUT; + return terminal_type::OUTPUT; else if (dynamic_cast<const analog_input_t *>(this) != nullptr) - return param_t::INPUT; + return terminal_type::INPUT; else if (dynamic_cast<const analog_output_t *>(this) != nullptr) - return param_t::OUTPUT; + return terminal_type::OUTPUT; else { netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name()); - return type_t::TERMINAL; // please compiler + return terminal_type::TERMINAL; // please compiler } } @@ -272,19 +253,16 @@ netlist_t::netlist_t(const pstring &aname) { state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue"); state().save_item(this, m_time, "m_time"); - m_setup = new setup_t(*this); + m_setup = plib::make_unique<setup_t>(*this); /* FIXME: doesn't really belong here */ NETLIST_NAME(base)(*m_setup); } netlist_t::~netlist_t() { - if (m_setup != nullptr) - delete m_setup; m_nets.clear(); m_devices.clear(); - pfree(m_lib); pstring::resetmem(); } @@ -303,48 +281,18 @@ void netlist_t::register_dev(plib::owned_ptr<core_device_t> dev) void netlist_t::remove_dev(core_device_t *dev) { - m_devices.erase( - std::remove_if( - m_devices.begin(), + m_devices.erase( + std::remove_if( + m_devices.begin(), m_devices.end(), - [&] (plib::owned_ptr<core_device_t> const& p) - { - return p.get() == dev; - }), + [&] (plib::owned_ptr<core_device_t> const& p) + { + return p.get() == dev; + }), m_devices.end() - ); + ); } -const logic_family_desc_t *netlist_t::family_from_model(const pstring &model) -{ - model_map_t map; - setup().model_parse(model, map); - - if (setup().model_value_str(map, "TYPE") == "TTL") - return family_TTL(); - if (setup().model_value_str(map, "TYPE") == "CD4XXX") - return family_CD4XXX(); - - for (auto & e : m_family_cache) - if (e.first == model) - return e.second.get(); - - auto ret = plib::make_unique_base<logic_family_desc_t, logic_family_std_proxy_t>(); - - ret->m_fixed_V = setup().model_value(map, "FV"); - ret->m_low_thresh_PCNT = setup().model_value(map, "IVL"); - ret->m_high_thresh_PCNT = setup().model_value(map, "IVH"); - ret->m_low_VO = setup().model_value(map, "OVL"); - ret->m_high_VO = setup().model_value(map, "OVH"); - ret->m_R_low = setup().model_value(map, "ORL"); - ret->m_R_high = setup().model_value(map, "ORH"); - - auto retp = ret.get(); - - m_family_cache.emplace_back(model, std::move(ret)); - - return retp; -} void netlist_t::start() @@ -372,6 +320,7 @@ void netlist_t::start() /* create devices */ + log().debug("Creating devices ...\n"); for (auto & e : setup().m_device_factory) { if ( !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second) @@ -394,9 +343,12 @@ void netlist_t::start() auto p = setup().m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE"); if (p != setup().m_param_values.end()) { - //FIXME: Error checking - auto v = p->second.as_long(); - d->set_hint_deactivate(!v); + //FIXME: turn this into a proper function + bool error; + auto v = p->second.as_double(&error); + if (error || std::abs(v - std::floor(v)) > 1e-6 ) + log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second); + d->set_hint_deactivate(v == 0.0); } } else @@ -404,11 +356,30 @@ void netlist_t::start() } pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); - m_lib = plib::palloc<plib::dynlib>(libpath); + m_lib = plib::make_unique<plib::dynlib>(libpath); /* resolve inputs */ setup().resolve_inputs(); + /* Make sure devices are fully created - now done in register_dev */ + + log().debug("Setting delegate pointers ...\n"); + for (auto &dev : m_devices) + dev->set_delegate_pointer(); + + log().verbose("looking for two terms connected to rail nets ..."); + for (auto & t : get_device_list<analog::NETLIB_NAME(twoterm)>()) + { + if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet()) + { + log().warning(MW_3_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3, + t->name(), t->m_N.net().name(), t->m_P.net().name()); + t->m_N.net().remove_terminal(t->m_N); + t->m_P.net().remove_terminal(t->m_P); + remove_dev(t); + } + } + log().verbose("initialize solver ...\n"); if (m_solver == nullptr) @@ -420,12 +391,6 @@ void netlist_t::start() 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() @@ -433,7 +398,8 @@ void netlist_t::stop() log().debug("Printing statistics ...\n"); print_stats(); log().debug("Stopping solver device ...\n"); - m_solver->stop(); + if (m_solver != nullptr) + m_solver->stop(); } detail::net_t *netlist_t::find_net(const pstring &name) @@ -474,16 +440,16 @@ void netlist_t::reset() dev->update_param(); // Step all devices once ! + /* + * INFO: The order here affects power up of e.g. breakout. However, such + * variations are explicitly stated in the breakout manual. + */ #if 0 for (std::size_t i = 0; i < m_devices.size(); i++) { m_devices[i]->update_dev(); } #else - /* FIXME: this makes breakout attract mode working again. - * It is however not acceptable that this depends on the startup order. - * Best would be, if reset would call update_dev for devices which need it. - */ std::size_t i = m_devices.size(); while (i>0) m_devices[--i]->update_dev(); @@ -495,7 +461,7 @@ void netlist_t::process_queue(const netlist_time &delta) { netlist_time stop(m_time + delta); - m_queue.push(nullptr, stop); + m_queue.push(detail::queue_t::entry_t(stop, nullptr)); m_stat_mainloop.start(); @@ -522,17 +488,20 @@ void netlist_t::process_queue(const netlist_time &delta) while (m_queue.top().m_exec_time > mc_time) { m_time = mc_time; - mc_time += inc; mc_net.toggle_new_Q(); mc_net.update_devs(); + mc_time += inc; } const detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; - if (e.m_object == nullptr) + if (e.m_object != nullptr) + { + e.m_object->update_devs(); + m_perf_out_processed.inc(); + } + else break; - e.m_object->update_devs(); - m_perf_out_processed.inc(); } mc_net.set_time(mc_time); } @@ -599,6 +568,21 @@ void netlist_t::print_stats() const } } +core_device_t *netlist_t::pget_single_device(const pstring classname, bool (*cc)(core_device_t *)) +{ + core_device_t *ret = nullptr; + for (auto &d : m_devices) + { + if (cc(d.get())) + { + if (ret != nullptr) + this->log().fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname); + else + ret = d.get(); + } + } + return ret; +} // ---------------------------------------------------------------------------------------- @@ -610,7 +594,7 @@ core_device_t::core_device_t(netlist_t &owner, const pstring &name) , logic_family_t() , netlist_ref(owner) , m_hint_deactivate(false) -#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL) +#if (!NL_USE_PMF_VIRTUAL) , m_static_update() #endif { @@ -623,7 +607,7 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name) , logic_family_t() , netlist_ref(owner.netlist()) , m_hint_deactivate(false) -#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL) +#if (!NL_USE_PMF_VIRTUAL) , m_static_update() #endif { @@ -639,17 +623,16 @@ core_device_t::~core_device_t() void core_device_t::set_delegate_pointer() { -#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 = plib::mfp::get_mfp<net_update_delegate>(&core_device_t::update, this); +#if (!NL_USE_PMF_VIRTUAL) + m_static_update.set_base(&core_device_t::update, this); #endif } +plib::plog_base<NL_DEBUG> &core_device_t::log() +{ + return netlist().log(); +} + // ---------------------------------------------------------------------------------------- // device_t // ---------------------------------------------------------------------------------------- @@ -697,7 +680,7 @@ void device_t::connect(const pstring &t1, const pstring &t2) void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { if (!setup().connect(t1, t2)) - netlist().log().fatal(MF_2_ERROR_CONNECTING_1_TO_2, t1.name(), t2.name()); + log().fatal(MF_2_ERROR_CONNECTING_1_TO_2, t1.name(), t2.name()); } @@ -705,9 +688,9 @@ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_term // family_setter_t // ----------------------------------------------------------------------------- -detail::family_setter_t::family_setter_t(core_device_t &dev, const char *desc) +detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring desc) { - dev.set_logic_family(dev.netlist().family_from_model(desc)); + dev.set_logic_family(dev.netlist().setup().family_from_model(desc)); } detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc) @@ -719,13 +702,6 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_ // net_t // ---------------------------------------------------------------------------------------- -// FIXME: move somewhere central - -struct do_nothing_deleter{ - template<typename T> void operator()(T*){} -}; - - detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : object_t(aname) , netlist_ref(nl) @@ -734,10 +710,9 @@ detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) , m_time(*this, "m_time", netlist_time::zero()) , m_active(*this, "m_active", 0) , m_in_queue(*this, "m_in_queue", 2) - , m_railterminal(nullptr) , m_cur_Analog(*this, "m_cur_Analog", 0.0) + , m_railterminal(mr) { - m_railterminal = mr; } detail::net_t::~net_t() @@ -758,7 +733,7 @@ void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT if (m_time > netlist().time()) { m_in_queue = 1; /* pending */ - netlist().queue().push(this, m_time); + netlist().queue().push(queue_t::entry_t(m_time, this)); } else { @@ -968,16 +943,20 @@ terminal_t::~terminal_t() void terminal_t::schedule_solve() { - // FIXME: Remove this after we found a way to remove *ALL* twoterms connected to railnets only. - if (net().solver() != nullptr) - net().solver()->update_forced(); + // Nets may belong to railnets which do not have a solver attached + // FIXME: Enforce that all terminals get connected? + if (this->has_net()) + if (net().solver() != nullptr) + net().solver()->update_forced(); } 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().solver() != nullptr) - net().solver()->update_after(after); + // Nets may belong to railnets which do not have a solver attached + // FIXME: Enforce that all terminals get connected? + if (this->has_net()) + if (net().solver() != nullptr) + net().solver()->update_after(after); } // ---------------------------------------------------------------------------------------- @@ -1037,7 +1016,7 @@ analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) netlist().m_nets.push_back(plib::owned_ptr<analog_net_t>(&m_my_net, false)); this->set_net(&m_my_net); - net().m_cur_Analog = NL_FCONST(0.0); + //net().m_cur_Analog = NL_FCONST(0.0); netlist().setup().register_term(*this); } @@ -1047,7 +1026,7 @@ analog_output_t::~analog_output_t() void analog_output_t::initial(const nl_double val) { - net().m_cur_Analog = val; + net().set_Q_Analog(val); } // ----------------------------------------------------------------------------- @@ -1133,11 +1112,11 @@ param_double_t::param_double_t(device_t &device, const pstring name, const doubl m_param = device.setup().get_initial_param_val(this->name(),val); netlist().save(*this, m_param, "m_param"); } - +#if 0 param_double_t::~param_double_t() { } - +#endif param_int_t::param_int_t(device_t &device, const pstring name, const int val) : param_t(device, name) { @@ -1145,9 +1124,11 @@ param_int_t::param_int_t(device_t &device, const pstring name, const int val) netlist().save(*this, m_param, "m_param"); } +#if 0 param_int_t::~param_int_t() { } +#endif param_logic_t::param_logic_t(device_t &device, const pstring name, const bool val) : param_t(device, name) @@ -1156,9 +1137,11 @@ param_logic_t::param_logic_t(device_t &device, const pstring name, const bool va netlist().save(*this, m_param, "m_param"); } +#if 0 param_logic_t::~param_logic_t() { } +#endif param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val) : param_t(device, name) @@ -1167,13 +1150,15 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val) //netlist().save(*this, m_param, "m_param"); } +#if 0 param_ptr_t::~param_ptr_t() { } +#endif void param_model_t::changed() { - netlist().log().fatal("Models can not be changed at runtime"); + netlist().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name()); m_map.clear(); } @@ -1200,8 +1185,6 @@ std::unique_ptr<plib::pistream> param_data_t::stream() return device().netlist().setup().get_data_stream(Value()); } - - namespace devices { // ---------------------------------------------------------------------------------------- |