netlist updates:

- First steps to move towards c++11.
- Base plist on std::vector
- Replace pstack with std::stack
- Remove pnamed_list
- use c++ "for each" in a number of places
- Fixed two "time bombs"
[couriersud]
This commit is contained in:
couriersud 2016-03-05 17:11:04 +01:00
parent 0e48eb2a43
commit 41c8a9f6fa
31 changed files with 407 additions and 632 deletions

View File

@ -21,8 +21,8 @@ NETLIST_START(dummy)
PARAM(Solver.LTE, 1e-1) PARAM(Solver.LTE, 1e-1)
#endif #endif
//FIXME proper models! //FIXME proper models!
NET_MODEL("2SC945 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)") //NET_MODEL("2SC945 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)")
NET_MODEL("1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)") //NET_MODEL("1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
//NET_C(R44.1, XU1.7) //NET_C(R44.1, XU1.7)

View File

@ -47,8 +47,8 @@ NETLIB_TRUTHTABLE(7404, 1, 1, 0);
#else #else
NETLIB_DEVICE(7404, NETLIB_DEVICE(7404,
public: public:
netlist_logic_input_t m_I[1]; logic_input_t m_I[1];
netlist_logic_output_t m_Q[1]; logic_output_t m_Q[1];
); );
#endif #endif

View File

@ -51,11 +51,11 @@ NETLIB_TRUTHTABLE(7486, 2, 1, 0);
#else #else
NETLIB_DEVICE(7486, NETLIB_DEVICE(7486,
public: public:
netlist_logic_input_t m_I[2]; logic_input_t m_I[2];
netlist_logic_output_t m_Q[1]; logic_output_t m_Q[1];
ATTR_HOT void inc_active(); ATTR_HOT void inc_active() override;
ATTR_HOT void dec_active(); ATTR_HOT void dec_active() override;
int m_active; int m_active;
); );
#endif #endif

View File

@ -22,7 +22,7 @@ NETLIB_UPDATE(82S16)
} }
else else
{ {
int adr = 0; unsigned int adr = 0;
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
//m_A[i].activate(); //m_A[i].activate();
@ -31,9 +31,9 @@ NETLIB_UPDATE(82S16)
if (!INPLOGIC(m_WEQ)) if (!INPLOGIC(m_WEQ))
{ {
m_ram[adr] = INPLOGIC(m_DIN); m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((UINT64) 1 << (adr & 0x3f))) | ((UINT64) INPLOGIC(m_DIN) << (adr & 0x3f));
} }
OUTLOGIC(m_DOUTQ, m_ram[adr] ^ 1, NLTIME_FROM_NS(20)); OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
} }
} }
@ -62,7 +62,7 @@ NETLIB_START(82S16)
NETLIB_RESET(82S16) NETLIB_RESET(82S16)
{ {
for (int i=0; i<256; i++) for (int i=0; i<4; i++)
{ {
m_ram[i] = 0; m_ram[i] = 0;
} }

View File

@ -44,7 +44,7 @@ NETLIB_DEVICE(82S16,
logic_output_t m_DOUTQ; logic_output_t m_DOUTQ;
//netlist_state_t<UINT8[256]> m_ram; //netlist_state_t<UINT8[256]> m_ram;
UINT8 m_ram[256]; UINT64 m_ram[4]; // 256 bits
); );
NETLIB_DEVICE_DERIVED_PURE(82S16_dip, 82S16); NETLIB_DEVICE_DERIVED_PURE(82S16_dip, 82S16);

View File

@ -58,13 +58,13 @@ NETLIB_TRUTHTABLE(9312, 12, 2, 0);
NETLIB_DEVICE(9312, NETLIB_DEVICE(9312,
public: public:
// C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ // C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ
netlist_logic_input_t m_A; logic_input_t m_A;
netlist_logic_input_t m_B; logic_input_t m_B;
netlist_logic_input_t m_C; logic_input_t m_C;
netlist_logic_input_t m_G; logic_input_t m_G;
netlist_logic_input_t m_D[8]; logic_input_t m_D[8];
netlist_logic_output_t m_Y; logic_output_t m_Y;
netlist_logic_output_t m_YQ; logic_output_t m_YQ;
UINT8 m_last_chan; UINT8 m_last_chan;
UINT8 m_last_G; UINT8 m_last_G;

View File

@ -329,7 +329,7 @@ NETLIB_START(function)
if (err) if (err)
netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value()); netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value());
} }
m_precompiled.add(rc); m_precompiled.push_back(rc);
} }
} }

View File

@ -100,7 +100,7 @@ UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
void truthtable_desc_t::help(unsigned cur, pstring_list_t list, void truthtable_desc_t::help(unsigned cur, pstring_list_t list,
UINT64 state,UINT16 val, UINT8 *timing_index) UINT64 state,UINT16 val, parray_t<UINT8> &timing_index)
{ {
pstring elem = list[cur].trim(); pstring elem = list[cur].trim();
int start = 0; int start = 0;
@ -192,8 +192,11 @@ void truthtable_desc_t::setup(const pstring_list_t &truthtable, UINT32 disabled_
tindex[j] = k; tindex[j] = k;
} }
help(0, inout, 0 , val, tindex.data()); help(0, inout, 0 , val, tindex);
ttline = truthtable[line]; if (line < truthtable.size())
ttline = truthtable[line];
else
ttline = "";
line++; line++;
} }

View File

@ -30,10 +30,10 @@
# _name, # _name, "+" _def_params); # _name, # _name, "+" _def_params);
#define TT_HEAD(_x) \ #define TT_HEAD(_x) \
ttd->m_desc.add(_x); ttd->m_desc.push_back(_x);
#define TT_LINE(_x) \ #define TT_LINE(_x) \
ttd->m_desc.add(_x); ttd->m_desc.push_back(_x);
#define TT_FAMILY(_x) \ #define TT_FAMILY(_x) \
ttd->m_family = setup.family_from_model(_x); ttd->m_family = setup.family_from_model(_x);
@ -69,7 +69,7 @@ struct truthtable_desc_t
private: private:
void help(unsigned cur, pstring_list_t list, void help(unsigned cur, pstring_list_t list,
UINT64 state,UINT16 val, UINT8 *timing_index); UINT64 state,UINT16 val, parray_t<UINT8> &timing_index);
static unsigned count_bits(UINT32 v); static unsigned count_bits(UINT32 v);
static UINT32 set_bits(UINT32 v, UINT32 b); static UINT32 set_bits(UINT32 v, UINT32 b);
UINT32 get_ignored_simple(UINT32 i); UINT32 get_ignored_simple(UINT32 i);
@ -114,7 +114,7 @@ public:
{ {
while (*desc != NULL && **desc != 0 ) while (*desc != NULL && **desc != 0 )
{ {
m_desc.add(*desc); m_desc.push_back(*desc);
desc++; desc++;
} }

View File

@ -186,16 +186,15 @@ netlist_t::netlist_t()
netlist_t::~netlist_t() netlist_t::~netlist_t()
{ {
for (std::size_t i=0; i < m_nets.size(); i++) for (net_t *net : m_nets)
{ {
if (!m_nets[i]->isRailNet()) if (!net->isRailNet())
{ {
pfree(m_nets[i]); pfree(net);
} }
} }
m_nets.clear(); m_nets.clear();
m_devices.clear_and_free(); m_devices.clear_and_free();
pstring::resetmem(); pstring::resetmem();
@ -237,12 +236,9 @@ ATTR_COLD void netlist_t::start()
m_use_deactivate = (m_params->m_use_deactivate.Value() ? true : false); m_use_deactivate = (m_params->m_use_deactivate.Value() ? true : false);
log().debug("Initializing devices ...\n"); log().debug("Initializing devices ...\n");
for (std::size_t i = 0; i < m_devices.size(); i++) for (device_t *dev : m_devices)
{
device_t *dev = m_devices[i];
if (dev != m_solver && dev != m_params) if (dev != m_solver && dev != m_params)
dev->start_dev(); dev->start_dev();
}
} }
@ -251,28 +247,23 @@ ATTR_COLD void netlist_t::stop()
/* find the main clock and solver ... */ /* find the main clock and solver ... */
log().debug("Stopping all devices ...\n"); log().debug("Stopping all devices ...\n");
for (device_t *dev : m_devices)
// Step all devices once ! dev->stop_dev();
for (std::size_t i = 0; i < m_devices.size(); i++)
{
m_devices[i]->stop_dev();
}
} }
ATTR_COLD net_t *netlist_t::find_net(const pstring &name) ATTR_COLD net_t *netlist_t::find_net(const pstring &name)
{ {
for (std::size_t i = 0; i < m_nets.size(); i++) for (net_t *net : m_nets)
{ if (net->name() == name)
if (m_nets[i]->name() == name) return net;
return m_nets[i];
}
return NULL; return NULL;
} }
ATTR_COLD void netlist_t::rebuild_lists() ATTR_COLD void netlist_t::rebuild_lists()
{ {
for (std::size_t i = 0; i < m_nets.size(); i++) for (net_t *net : m_nets)
m_nets[i]->rebuild_list(); net->rebuild_list();
} }
@ -303,9 +294,9 @@ ATTR_COLD void netlist_t::reset()
// FIXME: some const devices rely on this // FIXME: some const devices rely on this
/* make sure params are set now .. */ /* make sure params are set now .. */
for (std::size_t i = 0; i < m_devices.size(); i++) for (device_t *dev : m_devices)
{ {
m_devices[i]->update_param(); dev->update_param();
} }
} }
@ -318,7 +309,7 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta)
{ {
while ( (m_time < m_stop) && (m_queue.is_not_empty())) while ( (m_time < m_stop) && (m_queue.is_not_empty()))
{ {
const queue_t::entry_t e = *m_queue.pop(); const queue_t::entry_t &e = m_queue.pop();
m_time = e.exec_time(); m_time = e.exec_time();
e.object()->update_devs(); e.object()->update_devs();
@ -336,21 +327,25 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta)
{ {
if (m_queue.is_not_empty()) if (m_queue.is_not_empty())
{ {
while (m_queue.peek()->exec_time() > mc_time) while (m_queue.top().exec_time() > mc_time)
{ {
m_time = mc_time; m_time = mc_time;
mc_time += inc; mc_time += inc;
devices::NETLIB_NAME(mainclock)::mc_update(mc_net); mc_net.toggle_new_Q();
mc_net.update_devs();
//devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
} }
const queue_t::entry_t e = *m_queue.pop(); const queue_t::entry_t &e = m_queue.pop();
m_time = e.exec_time(); m_time = e.exec_time();
e.object()->update_devs(); e.object()->update_devs();
} else { } else {
m_time = mc_time; m_time = mc_time;
mc_time += inc; mc_time += inc;
devices::NETLIB_NAME(mainclock)::mc_update(mc_net); mc_net.toggle_new_Q();
mc_net.update_devs();
//devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
} }
add_to_stat(m_perf_out_processed, 1); add_to_stat(m_perf_out_processed, 1);
@ -435,13 +430,13 @@ ATTR_HOT netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp)
device_t::device_t() device_t::device_t()
: core_device_t(GENERIC), : core_device_t(GENERIC),
m_terminals(20) m_terminals()
{ {
} }
device_t::device_t(const family_t afamily) device_t::device_t(const family_t afamily)
: core_device_t(afamily), : core_device_t(afamily),
m_terminals(20) m_terminals()
{ {
} }
@ -477,7 +472,7 @@ ATTR_COLD void device_t::register_subalias(const pstring &name, core_terminal_t
setup().register_alias_nofqn(alias, term.name()); setup().register_alias_nofqn(alias, term.name());
if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL)) if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL))
m_terminals.add(alias); m_terminals.push_back(alias);
} }
ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &aliased) ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &aliased)
@ -497,7 +492,7 @@ ATTR_COLD void device_t::register_terminal(const pstring &name, terminal_t &port
{ {
setup().register_object(*this, name, port); setup().register_object(*this, name, port);
if (port.isType(terminal_t::INPUT) || port.isType(terminal_t::TERMINAL)) if (port.isType(terminal_t::INPUT) || port.isType(terminal_t::TERMINAL))
m_terminals.add(port.name()); m_terminals.push_back(port.name());
} }
ATTR_COLD void device_t::register_output(const pstring &name, logic_output_t &port) ATTR_COLD void device_t::register_output(const pstring &name, logic_output_t &port)
@ -515,13 +510,13 @@ ATTR_COLD void device_t::register_input(const pstring &name, logic_input_t &inp)
{ {
inp.set_logic_family(this->logic_family()); inp.set_logic_family(this->logic_family());
setup().register_object(*this, name, inp); setup().register_object(*this, name, inp);
m_terminals.add(inp.name()); m_terminals.push_back(inp.name());
} }
ATTR_COLD void device_t::register_input(const pstring &name, analog_input_t &inp) ATTR_COLD void device_t::register_input(const pstring &name, analog_input_t &inp)
{ {
setup().register_object(*this, name, inp); setup().register_object(*this, name, inp);
m_terminals.add(inp.name()); m_terminals.push_back(inp.name());
} }
ATTR_COLD void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2) ATTR_COLD void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2)
@ -584,7 +579,7 @@ ATTR_COLD net_t::~net_t()
ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname) ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname)
{ {
object_t::init_object(nl, aname); object_t::init_object(nl, aname);
nl.m_nets.add(this); nl.m_nets.push_back(this);
} }
ATTR_HOT void net_t::inc_active(core_terminal_t &term) ATTR_HOT void net_t::inc_active(core_terminal_t &term)
@ -638,10 +633,10 @@ ATTR_COLD void net_t::rebuild_list()
unsigned cnt = 0; unsigned cnt = 0;
m_list_active.clear(); m_list_active.clear();
for (std::size_t i=0; i < m_core_terms.size(); i++) for (core_terminal_t *term : m_core_terms)
if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE) if (term->state() != logic_t::STATE_INP_PASSIVE)
{ {
m_list_active.add(*m_core_terms[i]); m_list_active.add(*term);
cnt++; cnt++;
} }
m_active = cnt; m_active = cnt;
@ -689,14 +684,7 @@ ATTR_HOT /* inline */ void net_t::update_devs()
} }
for (int i=0; i<cnt; i++) for (int i=0; i<cnt; i++)
t[i]->netdev().update_dev(); t[i]->device().update_dev();
core_terminal_t *p = m_list_active.first();
while (p != NULL)
{
p->update_dev(mask);
p = m_list_active.next(p);
}
#else #else
core_terminal_t *p = m_list_active.first(); core_terminal_t *p = m_list_active.first();
@ -704,7 +692,7 @@ ATTR_HOT /* inline */ void net_t::update_devs()
while (p != NULL) while (p != NULL)
{ {
p->update_dev(mask); p->update_dev(mask);
p = p->m_next; p = m_list_active.next(p);
} }
#endif #endif
} }
@ -722,14 +710,14 @@ ATTR_COLD void net_t::reset()
/* rebuild m_list */ /* rebuild m_list */
m_list_active.clear(); m_list_active.clear();
for (std::size_t i=0; i < m_core_terms.size(); i++) for (core_terminal_t *ct : m_core_terms)
m_list_active.add(*m_core_terms[i]); m_list_active.add(*ct);
for (std::size_t i=0; i < m_core_terms.size(); i++) for (core_terminal_t *ct : m_core_terms)
m_core_terms[i]->do_reset(); ct->do_reset();
for (std::size_t i=0; i < m_core_terms.size(); i++) for (core_terminal_t *ct : m_core_terms)
if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE) if (ct->state() != logic_t::STATE_INP_PASSIVE)
m_active++; m_active++;
} }
@ -737,7 +725,7 @@ ATTR_COLD void net_t::register_con(core_terminal_t &terminal)
{ {
terminal.set_net(*this); terminal.set_net(*this);
m_core_terms.add(&terminal); m_core_terms.push_back(&terminal);
if (terminal.state() != logic_t::STATE_INP_PASSIVE) if (terminal.state() != logic_t::STATE_INP_PASSIVE)
m_active++; m_active++;
@ -745,11 +733,8 @@ ATTR_COLD void net_t::register_con(core_terminal_t &terminal)
ATTR_COLD void net_t::move_connections(net_t *dest_net) ATTR_COLD void net_t::move_connections(net_t *dest_net)
{ {
for (std::size_t i = 0; i < m_core_terms.size(); i++) for (core_terminal_t *ct : m_core_terms)
{ dest_net->register_con(*ct);
core_terminal_t *p = m_core_terms[i];
dest_net->register_con(*p);
}
m_core_terms.clear(); m_core_terms.clear();
m_active = 0; m_active = 0;
} }
@ -842,10 +827,9 @@ ATTR_COLD void analog_net_t::process_net(list_t *groups, int &cur_group)
if (num_cons() == 0) if (num_cons() == 0)
return; return;
/* add the net */ /* add the net */
groups[cur_group].add(this); groups[cur_group].push_back(this);
for (std::size_t i = 0; i < m_core_terms.size(); i++) for (core_terminal_t *p : m_core_terms)
{ {
core_terminal_t *p = m_core_terms[i];
if (p->isType(terminal_t::TERMINAL)) if (p->isType(terminal_t::TERMINAL))
{ {
terminal_t *pt = static_cast<terminal_t *>(p); terminal_t *pt = static_cast<terminal_t *>(p);
@ -863,7 +847,7 @@ ATTR_COLD void analog_net_t::process_net(list_t *groups, int &cur_group)
ATTR_COLD core_terminal_t::core_terminal_t(const type_t atype, const family_t afamily) ATTR_COLD core_terminal_t::core_terminal_t(const type_t atype, const family_t afamily)
: device_object_t(atype, afamily) : device_object_t(atype, afamily)
, plinkedlist_element_t<core_terminal_t>() , plinkedlist_element_t()
, m_net(NULL) , m_net(NULL)
, m_state(STATE_NONEX) , m_state(STATE_NONEX)
{ {

View File

@ -155,6 +155,8 @@
#ifndef NLBASE_H_ #ifndef NLBASE_H_
#define NLBASE_H_ #define NLBASE_H_
#include <vector>
#include "nl_lists.h" #include "nl_lists.h"
#include "nl_time.h" #include "nl_time.h"
#include "nl_util.h" #include "nl_util.h"
@ -165,7 +167,14 @@
// Type definitions // Type definitions
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
typedef UINT8 netlist_sig_t; //typedef UINT8 netlist_sig_t;
/*
* unsigned int would be a 20% speed increase over UINT8 for pong.
* For breakout it causes a slight decrease.
*
*/
typedef unsigned int netlist_sig_t;
//============================================================ //============================================================
// MACROS / netlist devices // MACROS / netlist devices
@ -1193,7 +1202,7 @@ namespace netlist
{ {
_device_class *dev = dynamic_cast<_device_class *>(m_devices[i]); _device_class *dev = dynamic_cast<_device_class *>(m_devices[i]);
if (dev != NULL) if (dev != NULL)
tmp.add(dev); tmp.push_back(dev);
} }
return tmp; return tmp;
} }
@ -1228,7 +1237,7 @@ namespace netlist
return ret; return ret;
} }
pnamedlist_t<device_t *> m_devices; plist_t<device_t *> m_devices;
net_t::list_t m_nets; net_t::list_t m_nets;
#if (NL_KEEP_STATISTICS) #if (NL_KEEP_STATISTICS)
pnamedlist_t<core_device_t *> m_started_devices; pnamedlist_t<core_device_t *> m_started_devices;

View File

@ -64,12 +64,12 @@ namespace netlist
/* Lock */ /* Lock */
while (atomic_exchange32(&m_lock, 1)) { } while (atomic_exchange32(&m_lock, 1)) { }
#endif #endif
const _Time t = e.exec_time(); const _Time &t = e.exec_time();
entry_t * i = m_end++; entry_t * i = m_end++;
while (t > (i - 1)->exec_time()) for (; t > (i - 1)->exec_time(); i--)
{ {
*(i) = *(i-1); *(i) = *(i-1);
i--; //i--;
inc_stat(m_prof_sortmove); inc_stat(m_prof_sortmove);
} }
*i = e; *i = e;
@ -80,14 +80,14 @@ namespace netlist
//nl_assert(m_end - m_list < _Size); //nl_assert(m_end - m_list < _Size);
} }
ATTR_HOT const entry_t *pop() ATTR_HOT const entry_t & pop()
{ {
return --m_end; return *(--m_end);
} }
ATTR_HOT const entry_t *peek() const ATTR_HOT const entry_t & top() const
{ {
return (m_end-1); return *(m_end-1);
} }
ATTR_HOT void remove(const _Element &elem) ATTR_HOT void remove(const _Element &elem)
@ -96,8 +96,7 @@ namespace netlist
#if HAS_OPENMP && USE_OPENMP #if HAS_OPENMP && USE_OPENMP
while (atomic_exchange32(&m_lock, 1)) { } while (atomic_exchange32(&m_lock, 1)) { }
#endif #endif
entry_t * i = m_end - 1; for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
while (i > &m_list[0])
{ {
if (i->object() == elem) if (i->object() == elem)
{ {
@ -112,7 +111,6 @@ namespace netlist
#endif #endif
return; return;
} }
i--;
} }
#if HAS_OPENMP && USE_OPENMP #if HAS_OPENMP && USE_OPENMP
m_lock = 0; m_lock = 0;
@ -148,9 +146,7 @@ namespace netlist
volatile INT32 m_lock; volatile INT32 m_lock;
#endif #endif
entry_t * m_end; entry_t * m_end;
//entry_t m_list[_Size];
parray_t<entry_t> m_list; parray_t<entry_t> m_list;
}; };
} }

View File

@ -168,13 +168,13 @@ void parser_t::net_truthtable_start()
if (token.is(m_tok_TT_HEAD)) if (token.is(m_tok_TT_HEAD))
{ {
require_token(m_tok_param_left); require_token(m_tok_param_left);
ttd->m_desc.add(get_string()); ttd->m_desc.push_back(get_string());
require_token(m_tok_param_right); require_token(m_tok_param_right);
} }
else if (token.is(m_tok_TT_LINE)) else if (token.is(m_tok_TT_LINE))
{ {
require_token(m_tok_param_left); require_token(m_tok_param_left);
ttd->m_desc.add(get_string()); ttd->m_desc.push_back(get_string());
require_token(m_tok_param_right); require_token(m_tok_param_right);
} }
else if (token.is(m_tok_TT_FAMILY)) else if (token.is(m_tok_TT_FAMILY))
@ -296,13 +296,13 @@ void parser_t::dippins()
{ {
pstring_list_t pins; pstring_list_t pins;
pins.add(get_identifier()); pins.push_back(get_identifier());
require_token(m_tok_comma); require_token(m_tok_comma);
while (true) while (true)
{ {
pstring t1 = get_identifier(); pstring t1 = get_identifier();
pins.add(t1); pins.push_back(t1);
token_t n = get_token(); token_t n = get_token();
if (n.is(m_tok_param_right)) if (n.is(m_tok_param_right))
break; break;

View File

@ -53,6 +53,7 @@ namespace netlist
setup_t::setup_t(netlist_t *netlist) setup_t::setup_t(netlist_t *netlist)
: m_netlist(netlist) : m_netlist(netlist)
, m_proxy_cnt(0) , m_proxy_cnt(0)
, m_frontier_cnt(0)
{ {
netlist->set_setup(this); netlist->set_setup(this);
m_factory = palloc(factory_list_t(*this)); m_factory = palloc(factory_list_t(*this));
@ -85,7 +86,7 @@ ATTR_COLD pstring setup_t::build_fqn(const pstring &obj_name) const
if (m_stack.empty()) if (m_stack.empty())
return netlist().name() + "." + obj_name; return netlist().name() + "." + obj_name;
else else
return m_stack.peek() + "." + obj_name; return m_stack.top() + "." + obj_name;
} }
void setup_t::namespace_push(const pstring &aname) void setup_t::namespace_push(const pstring &aname)
@ -93,7 +94,7 @@ void setup_t::namespace_push(const pstring &aname)
if (m_stack.empty()) if (m_stack.empty())
m_stack.push(netlist().name() + "." + aname); m_stack.push(netlist().name() + "." + aname);
else else
m_stack.push(m_stack.peek() + "." + aname); m_stack.push(m_stack.top() + "." + aname);
} }
void setup_t::namespace_pop() void setup_t::namespace_pop()
@ -108,8 +109,11 @@ device_t *setup_t::register_dev(device_t *dev, const pstring &name)
dev->init(netlist(), fqn); dev->init(netlist(), fqn);
if (!(netlist().m_devices.add(dev, false)==true)) for (auto & d : netlist().m_devices)
log().fatal("Error adding {1} to device list\n", name); if (d->name() == dev->name())
log().fatal("Error adding {1} to device list. Duplicate name \n", name);
netlist().m_devices.push_back(dev);
return dev; return dev;
} }
@ -118,7 +122,7 @@ void setup_t::register_lib_entry(const pstring &name)
if (m_lib.contains(name)) if (m_lib.contains(name))
log().warning("Lib entry collection already contains {1}. IGNORED", name); log().warning("Lib entry collection already contains {1}. IGNORED", name);
else else
m_lib.add(name); m_lib.push_back(name);
} }
device_t *setup_t::register_dev(const pstring &classname, const pstring &name) device_t *setup_t::register_dev(const pstring &classname, const pstring &name)
@ -235,7 +239,6 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
case terminal_t::PARAM: case terminal_t::PARAM:
{ {
param_t &param = dynamic_cast<param_t &>(obj); param_t &param = dynamic_cast<param_t &>(obj);
//printf("name: {1}\n", name);
if (m_params_temp.contains(name)) if (m_params_temp.contains(name))
{ {
const pstring val = m_params_temp[name]; const pstring val = m_params_temp[name];
@ -305,7 +308,7 @@ void setup_t::register_link_fqn(const pstring &sin, const pstring &sout)
{ {
link_t temp = link_t(sin, sout); link_t temp = link_t(sin, sout);
log().debug("link {1} <== {2}\n", sin, sout); log().debug("link {1} <== {2}\n", sin, sout);
m_links.add(temp); m_links.push_back(temp);
} }
void setup_t::register_link(const pstring &sin, const pstring &sout) void setup_t::register_link(const pstring &sin, const pstring &sout)
@ -317,11 +320,13 @@ void setup_t::remove_connections(const pstring pin)
{ {
pstring pinfn = build_fqn(pin); pstring pinfn = build_fqn(pin);
bool found = false; bool found = false;
for (std::size_t i = 0; i < m_links.size(); i++)
for (int i = m_links.size() - 1; i >= 0; i--)
{ {
if ((m_links[i].e1 == pinfn) || (m_links[i].e2 == pinfn)) auto &link = m_links[i];
if ((link.e1 == pinfn) || (link.e2 == pinfn))
{ {
log().verbose("removing connection: {1} <==> {2}\n", m_links[i].e1, m_links[i].e2); log().verbose("removing connection: {1} <==> {2}\n", link.e1, link.e2);
m_links.remove_at(i); m_links.remove_at(i);
found = true; found = true;
} }
@ -333,25 +338,24 @@ void setup_t::remove_connections(const pstring pin)
void setup_t::register_frontier(const pstring attach, const double r_IN, const double r_OUT) void setup_t::register_frontier(const pstring attach, const double r_IN, const double r_OUT)
{ {
static int frontier_cnt = 0; pstring frontier_name = pfmt("frontier_{1}")(m_frontier_cnt);
pstring frontier_name = pfmt("frontier_{1}")(frontier_cnt); m_frontier_cnt++;
frontier_cnt++;
device_t *front = register_dev("FRONTIER_DEV", frontier_name); device_t *front = register_dev("FRONTIER_DEV", frontier_name);
register_param(frontier_name + ".RIN", r_IN); register_param(frontier_name + ".RIN", r_IN);
register_param(frontier_name + ".ROUT", r_OUT); register_param(frontier_name + ".ROUT", r_OUT);
register_link(frontier_name + ".G", "GND"); register_link(frontier_name + ".G", "GND");
pstring attfn = build_fqn(attach); pstring attfn = build_fqn(attach);
bool found = false; bool found = false;
for (std::size_t i = 0; i < m_links.size(); i++) for (auto & link : m_links)
{ {
if (m_links[i].e1 == attfn) if (link.e1 == attfn)
{ {
m_links[i].e1 = front->name() + ".I"; link.e1 = front->name() + ".I";
found = true; found = true;
} }
else if (m_links[i].e2 == attfn) else if (link.e2 == attfn)
{ {
m_links[i].e2 = front->name() + ".I"; link.e2 = front->name() + ".I";
found = true; found = true;
} }
} }
@ -472,7 +476,6 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
{ {
nl_assert(out.isFamily(terminal_t::LOGIC)); nl_assert(out.isFamily(terminal_t::LOGIC));
//printf("proxy for {1}\n", out.name());;
logic_output_t &out_cast = dynamic_cast<logic_output_t &>(out); logic_output_t &out_cast = dynamic_cast<logic_output_t &>(out);
devices::nld_base_proxy *proxy = out_cast.get_proxy(); devices::nld_base_proxy *proxy = out_cast.get_proxy();
@ -486,18 +489,16 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
register_dev(new_proxy, x); register_dev(new_proxy, x);
new_proxy->start_dev(); new_proxy->start_dev();
#if 1
/* connect all existing terminals to new net */ /* connect all existing terminals to new net */
for (std::size_t i = 0; i < out.net().m_core_terms.size(); i++) for (core_terminal_t *p : out.net().m_core_terms)
{ {
core_terminal_t *p = out.net().m_core_terms[i];
p->clear_net(); // de-link from all nets ... p->clear_net(); // de-link from all nets ...
if (!connect(new_proxy->proxy_term(), *p)) if (!connect(new_proxy->proxy_term(), *p))
log().fatal("Error connecting {1} to {2}\n", new_proxy->proxy_term().name(), (*p).name()); log().fatal("Error connecting {1} to {2}\n", new_proxy->proxy_term().name(), (*p).name());
} }
out.net().m_core_terms.clear(); // clear the list out.net().m_core_terms.clear(); // clear the list
#endif
out.net().register_con(new_proxy->in()); out.net().register_con(new_proxy->in());
out_cast.set_proxy(new_proxy); out_cast.set_proxy(new_proxy);
proxy = new_proxy; proxy = new_proxy;
@ -648,13 +649,11 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t2, t1.net().railterminal()); ret = connect(t2, t1.net().railterminal());
if (!ret) if (!ret)
{ {
for (std::size_t i=0; i<t1.net().m_core_terms.size(); i++) for (core_terminal_t *t : t1.net().m_core_terms)
{ {
if (t1.net().m_core_terms[i]->isType(core_terminal_t::TERMINAL) if (t->isType(core_terminal_t::TERMINAL)
/*|| t1.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/) /*|| t1.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/)
{ ret = connect(t2, *t);
ret = connect(t2, *t1.net().m_core_terms[i]);
}
if (ret) if (ret)
break; break;
} }
@ -666,13 +665,11 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t1, t2.net().railterminal()); ret = connect(t1, t2.net().railterminal());
if (!ret) if (!ret)
{ {
for (std::size_t i=0; i<t2.net().m_core_terms.size(); i++) for (core_terminal_t *t : t2.net().m_core_terms)
{ {
if (t2.net().m_core_terms[i]->isType(core_terminal_t::TERMINAL) if (t->isType(core_terminal_t::TERMINAL)
/*|| t2.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/) /*|| t2.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/)
{ ret = connect(t1, *t);
ret = connect(t1, *t2.net().m_core_terms[i]);
}
if (ret) if (ret)
break; break;
} }
@ -774,24 +771,20 @@ void setup_t::resolve_inputs()
net_t::list_t todelete; net_t::list_t todelete;
for (std::size_t i = 0; i<netlist().m_nets.size(); i++) for (net_t *net : netlist().m_nets)
{ {
if (netlist().m_nets[i]->num_cons() == 0) if (net->num_cons() == 0)
{ todelete.push_back(net);
todelete.add(netlist().m_nets[i]);
}
else else
{ net->rebuild_list();
netlist().m_nets[i]->rebuild_list();
}
} }
for (std::size_t i=0; i < todelete.size(); i++) for (net_t *net : todelete)
{ {
log().verbose("Deleting net {1} ...", todelete[i]->name()); log().verbose("Deleting net {1} ...", net->name());
netlist().m_nets.remove(todelete[i]); netlist().m_nets.remove(net);
if (!todelete[i]->isRailNet()) if (!net->isRailNet())
pfree(todelete[i]); pfree(net);
} }
pstring errstr(""); pstring errstr("");
@ -819,13 +812,8 @@ void setup_t::resolve_inputs()
{ {
has_twoterms = true; has_twoterms = true;
if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet()) if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
#if 0
netlist().fatal("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name());
#else
log().warning("Found device {1} connected only to railterminals {2}/{3}\n", log().warning("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name()); t->name(), t->m_N.net().name(), t->m_P.net().name());
#endif
} }
} }
@ -848,15 +836,14 @@ void setup_t::start_devices()
if (env != "") if (env != "")
{ {
log().debug("Creating dynamic logs ...\n"); log().debug("Creating dynamic logs ...\n");
pstring_list_t ll(env, ":"); pstring_list_t loglist(env, ":");
for (unsigned i=0; i < ll.size(); i++) for (pstring ll : loglist)
{ {
log().debug("{1}: <{2}>\n",i, ll[i]);
log().debug("{1}: <{2}>\n",i, ll[i]);
device_t *nc = factory().new_device_by_name("LOG"); device_t *nc = factory().new_device_by_name("LOG");
pstring name = "log_" + ll[i]; pstring name = "log_" + ll;
register_dev(nc, name); register_dev(nc, name);
register_link(name + ".I", ll[i]); register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name);
} }
} }
@ -958,12 +945,12 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map)
remainder = remainder.left(remainder.len() - 1); remainder = remainder.left(remainder.len() - 1);
pstring_list_t pairs(remainder," ", true); pstring_list_t pairs(remainder," ", true);
for (unsigned i=0; i<pairs.size(); i++) for (pstring &pe : pairs)
{ {
int pose = pairs[i].find("="); int pose = pe.find("=");
if (pose < 0) if (pose < 0)
log().fatal("Model error on pair {1}\n", model); log().fatal("Model error on pair {1}\n", model);
map[pairs[i].left(pose).ucase()] = pairs[i].substr(pose+1); map[pe.left(pose).ucase()] = pe.substr(pose+1);
} }
} }
@ -1012,9 +999,9 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity)
void setup_t::include(const pstring &netlist_name) void setup_t::include(const pstring &netlist_name)
{ {
for (std::size_t i=0; i < m_sources.size(); i++) for (source_t *source : m_sources)
{ {
if (m_sources[i]->parse(*this, netlist_name)) if (source->parse(*this, netlist_name))
return; return;
} }
log().fatal("unable to find {1} in source collection", netlist_name); log().fatal("unable to find {1} in source collection", netlist_name);

View File

@ -181,7 +181,7 @@ namespace netlist
/* register a source */ /* register a source */
void register_source(source_t *src) { m_sources.add(src); } void register_source(source_t *src) { m_sources.push_back(src); }
factory_list_t &factory() { return *m_factory; } factory_list_t &factory() { return *m_factory; }
const factory_list_t &factory() const { return *m_factory; } const factory_list_t &factory() const { return *m_factory; }
@ -231,8 +231,9 @@ namespace netlist
phashmap_t<pstring, pstring> m_models; phashmap_t<pstring, pstring> m_models;
int m_proxy_cnt; int m_proxy_cnt;
int m_frontier_cnt;
pstack_t<pstring> m_stack; std::stack<pstring> m_stack;
source_t::list_t m_sources; source_t::list_t m_sources;
plist_t<pstring> m_lib; plist_t<pstring> m_lib;

View File

@ -12,7 +12,7 @@
#define PSTANDALONE (0) #define PSTANDALONE (0)
#endif #endif
//#define PHAS_INT128 (0) #define PHAS_INT128 (0)
#ifndef PHAS_INT128 #ifndef PHAS_INT128
#define PHAS_INT128 (0) #define PHAS_INT128 (0)

View File

@ -13,6 +13,8 @@
#include <cstring> #include <cstring>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <stack>
#include <vector>
#include "palloc.h" #include "palloc.h"
#include "pstring.h" #include "pstring.h"
@ -55,15 +57,8 @@ public:
m_list = NULL; m_list = NULL;
} }
/* using the [] operator will not allow gcc to vectorize code because ATTR_HOT _ListClass& operator[](const std::size_t index) { return m_list[index]; }
* basically a pointer is returned. ATTR_HOT const _ListClass& operator[](const std::size_t index) const { return m_list[index]; }
* array works around this.
*/
ATTR_HOT _ListClass *data() { return m_list; }
ATTR_HOT _ListClass& operator[](std::size_t index) { return m_list[index]; }
ATTR_HOT const _ListClass& operator[](std::size_t index) const { return m_list[index]; }
ATTR_HOT std::size_t size() const { return m_capacity; } ATTR_HOT std::size_t size() const { return m_capacity; }
@ -93,385 +88,78 @@ private:
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// plist_t: a simple list // plist_t: a simple list
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
#if 0
#include <vector>
//#define plist_t std::vector
template <typename _ListClass> template <typename _ListClass>
class plist_t : public std::vector<_ListClass> class plist_t : public std::vector<_ListClass>
{ {
public: public:
plist_t() : std::vector<_ListClass>() {} plist_t() : std::vector<_ListClass>() {}
plist_t(const int numElements) : std::vector<_ListClass>(numElements) {}
void add(const _ListClass &elem) { this->push_back(elem); }
void clear_and_free() void clear_and_free()
{ {
for (_ListClass *i = this->data(); i < this->data() + this->size(); i++) for (_ListClass i : *this)
{ {
pfree(*i); pfree(i);
} }
this->clear(); this->clear();
} }
bool contains(const _ListClass &elem) const
bool contains(const _ListClass &elem) const
{ {
for (const _ListClass *i = this->data(); i < this->data() + this->size(); i++) return (std::find(this->begin(), this->end(), elem) != this->end());
{
if (*i == elem)
return true;
}
return false;
} }
void remove(const _ListClass &elem) void remove(const _ListClass &elem)
{ {
for (int i = 0; i < this->size(); i++) this->erase(std::remove(this->begin(), this->end(), elem), this->end());
{
if (this->at(i) == elem)
{
this->erase(this->begin() + i);
return;
}
}
}
void remove_at(const int pos)
{
this->erase(this->begin() + pos);
} }
int indexof(const _ListClass &elem) const ATTR_HOT void insert_at(const std::size_t index, const _ListClass &elem)
{ {
for (int i = 0; i < this->size(); i++) this->insert(this->begin() + index, elem);
{
if (this->at(i) == elem)
return i;
}
return -1;
}
ATTR_HOT void swap(const int pos1, const int pos2)
{
//nl_assert((pos1>=0) && (pos1<m_count));
//nl_assert((pos2>=0) && (pos2<m_count));
_ListClass tmp = (*this)[pos1];
(*this)[pos1] = (*this)[pos2];
(*this)[pos2] =tmp;
}
};
#else
template <typename _ListClass>
class plist_t
{
public:
ATTR_COLD plist_t(const std::size_t numElements = 0)
{
m_capacity = numElements;
if (m_capacity == 0)
m_list = NULL;
else
m_list = this->alloc(m_capacity);
m_count = 0;
}
ATTR_COLD plist_t(const plist_t &rhs)
{
m_capacity = rhs.capacity();
if (m_capacity == 0)
m_list = NULL;
else
m_list = this->alloc(m_capacity);
m_count = 0;
for (std::size_t i=0; i<rhs.size(); i++)
{
this->add(rhs[i]);
}
}
ATTR_COLD plist_t &operator=(const plist_t &rhs)
{
this->clear();
for (std::size_t i=0; i<rhs.size(); i++)
{
this->add(rhs[i]);
}
return *this;
}
~plist_t()
{
if (m_list != NULL)
this->dealloc(m_list);
m_list = NULL;
}
ATTR_HOT _ListClass *data() { return m_list; }
ATTR_HOT _ListClass& operator[](std::size_t index) { return *(m_list + index); }
ATTR_HOT const _ListClass& operator[](std::size_t index) const { return *(m_list + index); }
ATTR_HOT void add(const _ListClass &elem)
{
if (m_count >= m_capacity){
std::size_t new_size = m_capacity * 2;
if (new_size < 32)
new_size = 32;
set_capacity(new_size);
}
m_list[m_count++] = elem;
}
ATTR_HOT void insert_at(const _ListClass &elem, const std::size_t index)
{
if (m_count >= m_capacity){
std::size_t new_size = m_capacity * 2;
if (new_size < 32)
new_size = 32;
set_capacity(new_size);
}
for (std::size_t i = m_count; i>index; i--)
m_list[i] = m_list[i-1];
m_list[index] = elem;
m_count++;
}
ATTR_HOT void remove(const _ListClass &elem)
{
for (std::size_t i = 0; i < m_count; i++)
{
if (m_list[i] == elem)
{
m_count --;
while (i < m_count)
{
m_list[i] = m_list[i+1];
i++;
}
return;
}
}
} }
ATTR_HOT void remove_at(const std::size_t pos) ATTR_HOT void remove_at(const std::size_t pos)
{ {
//nl_assert((pos>=0) && (pos<m_count)); this->erase(this->begin() + pos);
m_count--;
for (std::size_t i = pos; i < m_count; i++)
{
m_list[i] = m_list[i+1];
}
} }
ATTR_HOT void swap(const std::size_t pos1, const std::size_t pos2) int indexof(const _ListClass &elem) const
{ {
//nl_assert((pos1>=0) && (pos1<m_count)); for (int i = 0; i < this->size(); i++)
//nl_assert((pos2>=0) && (pos2<m_count));
_ListClass tmp = m_list[pos1];
m_list[pos1] = m_list[pos2];
m_list[pos2] =tmp;
}
ATTR_HOT bool contains(const _ListClass &elem) const
{
for (_ListClass *i = m_list; i < m_list + m_count; i++)
{ {
if (*i == elem) if (this->at(i) == elem)
return true;
}
return false;
}
ATTR_HOT int indexof(const _ListClass &elem) const
{
for (std::size_t i = 0; i < m_count; i++)
{
if (m_list[i] == elem)
return i; return i;
} }
return -1; return -1;
} }
ATTR_HOT std::size_t size() const { return m_count; }
ATTR_HOT bool is_empty() const { return (m_count == 0); }
ATTR_HOT void clear() { m_count = 0; }
ATTR_HOT std::size_t capacity() const { return m_capacity; }
ATTR_COLD void clear_and_free()
{
for (_ListClass *i = m_list; i < m_list + m_count; i++)
{
pfree(*i);
}
clear();
}
private:
ATTR_COLD void set_capacity(const std::size_t new_capacity)
{
std::size_t cnt = size();
if (new_capacity > 0)
{
_ListClass *m_new = this->alloc(new_capacity);
_ListClass *pd = m_new;
if (cnt > new_capacity)
cnt = new_capacity;
if (m_list != NULL)
{
for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
*pd = *ps;
this->dealloc(m_list);
}
m_list = m_new;
m_count = cnt;
}
else
{
if (m_list != NULL)
this->dealloc(m_list);
m_list = NULL;
m_count = 0;
}
m_capacity = new_capacity;
}
_ListClass *alloc(const std::size_t n)
{
return palloc_array(_ListClass, n);
}
void dealloc(_ListClass *p)
{
pfree_array(p);
}
std::size_t m_count;
_ListClass * m_list;
std::size_t m_capacity;
};
#endif
// ----------------------------------------------------------------------------------------
// pnamedlist_t: a simple list of elements which have a name() interface
// ----------------------------------------------------------------------------------------
template <class _ListClass>
class pnamedlist_t : public plist_t<_ListClass>
{
public:
_ListClass find_by_name(const pstring &name) const
{
for (std::size_t i=0; i < this->size(); i++)
if (get_name((*this)[i]) == name)
return (*this)[i];
return _ListClass(NULL);
}
int index_by_name(const pstring &name) const
{
for (std::size_t i=0; i < this->size(); i++)
if (get_name((*this)[i]) == name)
return (int) i;
return -1;
}
void remove_by_name(const pstring &name)
{
plist_t<_ListClass>::remove(find_by_name(name));
}
bool add(_ListClass dev, bool allow_duplicate)
{
if (allow_duplicate)
plist_t<_ListClass>::add(dev);
else
{
if (!(this->find_by_name(get_name(dev)) == _ListClass(NULL)))
return false;
plist_t<_ListClass>::add(dev);
}
return true;
}
private:
template <typename T> const pstring &get_name(const T *elem) const { return elem->name(); }
template <typename T> const pstring &get_name(T *elem) const { return elem->name(); }
template <typename T> const pstring &get_name(const T &elem) const { return elem.name(); }
};
// ----------------------------------------------------------------------------------------
// pstack_t: a simple stack
// ----------------------------------------------------------------------------------------
template <class _StackClass>
class pstack_t
{
public:
ATTR_COLD pstack_t(const int numElements = 128)
: m_list(numElements)
{
}
ATTR_COLD pstack_t(const pstack_t &rhs)
: m_list(rhs.m_list)
{
}
ATTR_COLD pstack_t &operator=(const pstack_t &rhs)
{
m_list = rhs.m_list;
return *this;
}
~pstack_t()
{
}
ATTR_HOT void push(const _StackClass &elem)
{
m_list.add(elem);
}
ATTR_HOT _StackClass peek() const
{
return m_list[m_list.size() - 1];
}
ATTR_HOT _StackClass pop()
{
_StackClass ret = peek();
m_list.remove_at(m_list.size() - 1);
return ret;
}
ATTR_HOT int count() const { return m_list.size(); }
ATTR_HOT bool empty() const { return (m_list.size() == 0); }
ATTR_HOT void reset() { m_list.reset(); }
ATTR_HOT int capacity() const { return m_list.capacity(); }
private:
plist_t<_StackClass> m_list;
};
template <class _ListClass>
struct plinkedlist_element_t
{
plinkedlist_element_t() : m_next(NULL) {}
_ListClass * m_next;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// plinkedlist_t: a simple linked list // plinkedlist_t: a simple linked list
// the list allows insertions / deletions if used properly
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <class _ListClass>
class plinkedlist_t;
#if 1
template <class _ListClass>
struct plinkedlist_element_t
{
public:
friend class plinkedlist_t<_ListClass>;
plinkedlist_element_t() : m_next(NULL) {}
_ListClass *next() const { return m_next; }
private:
_ListClass * m_next;
};
template <class _ListClass> template <class _ListClass>
class plinkedlist_t class plinkedlist_t
{ {
@ -499,7 +187,7 @@ public:
} }
p = p->m_next; p = p->m_next;
} }
throw pexception("element not found"); //throw pexception("element not found");
} }
} }
@ -541,6 +229,87 @@ public:
private: private:
_ListClass *m_head; _ListClass *m_head;
}; };
#else
template <class _ListClass>
struct plinkedlist_element_t
{
public:
friend class plinkedlist_t<_ListClass>;
plinkedlist_element_t() : m_next(NULL), m_prev(NULL) {}
_ListClass *next() const { return m_next; }
private:
_ListClass * m_next;
_ListClass * m_prev;
};
template <class _ListClass>
class plinkedlist_t
{
public:
plinkedlist_t() : m_head(NULL), m_tail(NULL) {}
ATTR_HOT void insert(_ListClass &elem)
{
if (m_head != NULL)
m_head->m_prev = &elem;
elem.m_next = m_head;
elem.m_prev = NULL;
m_head = &elem;
if (m_tail == NULL)
m_tail = &elem;
}
ATTR_HOT void add(_ListClass &elem)
{
if (m_tail != NULL)
m_tail->m_next = &elem;
elem.m_prev = m_tail;
m_tail = &elem;
elem.m_next = NULL;
if (m_head == NULL)
m_head = &elem;
}
ATTR_HOT void remove(const _ListClass &elem)
{
if (prev(elem) == NULL)
{
m_head = next(elem);
if (m_tail == &elem)
m_tail = NULL;
}
else
prev(elem)->m_next = next(elem);
if (next(elem) == NULL)
{
m_tail = prev(elem);
if (m_head == &elem)
m_head = NULL;
}
else
next(elem)->m_prev = prev(elem);
}
ATTR_HOT static _ListClass *next(const _ListClass &elem) { return static_cast<_ListClass *>(elem.m_next); }
ATTR_HOT static _ListClass *next(const _ListClass *elem) { return static_cast<_ListClass *>(elem->m_next); }
ATTR_HOT static _ListClass *prev(const _ListClass &elem) { return static_cast<_ListClass *>(elem.m_prev); }
ATTR_HOT static _ListClass *prev(const _ListClass *elem) { return static_cast<_ListClass *>(elem->m_prev); }
ATTR_HOT _ListClass *first() const { return m_head; }
ATTR_HOT void clear() { m_head = m_tail = NULL; }
ATTR_HOT bool is_empty() const { return (m_head == NULL); }
private:
_ListClass *m_head;
_ListClass *m_tail;
};
#endif
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// string list // string list
@ -562,7 +331,7 @@ public:
{ {
pstring t = str.substr(p, pn - p); pstring t = str.substr(p, pn - p);
if (!ignore_empty || t.len() != 0) if (!ignore_empty || t.len() != 0)
this->add(t); this->push_back(t);
p = pn + onstr.len(); p = pn + onstr.len();
pn = str.find(onstr, p); pn = str.find(onstr, p);
} }
@ -570,7 +339,7 @@ public:
{ {
pstring t = str.substr(p); pstring t = str.substr(p);
if (!ignore_empty || t.len() != 0) if (!ignore_empty || t.len() != 0)
this->add(t); this->push_back(t);
} }
} }
@ -594,10 +363,10 @@ public:
if (p>=0) if (p>=0)
{ {
if (col != "") if (col != "")
temp.add(col); temp.push_back(col);
col = ""; col = "";
temp.add(onstrl[p]); temp.push_back(onstrl[p]);
i += onstrl[p].blen(); i += onstrl[p].blen();
} }
else else
@ -608,7 +377,7 @@ public:
} }
} }
if (col != "") if (col != "")
temp.add(col); temp.push_back(col);
return temp; return temp;
} }
}; };
@ -768,7 +537,7 @@ public:
if (m_hash[pos] == -1) if (m_hash[pos] == -1)
{ {
unsigned vpos = m_values.size(); unsigned vpos = m_values.size();
m_values.add(element_t(key, hash, value)); m_values.push_back(element_t(key, hash, value));
m_hash[pos] = vpos; m_hash[pos] = vpos;
} }
else else
@ -781,7 +550,7 @@ public:
return false; /* duplicate */ return false; /* duplicate */
} }
unsigned vpos = m_values.size(); unsigned vpos = m_values.size();
m_values.add(element_t(key, hash, value)); m_values.push_back(element_t(key, hash, value));
m_values[vpos].m_next = m_hash[pos]; m_values[vpos].m_next = m_hash[pos];
m_hash[pos] = vpos; m_hash[pos] = vpos;
} }

View File

@ -127,7 +127,7 @@ public:
int i=0; int i=0;
while (o[i] != NULL) while (o[i] != NULL)
{ {
m_opts.add(o[i]); m_opts.push_back(o[i]);
i++; i++;
} }
} }
@ -139,7 +139,7 @@ public:
void register_option(poption *opt) void register_option(poption *opt)
{ {
m_opts.add(opt); m_opts.push_back(opt);
} }
int parse(int argc, char *argv[]) int parse(int argc, char *argv[])

View File

@ -255,16 +255,16 @@ ATTR_COLD void ptokenizer::error(const pstring &errs)
ppreprocessor::ppreprocessor() ppreprocessor::ppreprocessor()
: m_ifflag(0), m_level(0), m_lineno(0) : m_ifflag(0), m_level(0), m_lineno(0)
{ {
m_expr_sep.add("!"); m_expr_sep.push_back("!");
m_expr_sep.add("("); m_expr_sep.push_back("(");
m_expr_sep.add(")"); m_expr_sep.push_back(")");
m_expr_sep.add("+"); m_expr_sep.push_back("+");
m_expr_sep.add("-"); m_expr_sep.push_back("-");
m_expr_sep.add("*"); m_expr_sep.push_back("*");
m_expr_sep.add("/"); m_expr_sep.push_back("/");
m_expr_sep.add("=="); m_expr_sep.push_back("==");
m_expr_sep.add(" "); m_expr_sep.push_back(" ");
m_expr_sep.add("\t"); m_expr_sep.push_back("\t");
m_defines.add("__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")); m_defines.add("__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1"));
} }

View File

@ -96,7 +96,7 @@ public:
token_id_t register_token(pstring token) token_id_t register_token(pstring token)
{ {
m_tokens.add(token); m_tokens.push_back(token);
return token_id_t(m_tokens.size() - 1); return token_id_t(m_tokens.size() - 1);
} }

View File

@ -37,7 +37,7 @@ ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pst
}; };
pstate_entry_t *p = palloc(pstate_entry_t(stname, dt, owner, size, count, ptr, is_ptr)); pstate_entry_t *p = palloc(pstate_entry_t(stname, dt, owner, size, count, ptr, is_ptr));
m_save.add(p); m_save.push_back(p);
} }
ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner) ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
@ -47,7 +47,7 @@ ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
for (std::size_t i=0; i < m_save.size(); i++) for (std::size_t i=0; i < m_save.size(); i++)
{ {
if (m_save[i]->m_owner == owner) if (m_save[i]->m_owner == owner)
todelete.add(m_save[i]); todelete.push_back(m_save[i]);
} }
for (std::size_t i=0; i < todelete.size(); i++) for (std::size_t i=0; i < todelete.size(); i++)
{ {
@ -75,6 +75,6 @@ template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state,
//save_state_ptr(stname, DT_CUSTOM, 0, 1, &state); //save_state_ptr(stname, DT_CUSTOM, 0, 1, &state);
pstate_callback_t *state_p = &state; pstate_callback_t *state_p = &state;
pstate_entry_t *p = palloc(pstate_entry_t(stname, owner, state_p)); pstate_entry_t *p = palloc(pstate_entry_t(stname, owner, state_p));
m_save.add(p); m_save.push_back(p);
state.register_state(*this, stname); state.register_state(*this, stname);
} }

View File

@ -101,7 +101,7 @@ void pifilestream::close()
} }
} }
unsigned pifilestream::vread(void *buf, unsigned n) unsigned pifilestream::vread(void *buf, const unsigned n)
{ {
std::size_t r = fread(buf, 1, n, (FILE *) m_file); std::size_t r = fread(buf, 1, n, (FILE *) m_file);
if (r < n) if (r < n)
@ -115,7 +115,7 @@ unsigned pifilestream::vread(void *buf, unsigned n)
return r; return r;
} }
void pifilestream::vseek(pos_type n) void pifilestream::vseek(const pos_type n)
{ {
check_seekable(); check_seekable();
if (fseek((FILE *) m_file, SEEK_SET, n) < 0) if (fseek((FILE *) m_file, SEEK_SET, n) < 0)
@ -200,7 +200,7 @@ void pofilestream::close()
} }
} }
void pofilestream::vwrite(const void *buf, unsigned n) void pofilestream::vwrite(const void *buf, const unsigned n)
{ {
std::size_t r = fwrite(buf, 1, n, (FILE *) m_file); std::size_t r = fwrite(buf, 1, n, (FILE *) m_file);
if (r < n) if (r < n)
@ -211,7 +211,7 @@ void pofilestream::vwrite(const void *buf, unsigned n)
m_pos += r; m_pos += r;
} }
void pofilestream::vseek(pos_type n) void pofilestream::vseek(const pos_type n)
{ {
check_seekable(); check_seekable();
if (fseek((FILE *) m_file, SEEK_SET, n) < 0) if (fseek((FILE *) m_file, SEEK_SET, n) < 0)
@ -271,7 +271,7 @@ pimemstream::~pimemstream()
{ {
} }
unsigned pimemstream::vread(void *buf, unsigned n) unsigned pimemstream::vread(void *buf, const unsigned n)
{ {
unsigned ret = (m_pos + n <= m_len) ? n : m_len - m_pos; unsigned ret = (m_pos + n <= m_len) ? n : m_len - m_pos;
@ -287,7 +287,7 @@ unsigned pimemstream::vread(void *buf, unsigned n)
return ret; return ret;
} }
void pimemstream::vseek(pos_type n) void pimemstream::vseek(const pos_type n)
{ {
m_pos = (n>=m_len) ? m_len : n; m_pos = (n>=m_len) ? m_len : n;
clear_flag(FLAG_EOF); clear_flag(FLAG_EOF);
@ -314,7 +314,7 @@ pomemstream::~pomemstream()
pfree_array(m_mem); pfree_array(m_mem);
} }
void pomemstream::vwrite(const void *buf, unsigned n) void pomemstream::vwrite(const void *buf, const unsigned n)
{ {
if (m_pos + n >= m_capacity) if (m_pos + n >= m_capacity)
{ {
@ -336,7 +336,7 @@ void pomemstream::vwrite(const void *buf, unsigned n)
m_size = std::max(m_pos, m_size); m_size = std::max(m_pos, m_size);
} }
void pomemstream::vseek(pos_type n) void pomemstream::vseek(const pos_type n)
{ {
m_pos = n; m_pos = n;
m_size = std::max(m_pos, m_size); m_size = std::max(m_pos, m_size);

View File

@ -314,7 +314,7 @@ long pstring_t<F>::as_long(bool *error) const
#if 1 #if 1
static pstack_t<pstr_t *> *stk = NULL; static std::stack<pstr_t *> *stk = NULL;
static inline unsigned countleadbits(unsigned x) static inline unsigned countleadbits(unsigned x)
{ {
@ -373,7 +373,7 @@ template<typename F>
pstr_t *pstring_t<F>::salloc(int n) pstr_t *pstring_t<F>::salloc(int n)
{ {
if (stk == NULL) if (stk == NULL)
stk = palloc_array(pstack_t<pstr_t *>, 17); stk = palloc_array(std::stack<pstr_t *>, 17);
pstr_t *p; pstr_t *p;
unsigned sn= ((32 - countleadbits(n)) + 1) / 2; unsigned sn= ((32 - countleadbits(n)) + 1) / 2;
unsigned size = sizeof(pstr_t) + ((UINT64) 1<<(sn * 2)) + 1; unsigned size = sizeof(pstr_t) + ((UINT64) 1<<(sn * 2)) + 1;
@ -381,7 +381,8 @@ pstr_t *pstring_t<F>::salloc(int n)
p = (pstr_t *) palloc_array(char, size); p = (pstr_t *) palloc_array(char, size);
else else
{ {
p = stk[sn].pop(); p = stk[sn].top();
stk[sn].pop();
} }
// str_t *p = (str_t *) _mm_malloc(size, 8); // str_t *p = (str_t *) _mm_malloc(size, 8);
@ -395,8 +396,11 @@ void pstring_t<F>::resetmem()
{ {
for (unsigned i=0; i<=16; i++) for (unsigned i=0; i<=16; i++)
{ {
for (; stk[i].count() > 0; ) for (; stk[i].size() > 0; )
pfree_array(stk[i].pop()); {
pfree_array(stk[i].top());
stk[i].pop();
}
} }
pfree_array(stk); pfree_array(stk);
stk = NULL; stk = NULL;

View File

@ -272,7 +272,7 @@ plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
if (l != "") if (l != "")
{ {
input_t inp(netlist, l); input_t inp(netlist, l);
ret->add(inp); ret->push_back(inp);
} }
} }
} }

View File

@ -206,8 +206,8 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
{ {
if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0) if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0)
{ {
std::swap(m_terms[i],m_terms[i+1]); std::swap(m_terms[i], m_terms[i+1]);
m_nets.swap(i, i+1); std::swap(m_nets[i], m_nets[i+1]);
} }
} }
@ -253,14 +253,14 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
for (unsigned i = 0; i < t->m_railstart; i++) for (unsigned i = 0; i < t->m_railstart; i++)
{ {
if (!t->m_nzrd.contains(other[i]) && other[i] >= (int) (k + 1)) if (!t->m_nzrd.contains(other[i]) && other[i] >= (int) (k + 1))
t->m_nzrd.add(other[i]); t->m_nzrd.push_back(other[i]);
if (!t->m_nz.contains(other[i])) if (!t->m_nz.contains(other[i]))
t->m_nz.add(other[i]); t->m_nz.push_back(other[i]);
} }
} }
psort_list(t->m_nzrd); psort_list(t->m_nzrd);
t->m_nz.add(k); // add diagonal t->m_nz.push_back(k); // add diagonal
psort_list(t->m_nz); psort_list(t->m_nz);
} }
@ -283,7 +283,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
if (touched[row][k]) if (touched[row][k])
{ {
if (!m_terms[k]->m_nzbd.contains(row)) if (!m_terms[k]->m_nzbd.contains(row))
m_terms[k]->m_nzbd.add(row); m_terms[k]->m_nzbd.push_back(row);
for (unsigned col = k; col < N(); col++) for (unsigned col = k; col < N(); col++)
if (touched[k][col]) if (touched[k][col])
touched[row][col] = true; touched[row][col] = true;

View File

@ -287,7 +287,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0) if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0)
{ {
std::swap(m_terms[i],m_terms[i+1]); std::swap(m_terms[i],m_terms[i+1]);
m_nets.swap(i, i+1); std::swap(m_nets[i], m_nets[i+1]);
} }
} }

View File

@ -114,7 +114,7 @@ void matrix_solver_GMRES_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets)
for (unsigned i = mat.ia[k]; i<nz; i++) for (unsigned i = mat.ia[k]; i<nz; i++)
if (this->m_terms[k]->net_other()[j] == (int) mat.ja[i]) if (this->m_terms[k]->net_other()[j] == (int) mat.ja[i])
{ {
m_term_cr[k].add(i); m_term_cr[k].push_back(i);
break; break;
} }
nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart); nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart);

View File

@ -9,8 +9,11 @@
* the vectorizations fast-math enables pretty expensive * the vectorizations fast-math enables pretty expensive
*/ */
#pragma GCC optimize "-ffast-math"
#pragma GCC optimize "-fstrict-aliasing"
#if 0 #if 0
#pragma GCC optimize "-ffast-math" #pragma GCC optimize "-ffast-math"
#pragma GCC optimize "-fstrict-aliasing"
//#pragma GCC optimize "-ftree-parallelize-loops=4" //#pragma GCC optimize "-ftree-parallelize-loops=4"
#pragma GCC optimize "-funroll-loops" #pragma GCC optimize "-funroll-loops"
#pragma GCC optimize "-funswitch-loops" #pragma GCC optimize "-funswitch-loops"
@ -54,21 +57,21 @@ ATTR_COLD void terms_t::add(terminal_t *term, int net_other, bool sorted)
{ {
if (m_net_other[i] > net_other) if (m_net_other[i] > net_other)
{ {
m_term.insert_at(term, i); m_term.insert_at(i, term);
m_net_other.insert_at(net_other, i); m_net_other.insert_at(i, net_other);
m_gt.insert_at(0.0, i); m_gt.insert_at(i, 0.0);
m_go.insert_at(0.0, i); m_go.insert_at(i, 0.0);
m_Idr.insert_at(0.0, i); m_Idr.insert_at(i, 0.0);
m_other_curanalog.insert_at(NULL, i); m_other_curanalog.insert_at(i, NULL);
return; return;
} }
} }
m_term.add(term); m_term.push_back(term);
m_net_other.add(net_other); m_net_other.push_back(net_other);
m_gt.add(0.0); m_gt.push_back(0.0);
m_go.add(0.0); m_go.push_back(0.0);
m_Idr.add(0.0); m_Idr.push_back(0.0);
m_other_curanalog.add(NULL); m_other_curanalog.push_back(NULL);
} }
ATTR_COLD void terms_t::set_pointers() ATTR_COLD void terms_t::set_pointers()
@ -109,10 +112,8 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
m_nets.clear(); m_nets.clear();
for (std::size_t k = 0; k < nets.size(); k++) for (auto & net : nets)
{ m_nets.push_back(net);
m_nets.add(nets[k]);
}
for (std::size_t k = 0; k < nets.size(); k++) for (std::size_t k = 0; k < nets.size(); k++)
{ {
@ -122,9 +123,8 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
net->m_solver = this; net->m_solver = this;
for (std::size_t i = 0; i < net->m_core_terms.size(); i++) for (core_terminal_t *p : net->m_core_terms)
{ {
core_terminal_t *p = net->m_core_terms[i];
log().debug("{1} {2} {3}\n", p->name(), net->name(), (int) net->isRailNet()); log().debug("{1} {2} {3}\n", p->name(), net->name(), (int) net->isRailNet());
switch (p->type()) switch (p->type())
{ {
@ -133,7 +133,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
{ {
case device_t::CAPACITOR: case device_t::CAPACITOR:
if (!m_step_devices.contains(&p->device())) if (!m_step_devices.contains(&p->device()))
m_step_devices.add(&p->device()); m_step_devices.push_back(&p->device());
break; break;
case device_t::BJT_EB: case device_t::BJT_EB:
case device_t::DIODE: case device_t::DIODE:
@ -141,7 +141,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
case device_t::BJT_SWITCH: case device_t::BJT_SWITCH:
log().debug("found BJT/Diode/LVCCS\n"); log().debug("found BJT/Diode/LVCCS\n");
if (!m_dynamic_devices.contains(&p->device())) if (!m_dynamic_devices.contains(&p->device()))
m_dynamic_devices.add(&p->device()); m_dynamic_devices.push_back(&p->device());
break; break;
default: default:
break; break;
@ -155,10 +155,10 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
case terminal_t::INPUT: case terminal_t::INPUT:
{ {
analog_output_t *net_proxy_output = NULL; analog_output_t *net_proxy_output = NULL;
for (std::size_t j = 0; j < m_inps.size(); j++) for (auto & input : m_inps)
if (m_inps[j]->m_proxied_net == &p->net().as_analog()) if (input->m_proxied_net == &p->net().as_analog())
{ {
net_proxy_output = m_inps[j]; net_proxy_output = input;
break; break;
} }
@ -166,7 +166,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
{ {
net_proxy_output = palloc(analog_output_t); net_proxy_output = palloc(analog_output_t);
net_proxy_output->init_object(*this, this->name() + "." + pfmt("m{1}")(m_inps.size())); net_proxy_output->init_object(*this, this->name() + "." + pfmt("m{1}")(m_inps.size()));
m_inps.add(net_proxy_output); m_inps.push_back(net_proxy_output);
net_proxy_output->m_proxied_net = &p->net().as_analog(); net_proxy_output->m_proxied_net = &p->net().as_analog();
} }
net_proxy_output->net().register_con(*p); net_proxy_output->net().register_con(*p);
@ -399,9 +399,9 @@ NETLIB_UPDATE(solver)
if (m_params.m_dynamic) if (m_params.m_dynamic)
return; return;
const std::size_t t_cnt = m_mat_solvers.size();
#if HAS_OPENMP && USE_OPENMP #if HAS_OPENMP && USE_OPENMP
const std::size_t t_cnt = m_mat_solvers.size();
if (m_parallel.Value()) if (m_parallel.Value())
{ {
omp_set_num_threads(3); omp_set_num_threads(3);
@ -425,14 +425,10 @@ NETLIB_UPDATE(solver)
ATTR_UNUSED const nl_double ts = m_mat_solvers[i]->solve(); ATTR_UNUSED const nl_double ts = m_mat_solvers[i]->solve();
} }
#else #else
for (std::size_t i = 0; i < t_cnt; i++) for (auto & solver : m_mat_solvers)
{ if (solver->is_timestep())
if (m_mat_solvers[i]->is_timestep())
{
// Ignore return value // Ignore return value
ATTR_UNUSED const nl_double ts = m_mat_solvers[i]->solve(); ATTR_UNUSED const nl_double ts = solver->solve();
}
}
#endif #endif
/* step circuit */ /* step circuit */
@ -518,13 +514,13 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
netlist().log().verbose("Scanning net groups ..."); netlist().log().verbose("Scanning net groups ...");
// determine net groups // determine net groups
for (std::size_t i=0; i<netlist().m_nets.size(); i++) for (auto & net : netlist().m_nets)
{ {
netlist().log().debug("processing {1}\n", netlist().m_nets[i]->name()); netlist().log().debug("processing {1}\n", net->name());
if (!netlist().m_nets[i]->isRailNet()) if (!net->isRailNet())
{ {
netlist().log().debug(" ==> not a rail net\n"); netlist().log().debug(" ==> not a rail net\n");
analog_net_t *n = &netlist().m_nets[i]->as_analog(); analog_net_t *n = &net->as_analog();
if (!n->already_processed(groups, cur_group)) if (!n->already_processed(groups, cur_group))
{ {
cur_group++; cur_group++;
@ -621,7 +617,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
ms->vsetup(groups[i]); ms->vsetup(groups[i]);
m_mat_solvers.add(ms); m_mat_solvers.push_back(ms);
netlist().log().verbose("Solver {1}", ms->name()); netlist().log().verbose("Solver {1}", ms->name());
netlist().log().verbose(" # {1} ==> {2} nets", i, groups[i].size()); netlist().log().verbose(" # {1} ==> {2} nets", i, groups[i].size());

View File

@ -12,11 +12,11 @@
template<typename Class> template<typename Class>
static plist_t<int> bubble(const pnamedlist_t<Class *> &sl) static plist_t<int> bubble(const plist_t<Class *> &sl)
{ {
plist_t<int> ret(sl.size()); plist_t<int> ret;
for (unsigned i=0; i<sl.size(); i++) for (unsigned i=0; i<sl.size(); i++)
ret[i] = i; ret.push_back(i);
for(unsigned i=0; i < sl.size(); i++) for(unsigned i=0; i < sl.size(); i++)
{ {
@ -37,50 +37,64 @@ static plist_t<int> bubble(const pnamedlist_t<Class *> &sl)
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias) void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
{ {
m_pins.add(palloc(pin_alias_t(devname + "." + name, devname + "." + alias)), false); pstring pname = devname + "." + name;
m_pins.add(pname, palloc(pin_alias_t(pname, devname + "." + alias)));
} }
void nl_convert_base_t::add_ext_alias(const pstring &alias) void nl_convert_base_t::add_ext_alias(const pstring &alias)
{ {
m_ext_alias.add(alias); m_ext_alias.push_back(alias);
}
void nl_convert_base_t::add_device(dev_t *dev)
{
for (auto & d : m_devs)
if (d->name() == dev->name())
{
out("ERROR: Duplicate device {1} ignored.", dev->name());
return;
}
m_devs.push_back(dev);
} }
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel) void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
{ {
m_devs.add(palloc(dev_t(atype, aname, amodel)), false); add_device(palloc(dev_t(atype, aname, amodel)));
} }
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval) void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
{ {
m_devs.add(palloc(dev_t(atype, aname, aval)), false); add_device(palloc(dev_t(atype, aname, aval)));
} }
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname) void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
{ {
m_devs.add(palloc(dev_t(atype, aname)), false); add_device(palloc(dev_t(atype, aname)));
} }
void nl_convert_base_t::add_term(pstring netname, pstring termname) void nl_convert_base_t::add_term(pstring netname, pstring termname)
{ {
net_t * net = m_nets.find_by_name(netname); net_t * net = NULL;
if (net == NULL) if (m_nets.contains(netname))
net = m_nets[netname];
else
{ {
net = palloc(net_t(netname)); net = palloc(net_t(netname));
m_nets.add(net, false); m_nets.add(netname, net);
} }
/* if there is a pin alias, translate ... */ /* if there is a pin alias, translate ... */
pin_alias_t *alias = m_pins.find_by_name(termname); pin_alias_t *alias = m_pins[termname];
if (alias != NULL) if (alias != NULL)
net->terminals().add(alias->alias()); net->terminals().push_back(alias->alias());
else else
net->terminals().add(termname); net->terminals().push_back(termname);
} }
void nl_convert_base_t::dump_nl() void nl_convert_base_t::dump_nl()
{ {
for (std::size_t i=0; i<m_ext_alias.size(); i++) for (std::size_t i=0; i<m_ext_alias.size(); i++)
{ {
net_t *net = m_nets.find_by_name(m_ext_alias[i]); net_t *net = m_nets[m_ext_alias[i]];
// use the first terminal ... // use the first terminal ...
out("ALIAS({}, {})\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr()); out("ALIAS({}, {})\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr());
// if the aliased net only has this one terminal connected ==> don't dump // if the aliased net only has this one terminal connected ==> don't dump
@ -105,7 +119,7 @@ void nl_convert_base_t::dump_nl()
// print nets // print nets
for (std::size_t i=0; i<m_nets.size(); i++) for (std::size_t i=0; i<m_nets.size(); i++)
{ {
net_t * net = m_nets[i]; net_t * net = m_nets.value_at(i);
if (!net->is_no_export()) if (!net->is_no_export())
{ {
//printf("Net {}\n", net->name().cstr()); //printf("Net {}\n", net->name().cstr());
@ -118,8 +132,12 @@ void nl_convert_base_t::dump_nl()
} }
} }
m_devs.clear_and_free(); m_devs.clear_and_free();
m_nets.clear_and_free(); for (std::size_t i = 0; i < m_nets.size(); i++)
m_pins.clear_and_free(); pfree(m_nets.value_at(i));
m_nets.clear();
for (std::size_t i = 0; i < m_pins.size(); i++)
pfree(m_pins.value_at(i));
m_pins.clear();
m_ext_alias.clear(); m_ext_alias.clear();
} }

View File

@ -25,9 +25,13 @@ public:
nl_convert_base_t() : out(m_buf) {}; nl_convert_base_t() : out(m_buf) {};
virtual ~nl_convert_base_t() virtual ~nl_convert_base_t()
{ {
m_nets.clear_and_free(); for (std::size_t i = 0; i < m_nets.size(); i++)
pfree(m_nets.value_at(i));
m_nets.clear();
m_devs.clear_and_free(); m_devs.clear_and_free();
m_pins.clear_and_free(); for (std::size_t i = 0; i < m_pins.size(); i++)
pfree(m_pins.value_at(i));
m_pins.clear();
} }
const pstringbuffer &result() { return m_buf.str(); } const pstringbuffer &result() { return m_buf.str(); }
@ -55,6 +59,7 @@ protected:
pstream_fmt_writer_t out; pstream_fmt_writer_t out;
private: private:
struct net_t struct net_t
{ {
public: public:
@ -124,12 +129,14 @@ private:
private: private:
void add_device(dev_t *dev);
postringstream m_buf; postringstream m_buf;
pnamedlist_t<dev_t *> m_devs; plist_t<dev_t *> m_devs;
pnamedlist_t<net_t *> m_nets; phashmap_t<pstring, net_t *> m_nets;
plist_t<pstring> m_ext_alias; plist_t<pstring> m_ext_alias;
pnamedlist_t<pin_alias_t *> m_pins; phashmap_t<pstring, pin_alias_t *> m_pins;
static unit_t m_units[]; static unit_t m_units[];

View File

@ -127,7 +127,8 @@ void osd_free_executable(void *ptr, size_t size)
void osd_break_into_debugger(const char *message) void osd_break_into_debugger(const char *message)
{ {
#ifdef MAME_DEBUG //#ifdef MAME_DEBUG
#if 1
printf("MAME exception: %s\n", message); printf("MAME exception: %s\n", message);
printf("Attempting to fall into debugger\n"); printf("Attempting to fall into debugger\n");
kill(getpid(), SIGTRAP); kill(getpid(), SIGTRAP);