mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
netlist: Further simplification and optimization. (nw)
This commit is contained in:
parent
fa72f0bfe3
commit
759b7c3c88
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
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
|
||||
{
|
||||
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, 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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
switch (mask)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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>
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
* if PHAS_RDTSCP == 1
|
||||
*/
|
||||
#ifndef PUSE_ACCURATE_STATS
|
||||
#define PUSE_ACCURATE_STATS (1)
|
||||
#define PUSE_ACCURATE_STATS (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -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_ */
|
||||
|
@ -337,79 +337,83 @@ 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);
|
||||
|
||||
std::vector<input_t> inps = read_input(nt.setup(), opt_inp());
|
||||
nt.read_netlist(opt_file(), opt_name(),
|
||||
opt_logs(),
|
||||
m_options, opt_rfolders());
|
||||
|
||||
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())
|
||||
{
|
||||
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;
|
||||
netlist::netlist_time nlt = nt.time();
|
||||
|
||||
|
||||
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++;
|
||||
auto t_guard(t.guard());
|
||||
|
||||
// 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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
pout("runnning ...\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
t.stop();
|
||||
|
||||
double emutime = t.as_seconds();
|
||||
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n",
|
||||
(ttr - nlt).as_double(), emutime,
|
||||
|
@ -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;
|
||||
|
@ -1703,7 +1703,7 @@ CIRCUIT_LAYOUT( breakout )
|
||||
NET_C(GND, D9.1, D9.2, D9.13, D9.3, D9.4, D9.5)
|
||||
|
||||
#if 1
|
||||
// 158% -- manually optimized
|
||||
// 163% -- manually optimized
|
||||
HINT(B6.s3, NO_DEACTIVATE)
|
||||
HINT(C4.s3, NO_DEACTIVATE)
|
||||
HINT(C4.s4, NO_DEACTIVATE)
|
||||
@ -1729,10 +1729,10 @@ CIRCUIT_LAYOUT( breakout )
|
||||
HINT(N7.s3, NO_DEACTIVATE)
|
||||
|
||||
#else
|
||||
// 152% hints provided by log output
|
||||
// 167% hints provided by log output - manually optimized
|
||||
HINT(M4.s2, NO_DEACTIVATE) // 29.001761 197676 6816
|
||||
HINT(M3.s3, NO_DEACTIVATE) // inf 129571 0
|
||||
HINT(N7.s3, NO_DEACTIVATE) // inf 7850387 0
|
||||
HINT(N7.s3, NO_DEACTIVATE) // inf 7850387 0 xx
|
||||
HINT(M3.s2, NO_DEACTIVATE) // 23.234535 395870 17038
|
||||
HINT(M3.s1, NO_DEACTIVATE) // 14.500880 197676 13632
|
||||
HINT(L7.s3, NO_DEACTIVATE) // 122672.000000 122672 1
|
||||
@ -1741,30 +1741,28 @@ CIRCUIT_LAYOUT( breakout )
|
||||
HINT(K7.s3, NO_DEACTIVATE) // 122672.000000 122672 1
|
||||
HINT(K7.s2, NO_DEACTIVATE) // 122673.000000 122673 1
|
||||
HINT(K7.s1, NO_DEACTIVATE) // 122673.000000 122673 1
|
||||
HINT(K4.s4, NO_DEACTIVATE) // 1438.774735 4202661 2921
|
||||
HINT(K4.s2, NO_DEACTIVATE) // 3.939380 847790 215209
|
||||
HINT(E2.s2, NO_DEACTIVATE) // 108.050000 315506 2920
|
||||
HINT(K4.s4, NO_DEACTIVATE) // 1438.774735 4202661 2921 xx
|
||||
HINT(K4.s2, NO_DEACTIVATE) // 3.939380 847790 215209 xx
|
||||
HINT(E2.s2, NO_DEACTIVATE) // 108.050000 315506 2920 xx
|
||||
HINT(L7.s4, NO_DEACTIVATE) // 122672.000000 122672 1
|
||||
HINT(E9.s6, NO_DEACTIVATE) // inf 129571 0
|
||||
HINT(J2.s6, NO_DEACTIVATE) // 493.408951 959187 1944
|
||||
//HINT(J2.s6, NO_DEACTIVATE) // 493.408951 959187 1944
|
||||
HINT(C5.s3, NO_DEACTIVATE) // inf 195514 0
|
||||
HINT(M3.s4, NO_DEACTIVATE) // 27.744898 418726 15092
|
||||
HINT(M3.s4, NO_DEACTIVATE) // 27.744898 418726 15092 xx
|
||||
HINT(J8.s1, NO_DEACTIVATE) // 40890.000000 122670 3
|
||||
HINT(E3.s2, NO_DEACTIVATE) // 203581.000000 203581 1
|
||||
HINT(M9.s4, NO_DEACTIVATE) // inf 323268 0
|
||||
HINT(L4.s2, NO_DEACTIVATE) // 7.290053 1192536 163584
|
||||
HINT(J3.s4, NO_DEACTIVATE) // 393.639951 957726 2433
|
||||
//HINT(L4.s2, NO_DEACTIVATE) // 7.290053 1192536 163584
|
||||
HINT(J3.s4, NO_DEACTIVATE) // 393.639951 957726 2433 xx
|
||||
HINT(L7.s1, NO_DEACTIVATE) // inf 122672 0
|
||||
HINT(F2.s1, NO_DEACTIVATE) // 286289.000000 286289 1
|
||||
HINT(M8.s1, NO_DEACTIVATE) // 129571.000000 129571 1
|
||||
HINT(J7.s2, NO_DEACTIVATE) // inf 122672 0
|
||||
HINT(H2.s1, NO_DEACTIVATE) // 393.839704 958212 2433
|
||||
HINT(H3.s1, NO_DEACTIVATE) // 3.932473 850122 216180
|
||||
//HINT(H2.s1, NO_DEACTIVATE) // 393.839704 958212 2433
|
||||
HINT(H3.s1, NO_DEACTIVATE) // 3.932473 850122 216180 xx
|
||||
HINT(J2.s5, NO_DEACTIVATE) // 26.140344 203581 7788
|
||||
HINT(J7.s1, NO_DEACTIVATE) // inf 122672 0
|
||||
HINT(J8.s3, NO_DEACTIVATE) // 40890.000000 122670 3
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
CIRCUIT_LAYOUT_END
|
||||
|
Loading…
Reference in New Issue
Block a user