summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-02-04 19:22:21 +0100
committer couriersud <couriersud@gmx.org>2019-02-04 19:36:02 +0100
commit759b7c3c88368ce833b59404d1d205dc88606996 (patch)
treee518710aa135dbfbdf97798d4bb4e1a54245a70d /src/lib
parentfa72f0bfe3ccd57fd2937ca64038dc1189cd3ca6 (diff)
netlist: Further simplification and optimization. (nw)
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/devices/nld_7474.cpp2
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.h104
-rw-r--r--src/lib/netlist/nl_base.cpp40
-rw-r--r--src/lib/netlist/nl_base.h23
-rw-r--r--src/lib/netlist/nl_lists.h32
-rw-r--r--src/lib/netlist/nl_setup.h14
-rw-r--r--src/lib/netlist/plib/pchrono.h26
-rw-r--r--src/lib/netlist/plib/pconfig.h2
-rw-r--r--src/lib/netlist/plib/plists.h97
-rw-r--r--src/lib/netlist/prg/nltool.cpp110
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp2
11 files changed, 282 insertions, 170 deletions
diff --git a/src/lib/netlist/devices/nld_7474.cpp b/src/lib/netlist/devices/nld_7474.cpp
index e50faef607b..d9129ad1ba9 100644
--- a/src/lib/netlist/devices/nld_7474.cpp
+++ b/src/lib/netlist/devices/nld_7474.cpp
@@ -1,3 +1,4 @@
+
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
@@ -110,6 +111,7 @@ namespace netlist
NETLIB_RESET(7474)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
+ m_D.set_state(logic_t::STATE_INP_ACTIVE);
m_nextD = 0;
}
diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h
index c633a6991a1..6896c656750 100644
--- a/src/lib/netlist/devices/nlid_truthtable.h
+++ b/src/lib/netlist/devices/nlid_truthtable.h
@@ -86,7 +86,6 @@ namespace devices
static constexpr const std::size_t m_num_bits = m_NI;
static constexpr const std::size_t m_size = (1 << (m_num_bits));
static constexpr const type_t m_outmask = ((1 << m_NO) - 1);
- static constexpr const std::size_t m_min_inputs_for_deactivate = 2;
struct truthtable_t
{
@@ -106,7 +105,6 @@ namespace devices
: device_t(owner, name)
, m_fam(*this, fam)
, m_ign(*this, "m_ign", 0)
- , m_active_outputs(*this, "m_active_outputs", 1)
, m_ttp(ttp)
{
init(desc);
@@ -116,13 +114,14 @@ namespace devices
NETLIB_RESETI()
{
- m_active_outputs = 0;
+ int active_outputs = 0;
m_ign = 0;
for (auto &i : m_I)
i.activate();
for (auto &q : m_Q)
if (q.has_net() && q.net().num_cons() > 0)
- m_active_outputs++;
+ active_outputs++;
+ set_active_outputs(active_outputs);
}
NETLIB_UPDATEI()
@@ -132,28 +131,14 @@ namespace devices
void inc_active() NL_NOEXCEPT override
{
- if (m_NI >= m_min_inputs_for_deactivate)
- if (++m_active_outputs == 1)
- {
- process<false>();
- }
+ process<false>();
}
void dec_active() NL_NOEXCEPT override
{
- /* FIXME:
- * Based on current measurements there is no point to disable
- * 1 input devices. This should actually be a parameter so that we
- * can decide for each individual gate whether it is beneficial to
- * ignore deactivation.
- */
- if (m_NI >= m_min_inputs_for_deactivate)
- if (--m_active_outputs == 0)
- {
- for (std::size_t i = 0; i< m_NI; i++)
- m_I[i].inactivate();
- m_ign = (1<<m_NI)-1;
- }
+ for (std::size_t i = 0; i< m_NI; i++)
+ m_I[i].inactivate();
+ m_ign = (1<<m_NI)-1;
}
plib::uninitialised_array_t<logic_input_t, m_NI> m_I;
@@ -169,52 +154,35 @@ namespace devices
netlist_time mt(netlist_time::zero());
type_t nstate(0);
- if (m_NI >= m_min_inputs_for_deactivate)
- {
- type_t ign(m_ign);
+ type_t ign(m_ign);
#if 1
- if (!doOUT)
- for (std::size_t i = 0; i < m_NI; i++)
- {
- m_I[i].activate();
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
- mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
- }
- else
- for (std::size_t i = 0; i < m_NI; i++)
- {
- if ((ign & 1))
- m_I[i].activate();
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
- ign >>= 1;
- }
-#else
- if (!doOUT)
+ if (!doOUT)
+ for (std::size_t i = 0; i < m_NI; i++)
{
- nstate = aa<m_NI, type_t>().f(m_I, ~0);
- for (std::size_t i = 0; i < m_NI; i++)
- mt = std::max(this->m_I[i].net().time(), mt);
+ m_I[i].activate();
+ //nstate |= (m_I[i]() ? (1 << i) : 0);
+ nstate |= (m_I[i]() << i);
+ mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
}
- else
- nstate = aa<m_NI, type_t>().f(m_I, ign);
-#endif
- }
else
+ for (std::size_t i = 0; i < m_NI; i++)
+ {
+ if ((ign & 1))
+ m_I[i].activate();
+ //nstate |= (m_I[i]() ? (1 << i) : 0);
+ nstate |= (m_I[i]() << i);
+ ign >>= 1;
+ }
+#else
+ if (!doOUT)
{
- if (!doOUT)
- for (std::size_t i = 0; i < m_NI; i++)
- {
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
- mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
- }
- else
- for (std::size_t i = 0; i < m_NI; i++)
- //nstate |= (m_I[i]() ? (1 << i) : 0);
- nstate |= (m_I[i]() << i);
+ nstate = aa<m_NI, type_t>().f(m_I, ~0);
+ for (std::size_t i = 0; i < m_NI; i++)
+ mt = std::max(this->m_I[i].net().time(), mt);
}
+ else
+ nstate = aa<m_NI, type_t>().f(m_I, ign);
+#endif
const type_t outstate(m_ttp.m_out_state[nstate]);
type_t out(outstate & m_outmask);
@@ -232,18 +200,14 @@ namespace devices
for (std::size_t i = 0; i < m_NO; out >>= 1, ++i)
m_Q[i].set_Q_time(out & 1, mt + tim[t[i]]);
- if (m_NI >= m_min_inputs_for_deactivate)
- {
- type_t ign(m_ign);
- for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
- if (ign & 1)
- I->inactivate();
- }
+ ign = m_ign;
+ for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
+ if (ign & 1)
+ I->inactivate();
}
/* FIXME: check width */
state_var<type_t> m_ign;
- state_var_s32 m_active_outputs;
const truthtable_t &m_ttp;
};
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 4ce980dbba8..cc057de25f8 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -430,7 +430,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
m_queue.push(detail::queue_t::entry_t(stop, nullptr));
- m_stat_mainloop.start();
+ auto sm_guard(m_stat_mainloop.guard());
if (m_mainclock == nullptr)
{
@@ -472,7 +472,6 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
} while (true); //while (e.m_object != nullptr);
mc_net.set_next_scheduled_time(mc_time);
}
- m_stat_mainloop.stop();
}
void netlist_t::print_stats() const
@@ -504,13 +503,13 @@ void netlist_t::print_stats() const
nperftime_t<NL_KEEP_STATISTICS> overhead;
nperftime_t<NL_KEEP_STATISTICS> test;
- overhead.start();
- for (int j=0; j<100000;j++)
{
- test.start();
- test.stop();
+ auto overhead_guard(overhead.guard());
+ for (int j=0; j<100000;j++)
+ {
+ auto test_guard(test.guard());
+ }
}
- overhead.stop();
nperftime_t<NL_KEEP_STATISTICS>::type total_overhead = overhead()
* static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(total_count)
@@ -518,6 +517,8 @@ void netlist_t::print_stats() const
log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call());
log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove());
+ log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove());
+ log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime());
log().verbose("Total loop {1:15}", m_stat_mainloop());
/* Only one serialization should be counted in total time */
@@ -570,6 +571,7 @@ core_device_t::core_device_t(netlist_base_t &owner, const pstring &name)
, logic_family_t()
, netlist_ref(owner)
, m_hint_deactivate(false)
+ , m_active_outputs(*this, "m_active_outputs", 1)
{
if (logic_family() == nullptr)
set_logic_family(family_TTL());
@@ -580,6 +582,7 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name)
, logic_family_t()
, netlist_ref(owner.state())
, m_hint_deactivate(false)
+ , m_active_outputs(*this, "m_active_outputs", 1)
{
set_logic_family(owner.logic_family());
if (logic_family() == nullptr)
@@ -723,9 +726,10 @@ void detail::net_t::process(const T mask)
p.device().m_stat_call_count.inc();
if ((p.terminal_state() & mask))
{
- p.device().m_stat_total_time.start();
+ auto g(p.device().m_stat_total_time.guard());
+ //p.device().m_stat_total_time.start();
p.m_delegate();
- p.device().m_stat_total_time.stop();
+ //p.device().m_stat_total_time.stop();
}
}
}
@@ -740,16 +744,16 @@ void detail::net_t::update_devs() NL_NOEXCEPT
| (m_cur_Q << core_terminal_t::INP_HL_SHIFT));
m_in_queue = QS_DELIVERED; /* mark as taken ... */
-
- if (mask == core_terminal_t::STATE_INP_HL)
- {
- m_cur_Q = new_Q;
- process(core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE);
- }
- else if (mask == core_terminal_t::STATE_INP_LH)
+ switch (mask)
{
- m_cur_Q = new_Q;
- process(core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE);
+ case core_terminal_t::STATE_INP_HL:
+ case core_terminal_t::STATE_INP_LH:
+ m_cur_Q = new_Q;
+ process(mask | core_terminal_t::STATE_INP_ACTIVE);
+ break;
+ default:
+ /* do nothing */
+ break;
}
}
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 35ecc694cfd..2d8f8154ed0 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -493,9 +493,9 @@ namespace netlist
using list_t = std::vector<core_terminal_t *>;
- static constexpr const unsigned INP_HL_SHIFT = 0;
- static constexpr const unsigned INP_LH_SHIFT = 1;
- static constexpr const unsigned INP_ACTIVE_SHIFT = 2;
+ static constexpr const auto INP_HL_SHIFT = 0;
+ static constexpr const auto INP_LH_SHIFT = 1;
+ static constexpr const auto INP_ACTIVE_SHIFT = 2;
enum state_e {
STATE_INP_PASSIVE = 0,
@@ -1084,19 +1084,27 @@ namespace netlist
{
if (m_hint_deactivate)
{
- m_stat_inc_active.inc();
- inc_active();
+ if (++m_active_outputs == 1)
+ {
+ m_stat_inc_active.inc();
+ inc_active();
+ }
}
}
void do_dec_active() NL_NOEXCEPT
{
if (m_hint_deactivate)
- dec_active();
+ if (--m_active_outputs == 0)
+ {
+ dec_active();
+ }
}
void set_hint_deactivate(bool v) { m_hint_deactivate = v; }
bool get_hint_deactivate() { return m_hint_deactivate; }
+ /* Has to be set in device reset */
+ void set_active_outputs(int n) { m_active_outputs = n; }
void set_default_delegate(detail::core_terminal_t &term);
@@ -1124,7 +1132,8 @@ namespace netlist
virtual bool is_timestep() const { return false; }
private:
- bool m_hint_deactivate;
+ bool m_hint_deactivate;
+ state_var_s32 m_active_outputs;
};
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index 924dfb19e39..042a823259f 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -67,27 +67,27 @@ namespace netlist
struct QueueOp
{
- static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
+ inline static constexpr bool less(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
{
return (lhs.m_exec_time < rhs.m_exec_time);
}
- static constexpr bool lessequal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
+ inline static constexpr bool lessequal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
{
return (lhs.m_exec_time <= rhs.m_exec_time);
}
- static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
+ inline static constexpr bool equal(const pqentry_t &lhs, const pqentry_t &rhs) noexcept
{
return lhs.m_object == rhs.m_object;
}
- static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept
+ inline static constexpr bool equal(const pqentry_t &lhs, const Element &rhs) noexcept
{
return lhs.m_object == rhs;
}
- static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
+ inline static constexpr pqentry_t never() noexcept { return pqentry_t(Time::never(), nullptr); }
};
Time m_exec_time;
@@ -109,29 +109,31 @@ namespace netlist
std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
bool empty() const noexcept { return (m_end == &m_list[1]); }
- void push(T &&e) noexcept
+ void push(T e) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
- T * i(m_end);
- for (; QueueOp::less(*(i - 1), e); --i)
+ T * i(m_end-1);
+ for (; QueueOp::less(*(i), e); --i)
{
- *(i) = std::move(*(i-1));
+ *(i+1) = *(i);
m_prof_sortmove.inc();
}
- *i = std::move(e);
+ *(i+1) = e;
++m_end;
m_prof_call.inc();
}
T pop() noexcept { return *(--m_end); }
- const T top() const noexcept { return *(m_end-1); }
+ const T &top() const noexcept { return *(m_end-1); }
template <class R>
- void remove(const R &elem) noexcept
+ void remove(const R elem) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
+ m_prof_remove.inc();
+
for (T * i = m_end - 1; i > &m_list[0]; --i)
{
if (QueueOp::equal(*i, elem))
@@ -142,10 +144,12 @@ namespace netlist
}
}
- void retime(const T &elem) noexcept
+ void retime(T elem) noexcept
{
/* Lock */
lock_guard_type lck(m_lock);
+ m_prof_retime.inc();
+
for (T * i = m_end - 1; i > &m_list[0]; --i)
{
if (QueueOp::equal(*i, elem)) // partial equal!
@@ -195,6 +199,8 @@ namespace netlist
// profiling
nperfcount_t<KEEPSTAT> m_prof_sortmove;
nperfcount_t<KEEPSTAT> m_prof_call;
+ nperfcount_t<KEEPSTAT> m_prof_remove;
+ nperfcount_t<KEEPSTAT> m_prof_retime;
};
template <class T, bool TS, bool KEEPSTAT, class QueueOp = typename T::QueueOp>
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 25201bee1b5..d0a5c002928 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -172,6 +172,9 @@ namespace netlist
class source_t
{
public:
+
+ friend class setup_t;
+
enum type_t
{
SOURCE,
@@ -187,10 +190,12 @@ namespace netlist
virtual ~source_t() { }
virtual bool parse(const pstring &name);
- virtual std::unique_ptr<plib::pistream> stream(const pstring &name) = 0;
-
setup_t &setup() { return m_setup; }
type_t type() const { return m_type; }
+
+ protected:
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) = 0;
+
private:
setup_t &m_setup;
const type_t m_type;
@@ -370,6 +375,7 @@ namespace netlist
{
}
+ protected:
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
@@ -385,6 +391,7 @@ namespace netlist
{
}
+ protected:
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
@@ -399,6 +406,7 @@ namespace netlist
{
}
+ protected:
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
@@ -416,6 +424,8 @@ namespace netlist
}
virtual bool parse(const pstring &name) override;
+
+ protected:
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
private:
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index a229128e7b8..c3ea4ba9535 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -170,13 +170,22 @@ namespace chrono {
{
typedef typename T::type type;
typedef uint_least64_t ctype;
+ constexpr static bool enabled = enabled_;
+
+ struct guard_t
+ {
+ guard_t(timer &m) : m_m(m) { m_m.m_time -= T::start();; }
+ ~guard_t() { m_m.m_time += T::stop(); ++m_m.m_count; }
+ private:
+ timer &m_m;
+ };
+
+ friend struct guard_t;
timer() : m_time(0), m_count(0) { }
type operator()() const { return m_time; }
- void start() { m_time -= T::start(); }
- void stop() { m_time += T::stop(); ++m_count; }
void reset() { m_time = 0; m_count = 0; }
type average() const { return (m_count == 0) ? 0 : m_time / m_count; }
type total() const { return m_time; }
@@ -185,7 +194,7 @@ namespace chrono {
double as_seconds() const { return static_cast<double>(total())
/ static_cast<double>(T::per_second()); }
- constexpr static bool enabled = enabled_;
+ guard_t guard() { return guard_t(*this); }
private:
type m_time;
ctype m_count;
@@ -196,17 +205,24 @@ namespace chrono {
{
typedef typename T::type type;
typedef uint_least64_t ctype;
+
+ struct guard_t
+ {
+ guard_t() {}
+ ~guard_t() {}
+ };
+
constexpr type operator()() const { return 0; }
- void start() const { }
- void stop() const { }
void reset() const { }
constexpr type average() const { return 0; }
constexpr type total() const { return 0; }
constexpr ctype count() const { return 0; }
constexpr double as_seconds() const { return 0.0; }
constexpr static bool enabled = false;
+ guard_t guard() { return guard_t(); }
};
+
} // namespace chrono
} // namespace plib
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index bef33323670..731ae1f18fd 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -21,7 +21,7 @@
* if PHAS_RDTSCP == 1
*/
#ifndef PUSE_ACCURATE_STATS
-#define PUSE_ACCURATE_STATS (1)
+#define PUSE_ACCURATE_STATS (0)
#endif
/*
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index d440d76de2a..19e65cb7cdc 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -83,6 +83,7 @@ private:
// the list allows insertions / deletions if used properly
// ----------------------------------------------------------------------------------------
+#if 0
template <class LC>
class linkedlist_t
{
@@ -167,7 +168,103 @@ public:
private:
LC *m_head;
};
+#else
+template <class LC>
+class linkedlist_t
+{
+public:
+
+ struct element_t
+ {
+ public:
+
+ friend class linkedlist_t<LC>;
+
+ constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
+ constexpr element_t(const element_t &rhs) = delete;
+ constexpr element_t(element_t &&rhs) = delete;
+
+ constexpr LC *next() const noexcept { return m_next; }
+ constexpr LC *prev() const noexcept { return m_prev; }
+
+ protected:
+ ~element_t() = default;
+ private:
+ LC * m_next;
+ LC * m_prev;
+ };
+
+ struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
+ {
+ private:
+ LC* p;
+ public:
+ explicit constexpr iter_t(LC* x) noexcept : p(x) { }
+ explicit constexpr iter_t(iter_t &rhs) noexcept : p(rhs.p) { }
+ iter_t(iter_t &&rhs) noexcept { std::swap(*this, rhs); }
+ iter_t& operator=(iter_t &rhs) { iter_t t(rhs); std::swap(*this, t); return *this; }
+ iter_t& operator=(iter_t &&rhs) { std::swap(*this, rhs); return *this; }
+ iter_t& operator++() noexcept {p = p->next();return *this;}
+ iter_t operator++(int) noexcept {iter_t tmp(*this); operator++(); return tmp;}
+ constexpr bool operator==(const iter_t& rhs) const noexcept {return p == rhs.p;}
+ constexpr bool operator!=(const iter_t& rhs) const noexcept {return p != rhs.p;}
+ /* constexpr */ LC& operator*() noexcept {return *p;}
+ /* constexpr */ LC* operator->() noexcept {return p;}
+
+ constexpr LC& operator*() const noexcept {return *p;}
+ constexpr LC* operator->() const noexcept {return p;}
+ };
+
+ constexpr linkedlist_t() : m_head(nullptr) {}
+ constexpr iter_t begin() const noexcept { return iter_t(m_head); }
+ constexpr iter_t end() const noexcept { return iter_t(nullptr); }
+
+ void push_front(LC *elem) noexcept
+ {
+ elem->m_next = m_head;
+ elem->m_prev = nullptr;
+ if (elem->m_next)
+ elem->m_next->m_prev = elem;
+ m_head = elem;
+ }
+
+ void push_back(LC *elem) noexcept
+ {
+ LC ** p(&m_head);
+ LC * prev(nullptr);
+ while (*p != nullptr)
+ {
+ prev = *p;
+ p = &((*p)->m_next);
+ }
+ *p = elem;
+ elem->m_prev = prev;
+ elem->m_next = nullptr;
+ }
+
+ void remove(const LC *elem) noexcept
+ {
+ if (elem->m_prev)
+ elem->m_prev->m_next = elem->m_next;
+ else
+ m_head = elem->m_next;
+ if (elem->m_next)
+ elem->m_next->m_prev = elem->m_prev;
+ else
+ {
+ /* update tail */
+ }
+ }
+
+ LC *front() const noexcept { return m_head; }
+ void clear() noexcept { m_head = nullptr; }
+ constexpr bool empty() const noexcept { return (m_head == nullptr); }
+
+private:
+ LC *m_head;
+};
+#endif
}
#endif /* PLISTS_H_ */
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 984f8703079..814538e688e 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -337,78 +337,82 @@ static std::vector<input_t> read_input(const netlist::setup_t &setup, pstring fn
void tool_app_t::run()
{
plib::chrono::timer<plib::chrono::system_ticks> t;
- t.start();
-
+ std::vector<input_t> inps;
+ netlist::netlist_time ttr;
netlist_tool_t nt(*this, "netlist");
- //plib::perftime_t<plib::exact_ticks> t;
- nt.init();
+ {
+ auto t_guard(t.guard());
+ //plib::perftime_t<plib::exact_ticks> t;
- if (!opt_verb())
- nt.log().verbose.set_enabled(false);
- if (opt_quiet())
- nt.log().warning.set_enabled(false);
+ nt.init();
- nt.read_netlist(opt_file(), opt_name(),
- opt_logs(),
- m_options, opt_rfolders());
+ if (!opt_verb())
+ nt.log().verbose.set_enabled(false);
+ if (opt_quiet())
+ nt.log().warning.set_enabled(false);
+
+ nt.read_netlist(opt_file(), opt_name(),
+ opt_logs(),
+ m_options, opt_rfolders());
- std::vector<input_t> inps = read_input(nt.setup(), opt_inp());
+ inps = read_input(nt.setup(), opt_inp());
+ ttr = netlist::netlist_time::from_double(opt_ttr());
+ }
- netlist::netlist_time ttr = netlist::netlist_time::from_double(opt_ttr());
- t.stop();
pout("startup time ==> {1:5.3f}\n", t.as_seconds() );
t.reset();
- t.start();
- // FIXME: error handling
- if (opt_loadstate.was_specified())
+ netlist::netlist_time nlt = nt.time();
{
- plib::pifilestream strm(opt_loadstate());
- 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.time().as_double());
- }
+ auto t_guard(t.guard());
- unsigned pos = 0;
- netlist::netlist_time nlt = nt.time();
+ // FIXME: error handling
+ if (opt_loadstate.was_specified())
+ {
+ plib::pifilestream strm(opt_loadstate());
+ 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.time().as_double());
+ }
+ unsigned pos = 0;
- while (pos < inps.size()
- && inps[pos].m_time < ttr
- && inps[pos].m_time >= nlt)
- {
- nt.process_queue(inps[pos].m_time - nlt);
- inps[pos].setparam();
- nlt = inps[pos].m_time;
- pos++;
- }
- pout("runnning ...\n");
+ while (pos < inps.size()
+ && inps[pos].m_time < ttr
+ && inps[pos].m_time >= nlt)
+ {
+ nt.process_queue(inps[pos].m_time - nlt);
+ inps[pos].setparam();
+ nlt = inps[pos].m_time;
+ pos++;
+ }
- if (ttr > nlt)
- nt.process_queue(ttr - nlt);
- else
- {
- pout("end time {1:.6f} less than saved time {2:.6f}\n",
- ttr.as_double(), nlt.as_double());
- ttr = nlt;
- }
+ pout("runnning ...\n");
- if (opt_savestate.was_specified())
- {
- auto savestate = nt.save_state();
- plib::pofilestream strm(opt_savestate());
- plib::pbinary_writer writer(strm);
- writer.write(savestate);
- }
- nt.stop();
+ if (ttr > nlt)
+ nt.process_queue(ttr - nlt);
+ else
+ {
+ pout("end time {1:.6f} less than saved time {2:.6f}\n",
+ ttr.as_double(), nlt.as_double());
+ ttr = nlt;
+ }
- t.stop();
+ if (opt_savestate.was_specified())
+ {
+ auto savestate = nt.save_state();
+ plib::pofilestream strm(opt_savestate());
+ plib::pbinary_writer writer(strm);
+ writer.write(savestate);
+ }
+ nt.stop();
+ }
double emutime = t.as_seconds();
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n",
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 4350f892716..6779e50088b 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -302,7 +302,7 @@ void NETLIB_NAME(solver)::post_start()
else
ms = create_solver<double, 2>(2, sname);
break;
-#if 0
+#if 1
case 3:
ms = create_solver<double, 3>(3, sname);
break;