diff options
author | couriersud <couriersud@gmx.org> | 2020-01-31 20:23:40 +0100 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2020-01-31 20:23:40 +0100 |
commit | 84e3eb1debc6d637d5282bbc43a431aaeb867997 (patch) | |
tree | 7d08e981398fa7608e64e8fc9fd4579dafee2e8d | |
parent | 72f86082aaef3166335dad915fa4656073a51a76 (diff) |
netlist: Code symplification and bugfixes. (nw)
- Fixes performance regression and net_splitter struct.
- Fixes nltool time measurements
- pstream simplification
-rw-r--r-- | src/lib/netlist/analog/nld_generic_models.h | 16 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 8 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.h | 40 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 66 | ||||
-rw-r--r-- | src/lib/netlist/prg/nlwav.cpp | 7 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_solver.cpp | 68 | ||||
-rw-r--r-- | src/lib/netlist/tools/nl_convert.cpp | 6 |
8 files changed, 111 insertions, 102 deletions
diff --git a/src/lib/netlist/analog/nld_generic_models.h b/src/lib/netlist/analog/nld_generic_models.h index 799c28c5a28..570a4339bbb 100644 --- a/src/lib/netlist/analog/nld_generic_models.h +++ b/src/lib/netlist/analog/nld_generic_models.h @@ -149,6 +149,15 @@ namespace analog , nlconst::magic(300.0)); } + // Basic math + // + // I(V) = f(V) + // + // G(V) = df/dV(V) + // + // Ieq(V) = I(V) - V * G(V) + // + // void update_diode(nl_fptype nVd) noexcept { if (TYPE == diode_e::BIPOLAR) @@ -163,11 +172,9 @@ namespace analog const nl_fptype d = std::min(+fp_constants<nl_fptype>::DIODE_MAXDIFF(), nVd - old); const nl_fptype a = plib::abs(d) * m_VtInv; m_Vd = old + nlconst::magic(d < 0 ? -1.0 : 1.0) * plib::log1p(a) * m_Vt; - //printf("new VD: %g\n", (nl_fptype)m_Vd); } else m_Vd = std::max(-fp_constants<nl_fptype>::DIODE_MAXDIFF(), nVd); - //m_Vd = nVd; if (m_Vd < m_Vmin) { @@ -183,15 +190,14 @@ namespace analog } else if (TYPE == diode_e::MOS) { + m_Vd = nVd; if (nVd < nlconst::zero()) { - m_Vd = nVd; m_G = m_Is * m_VtInv + m_gmin; m_Id = m_G * m_Vd; } else // log stepping should already be done in mosfet { - m_Vd = nVd; const auto IseVDVt = plib::exp(std::min(+fp_constants<nl_fptype>::DIODE_MAXVOLT(), m_logIs + m_Vd * m_VtInv)); m_Id = IseVDVt - m_Is; m_G = IseVDVt * m_VtInv + m_gmin; @@ -209,9 +215,9 @@ namespace analog m_Vmin = nlconst::magic(-5.0) * m_Vt; + // Vcrit : f(V) has smallest radius of curvature rho(V) == min(rho(v)) m_Vcrit = m_Vt * plib::log(m_Vt / m_Is / nlconst::sqrt2()); m_VtInv = plib::reciprocal(m_Vt); - //printf("%g %g\n", m_Vmin, m_Vcrit); } diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 5cda3e03d64..727b37c54c6 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -313,9 +313,9 @@ namespace netlist bool nlparse_t::parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name) { - plib::ppreprocessor y(m_includes, &m_defines); - plib::ppreprocessor &x(y.process(std::move(istrm))); - return parser_t(std::move(x), *this).parse(name); + auto y = plib::make_unique<plib::ppreprocessor>(m_includes, &m_defines); + y->process(std::move(istrm)); + return parser_t(std::move(y), *this).parse(name); //return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name); } @@ -1057,7 +1057,7 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map) } } -pstring models_t::model_string(const model_map_t &map) const +pstring models_t::model_string(const model_map_t &map) { // operator [] has no const implementation pstring ret = map.at("COREMODEL") + "("; diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 42a517e20a2..946f271fafa 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -224,7 +224,7 @@ namespace netlist using model_map_t = std::unordered_map<pstring, pstring>; void model_parse(const pstring &model, model_map_t &map); - pstring model_string(const model_map_t &map) const; + static pstring model_string(const model_map_t &map); std::unordered_map<pstring, pstring> m_models; std::unordered_map<pstring, model_map_t> m_cache; diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index ea19d673931..b1dd55669b7 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -26,12 +26,6 @@ namespace plib { -template <typename T> -struct constructor_helper -{ - plib::unique_ptr<std::istream> operator()(T &&s) { return std::move(plib::make_unique<T>(std::move(s))); } -}; - /// /// \brief: putf8reader_t: reader on top of istream. /// @@ -43,17 +37,24 @@ class putf8_reader public: COPYASSIGN(putf8_reader, delete) - putf8_reader &operator=(putf8_reader &&src) = delete; virtual ~putf8_reader() = default; - template <typename T> - friend struct constructor_helper; + putf8_reader(putf8_reader &&rhs) + : m_strm(std::move(rhs.m_strm)) + , m_linebuf(std::move(rhs.m_linebuf)) + { + } - template <typename T> - putf8_reader(T &&strm) // NOLINT(cppcoreguidelines-special-member-functions, misc-forwarding-reference-overload, bugprone-forwarding-reference-overload) - : m_strm(std::move(constructor_helper<T>()(std::move(strm)))) // NOLINT(bugprone-move-forwarding-reference) + putf8_reader(plib::unique_ptr<std::istream> &&rhs) + : m_strm(std::move(rhs)) + { + } +#if 0 + template<typename T, typename... Args> + putf8_reader(Args&&... args) + : m_strm(plib::make_unique<T>(std::forward<Args>(args)...)) {} - +#endif bool eof() const { return m_strm->eof(); } bool readline(pstring &line) @@ -111,19 +112,6 @@ private: putf8string m_linebuf; }; -template <> -struct constructor_helper<putf8_reader> -{ - plib::unique_ptr<std::istream> operator()(putf8_reader &&s) const { return std::move(s.m_strm); } -}; - -template <> -struct constructor_helper<plib::unique_ptr<std::istream>> -{ - plib::unique_ptr<std::istream> operator()(plib::unique_ptr<std::istream> &&s) const { return std::move(s); } -}; - - // ----------------------------------------------------------------------------- // putf8writer_t: writer on top of ostream // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 0f9d1088076..af1e212439e 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -368,7 +368,7 @@ static std::vector<input_t> read_input(const netlist::setup_t &setup, const pstr std::vector<input_t> ret; if (fname != "") { - plib::putf8_reader r = plib::putf8_reader(std::ifstream(plib::filesystem::u8path(fname))); + plib::putf8_reader r = plib::putf8_reader(plib::make_unique<std::ifstream>(plib::filesystem::u8path(fname))); if (r.stream().fail()) throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(fname)); r.stream().imbue(std::locale::classic()); @@ -416,28 +416,31 @@ void tool_app_t::run() pout("startup time ==> {1:5.3f}\n", t.as_seconds<nl_fptype>() ); + // FIXME: error handling + if (opt_loadstate.was_specified()) + { + std::ifstream strm(plib::filesystem::u8path(opt_loadstate())); + if (strm.fail()) + throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_loadstate())); + strm.imbue(std::locale::classic()); + plib::pbinary_reader reader(strm); + std::vector<char> loadstate; + reader.read(loadstate); + nt.load_state(loadstate); + pout("Loaded state, run will continue at {1:.6f}\n", nt.exec().time().as_double()); + } + t.reset(); - netlist::netlist_time_ext nlt = nt.exec().time(); + netlist::netlist_time_ext nlstart = nt.exec().time(); { auto t_guard(t.guard()); - // FIXME: error handling - if (opt_loadstate.was_specified()) - { - std::ifstream strm(plib::filesystem::u8path(opt_loadstate())); - if (strm.fail()) - throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_loadstate())); - strm.imbue(std::locale::classic()); - plib::pbinary_reader reader(strm); - std::vector<char> loadstate; - reader.read(loadstate); - nt.load_state(loadstate); - pout("Loaded state, run will continue at {1:.6f}\n", nt.exec().time().as_double()); - } + pout("runnning ...\n"); unsigned pos = 0; + netlist::netlist_time_ext nlt = nlstart; while (pos < inps.size() && inps[pos].m_time < ttr @@ -449,8 +452,6 @@ void tool_app_t::run() pos++; } - pout("runnning ...\n"); - if (ttr > nlt) nt.exec().process_queue(ttr - nlt); else @@ -460,24 +461,25 @@ void tool_app_t::run() ttr = nlt; } - if (opt_savestate.was_specified()) - { - auto savestate = nt.save_state(); - std::ofstream strm(plib::filesystem::u8path(opt_savestate()), std::ios_base::binary); - if (strm.fail()) - throw plib::file_open_e(opt_savestate()); - strm.imbue(std::locale::classic()); - - plib::pbinary_writer writer(strm); - writer.write(savestate); - } - nt.exec().stop(); } + if (opt_savestate.was_specified()) + { + auto savestate = nt.save_state(); + std::ofstream strm(plib::filesystem::u8path(opt_savestate()), std::ios_base::binary); + if (strm.fail()) + throw plib::file_open_e(opt_savestate()); + strm.imbue(std::locale::classic()); + + plib::pbinary_writer writer(strm); + writer.write(savestate); + } + nt.exec().stop(); + auto emutime(t.as_seconds<nl_fptype>()); pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", - (ttr - nlt).as_fp<nl_fptype>(), emutime, - (ttr - nlt).as_fp<nl_fptype>() / emutime * netlist::nlconst::magic(100.0)); + (ttr - nlstart).as_fp<nl_fptype>(), emutime, + (ttr - nlstart).as_fp<nl_fptype>() / emutime * netlist::nlconst::magic(100.0)); } void tool_app_t::validate() @@ -578,7 +580,7 @@ struct doc_ext static doc_ext read_docsrc(const pstring &fname, const pstring &id) { //printf("file %s\n", fname.c_str()); - plib::putf8_reader r = plib::putf8_reader(std::ifstream(plib::filesystem::u8path(fname))); + plib::putf8_reader r = plib::putf8_reader(plib::make_unique<std::ifstream>(plib::filesystem::u8path(fname))); if (r.stream().fail()) throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(fname)); r.stream().imbue(std::locale::classic()); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 93a6d6e24a5..a6334edbda9 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -138,6 +138,7 @@ public: bool readmore(std::vector<plib::putf8_reader> &r) { + fprintf(stderr, "%d %d\n", (int) m_e.size(), (int) r.size()); bool success = false; for (std::size_t i = 0; i< r.size(); i++) { @@ -145,11 +146,13 @@ public: { pstring line; m_e[i].eof = !r[i].readline(line); + //fprintf(stderr, "bla: <%s>\n", line.c_str()); if (!m_e[i].eof) { // sscanf is very fast ... // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - std::sscanf(line.c_str(), "%lf %lf", &m_e[i].t, &m_e[i].v); + if (2 != std::sscanf(line.c_str(), "%lf %lf", &m_e[i].t, &m_e[i].v)) + fprintf(stderr, "arg: <%s>\n", line.c_str()); m_e[i].need_more = false; } } @@ -515,7 +518,7 @@ int nlwav_app::execute() for (auto &oi: opt_args()) { plib::unique_ptr<std::istream> fin; - + printf("%s\n", oi.c_str()); if (oi == "-") { auto temp(plib::make_unique<std::stringstream>()); diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 977b6ae7b20..2d003354455 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -252,8 +252,45 @@ namespace devices struct net_splitter { + void run(netlist_state_t &netlist) + { + for (auto & net : netlist.nets()) + { + netlist.log().verbose("processing {1}", net->name()); + if (!net->isRailNet() && net->num_cons() > 0) + { + netlist.log().verbose(" ==> not a rail net"); + // Must be an analog net + auto &n = *static_cast<analog_net_t *>(net.get()); + if (!already_processed(n)) + { + groupspre.emplace_back(analog_net_t::list_t()); + process_net(netlist, n); + } + } + } + for (auto &g : groupspre) + if (!g.empty()) + groups.push_back(g); + } + + std::vector<analog_net_t::list_t> groups; + + private: - bool already_processed(const analog_net_t &n) + bool already_processed(const analog_net_t &n) const + { + // no need to process rail nets - these are known variables + if (n.isRailNet()) + return true; + // if it's already processed - no need to continue + for (auto & grp : groups) + if (plib::container::contains(grp, &n)) + return true; + return false; + } + + bool check_if_processed_and_join(const analog_net_t &n) { // no need to process rail nets - these are known variables if (n.isRailNet()) @@ -297,41 +334,14 @@ namespace devices { auto *pt = static_cast<terminal_t *>(term); // check the connected terminal - // analog_net_t &connected_net = pt->connected_terminal()->net(); analog_net_t &connected_net = netlist.setup().get_connected_terminal(*pt)->net(); netlist.log().verbose(" Connected net {}", connected_net.name()); - if (!already_processed(connected_net)) + if (!check_if_processed_and_join(connected_net)) process_net(netlist, connected_net); } } } - void run(netlist_state_t &netlist) - { - for (auto & net : netlist.nets()) - { - netlist.log().debug("processing {1}", net->name()); - netlist.log().verbose("processing {1}", net->name()); - if (!net->isRailNet() && net->num_cons() > 0) - { - netlist.log().debug(" ==> not a rail net"); - netlist.log().verbose(" ==> not a rail net"); - // Must be an analog net - auto &n = *static_cast<analog_net_t *>(net.get()); - if (!already_processed(n)) - { - groupspre.emplace_back(analog_net_t::list_t()); - process_net(netlist, n); - } - } - } - for (auto &g : groupspre) - if (!g.empty()) - groups.push_back(g); - } - - std::vector<analog_net_t::list_t> groups; - private: std::vector<analog_net_t::list_t> groupspre; }; diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index dfc98598a97..58bf8fa2a47 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -43,7 +43,7 @@ using lib_map_t = std::unordered_map<pstring, lib_map_entry>; static lib_map_t read_lib_map(const pstring &lm) { - auto reader = plib::putf8_reader(std::istringstream(lm)); + auto reader = plib::putf8_reader(plib::make_unique<std::istringstream>(lm)); reader.stream().imbue(std::locale::classic()); lib_map_t m; pstring line; @@ -653,7 +653,7 @@ void nl_convert_eagle_t::tokenizer::verror(const pstring &msg) void nl_convert_eagle_t::convert(const pstring &contents) { - tokenizer tok(*this, plib::putf8_reader(std::istringstream(contents))); + tokenizer tok(*this, plib::putf8_reader(plib::make_unique<std::istringstream>(contents))); tok.stream().stream().imbue(std::locale::classic()); out("NETLIST_START(dummy)\n"); @@ -800,7 +800,7 @@ void nl_convert_rinf_t::tokenizer::verror(const pstring &msg) void nl_convert_rinf_t::convert(const pstring &contents) { - tokenizer tok(*this, plib::putf8_reader(std::istringstream(contents))); + tokenizer tok(*this, plib::putf8_reader(plib::make_unique<std::istringstream>(contents))); tok.stream().stream().imbue(std::locale::classic()); auto lm = read_lib_map(s_lib_map); |