Fix netlist stats collection. Code refactoring:

Small improvement for 7493.
Convert 9316 from subdevice to delegate.
Convert 74107 from subdevice style to delegate. 
Also refactored inconsistencies in other parts of the code. (nw)
This commit is contained in:
couriersud 2017-02-23 01:14:44 +01:00
parent acd0382d90
commit 7c1ba76f3b
9 changed files with 162 additions and 246 deletions

View File

@ -308,7 +308,7 @@ public:
m_param[i]->setTo(v * (*m_param_mult[i])() + (*m_param_offset[i])());
}
m_pos++;
m_Q.push(!m_Q.net().new_Q(), m_inc );
m_Q.net().toggle_and_push_to_queue(m_inc);
}
public:

View File

@ -16,60 +16,44 @@ namespace netlist
static const netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) };
static const netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) };
NETLIB_OBJECT(74107Asub)
NETLIB_OBJECT(74107A)
{
NETLIB_CONSTRUCTOR(74107Asub)
, m_clk(*this, "CLK")
NETLIB_CONSTRUCTOR(74107A)
, m_clk(*this, "CLK", NETLIB_DELEGATE(74107A, clk))
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_Q1(*this, "m_Q1", 0)
, m_Q2(*this, "m_Q2", 0)
, m_F(*this, "m_F", 0)
, m_delay(delay_107A)
, m_J(*this, "J")
, m_K(*this, "K")
, m_clrQ(*this, "CLRQ")
{
}
friend class NETLIB_NAME(74107_dip);
friend class NETLIB_NAME(74107);
//friend class NETLIB_NAME(74107A_dip);
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(clk);
public:
private:
logic_input_t m_clk;
logic_output_t m_Q;
logic_output_t m_QQ;
state_var<netlist_sig_t> m_Q1;
state_var<netlist_sig_t> m_Q2;
state_var<netlist_sig_t> m_F;
void newstate(const netlist_sig_t state);
const netlist_time *m_delay;
};
NETLIB_OBJECT(74107A)
{
NETLIB_CONSTRUCTOR(74107A)
, m_sub(*this, "sub")
, m_J(*this, "J")
, m_K(*this, "K")
, m_clrQ(*this, "CLRQ")
{
register_subalias("CLK", m_sub.m_clk);
register_subalias("Q", m_sub.m_Q);
register_subalias("QQ", m_sub.m_QQ);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(74107Asub) m_sub;
logic_input_t m_J;
logic_input_t m_K;
logic_input_t m_clrQ;
void newstate(const netlist_sig_t state)
{
m_Q.push(state, m_delay[state]);
m_QQ.push(state ^ 1, m_delay[state ^ 1]);
}
};
NETLIB_OBJECT_DERIVED(74107, 74107A)
@ -77,7 +61,7 @@ namespace netlist
public:
NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A)
{
m_sub.m_delay = delay_107;
m_delay = delay_107;
}
};
@ -88,21 +72,21 @@ namespace netlist
, m_2(*this, "2")
{
register_subalias("1", m_1.m_J);
register_subalias("2", m_1.m_sub.m_QQ);
register_subalias("3", m_1.m_sub.m_Q);
register_subalias("2", m_1.m_QQ);
register_subalias("3", m_1.m_Q);
register_subalias("4", m_1.m_K);
register_subalias("5", m_2.m_sub.m_Q);
register_subalias("6", m_2.m_sub.m_QQ);
register_subalias("5", m_2.m_Q);
register_subalias("6", m_2.m_QQ);
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.m_J);
register_subalias("9", m_2.m_sub.m_clk);
register_subalias("9", m_2.m_clk);
register_subalias("10", m_2.m_clrQ);
register_subalias("11", m_2.m_K);
register_subalias("12", m_1.m_sub.m_clk);
register_subalias("12", m_1.m_clk);
register_subalias("13", m_1.m_clrQ);
// register_subalias("14", ); ==> VCC
@ -116,69 +100,41 @@ namespace netlist
NETLIB_SUB(74107) m_2;
};
NETLIB_RESET(74107Asub)
NETLIB_RESET(74107A)
{
m_clk.set_state(logic_t::STATE_INP_HL);
//m_Q.initial(0);
//m_QQ.initial(1);
m_Q1 = 0;
m_Q2 = 0;
m_F = 0;
}
inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state)
NETLIB_HANDLER(74107A, clk)
{
m_Q.push(state, m_delay[state]);
m_QQ.push(state ^ 1, m_delay[state ^ 1]);
}
NETLIB_UPDATE(74107Asub)
{
const netlist_sig_t t = m_Q.net().Q();
newstate(((t ^ 1) & m_Q1) | (t & m_Q2) | m_F);
if (m_Q1 ^ 1)
const netlist_sig_t t(m_Q.net().Q());
/*
* J K Q1 Q2 F t Q
* 0 0 0 1 0 0 0
* 0 1 0 0 0 0 0
* 1 0 0 0 1 0 1
* 1 1 1 0 0 0 1
* 0 0 0 1 0 1 1
* 0 1 0 0 0 1 0
* 1 0 0 0 1 1 1
* 1 1 1 0 0 1 0
*/
if ((m_J() & m_K()) ^ 1)
m_clk.inactivate();
newstate(((t ^ 1) & m_J()) | (t & (m_K() ^ 1)));
}
NETLIB_UPDATE(74107A)
{
const auto JK = (m_J() << 1) | m_K();
switch (JK)
{
case 0:
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 1;
m_sub.m_F = 0;
m_sub.m_clk.inactivate();
break;
case 1: // (!m_J) & m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
case 2: // (m_J) & !m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 1;
break;
case 3: // (m_J) & m_K))
m_sub.m_Q1 = 1;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
default:
break;
}
if (!m_clrQ())
{
m_sub.m_clk.inactivate();
m_sub.newstate(0);
m_clk.inactivate();
newstate(0);
}
else if (!m_sub.m_Q2)
m_sub.m_clk.activate_hl();
else if (m_J() | m_K())
m_clk.activate_hl();
}
NETLIB_DEVICE_IMPL(74107)

View File

@ -52,9 +52,9 @@ namespace netlist
if (m_reset)
{
m_bcd = (m_bcd + 1) & 0x07;
m_QB.push(m_bcd & 1, out_delay);
m_QC.push((m_bcd >> 1) & 1, out_delay2);
m_QD.push((m_bcd >> 2) & 1, out_delay3);
m_QC.push((m_bcd >> 1) & 1, out_delay2);
m_QB.push(m_bcd & 1, out_delay);
}
}

View File

@ -14,64 +14,47 @@ namespace netlist
{
namespace devices
{
NETLIB_OBJECT(9316_subABCD)
NETLIB_OBJECT(9316)
{
NETLIB_CONSTRUCTOR(9316_subABCD)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
{
}
//NETLIB_RESETI()
//NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
unsigned read_ABCD() const
{
return (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0);
}
};
NETLIB_OBJECT(9316_sub)
{
NETLIB_CONSTRUCTOR(9316_sub)
, m_CLK(*this, "CLK")
NETLIB_CONSTRUCTOR(9316)
, m_CLK(*this, "CLK", NETLIB_DELEGATE(9316, clk))
, m_cnt(*this, "m_cnt", 0)
, m_loadq(*this, "m_loadq", 0)
, m_ent(*this, "m_ent", 0)
, m_ENP(*this, "ENP")
, m_ENT(*this, "ENT")
, m_CLRQ(*this, "CLRQ")
, m_LOADQ(*this, "LOADQ")
, m_A(*this, "A", NETLIB_DELEGATE(9316, noop))
, m_B(*this, "B", NETLIB_DELEGATE(9316, noop))
, m_C(*this, "C", NETLIB_DELEGATE(9316, noop))
, m_D(*this, "D", NETLIB_DELEGATE(9316, noop))
, m_QA(*this, "QA")
, m_QB(*this, "QB")
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_RC(*this, "RC")
, m_ABCD(nullptr)
{
}
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(clk);
NETLIB_HANDLERI(noop) { }
public:
void update_outputs_all(const unsigned cnt, const netlist_time out_delay)
{
m_QA.push((cnt >> 0) & 1, out_delay);
m_QB.push((cnt >> 1) & 1, out_delay);
m_QC.push((cnt >> 2) & 1, out_delay);
m_QD.push((cnt >> 3) & 1, out_delay);
}
protected:
logic_input_t m_CLK;
state_var<unsigned> m_cnt;
state_var<netlist_sig_t> m_loadq;
state_var<netlist_sig_t> m_ent;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_output_t m_QA;
logic_output_t m_QB;
@ -79,45 +62,15 @@ namespace netlist
logic_output_t m_QD;
logic_output_t m_RC;
NETLIB_NAME(9316_subABCD) *m_ABCD;
};
NETLIB_OBJECT(9316)
{
NETLIB_CONSTRUCTOR(9316)
, sub(*this, "sub")
, subABCD(*this, "subABCD")
, m_ENP(*this, "ENP")
, m_ENT(*this, "ENT")
, m_CLRQ(*this, "CLRQ")
, m_LOADQ(*this, "LOADQ")
private:
void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay)
{
sub.m_ABCD = &(subABCD);
register_subalias("CLK", sub.m_CLK);
register_subalias("A", subABCD.m_A);
register_subalias("B", subABCD.m_B);
register_subalias("C", subABCD.m_C);
register_subalias("D", subABCD.m_D);
register_subalias("QA", sub.m_QA);
register_subalias("QB", sub.m_QB);
register_subalias("QC", sub.m_QC);
register_subalias("QD", sub.m_QD);
register_subalias("RC", sub.m_RC);
m_QA.push((cnt >> 0) & 1, out_delay);
m_QB.push((cnt >> 1) & 1, out_delay);
m_QC.push((cnt >> 2) & 1, out_delay);
m_QD.push((cnt >> 3) & 1, out_delay);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(9316_sub) sub;
NETLIB_SUB(9316_subABCD) subABCD;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
};
NETLIB_OBJECT_DERIVED(9316_dip, 9316)
@ -125,90 +78,65 @@ namespace netlist
NETLIB_CONSTRUCTOR_DERIVED(9316_dip, 9316)
{
register_subalias("1", m_CLRQ);
register_subalias("2", sub.m_CLK);
register_subalias("3", subABCD.m_A);
register_subalias("4", subABCD.m_B);
register_subalias("5", subABCD.m_C);
register_subalias("6", subABCD.m_D);
register_subalias("2", m_CLK);
register_subalias("3", m_A);
register_subalias("4", m_B);
register_subalias("5", m_C);
register_subalias("6", m_D);
register_subalias("7", m_ENP);
// register_subalias("8", ); -. GND
register_subalias("9", m_LOADQ);
register_subalias("10", m_ENT);
register_subalias("11", sub.m_QD);
register_subalias("12", sub.m_QC);
register_subalias("13", sub.m_QB);
register_subalias("14", sub.m_QA);
register_subalias("15", sub.m_RC);
register_subalias("11", m_QD);
register_subalias("12", m_QC);
register_subalias("13", m_QB);
register_subalias("14", m_QA);
register_subalias("15", m_RC);
// register_subalias("16", ); -. VCC
}
};
NETLIB_RESET(9316)
{
sub.do_reset();
subABCD.do_reset();
}
NETLIB_RESET(9316_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_loadq = 1;
m_ent = 1;
}
NETLIB_UPDATE(9316_sub)
NETLIB_HANDLER(9316, clk)
{
if (m_loadq)
if (m_LOADQ())
{
if (m_cnt < MAXCNT - 1)
{
m_cnt++;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
else if (m_cnt == MAXCNT - 1)
{
m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(27));
m_QA.push(1, NLTIME_FROM_NS(20));
}
else // MAXCNT
{
m_RC.push(0, NLTIME_FROM_NS(27));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
m_cnt = (m_cnt < MAXCNT ? m_cnt + 1 : 0);
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
m_cnt = m_ABCD->read_ABCD();
m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
m_cnt = (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0);
m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
}
}
NETLIB_UPDATE(9316)
{
sub.m_loadq = m_LOADQ();
sub.m_ent = m_ENT();
const netlist_sig_t clrq = m_CLRQ();
if (((sub.m_loadq ^ 1) | (sub.m_ent & m_ENP())) & clrq)
if (((m_LOADQ() ^ 1) | (m_ENT() & m_ENP())) & clrq)
{
sub.m_CLK.activate_lh();
sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
m_CLK.activate_lh();
m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
sub.m_CLK.inactivate();
if (!clrq && (sub.m_cnt>0))
m_CLK.inactivate();
if (!clrq && (m_cnt>0))
{
sub.update_outputs_all(0, NLTIME_FROM_NS(36));
sub.m_cnt = 0;
//return;
update_outputs_all(0, NLTIME_FROM_NS(36));
m_cnt = 0;
}
sub.m_RC.push(sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}

View File

@ -87,7 +87,7 @@ namespace netlist
NETLIB_UPDATE(MM5837_dip)
{
m_Q.push(!m_feedback.Q(), m_inc);
m_Q.push(!m_feedback(), m_inc);
/* shift register
*

View File

@ -553,7 +553,9 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT
const netlist_time inc = m_mainclock->m_inc;
netlist_time mc_time(mc_net.time());
while (1)
detail::queue_t::entry_t e;
do
{
while (m_queue.top().m_exec_time > mc_time)
{
@ -563,16 +565,14 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT
mc_time += inc;
}
const detail::queue_t::entry_t e(m_queue.pop());
e = m_queue.pop();
m_time = e.m_exec_time;
if (e.m_object != nullptr)
{
e.m_object->update_devs();
m_perf_out_processed.inc();
}
else
break;
}
} while (e.m_object != nullptr);
mc_net.set_time(mc_time);
}
m_stat_mainloop.stop();
@ -862,7 +862,11 @@ void detail::net_t::update_devs() NL_NOEXCEPT
{
p.device().m_stat_call_count.inc();
if ((p.state() & mask) != 0)
{
p.device().m_stat_total_time.start();
p.m_delegate();
p.device().m_stat_total_time.stop();
}
}
}

View File

@ -636,11 +636,8 @@ namespace netlist
nldelegate delegate = nldelegate());
virtual ~logic_input_t();
netlist_sig_t Q() const NL_NOEXCEPT;
netlist_sig_t operator()() const NL_NOEXCEPT
{
nl_assert(state() != STATE_INP_PASSIVE);
return Q();
}
@ -648,7 +645,8 @@ namespace netlist
void activate() NL_NOEXCEPT;
void activate_hl() NL_NOEXCEPT;
void activate_lh() NL_NOEXCEPT;
private:
netlist_sig_t Q() const NL_NOEXCEPT;
};
// -----------------------------------------------------------------------------
@ -768,7 +766,6 @@ namespace netlist
virtual ~logic_net_t();
netlist_sig_t Q() const NL_NOEXCEPT { return m_cur_Q; }
netlist_sig_t new_Q() const NL_NOEXCEPT { return m_new_Q; }
void initial(const netlist_sig_t val) NL_NOEXCEPT { m_cur_Q = m_new_Q = val; }
void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
@ -1059,9 +1056,7 @@ namespace netlist
void update_dev() NL_NOEXCEPT
{
m_stat_total_time.start();
do_update();
m_stat_total_time.stop();
}
void do_inc_active() NL_NOEXCEPT
@ -1438,6 +1433,7 @@ namespace netlist
inline netlist_sig_t logic_input_t::Q() const NL_NOEXCEPT
{
nl_assert(state() != STATE_INP_PASSIVE);
return net().Q();
}

View File

@ -131,8 +131,26 @@ namespace netlist
void retime(const Element &elem, const Time t) noexcept
{
remove(elem);
push(entry_t(t, elem));
/* Lock */
tqlock lck(m_lock);
for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
{
if (i->m_object == elem)
{
i->m_exec_time = t;
while ((i-1)->m_exec_time < i->m_exec_time)
{
std::swap(*(i-1), *i);
i--;
}
while (i < m_end && (i+1)->m_exec_time > i->m_exec_time)
{
std::swap(*(i+1), *i);
i++;
}
return;
}
}
}
void clear()
@ -212,28 +230,28 @@ namespace netlist
};
timed_queue(const std::size_t list_size)
: m_list(list_size)
{
m_list.reserve(list_size);
clear();
}
constexpr std::size_t capacity() const noexcept { return m_list.capacity(); }
constexpr bool empty() const noexcept { return m_list.empty(); }
constexpr bool empty() const noexcept { return &m_list[0] == m_end; }
void push(entry_t &&e) noexcept
{
/* Lock */
tqlock lck(m_lock);
m_list.push_back(e);
std::push_heap(m_list.begin(), m_list.end(), compare());
*m_end++ = e;
std::push_heap(&m_list[0], m_end, compare());
m_prof_call.inc();
}
entry_t pop() noexcept
{
entry_t t(m_list[0]);
std::pop_heap(m_list.begin(), m_list.end(), compare());
m_list.pop_back();
std::pop_heap(&m_list[0], m_end, compare());
m_end--;
return t;
}
@ -243,26 +261,39 @@ namespace netlist
{
/* Lock */
tqlock lck(m_lock);
for (entry_t * i = &m_list[m_list.size() - 1]; i >= &m_list[0]; i--)
for (entry_t * i = m_end - 1; i >= &m_list[0]; i--)
{
if (i->m_object == elem)
{
m_list.erase(m_list.begin() + (i - &m_list[0]));
std::make_heap(m_list.begin(), m_list.end(), compare());
m_end--;
for (;i < m_end; i++)
*i = std::move(*(i+1));
std::make_heap(&m_list[0], m_end, compare());
return;
}
}
}
void retime(const Element &elem, const Time t) noexcept
{
remove(elem);
push(entry_t(t, elem));
/* Lock */
tqlock lck(m_lock);
for (entry_t * i = m_end - 1; i >= &m_list[0]; i--)
{
if (i->m_object == elem)
{
i->m_exec_time = t;
std::make_heap(&m_list[0], m_end, compare());
return;
}
}
}
void clear()
{
tqlock lck(m_lock);
m_list.clear();
m_end = &m_list[0];
}
// save state support & mame disasm
@ -280,6 +311,7 @@ namespace netlist
tqmutex m_lock;
std::vector<entry_t> m_list;
entry_t *m_end;
public:
// profiling

View File

@ -208,7 +208,7 @@ namespace plib {
#endif
}
template<typename O>
inline R call(O *obj, Targs... args) const
R call(O *obj, Targs... args) const
{
using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args);
return (reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);