summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-01-31 20:23:40 +0100
committer couriersud <couriersud@gmx.org>2020-01-31 20:23:40 +0100
commit84e3eb1debc6d637d5282bbc43a431aaeb867997 (patch)
tree7d08e981398fa7608e64e8fc9fd4579dafee2e8d /src/lib
parent72f86082aaef3166335dad915fa4656073a51a76 (diff)
netlist: Code symplification and bugfixes. (nw)
- Fixes performance regression and net_splitter struct. - Fixes nltool time measurements - pstream simplification
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/analog/nld_generic_models.h16
-rw-r--r--src/lib/netlist/nl_setup.cpp8
-rw-r--r--src/lib/netlist/nl_setup.h2
-rw-r--r--src/lib/netlist/plib/pstream.h40
-rw-r--r--src/lib/netlist/prg/nltool.cpp66
-rw-r--r--src/lib/netlist/prg/nlwav.cpp7
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp68
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp6
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);