summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/netlist.lua3
-rw-r--r--src/devices/machine/netlist.cpp2
-rw-r--r--src/devices/machine/netlist.h6
-rw-r--r--src/lib/netlist/build/makefile33
-rw-r--r--src/lib/netlist/devices/nld_74279.cpp4
-rw-r--r--src/lib/netlist/devices/nld_7493.cpp4
-rw-r--r--src/lib/netlist/devices/nld_9312.cpp2
-rw-r--r--src/lib/netlist/devices/nld_9316.cpp78
-rw-r--r--src/lib/netlist/devices/nld_truthtable.cpp31
-rw-r--r--src/lib/netlist/devices/nld_truthtable.h78
-rw-r--r--src/lib/netlist/macro/nlm_cd4xxx.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_other.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.cpp54
-rw-r--r--src/lib/netlist/nl_base.cpp139
-rw-r--r--src/lib/netlist/nl_base.h76
-rw-r--r--src/lib/netlist/nl_config.h17
-rw-r--r--src/lib/netlist/nl_factory.h12
-rw-r--r--src/lib/netlist/nl_lists.h20
-rw-r--r--src/lib/netlist/nl_parser.cpp33
-rw-r--r--src/lib/netlist/nl_parser.h2
-rw-r--r--src/lib/netlist/nl_setup.cpp90
-rw-r--r--src/lib/netlist/nl_setup.h167
-rw-r--r--src/lib/netlist/nl_time.h22
-rw-r--r--src/lib/netlist/plib/pchrono.cpp55
-rw-r--r--src/lib/netlist/plib/pchrono.h213
-rw-r--r--src/lib/netlist/plib/pconfig.h43
-rw-r--r--src/lib/netlist/plib/poptions.cpp226
-rw-r--r--src/lib/netlist/plib/poptions.h176
-rw-r--r--src/lib/netlist/plib/pstring.cpp2
-rw-r--r--src/lib/netlist/prg/nltool.cpp73
-rw-r--r--src/lib/netlist/prg/nlwav.cpp60
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp23
-rw-r--r--src/lib/netlist/tools/nl_convert.h8
-rw-r--r--src/mame/machine/nl_breakout.cpp31
-rw-r--r--src/mame/machine/nl_pong.cpp43
35 files changed, 1196 insertions, 634 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index c038f14a28e..3d3558a2754 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -38,11 +38,14 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/plib/pconfig.h",
MAME_DIR .. "src/lib/netlist/plib/palloc.cpp",
MAME_DIR .. "src/lib/netlist/plib/palloc.h",
+ MAME_DIR .. "src/lib/netlist/plib/pchrono.cpp",
+ MAME_DIR .. "src/lib/netlist/plib/pchrono.h",
MAME_DIR .. "src/lib/netlist/plib/pfmtlog.cpp",
MAME_DIR .. "src/lib/netlist/plib/pfmtlog.h",
MAME_DIR .. "src/lib/netlist/plib/plists.h",
MAME_DIR .. "src/lib/netlist/plib/pdynlib.cpp",
MAME_DIR .. "src/lib/netlist/plib/pdynlib.h",
+ MAME_DIR .. "src/lib/netlist/plib/poptions.cpp",
MAME_DIR .. "src/lib/netlist/plib/poptions.h",
MAME_DIR .. "src/lib/netlist/plib/pparser.cpp",
MAME_DIR .. "src/lib/netlist/plib/pparser.h",
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 7160b696b52..b924e052e50 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -103,7 +103,7 @@ void netlist_mame_analog_output_t::custom_netlist_additions(netlist::setup_t &se
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(m_delegate);
- setup.register_dev(std::move(dev));
+ setup.netlist().register_dev(std::move(dev));
setup.register_link(dname + ".IN", m_in);
}
diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h
index 606cd4af283..ad2cfdd47d1 100644
--- a/src/devices/machine/netlist.h
+++ b/src/devices/machine/netlist.h
@@ -66,11 +66,11 @@
// Extensions to interface netlist with MAME code ....
// ----------------------------------------------------------------------------------------
-class netlist_source_memregion_t : public netlist::setup_t::source_t
+class netlist_source_memregion_t : public netlist::source_t
{
public:
netlist_source_memregion_t(pstring name)
- : netlist::setup_t::source_t(), m_name(name)
+ : netlist::source_t(), m_name(name)
{
}
@@ -80,7 +80,7 @@ private:
};
#define MEMREGION_SOURCE(_name) \
- setup.register_source(std::make_shared<netlist_source_memregion_t>(_name));
+ setup.register_source(plib::make_unique_base<netlist::source_t, netlist_source_memregion_t>(_name));
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
void _name(const double data, const attotime &time)
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index c1729cc0c39..0a3efaa70f8 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -23,7 +23,7 @@ CDEFS = -DPSTANDALONE=1 -DPTR64=1
CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter
LDFLAGS = $(LTO) -g -O3 -std=c++11 -lpthread -ldl
-CC = @g++-5
+CC = g++-5
LD = @g++-5
MD = @mkdir
RM = @rm
@@ -49,8 +49,10 @@ OBJS = $(POBJS) $(NLOBJS)
POBJS := \
$(POBJ)/pstring.o \
$(POBJ)/palloc.o \
+ $(POBJ)/pchrono.o \
$(POBJ)/pdynlib.o \
$(POBJ)/pfmtlog.o \
+ $(POBJ)/poptions.o \
$(POBJ)/pparser.o \
$(POBJ)/pstate.o \
$(POBJ)/pstream.o \
@@ -101,6 +103,13 @@ NLOBJS := \
$(NLOBJ)/solver/nld_solver.o \
$(NLOBJ)/tools/nl_convert.o \
+ALL_OBJS = $(OBJS) $(NLOBJ)/prg/nltool.o $(NLOBJ)/prg/nlwav.o
+SOURCES = $(patsubst $(OBJ)%, $(SRC)%, $(ALL_OBJS:.o=.cpp))
+
+#-------------------------------------------------
+# all
+#-------------------------------------------------
+
all: maketree $(TARGETS)
#-------------------------------------------------
@@ -108,7 +117,7 @@ all: maketree $(TARGETS)
#-------------------------------------------------
clean:
- $(RM) -rf $(OBJS) $(TARGETS)
+ $(RM) -rf $(OBJS) $(TARGETS) .depend
#-------------------------------------------------
# nltool
@@ -131,6 +140,20 @@ $(sort $(OBJDIRS)):
maketree: $(sort $(OBJDIRS))
+#-------------------------------------------------
+# depends
+#-------------------------------------------------
+
+depend: .depend
+
+.depend: $(SOURCES)
+ @echo creating .depend
+ @rm -f ./.depend
+ @for i in $(SOURCES); do \
+ $(CC) $(CFLAGS) -MM $$i -MT `echo $$i | sed -e 's/$(SRC)/$(OBJ)/' -e 's/.cpp/.o/' ` >>./.depend; \
+ done
+
+-include .depend
#-------------------------------------------------
# generic rules
@@ -138,15 +161,15 @@ maketree: $(sort $(OBJDIRS))
$(OBJ)/%.o: $(SRC)/%.cpp
@echo Compiling $<...
- $(CC) $(CDEFS) $(CFLAGS) -c $< -o $@
+ @$(CC) $(CDEFS) $(CFLAGS) -c $< -o $@
$(OBJ)/%.pp: $(SRC)/%.cpp | $(OSPREBUILD)
@echo Compiling $<...
- $(CC) $(CDEFS) $(CFLAGS) -E $< -o $@
+ @$(CC) $(CDEFS) $(CFLAGS) -E $< -o $@
$(OBJ)/%.s: $(SRC)/%.cpp | $(OSPREBUILD)
@echo Compiling $<...
- $(CC) $(CDEFS) $(CFLAGS) -S $< -o $@
+ @$(CC) $(CDEFS) $(CFLAGS) -S $< -o $@
$(OBJ)/%.a:
@echo Archiving $@...
diff --git a/src/lib/netlist/devices/nld_74279.cpp b/src/lib/netlist/devices/nld_74279.cpp
index 7fb75f946fb..7bcbadff855 100644
--- a/src/lib/netlist/devices/nld_74279.cpp
+++ b/src/lib/netlist/devices/nld_74279.cpp
@@ -13,8 +13,8 @@ namespace netlist
namespace devices
{
- NETLIB_TRUTHTABLE(74279A, 3, 1, 0);
- NETLIB_TRUTHTABLE(74279B, 4, 1, 0);
+ NETLIB_TRUTHTABLE(74279A, 3, 1);
+ NETLIB_TRUTHTABLE(74279B, 4, 1);
NETLIB_OBJECT(74279_dip)
{
diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp
index 8a12333e596..31faa5191dc 100644
--- a/src/lib/netlist/devices/nld_7493.cpp
+++ b/src/lib/netlist/devices/nld_7493.cpp
@@ -101,8 +101,8 @@ namespace netlist
NETLIB_UPDATE(7493ff)
{
- const netlist_time out_delay = NLTIME_FROM_NS(18);
- if (m_reset != 0)
+ constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
+ if (m_reset)
{
m_state ^= 1;
OUTLOGIC(m_Q, m_state, out_delay);
diff --git a/src/lib/netlist/devices/nld_9312.cpp b/src/lib/netlist/devices/nld_9312.cpp
index 0191a905ebc..33b6d8e7a87 100644
--- a/src/lib/netlist/devices/nld_9312.cpp
+++ b/src/lib/netlist/devices/nld_9312.cpp
@@ -32,7 +32,7 @@ namespace netlist
/* The truthtable implementation is a lot faster than
* the carefully crafted code :-(
*/
- NETLIB_TRUTHTABLE(9312, 12, 2, 0);
+ NETLIB_TRUTHTABLE(9312, 12, 2);
#else
NETLIB_OBJECT(9312)
diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp
index 8c6b70c5810..3033ace81bc 100644
--- a/src/lib/netlist/devices/nld_9316.cpp
+++ b/src/lib/netlist/devices/nld_9316.cpp
@@ -44,15 +44,15 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(9316_sub)
, m_CLK(*this, "CLK")
+ , m_cnt(*this, "m_cnt", 0)
+ , m_loadq(*this, "m_loadq", 0)
+ , m_ent(*this, "m_ent", 0)
, m_QA(*this, "QA")
, m_QB(*this, "QB")
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_RC(*this, "RC")
, m_ABCD(nullptr)
- , m_cnt(*this, "m_cnt", 0)
- , m_loadq(*this, "m_loadq", 0)
- , m_ent(*this, "m_ent", 0)
{
}
@@ -60,11 +60,20 @@ namespace netlist
NETLIB_UPDATEI();
public:
- inline void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay);
- inline void update_outputs(const uint_fast8_t cnt);
+ void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay)
+ {
+ OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
+ OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
+ OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
+ OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
+ }
logic_input_t m_CLK;
+ state_var_u8 m_cnt;
+ state_var_u8 m_loadq;
+ state_var_u8 m_ent;
+
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
@@ -72,11 +81,6 @@ namespace netlist
logic_output_t m_RC;
NETLIB_NAME(9316_subABCD) *m_ABCD;
-
- state_var_u8 m_cnt;
- state_var_u8 m_loadq;
- state_var_u8 m_ent;
-
};
NETLIB_OBJECT(9316)
@@ -173,7 +177,7 @@ namespace netlist
break;
default:
m_cnt++;
- update_outputs(m_cnt);
+ update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
}
}
@@ -209,58 +213,6 @@ namespace netlist
}
}
- inline NETLIB_FUNC_VOID(9316_sub, update_outputs_all, (const uint_fast8_t cnt, const netlist_time out_delay))
- {
- OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
- OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
- OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
- OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
- }
-
- inline NETLIB_FUNC_VOID(9316_sub, update_outputs, (const uint_fast8_t cnt))
- {
- /* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
- #if 0
- // for (int i=0; i<4; i++)
- // OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]);
- OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
- OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
- OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
- OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
- #else
- if ((cnt & 1) == 1)
- OUTLOGIC(m_QA, 1, out_delay);
- else
- {
- OUTLOGIC(m_QA, 0, out_delay);
- switch (cnt)
- {
- case 0x00:
- OUTLOGIC(m_QB, 0, out_delay);
- OUTLOGIC(m_QC, 0, out_delay);
- OUTLOGIC(m_QD, 0, out_delay);
- break;
- case 0x02:
- case 0x06:
- case 0x0A:
- case 0x0E:
- OUTLOGIC(m_QB, 1, out_delay);
- break;
- case 0x04:
- case 0x0C:
- OUTLOGIC(m_QB, 0, out_delay);
- OUTLOGIC(m_QC, 1, out_delay);
- break;
- case 0x08:
- OUTLOGIC(m_QB, 0, out_delay);
- OUTLOGIC(m_QC, 0, out_delay);
- OUTLOGIC(m_QD, 1, out_delay);
- break;
- }
-
- }
- #endif
- }
NETLIB_DEVICE_IMPL(9316)
NETLIB_DEVICE_IMPL(9316_dip)
diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp
index 9ed524e58b1..29895ae8b4c 100644
--- a/src/lib/netlist/devices/nld_truthtable.cpp
+++ b/src/lib/netlist/devices/nld_truthtable.cpp
@@ -7,13 +7,14 @@
#include "nld_truthtable.h"
#include "plib/plists.h"
+#include "nl_setup.h"
namespace netlist
{
namespace devices
{
- template<unsigned m_NI, unsigned m_NO, int has_state>
+ template<unsigned m_NI, unsigned m_NO>
class netlist_factory_truthtable_t : public netlist_base_factory_truthtable_t
{
P_PREVENT_COPYING(netlist_factory_truthtable_t)
@@ -25,11 +26,11 @@ namespace netlist
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
- typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type;
+ typedef nld_truthtable_t<m_NI, m_NO> tt_type;
return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, &m_ttbl, m_desc);
}
private:
- typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl;
+ typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl;
};
static const uint_least64_t all_set = ~((uint_least64_t) 0);
@@ -259,20 +260,17 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_lea
}
-#define ENTRYX(n, m, h) case (n * 1000 + m * 10 + h): \
- { using xtype = netlist_factory_truthtable_t<n, m, h>; \
- return plib::owned_ptr<netlist_base_factory_truthtable_t>::Create<xtype>(name,classname,def_param); } break
-
-#define ENTRYY(n, m) ENTRYX(n, m, 0); ENTRYX(n, m, 1)
+#define ENTRYY(n, m) case (n * 100 + m): \
+ { using xtype = netlist_factory_truthtable_t<n, m>; \
+ ret = new xtype(desc.name, desc.classname, desc.def_param); } break
#define ENTRY(n) ENTRYY(n, 1); ENTRYY(n, 2); ENTRYY(n, 3); ENTRYY(n, 4); ENTRYY(n, 5); ENTRYY(n, 6)
-plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no,
- const unsigned has_state,
- const pstring &name, const pstring &classname,
- const pstring &def_param)
+void tt_factory_create(setup_t &setup, tt_desc &desc)
{
- switch (ni * 1000 + no * 10 + has_state)
+ netlist_base_factory_truthtable_t *ret;
+
+ switch (desc.ni * 100 + desc.no)
{
ENTRY(1);
ENTRY(2);
@@ -285,10 +283,13 @@ plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const un
ENTRY(9);
ENTRY(10);
default:
- pstring msg = plib::pfmt("unable to create truthtable<{1},{2},{3}>")(ni)(no)(has_state);
+ pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no);
nl_assert_always(false, msg);
}
- //return nullptr;
+ ret->m_desc = desc.desc;
+ if (desc.family != "")
+ ret->m_family = setup.family_from_model(desc.family);
+ setup.factory().register_device(std::unique_ptr<netlist_base_factory_truthtable_t>(ret));
}
} //namespace devices
diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h
index d30ff03704c..157aea166fc 100644
--- a/src/lib/netlist/devices/nld_truthtable.h
+++ b/src/lib/netlist/devices/nld_truthtable.h
@@ -13,39 +13,22 @@
#include <new>
#include <cstdint>
-#include "nl_base.h"
+#include "nl_setup.h"
#include "nl_factory.h"
#include "plib/plists.h"
-#define NETLIB_TRUTHTABLE(cname, nIN, nOUT, state) \
- class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT, state> \
+#define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \
+ class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT> \
{ \
public: \
template <class C> \
- NETLIB_NAME(cname)(C &owner, const pstring &name) \
- : nld_truthtable_t<nIN, nOUT, state>(owner, name, nullptr, &m_ttbl, m_desc) { } \
+ NETLIB_NAME(cname)(C &owner, const pstring &name) \
+ : nld_truthtable_t<nIN, nOUT>(owner, name, nullptr, &m_ttbl, m_desc) { } \
private: \
static truthtable_t m_ttbl; \
static const char *m_desc[]; \
}
-#define TRUTHTABLE_START(cname, in, out, has_state, def_params) \
- { \
- auto ttd = netlist::devices::nl_tt_factory_create(in, out, has_state, \
- # cname, # cname, "+" def_params);
-
-#define TT_HEAD(x) \
- ttd->m_desc.push_back(x);
-
-#define TT_LINE(x) \
- ttd->m_desc.push_back(x);
-
-#define TT_FAMILY(x) \
- ttd->m_family = setup.family_from_model(x);
-
-#define TRUTHTABLE_END() \
- setup.factory().register_device(std::move(ttd)); \
- }
namespace netlist
{
@@ -121,11 +104,11 @@ namespace netlist
struct truthtable_desc_t
{
- truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
+ truthtable_desc_t(int NO, int NI, bool *initialized,
packed_int outs, uint_least8_t *timing, netlist_time *timing_nt)
- : m_NO(NO), m_NI(NI), /*m_has_state(has_state),*/ m_initialized(initialized),
+ : m_NO(NO), m_NI(NI), m_initialized(initialized),
m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
- m_num_bits(m_NI + has_state * (m_NI + m_NO)),
+ m_num_bits(m_NI),
m_size(1 << (m_num_bits))
{
}
@@ -154,15 +137,15 @@ namespace netlist
};
- template<unsigned m_NI, unsigned m_NO, int m_has_state>
+ template<unsigned m_NI, unsigned m_NO>
NETLIB_OBJECT(truthtable_t)
{
private:
family_setter_t m_fam;
public:
- static const int m_num_bits = m_NI + m_has_state * (m_NI + m_NO);
- static const int m_size = (1 << (m_num_bits));
+ static constexpr int m_num_bits = m_NI;
+ static constexpr int m_size = (1 << (m_num_bits));
struct truthtable_t
{
@@ -180,10 +163,8 @@ namespace netlist
truthtable_t *ttp, const char *desc[])
: device_t(owner, name)
, m_fam(*this, fam)
- , m_last_state(*this, "m_last_state", 0)
, m_ign(*this, "m_ign", 0)
, m_active(*this, "m_active", 1)
- , m_use_deactivate(*this, "USE_DEACTIVATE", true)
, m_ttp(ttp)
{
while (*desc != nullptr && **desc != 0 )
@@ -199,10 +180,8 @@ namespace netlist
truthtable_t *ttp, const plib::pstring_vector_t &desc)
: device_t(owner, name)
, m_fam(*this, fam)
- , m_last_state(*this, "m_last_state", 0)
, m_ign(*this, "m_ign", 0)
, m_active(*this, "m_active", 1)
- , m_use_deactivate(*this, "USE_DEACTIVATE", true)
, m_ttp(ttp)
{
m_desc = desc;
@@ -211,6 +190,8 @@ namespace netlist
void startxx()
{
+ set_hint_deactivate(true);
+
pstring header = m_desc[0];
plib::pstring_vector_t io(header,"|");
@@ -249,8 +230,9 @@ namespace netlist
m_ign = 0;
- truthtable_desc_t desc(m_NO, m_NI, m_has_state,
- &m_ttp->m_initialized, packed_int(m_ttp->m_outs), m_ttp->m_timing, m_ttp->m_timing_nt);
+ truthtable_desc_t desc(m_NO, m_NI, &m_ttp->m_initialized,
+ packed_int(m_ttp->m_outs),
+ m_ttp->m_timing, m_ttp->m_timing_nt);
desc.setup(m_desc, disabled_ignore * 0);
#if 0
@@ -272,7 +254,6 @@ namespace netlist
for (std::size_t i=0; i<m_NO;i++)
if (this->m_Q[i].net().num_cons()>0)
m_active++;
- m_last_state = 0;
}
NETLIB_UPDATEI()
@@ -283,7 +264,7 @@ namespace netlist
public:
void inc_active() override
{
- if (m_NI > 1 && m_has_state == 0 && m_use_deactivate)
+ if (m_NI > 1)
if (++m_active == 1)
{
process<false>();
@@ -298,7 +279,7 @@ namespace netlist
* can decide for each individual gate whether it is benefitial to
* ignore deactivation.
*/
- if (m_NI > 1 && m_has_state == 0 && m_use_deactivate)
+ if (m_NI > 1)
if (--m_active == 0)
{
for (std::size_t i = 0; i< m_NI; i++)
@@ -322,7 +303,7 @@ namespace netlist
netlist_time mt = netlist_time::zero();
uint_least64_t state = 0;
- if (m_NI > 1 && !m_has_state)
+ if (m_NI > 1)
{
auto ign = m_ign;
if (!doOUT)
@@ -354,9 +335,6 @@ namespace netlist
}
auto nstate = state;
- if (m_has_state)
- nstate |= (m_last_state << m_NI);
-
const auto outstate = m_ttp->m_outs[nstate];
const auto out = outstate & ((1 << m_NO) - 1);
@@ -373,10 +351,7 @@ namespace netlist
for (std::size_t i = 0; i < m_NO; i++)
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
- if (m_has_state)
- m_last_state = (state << m_NO) | out;
-
- if (m_NI > 1 && !m_has_state)
+ if (m_NI > 1)
{
auto ign(m_ign);
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
@@ -386,11 +361,9 @@ namespace netlist
}
/* FIXME: check width */
- state_var_u32 m_last_state;
- state_var_u32 m_ign;
- state_var_s32 m_active;
- param_logic_t m_use_deactivate;
- truthtable_t *m_ttp;
+ state_var_u32 m_ign;
+ state_var_s32 m_active;
+ truthtable_t * m_ttp;
plib::pstring_vector_t m_desc;
};
@@ -411,10 +384,7 @@ namespace netlist
const logic_family_desc_t *m_family;
};
- plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no,
- const unsigned has_state,
- const pstring &name, const pstring &classname,
- const pstring &def_param);
+ void tt_factory_create(setup_t &setup, tt_desc &desc);
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp
index f7eda575bab..d622881abb4 100644
--- a/src/lib/netlist/macro/nlm_cd4xxx.cpp
+++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp
@@ -155,7 +155,7 @@ NETLIST_END()
NETLIST_START(CD4XXX_lib)
- TRUTHTABLE_START(CD4001_NOR, 2, 1, 0, "")
+ TRUTHTABLE_START(CD4001_NOR, 2, 1, "")
TT_HEAD("A , B | Q ")
TT_LINE("0,0|1|85")
TT_LINE("X,1|0|120")
diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp
index 9a5e54af737..6fd73a29fe8 100644
--- a/src/lib/netlist/macro/nlm_other.cpp
+++ b/src/lib/netlist/macro/nlm_other.cpp
@@ -45,7 +45,7 @@ NETLIST_START(MC14584B_DIP)
NETLIST_END()
NETLIST_START(otheric_lib)
- TRUTHTABLE_START(MC14584B_GATE, 1, 1, 0, "")
+ TRUTHTABLE_START(MC14584B_GATE, 1, 1, "")
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |100")
TT_LINE(" 1 | 0 |100")
diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp
index 25bf7573c03..41065012690 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx.cpp
+++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp
@@ -542,7 +542,7 @@ NETLIST_END()
NETLIST_START(TTL74XX_lib)
- TRUTHTABLE_START(TTL_7400_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7400_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -550,7 +550,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7400_NAND, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7400_NAND, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -558,7 +558,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7402_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7402_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|1|22")
TT_LINE("X,1|0|15")
@@ -566,7 +566,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7402_NOR, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7402_NOR, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|1|22")
TT_LINE("X,1|0|15")
@@ -574,21 +574,21 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7404_GATE, 1, 1, 0, "")
+ TRUTHTABLE_START(TTL_7404_GATE, 1, 1, "")
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |22")
TT_LINE(" 1 | 0 |15")
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, 0, "A")
+ TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, "A")
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |22")
TT_LINE(" 1 | 0 |15")
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7408_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7408_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|0|15")
TT_LINE("X,0|0|15")
@@ -596,7 +596,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7408_AND, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7408_AND, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|0|15")
TT_LINE("X,0|0|15")
@@ -604,7 +604,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7410_NAND, 3, 1, 0, "A,B,C")
+ TRUTHTABLE_START(TTL_7410_NAND, 3, 1, "A,B,C")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|1|22")
TT_LINE("X,0,X|1|22")
@@ -613,7 +613,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7410_GATE, 3, 1, 0, "")
+ TRUTHTABLE_START(TTL_7410_GATE, 3, 1, "")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|1|22")
TT_LINE("X,0,X|1|22")
@@ -622,7 +622,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7411_AND, 3, 1, 0, "A,B,C")
+ TRUTHTABLE_START(TTL_7411_AND, 3, 1, "A,B,C")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|0|15")
TT_LINE("X,0,X|0|15")
@@ -631,7 +631,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7411_GATE, 3, 1, 0, "")
+ TRUTHTABLE_START(TTL_7411_GATE, 3, 1, "")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|0|15")
TT_LINE("X,0,X|0|15")
@@ -640,7 +640,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7416_GATE, 1, 1, 0, "")
+ TRUTHTABLE_START(TTL_7416_GATE, 1, 1, "")
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |15")
TT_LINE(" 1 | 0 |23")
@@ -648,7 +648,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XXOC")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7420_GATE, 4, 1, 0, "")
+ TRUTHTABLE_START(TTL_7420_GATE, 4, 1, "")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("0,X,X,X|1|22")
TT_LINE("X,0,X,X|1|22")
@@ -658,7 +658,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7420_NAND, 4, 1, 0, "A,B,C,D")
+ TRUTHTABLE_START(TTL_7420_NAND, 4, 1, "A,B,C,D")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("0,X,X,X|1|22")
TT_LINE("X,0,X,X|1|22")
@@ -668,7 +668,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7425_GATE, 4, 1, 0, "")
+ TRUTHTABLE_START(TTL_7425_GATE, 4, 1, "")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("1,X,X,X|0|15")
TT_LINE("X,1,X,X|0|15")
@@ -678,7 +678,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7425_NOR, 4, 1, 0, "A,B,C,D")
+ TRUTHTABLE_START(TTL_7425_NOR, 4, 1, "A,B,C,D")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("1,X,X,X|0|15")
TT_LINE("X,1,X,X|0|15")
@@ -688,7 +688,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7427_GATE, 3, 1, 0, "")
+ TRUTHTABLE_START(TTL_7427_GATE, 3, 1, "")
TT_HEAD("A,B,C|Q ")
TT_LINE("1,X,X|0|15")
TT_LINE("X,1,X|0|15")
@@ -697,7 +697,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7427_NOR, 3, 1, 0, "A,B,C")
+ TRUTHTABLE_START(TTL_7427_NOR, 3, 1, "A,B,C")
TT_HEAD("A,B,C|Q ")
TT_LINE("1,X,X|0|15")
TT_LINE("X,1,X|0|15")
@@ -706,7 +706,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7430_GATE, 8, 1, 0, "")
+ TRUTHTABLE_START(TTL_7430_GATE, 8, 1, "")
TT_HEAD("A,B,C,D,E,F,G,H|Q ")
TT_LINE("0,X,X,X,X,X,X,X|1|22")
TT_LINE("X,0,X,X,X,X,X,X|1|22")
@@ -720,7 +720,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7430_NAND, 8, 1, 0, "A,B,C,D,E,F,G,H")
+ TRUTHTABLE_START(TTL_7430_NAND, 8, 1, "A,B,C,D,E,F,G,H")
TT_HEAD("A,B,C,D,E,F,G,H|Q ")
TT_LINE("0,X,X,X,X,X,X,X|1|22")
TT_LINE("X,0,X,X,X,X,X,X|1|22")
@@ -734,7 +734,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7432_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7432_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("1,X|1|22")
TT_LINE("X,1|1|22")
@@ -742,7 +742,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7432_OR, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7432_OR, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("1,X|1|22")
TT_LINE("X,1|1|22")
@@ -754,7 +754,7 @@ NETLIST_START(TTL74XX_lib)
* Netlist currently does not model over currents (should it ever?)
*/
- TRUTHTABLE_START(TTL_7437_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7437_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -762,7 +762,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7437_NAND, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7437_NAND, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -770,7 +770,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7486_GATE, 2, 1, 0, "")
+ TRUTHTABLE_START(TTL_7486_GATE, 2, 1, "")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|0|15")
TT_LINE("0,1|1|22")
@@ -779,7 +779,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7486_XOR, 2, 1, 0, "A,B")
+ TRUTHTABLE_START(TTL_7486_XOR, 2, 1, "A,B")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|0|15")
TT_LINE("0,1|1|22")
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index e40ec1dc5d3..e20c240a374 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -189,7 +189,6 @@ netlist_t::netlist_t(const pstring &aname)
: m_state()
, m_time(netlist_time::zero())
, m_queue(*this)
- , m_use_deactivate(0)
, m_mainclock(nullptr)
, m_solver(nullptr)
, m_gnd(nullptr)
@@ -218,6 +217,14 @@ nl_double netlist_t::gmin() const
return solver()->gmin();
}
+void netlist_t::register_dev(plib::owned_ptr<device_t> dev)
+{
+ for (auto & d : m_devices)
+ if (d->name() == dev->name())
+ log().fatal("Error adding {1} to device list. Duplicate name \n", d->name());
+ m_devices.push_back(std::move(dev));
+}
+
void netlist_t::start()
{
/* load the library ... */
@@ -226,42 +233,6 @@ void netlist_t::start()
m_lib = plib::palloc<plib::dynlib>(libpath);
- /* make sure the solver and parameters are started first! */
-
- for (auto & e : setup().m_device_factory)
- {
- if ( setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
- || setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- || setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
- || setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
- setup().register_dev(std::move(dev));
- }
- }
-
- log().debug("Searching for mainclock and solver ...\n");
-
- m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
- m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver");
- m_gnd = get_single_device<devices::NETLIB_NAME(gnd)>("gnd");
- m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
-
- m_use_deactivate = (m_params->m_use_deactivate.Value() ? true : false);
-
- /* create devices */
-
- for (auto & e : setup().m_device_factory)
- {
- if ( !setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
- && !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- && !setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
- && !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
- setup().register_dev(std::move(dev));
- }
- }
}
@@ -334,6 +305,8 @@ void netlist_t::process_queue(const netlist_time &delta)
m_queue.push(stop, nullptr);
+ m_stat_mainloop.start();
+
if (m_mainclock == nullptr)
{
queue_t::entry_t e(m_queue.pop());
@@ -341,7 +314,7 @@ void netlist_t::process_queue(const netlist_time &delta)
while (e.m_object != nullptr)
{
e.m_object->update_devs();
- add_to_stat(m_perf_out_processed, 1);
+ m_perf_out_processed.inc();
e = m_queue.pop();
m_time = e.m_exec_time;
}
@@ -367,27 +340,67 @@ void netlist_t::process_queue(const netlist_time &delta)
if (e.m_object == nullptr)
break;
e.m_object->update_devs();
- add_to_stat(m_perf_out_processed, 1);
+ m_perf_out_processed.inc();
}
mc_net.set_time(mc_time);
}
+ m_stat_mainloop.stop();
}
void netlist_t::print_stats() const
{
-#if (NL_KEEP_STATISTICS)
+ if (nperftime_t::enabled)
{
- for (auto & entry : m_devices)
+ std::vector<size_t> index;
+ for (size_t i=0; i<m_devices.size(); i++)
+ index.push_back(i);
+
+ std::sort(index.begin(), index.end(),
+ [&](size_t i1, size_t i2) { return m_devices[i1]->m_stat_total_time.total() < m_devices[i2]->m_stat_total_time.total(); });
+
+ nperftime_t::type total_time(0);
+ uint_least64_t total_count(0);
+
+ for (auto & j : index)
{
- log().verbose("Device {1:20} : {2:12} {3:12} {4:15}", entry->name(),
- entry->stat_call_count, entry->stat_update_count,
- (long int) entry->stat_total_time / (entry->stat_update_count + 1));
+ auto entry = m_devices[j].get();
+ log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
+ entry->m_stat_call_count(), entry->m_stat_total_time.count(),
+ entry->m_stat_total_time.total(), entry->m_stat_inc_active());
+ total_time += entry->m_stat_total_time.total();
+ total_count += entry->m_stat_total_time.count();
}
- log().verbose("Queue Pushes {1:15}", queue().m_prof_call);
- log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove);
+ nperftime_t overhead;
+ nperftime_t test;
+ overhead.start();
+ for (int j=0; j<100000;j++)
+ {
+ test.start();
+ test.stop();
+ }
+ overhead.stop();
+
+ uint_least64_t total_overhead = (uint_least64_t) overhead()*(uint_least64_t)total_count/(uint_least64_t)200000;
+
+ log().verbose("Queue Pushes {1:15}", queue().m_prof_call());
+ log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove());
+
+ log().verbose("Total loop {1:15}", m_stat_mainloop());
+ /* Only one serialization should be counted in total time */
+ /* But two are contained in m_stat_mainloop */
+ log().verbose("Total devices {1:15}", total_time);
+ log().verbose("");
+ log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
+ log().verbose("Total overhead {1:15}", total_overhead);
+ log().verbose("Overhead per pop {1:11}", (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead ))/queue().m_prof_call());
+ log().verbose("");
+ for (auto &entry : m_devices)
+ {
+ if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count())
+ log().verbose("HINT({}, NO_DEACTIVATE)", entry->name());
+ }
}
-#endif
}
// ----------------------------------------------------------------------------------------
@@ -419,10 +432,9 @@ core_device_t::core_device_t(netlist_t &owner, const pstring &name)
: object_t(name)
, logic_family_t()
, netlist_ref(owner)
-#if (NL_KEEP_STATISTICS)
- , stat_total_time(0)
- , stat_update_count(0)
- , stat_call_count(0)
+ , m_hint_deactivate(false)
+#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
+ , m_static_update()
#endif
{
if (logic_family() == nullptr)
@@ -433,10 +445,9 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name)
: object_t(owner.name() + "." + name)
, logic_family_t()
, netlist_ref(owner.netlist())
-#if (NL_KEEP_STATISTICS)
- , stat_total_time(0)
- , stat_update_count(0)
- , stat_call_count(0)
+ , m_hint_deactivate(false)
+#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
+ , m_static_update()
#endif
{
set_logic_family(owner.logic_family());
@@ -586,14 +597,10 @@ void net_t::inc_active(core_terminal_t &term)
{
m_active++;
m_list_active.push_front(&term);
- nl_assert(m_active <= num_cons());
+ nl_assert(m_active <= (int) num_cons());
if (m_active == 1)
{
- if (netlist().use_deactivate())
- {
- railterminal().device().do_inc_active();
- //m_cur_Q = m_new_Q;
- }
+ railterminal().device().do_inc_active();
if (m_in_queue == 0)
{
if (m_time > netlist().time())
@@ -607,8 +614,6 @@ void net_t::inc_active(core_terminal_t &term)
m_in_queue = 2;
}
}
- //else if (netlist().use_deactivate())
- // m_cur_Q = m_new_Q;
}
}
@@ -617,7 +622,7 @@ void net_t::dec_active(core_terminal_t &term)
--m_active;
nl_assert(m_active >= 0);
m_list_active.remove(&term);
- if (m_active == 0 && netlist().use_deactivate())
+ if (m_active == 0)
railterminal().device().do_dec_active();
}
@@ -656,7 +661,7 @@ void net_t::update_devs()
for (auto & p : m_list_active)
{
- inc_stat(p.device().stat_call_count);
+ p.device().m_stat_call_count.inc();
if ((p.state() & mask) != 0)
p.device().update_dev();
}
@@ -945,10 +950,6 @@ nl_double param_model_t::model_value(const pstring &entity)
}
-} // namespace
-
-namespace netlist
-{
namespace devices
{
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 1587cefb99b..1451e18038d 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -892,10 +892,9 @@ namespace netlist
void update_dev()
{
- begin_timing(stat_total_time);
- inc_stat(stat_update_count);
+ m_stat_total_time.start();
do_update();
- end_timing(stat_total_time);
+ m_stat_total_time.stop();
}
void do_update() NOEXCEPT
@@ -912,9 +911,21 @@ namespace netlist
void set_delegate_pointer();
void stop_dev();
- void do_inc_active() { inc_active(); }
- void do_dec_active() { dec_active(); }
+ void do_inc_active()
+ {
+ if (m_hint_deactivate)
+ {
+ m_stat_inc_active.inc();
+ inc_active();
+ }
+ }
+ void do_dec_active()
+ {
+ if (m_hint_deactivate)
+ dec_active();
+ }
void do_reset() { reset(); }
+ void set_hint_deactivate(bool v) { m_hint_deactivate = v; }
netlist_sig_t INPLOGIC_PASSIVE(logic_input_t &inp);
netlist_sig_t INPLOGIC(const logic_input_t &inp) const
@@ -928,12 +939,10 @@ namespace netlist
nl_double TERMANALOG(const terminal_t &term) const { return term.net().Q_Analog(); }
void OUTANALOG(analog_output_t &out, const nl_double val) { out.set_Q(val); }
- #if (NL_KEEP_STATISTICS)
/* stats */
- plib::ticks_t stat_total_time;
- int_fast32_t stat_update_count;
- int_fast32_t stat_call_count;
- #endif
+ nperftime_t m_stat_total_time;
+ nperfcount_t m_stat_call_count;
+ nperfcount_t m_stat_inc_active;
protected:
@@ -953,12 +962,12 @@ namespace netlist
virtual bool needs_update_after_param_change() const { return false; }
private:
-
- #if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
+ bool m_hint_deactivate;
+ #if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
typedef void (core_device_t::*net_update_delegate)();
- #elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
+ #elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
using net_update_delegate = MEMBER_ABI void (*)(core_device_t *);
- #endif
+ #endif
#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
net_update_delegate m_static_update;
@@ -966,22 +975,6 @@ namespace netlist
};
// -----------------------------------------------------------------------------
- // param_ref_t
- // -----------------------------------------------------------------------------
-
- struct param_ref_t
- {
- param_ref_t(const pstring name, core_device_t &device, param_t &param)
- : m_name(name)
- , m_device(device)
- , m_param(param)
- { }
- pstring m_name;
- core_device_t &m_device;
- param_t &m_param;
- };
-
- // -----------------------------------------------------------------------------
// device_t
// -----------------------------------------------------------------------------
@@ -1071,8 +1064,9 @@ namespace netlist
// -----------------------------------------------------------------------------
- class netlist_t : public plib::plog_dispatch_intf //, public device_owner_t
+ class netlist_t : public plib::plog_dispatch_intf
{
+ friend class setup_t;
P_PREVENT_COPYING(netlist_t)
public:
@@ -1097,13 +1091,14 @@ namespace netlist
void process_queue(const netlist_time &delta);
void abort_current_queue_slice() { m_queue.retime(m_time, nullptr); }
- bool use_deactivate() const { return m_use_deactivate; }
-
void rebuild_lists(); /* must be called after post_load ! */
void set_setup(setup_t *asetup) { m_setup = asetup; }
setup_t &setup() { return *m_setup; }
+
+ void register_dev(plib::owned_ptr<device_t> dev);
+
net_t *find_net(const pstring &name);
template<class device_class>
@@ -1165,22 +1160,21 @@ namespace netlist
/* sole use is to manage lifetime of family objects */
std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
-protected:
+ protected:
- #if (NL_KEEP_STATISTICS)
// performance
- int m_perf_out_processed;
- int m_perf_inp_processed;
- int m_perf_inp_active;
- #endif
+ nperfcount_t m_perf_out_processed;
+ nperfcount_t m_perf_inp_processed;
+ nperfcount_t m_perf_inp_active;
private:
plib::state_manager_t m_state;
/* mostly rw */
netlist_time m_time;
queue_t m_queue;
- /* mostly rw */
- bool m_use_deactivate;
+
+ nperftime_t m_stat_mainloop;
+ /* mostly ro */
devices::NETLIB_NAME(mainclock) * m_mainclock;
devices::NETLIB_NAME(solver) * m_solver;
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 19d8e3561ad..153057dbc22 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -11,6 +11,7 @@
#include <cstdint>
#include "plib/pconfig.h"
+#include "plib/pchrono.h"
//============================================================
// SETUP
@@ -111,18 +112,16 @@
// Performance tracking
//============================================================
+namespace netlist
+{
#if NL_KEEP_STATISTICS
-#define add_to_stat(v,x) do { v += (x); } while (0)
-#define inc_stat(v) add_to_stat(v, 1)
-#define begin_timing(v) do { v -= plib::profile_ticks(); } while (0)
-#define end_timing(v) do { v += plib::profile_ticks(); } while (0)
+using nperftime_t = plib::timer<plib::exact_ticks, true>;
+using nperfcount_t = plib::counter<true>;
#else
-#define add_to_stat(v,x) do { } while (0)
-#define inc_stat(v) add_to_stat(v, 1)
-#define begin_timing(v) do { } while (0)
-#define end_timing(v) do { } while (0)
+using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, false>;
+using nperfcount_t = plib::chrono::counter<false>;
#endif
-
+}
//============================================================
// General
//============================================================
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index b85e85bf6b8..f97dad9bf5a 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -65,7 +65,7 @@ namespace netlist
}
};
- class factory_list_t : public std::vector<plib::owned_ptr<base_factory_t>>
+ class factory_list_t : public std::vector<std::unique_ptr<base_factory_t>>
{
public:
factory_list_t(setup_t &m_setup);
@@ -75,10 +75,10 @@ namespace netlist
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- register_device(plib::owned_ptr<base_factory_t>::Create<factory_t<device_class>>(name, classname, def_param));
+ register_device(std::unique_ptr<base_factory_t>(new factory_t<device_class>(name, classname, def_param)));
}
- void register_device(plib::owned_ptr<base_factory_t> factory)
+ void register_device(std::unique_ptr<base_factory_t> factory)
{
for (auto & e : *this)
if (e->name() == factory->name())
@@ -104,14 +104,14 @@ namespace netlist
// factory_creator_ptr_t
// -----------------------------------------------------------------------------
- using factory_creator_ptr_t = plib::owned_ptr<base_factory_t> (*)(const pstring &name, const pstring &classname,
+ using factory_creator_ptr_t = std::unique_ptr<base_factory_t> (*)(const pstring &name, const pstring &classname,
const pstring &def_param);
template <typename T>
- plib::owned_ptr<base_factory_t> factory_creator_t(const pstring &name, const pstring &classname,
+ std::unique_ptr<base_factory_t> factory_creator_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- return plib::owned_ptr<base_factory_t>::Create<factory_t<T>>(name, classname, def_param);
+ return std::unique_ptr<base_factory_t>(new factory_t<T>(name, classname, def_param));
}
}
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index 475e0e285c2..9e6cc335b5b 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -10,10 +10,11 @@
#ifndef NLLISTS_H_
#define NLLISTS_H_
+#include <atomic>
+
#include "nl_config.h"
#include "plib/plists.h"
-
-#include <atomic>
+#include "plib/pchrono.h"
// ----------------------------------------------------------------------------------------
@@ -36,10 +37,6 @@ namespace netlist
timed_queue(unsigned list_size)
: m_list(list_size)
-#if (NL_KEEP_STATISTICS)
- , m_prof_sortmove(0)
- , m_prof_call(0)
-#endif
{
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@@ -60,11 +57,11 @@ namespace netlist
for (; t > (i - 1)->m_exec_time; --i)
{
*(i) = *(i-1);
- inc_stat(m_prof_sortmove);
+ m_prof_sortmove.inc();
}
*i = { t, o };
++m_end;
- inc_stat(m_prof_call);
+ m_prof_call.inc();
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
#endif
@@ -132,12 +129,9 @@ namespace netlist
std::vector<entry_t> m_list;
public:
- #if (NL_KEEP_STATISTICS)
// profiling
- std::size_t m_prof_sortmove;
- std::size_t m_prof_call;
- #endif
-
+ nperfcount_t m_prof_sortmove;
+ nperfcount_t m_prof_call;
};
}
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 14aabdf4a0e..bc27913e6b0 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -45,6 +45,7 @@ bool parser_t::parse(const pstring nlname)
m_tok_NET_C = register_token("NET_C");
m_tok_FRONTIER = register_token("OPTIMIZE_FRONTIER");
m_tok_PARAM = register_token("PARAM");
+ m_tok_HINT = register_token("HINT");
m_tok_NET_MODEL = register_token("NET_MODEL");
m_tok_INCLUDE = register_token("INCLUDE");
m_tok_LOCAL_SOURCE = register_token("LOCAL_SOURCE");
@@ -120,6 +121,8 @@ void parser_t::parse_netlist(ATTR_UNUSED const pstring &nlname)
frontier();
else if (token.is(m_tok_PARAM))
netdev_param();
+ else if (token.is(m_tok_HINT))
+ netdev_hint();
else if (token.is(m_tok_NET_MODEL))
net_model();
else if (token.is(m_tok_SUBMODEL))
@@ -153,13 +156,16 @@ void parser_t::net_truthtable_start()
require_token(m_tok_comma);
unsigned no = get_number_long();
require_token(m_tok_comma);
- unsigned hs = get_number_long();
- require_token(m_tok_comma);
pstring def_param = get_string();
require_token(m_tok_param_right);
- plib::owned_ptr<netlist::devices::netlist_base_factory_truthtable_t> ttd = netlist::devices::nl_tt_factory_create(ni, no, hs,
- name, name, "+" + def_param);
+ netlist::tt_desc desc;
+ desc.classname = name;
+ desc.name = name;
+ desc.ni = ni;
+ desc.no = no;
+ desc.def_param = "+" + def_param;
+ desc.family = "";
while (true)
{
@@ -168,19 +174,19 @@ void parser_t::net_truthtable_start()
if (token.is(m_tok_TT_HEAD))
{
require_token(m_tok_param_left);
- ttd->m_desc.push_back(get_string());
+ desc.desc.push_back(get_string());
require_token(m_tok_param_right);
}
else if (token.is(m_tok_TT_LINE))
{
require_token(m_tok_param_left);
- ttd->m_desc.push_back(get_string());
+ desc.desc.push_back(get_string());
require_token(m_tok_param_right);
}
else if (token.is(m_tok_TT_FAMILY))
{
require_token(m_tok_param_left);
- ttd->m_family = m_setup.family_from_model(get_string());
+ desc.family = get_string();
require_token(m_tok_param_right);
}
else
@@ -188,7 +194,7 @@ void parser_t::net_truthtable_start()
require_token(token, m_tok_TRUTHTABLE_END);
require_token(m_tok_param_left);
require_token(m_tok_param_right);
- m_setup.factory().register_device(std::move(ttd));
+ netlist::devices::tt_factory_create(m_setup, desc);
return;
}
}
@@ -339,6 +345,15 @@ void parser_t::netdev_param()
require_token(m_tok_param_right);
}
+void parser_t::netdev_hint()
+{
+ pstring dev(get_identifier());
+ require_token(m_tok_comma);
+ pstring hint(get_identifier());
+ m_setup.register_param(dev + ".HINT_" + hint, 1);
+ require_token(m_tok_param_right);
+}
+
void parser_t::device(const pstring &dev_type)
{
if (m_setup.is_library_item(dev_type))
@@ -431,7 +446,7 @@ nl_double parser_t::eval_param(const token_t tok)
val = tok.str();
ret = val.as_double(&e);
if (e)
- error("Error with parameter ...\n");
+ error(plib::pfmt("Error with parameter {1}...\n")(val));
}
return ret * facs[f];
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index 7338fb01abd..5c915e69997 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -27,6 +27,7 @@ namespace netlist
void net_alias();
void dippins();
void netdev_param();
+ void netdev_hint();
void net_c();
void frontier();
void device(const pstring &dev_type);
@@ -54,6 +55,7 @@ namespace netlist
token_id_t m_tok_DIPPINS;
token_id_t m_tok_FRONTIER;
token_id_t m_tok_PARAM;
+ token_id_t m_tok_HINT;
token_id_t m_tok_NET_MODEL;
token_id_t m_tok_NETLIST_START;
token_id_t m_tok_NETLIST_END;
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 5b7099a9e14..0582f8a9070 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -16,6 +16,7 @@
#include "nl_parser.h"
#include "nl_factory.h"
#include "devices/net_lib.h"
+#include "devices/nld_truthtable.h"
#include "devices/nlid_system.h"
#include "analog/nld_twoterm.h"
#include "solver/nld_solver.h"
@@ -99,15 +100,6 @@ void setup_t::namespace_pop()
m_namespace_stack.pop();
}
-
-void setup_t::register_dev(plib::owned_ptr<device_t> dev)
-{
- for (auto & d : netlist().m_devices)
- if (d->name() == dev->name())
- log().fatal("Error adding {1} to device list. Duplicate name \n", d->name());
- netlist().m_devices.push_back(std::move(dev));
-}
-
void setup_t::register_lib_entry(const pstring &name)
{
if (plib::container::contains(m_lib, name))
@@ -453,7 +445,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
proxy = new_proxy.get();
- register_dev(std::move(new_proxy));
+ netlist().register_dev(std::move(new_proxy));
}
return proxy;
}
@@ -471,7 +463,7 @@ void setup_t::connect_input_output(core_terminal_t &in, core_terminal_t &out)
proxy->m_Q.net().register_con(in);
out.net().register_con(proxy->m_I);
- register_dev(std::move(proxy));
+ netlist().register_dev(std::move(proxy));
}
else if (out.is_logic() && in.is_analog())
@@ -514,7 +506,7 @@ void setup_t::connect_terminal_input(terminal_t &term, core_terminal_t &inp)
else
proxy->m_Q.net().register_con(inp);
- register_dev(std::move(proxy));
+ netlist().register_dev(std::move(proxy));
}
else
{
@@ -781,13 +773,77 @@ void setup_t::start_devices()
auto nc = factory().factory_by_name("LOG")->Create(netlist(), name);
register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name);
- register_dev(std::move(nc));
+ netlist().register_dev(std::move(nc));
+ }
+ }
+
+ /* make sure the solver and parameters are started first! */
+
+ for (auto & e : m_device_factory)
+ {
+ if ( factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
+ || factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ || factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
+ || factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first));
+ netlist().register_dev(std::move(dev));
+ }
+ }
+
+ log().debug("Searching for mainclock and solver ...\n");
+
+ netlist().m_mainclock = netlist().get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+ netlist().m_solver = netlist().get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ netlist().m_gnd = netlist().get_single_device<devices::NETLIB_NAME(gnd)>("gnd");
+ netlist().m_params = netlist().get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+
+ /* create devices */
+
+ for (auto & e : m_device_factory)
+ {
+ if ( !factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
+ && !factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ && !factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
+ && !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first));
+ netlist().register_dev(std::move(dev));
+ }
+ }
+
+ bool use_deactivate = (netlist().m_params->m_use_deactivate.Value() ? true : false);
+
+ for (auto &d : netlist().m_devices)
+ {
+ if (use_deactivate)
+ {
+ auto p = m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE");
+ if (p != m_param_values.end())
+ {
+ //FIXME: Error checking
+ auto v = p->second.as_long();
+ d->set_hint_deactivate(!v);
+ }
}
+ else
+ d->set_hint_deactivate(false);
}
netlist().start();
+
}
+plib::plog_base<NL_DEBUG> &setup_t::log()
+{
+ return netlist().log();
+}
+const plib::plog_base<NL_DEBUG> &setup_t::log() const
+{
+ return netlist().log();
+}
+
+
// ----------------------------------------------------------------------------------------
// Model / family
// ----------------------------------------------------------------------------------------
@@ -926,13 +982,19 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity)
return tmp.as_double() * factor;
}
+void setup_t::tt_factory_create(tt_desc &desc)
+{
+ devices::tt_factory_create(*this, desc);
+}
+
+
// ----------------------------------------------------------------------------------------
// Sources
// ----------------------------------------------------------------------------------------
void setup_t::include(const pstring &netlist_name)
{
- for (auto source : m_sources)
+ for (auto &source : m_sources)
{
if (source->parse(*this, netlist_name))
return;
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 39ef1c514ff..2fee7210aa9 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -11,7 +11,13 @@
#include <memory>
#include <stack>
#include <unordered_map>
+#include <vector>
+#include "plib/pstring.h"
+#include "plib/palloc.h"
+#include "plib/pfmtlog.h"
+#include "plib/putil.h"
+#include "nl_config.h"
#include "nl_base.h"
#include "nl_factory.h"
@@ -34,75 +40,136 @@
#define NET_REGISTER_DEV(type, name) \
setup.register_dev(# type, # name);
-#define NET_CONNECT(name, input, output) \
+#define NET_CONNECT(name, input, output) \
setup.register_link(# name "." # input, # output);
-#define NET_C(term1, ...) \
+#define NET_C(term1, ...) \
setup.register_link_arr( # term1 ", " # __VA_ARGS__);
-#define PARAM(name, val) \
+#define PARAM(name, val) \
setup.register_param(# name, val);
-#define NETDEV_PARAMI(name, param, val) \
+#define HINT(name, val) \
+ setup.register_param(# name ".HINT_" # val, 1);
+
+#define NETDEV_PARAMI(name, param, val) \
setup.register_param(# name "." # param, val);
#define NETLIST_NAME(name) netlist ## _ ## name
-#define NETLIST_EXTERNAL(name) \
+#define NETLIST_EXTERNAL(name) \
void NETLIST_NAME(name)(netlist::setup_t &setup);
-#define NETLIST_START(name) \
-void NETLIST_NAME(name)(netlist::setup_t &setup) \
+#define NETLIST_START(name) \
+void NETLIST_NAME(name)(netlist::setup_t &setup) \
{
+
#define NETLIST_END() }
-#define LOCAL_SOURCE(name) \
- setup.register_source(std::make_shared<netlist::source_proc_t>(# name, &NETLIST_NAME(name)));
+#define LOCAL_SOURCE(name) \
+ setup.register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>(# name, &NETLIST_NAME(name)));
-#define LOCAL_LIB_ENTRY(name) \
- LOCAL_SOURCE(name) \
+#define LOCAL_LIB_ENTRY(name) \
+ LOCAL_SOURCE(name) \
setup.register_lib_entry(# name);
-#define INCLUDE(name) \
+#define INCLUDE(name) \
setup.include(# name);
-#define SUBMODEL(model, name) \
- setup.namespace_push(# name); \
- NETLIST_NAME(model)(setup); \
+#define SUBMODEL(model, name) \
+ setup.namespace_push(# name); \
+ NETLIST_NAME(model)(setup); \
setup.namespace_pop();
-// ----------------------------------------------------------------------------------------
-// netlist_setup_t
-// ----------------------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// truthtable defines
+// -----------------------------------------------------------------------------
+
+#define TRUTHTABLE_START(cname, in, out, def_params) \
+ { \
+ netlist::tt_desc desc; \
+ desc.name = #cname ; \
+ desc.classname = #cname ; \
+ desc.ni = in; \
+ desc.no = out; \
+ desc.def_param = pstring("+") + def_params; \
+ desc.family = "";
+
+#define TT_HEAD(x) \
+ desc.desc.push_back(x);
+
+#define TT_LINE(x) \
+ desc.desc.push_back(x);
+
+#define TT_FAMILY(x) \
+ desc.family = x;
+
+#define TRUTHTABLE_END() \
+ netlist::devices::tt_factory_create(setup, desc); \
+ }
+
namespace netlist
{
- // Forward definition so we keep nl_factory.h out of the public
- class factory_list_t;
+ // -----------------------------------------------------------------------------
+ // truthtable desc
+ // -----------------------------------------------------------------------------
- class setup_t
+ struct tt_desc
+ {
+ pstring name;
+ pstring classname;
+ unsigned ni;
+ unsigned no;
+ pstring def_param;
+ plib::pstring_vector_t desc;
+ pstring family;
+ };
+
+ // -----------------------------------------------------------------------------
+ // param_ref_t
+ // -----------------------------------------------------------------------------
+
+ struct param_ref_t
+ {
+ param_ref_t(const pstring name, core_device_t &device, param_t &param)
+ : m_name(name)
+ , m_device(device)
+ , m_param(param)
+ { }
+ pstring m_name;
+ core_device_t &m_device;
+ param_t &m_param;
+ };
+
+ // ----------------------------------------------------------------------------------------
+ // A Generic netlist sources implementation
+ // ----------------------------------------------------------------------------------------
+
+ class source_t
{
- P_PREVENT_COPYING(setup_t)
public:
+ using list_t = std::vector<std::unique_ptr<source_t>>;
- // ----------------------------------------------------------------------------------------
- // A Generic netlist sources implementation
- // ----------------------------------------------------------------------------------------
+ source_t()
+ {}
- class source_t
- {
- public:
- using list_t = std::vector<std::shared_ptr<source_t>>;
+ virtual ~source_t() { }
+
+ virtual bool parse(setup_t &setup, const pstring &name) = 0;
+ private:
+ };
- source_t()
- {}
+ // ----------------------------------------------------------------------------------------
+ // setup_t
+ // ----------------------------------------------------------------------------------------
- virtual ~source_t() { }
- virtual bool parse(setup_t &setup, const pstring &name) = 0;
- private:
- };
+ class setup_t
+ {
+ P_PREVENT_COPYING(setup_t)
+ public:
using link_t = std::pair<pstring, pstring>;
@@ -118,7 +185,6 @@ namespace netlist
void register_term(core_terminal_t &obj);
- void register_dev(plib::owned_ptr<device_t> dev);
void register_dev(const pstring &classname, const pstring &name);
void register_lib_entry(const pstring &name);
@@ -160,10 +226,9 @@ namespace netlist
/* register a source */
- template <class C>
- void register_source(std::shared_ptr<C> src)
+ void register_source(std::unique_ptr<source_t> &&src)
{
- m_sources.push_back(std::static_pointer_cast<source_t>(src));
+ m_sources.push_back(std::move(src));
}
factory_list_t &factory() { return m_factory; }
@@ -179,11 +244,15 @@ namespace netlist
void model_parse(const pstring &model, model_map_t &map);
- plib::plog_base<NL_DEBUG> &log() { return netlist().log(); }
- const plib::plog_base<NL_DEBUG> &log() const { return netlist().log(); }
+ plib::plog_base<NL_DEBUG> &log();
+ const plib::plog_base<NL_DEBUG> &log() const;
std::vector<std::pair<pstring, base_factory_t *>> m_device_factory;
+ /* FIXME: truth table trampoline */
+
+ void tt_factory_create(tt_desc &desc);
+
protected:
private:
@@ -232,12 +301,12 @@ namespace netlist
// ----------------------------------------------------------------------------------------
- class source_string_t : public setup_t::source_t
+ class source_string_t : public source_t
{
public:
source_string_t(const pstring &source)
- : setup_t::source_t(), m_str(source)
+ : source_t(), m_str(source)
{
}
@@ -247,12 +316,12 @@ namespace netlist
pstring m_str;
};
- class source_file_t : public setup_t::source_t
+ class source_file_t : public source_t
{
public:
source_file_t(const pstring &filename)
- : setup_t::source_t(), m_filename(filename)
+ : source_t(), m_filename(filename)
{
}
@@ -262,11 +331,11 @@ namespace netlist
pstring m_filename;
};
- class source_mem_t : public setup_t::source_t
+ class source_mem_t : public source_t
{
public:
source_mem_t(const char *mem)
- : setup_t::source_t(), m_str(mem)
+ : source_t(), m_str(mem)
{
}
@@ -276,11 +345,11 @@ namespace netlist
pstring m_str;
};
- class source_proc_t : public setup_t::source_t
+ class source_proc_t : public source_t
{
public:
source_proc_t(pstring name, void (*setup_func)(setup_t &))
- : setup_t::source_t(),
+ : source_t(),
m_setup_func(setup_func),
m_setup_func_name(name)
{
diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h
index 0a4caac1ac6..974ba4c669c 100644
--- a/src/lib/netlist/nl_time.h
+++ b/src/lib/netlist/nl_time.h
@@ -42,7 +42,7 @@ namespace netlist
constexpr explicit ptime(const double t) = delete;
//: m_time((internal_type) ( t * (double) resolution)) { }
- constexpr explicit ptime(const internal_type nom, const internal_type den)
+ constexpr explicit ptime(const internal_type nom, const internal_type den) NOEXCEPT
: m_time(nom * (resolution / den)) { }
ptime &operator=(const ptime rhs) { m_time = rhs.m_time; return *this; }
@@ -100,7 +100,7 @@ namespace netlist
friend bool operator!=(const ptime &lhs, const ptime &rhs)
{
- return lhs.m_time != rhs.m_time;
+ return !(lhs == rhs);
}
constexpr internal_type as_raw() const { return m_time; }
@@ -109,16 +109,16 @@ namespace netlist
// for save states ....
internal_type *get_internaltype_ptr() { return &m_time; }
- static inline constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); }
- static inline constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); }
- static inline constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); }
- static inline constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); }
- static inline constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); }
- static inline constexpr ptime from_double(const double t) { return ptime((internal_type) ( t * (double) resolution), resolution); }
+ static constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); }
+ static constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); }
+ static constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); }
+ static constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); }
+ static constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); }
+ static constexpr ptime from_double(const double t) { return ptime((internal_type) ( t * (double) resolution), resolution); }
- static inline constexpr ptime zero() { return ptime(0, resolution); }
- static inline constexpr ptime quantum() { return ptime(1, resolution); }
- static inline constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
+ static constexpr ptime zero() { return ptime(0, resolution); }
+ static constexpr ptime quantum() { return ptime(1, resolution); }
+ static constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
private:
internal_type m_time;
};
diff --git a/src/lib/netlist/plib/pchrono.cpp b/src/lib/netlist/plib/pchrono.cpp
new file mode 100644
index 00000000000..3beb3b2f161
--- /dev/null
+++ b/src/lib/netlist/plib/pchrono.cpp
@@ -0,0 +1,55 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+#include <chrono>
+
+#include "pchrono.h"
+
+namespace plib {
+namespace chrono {
+
+
+#if defined(__x86_64__) && !defined(_clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
+
+fast_ticks::type fast_ticks::per_second()
+{
+ static type persec = 0;
+ if (persec == 0)
+ {
+ type x = 0;
+ system_ticks::type t = system_ticks::start();
+ system_ticks::type e;
+ x = -start();
+ do {
+ e = system_ticks::stop();
+ } while (e - t < system_ticks::per_second() / 100 );
+ x += stop();
+ persec = (type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
+ }
+ return persec;
+}
+
+#if PUSE_ACCURATE_STATS && PHAS_RDTSCP
+exact_ticks::type exact_ticks::per_second()
+{
+ static type persec = 0;
+ if (persec == 0)
+ {
+ type x = 0;
+ system_ticks::type t = system_ticks::start();
+ system_ticks::type e;
+ x = -start();
+ do {
+ e = system_ticks::stop();
+ } while (e - t < system_ticks::per_second() / 100 );
+ x += stop();
+ persec = (type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
+ }
+ return persec;
+}
+#endif
+
+#endif
+
+}
+}
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
new file mode 100644
index 00000000000..805842007f2
--- /dev/null
+++ b/src/lib/netlist/plib/pchrono.h
@@ -0,0 +1,213 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * pchrono.h
+ *
+ */
+
+#ifndef PCHRONO_H_
+#define PCHRONO_H_
+
+#include <cstdint>
+#include <thread>
+#include <chrono>
+
+#include "pconfig.h"
+
+namespace plib {
+namespace chrono {
+ template <typename T>
+ struct sys_ticks
+ {
+ typedef typename T::rep type;
+ static inline type start() { return T::now().time_since_epoch().count(); }
+ static inline type stop() { return T::now().time_since_epoch().count(); }
+ static inline constexpr type per_second() { return T::period::den / T::period::num; }
+ };
+
+ using hires_ticks = sys_ticks<std::chrono::high_resolution_clock>;
+ using steady_ticks = sys_ticks<std::chrono::steady_clock>;
+ using system_ticks = sys_ticks<std::chrono::system_clock>;
+
+ #if defined(__x86_64__) && !defined(_clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
+
+ #if PHAS_RDTSCP
+ struct fast_ticks
+ {
+ typedef int64_t type;
+ static inline type start()
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtscp;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : /* inputs */
+ : "%rcx", "%rdx" /* clobbers */
+ );
+ return v;
+ }
+ static inline type stop()
+ {
+ return start();
+ }
+ static type per_second();
+ };
+
+ #else
+ struct fast_ticks
+ {
+ typedef int64_t type;
+ static inline type start()
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtsc;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : /* inputs */
+ : "%rdx" /* clobbers */
+ );
+ return v;
+ }
+ static inline type stop()
+ {
+ return start();
+ }
+ static type per_second();
+ };
+
+ #endif
+
+
+ /* Based on "How to Benchmark Code Execution Times on IntelĀ® IA-32 and IA-64
+ * Instruction Set Architectures", Intel, 2010
+ *
+ */
+ #if PUSE_ACCURATE_STATS && PHAS_RDTSCP
+ /*
+ * kills performance completely, but is accurate
+ * cpuid serializes, but clobbers ebx and ecx
+ *
+ */
+
+ struct exact_ticks
+ {
+ typedef int64_t type;
+
+ static inline type start()
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "cpuid;"
+ //"xor %%eax, %%eax\n\t"
+ "rdtsc;"
+ "shl $32, %%rdx;"
+ "or %%rdx, %%rax;"
+ : "=a"(v) /* outputs */
+ : "a"(0x0) /* inputs */
+ : "%ebx", "%ecx", "%rdx" /* clobbers*/
+ );
+ return v;
+ }
+ static inline type stop()
+ {
+ int64_t v;
+ __asm__ __volatile__ (
+ "rdtscp;"
+ "shl $32, %%rdx;"
+ "or %%rax, %%rdx;"
+ "mov %%rdx, %%r10;"
+ "xor %%eax, %%eax\n\t"
+ "cpuid;"
+ "mov %%r10, %%rax;"
+ : "=a" (v)
+ :
+ : "%ebx", "%ecx", "%rdx", "%r10"
+ );
+ return v;
+ }
+
+ static type per_second();
+ };
+ #else
+ using exact_ticks = fast_ticks;
+ #endif
+
+
+ #else
+ using fast_ticks = hires_ticks;
+ using exact_ticks = fast_ticks;
+ #endif
+
+ template<bool enabled_>
+ struct counter
+ {
+ counter() : m_count(0) { }
+ typedef uint_least64_t type;
+ type operator()() const { return m_count; }
+ void inc() { ++m_count; }
+ void reset() { m_count = 0; }
+ constexpr static bool enabled = enabled_;
+ private:
+ type m_count;
+ };
+
+ template<>
+ struct counter<false>
+ {
+ typedef uint_least64_t type;
+ constexpr type operator()() const { return 0; }
+ void inc() const { }
+ void reset() const { }
+ constexpr static bool enabled = false;
+ };
+
+
+ template< typename T, bool enabled_ = true>
+ struct timer
+ {
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
+
+ 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; }
+ ctype count() const { return m_count; }
+
+ double as_seconds() const { return (double) total() / (double) T::per_second(); }
+
+ constexpr static bool enabled = enabled_;
+ private:
+ type m_time;
+ ctype m_count;
+ };
+
+ template<typename T>
+ struct timer<T, false>
+ {
+ typedef typename T::type type;
+ typedef uint_least64_t ctype;
+ 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;
+ };
+
+ } // namespace chrono
+} // namespace plib
+
+#endif /* PCHRONO_H_ */
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index 48a7e740a8f..5c1582cdec8 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -12,9 +12,22 @@
#include <thread>
#include <chrono>
-#ifndef PSTANDALONE
- #define PSTANDALONE (0)
-#endif
+/*
+ * Define this for more accurate measurements if you processor supports
+ * RDTSCP.
+ */
+#define PHAS_RDTSCP (1)
+
+/*
+ * Define this to use accurate timing measurements. Only works
+ * if PHAS_RDTSCP == 1
+ */
+#define PUSE_ACCURATE_STATS (1)
+
+/*
+ * Set this to one if you want to use 128 bit int for ptime.
+ * This is for tests only.
+ */
#define PHAS_INT128 (0)
@@ -75,30 +88,6 @@ typedef __int128_t INT128;
namespace plib {
-using ticks_t = int64_t;
-
-static inline ticks_t ticks()
-{
- return std::chrono::high_resolution_clock::now().time_since_epoch().count();
-}
-static inline ticks_t ticks_per_second()
-{
- return std::chrono::high_resolution_clock::period::den / std::chrono::high_resolution_clock::period::num;
-}
-
-#if defined(__x86_64__) && !defined(_clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
-
-static inline ticks_t profile_ticks()
-{
- unsigned hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
-}
-
-#else
-static inline ticks_t profile_ticks() { return ticks(); }
-#endif
-
/*
* The following class was derived from the MAME delegate.h code.
* It derives a pointer to a member function.
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp
new file mode 100644
index 00000000000..8b2db8cf19e
--- /dev/null
+++ b/src/lib/netlist/plib/poptions.cpp
@@ -0,0 +1,226 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * poptions.cpp
+ *
+ */
+
+#include "poptions.h"
+
+namespace plib {
+
+/***************************************************************************
+ Options
+***************************************************************************/
+
+ option::option()
+ : m_short(""), m_long(""), m_help(""), m_has_argument(false)
+ {}
+
+ option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument)
+ : m_short(ashort), m_long(along), m_help(help), m_has_argument(has_argument)
+ {
+ parent.register_option(this);
+ }
+
+ option::~option()
+ {
+ }
+
+ int option_str::parse(pstring argument)
+ {
+ m_val = argument;
+ return 0;
+ }
+
+ int option_str_limit::parse(pstring argument)
+ {
+ if (plib::container::contains(m_limit, argument))
+ {
+ m_val = argument;
+ return 0;
+ }
+ else
+ return 1;
+ }
+
+ int option_bool::parse(ATTR_UNUSED pstring argument)
+ {
+ m_val = true;
+ return 0;
+ }
+
+ int option_double::parse(pstring argument)
+ {
+ bool err = false;
+ m_val = argument.as_double(&err);
+ return (err ? 1 : 0);
+ }
+
+ options::options()
+ {
+
+ }
+
+ options::options(option *o[])
+ {
+ int i=0;
+ while (o[i] != nullptr)
+ {
+ m_opts.push_back(o[i]);
+ i++;
+ }
+ }
+
+ options::~options()
+ {
+ m_opts.clear();
+ }
+
+ void options::register_option(option *opt)
+ {
+ m_opts.push_back(opt);
+ }
+
+ int options::parse(int argc, char *argv[])
+ {
+ m_app = argv[0];
+
+ for (int i=1; i<argc; )
+ {
+ pstring arg(argv[i]);
+ option *opt = nullptr;
+ pstring opt_arg;
+ bool has_equal_arg = false;
+
+ if (arg.startsWith("--"))
+ {
+ auto v = pstring_vector_t(arg.substr(2),"=");
+ opt = getopt_long(v[0]);
+ has_equal_arg = (v.size() > 1);
+ if (has_equal_arg) opt_arg = v[1];
+ }
+ else if (arg.startsWith("-"))
+ {
+ opt = getopt_short(arg.substr(1));
+ }
+ else
+ return i;
+ if (opt == nullptr)
+ return i;
+ if (opt->has_argument())
+ {
+ if (has_equal_arg)
+ {
+ if (opt->parse(opt_arg) != 0)
+ return i;
+ }
+ else
+ {
+ i++; // FIXME: are there more arguments?
+ if (opt->parse(argv[i]) != 0)
+ return i - 1;
+ }
+ }
+ else
+ {
+ if (has_equal_arg)
+ return i;
+ opt->parse("");
+ }
+ i++;
+ }
+ return argc;
+ }
+
+ pstring options::split_paragraphs(pstring text, unsigned width, unsigned ident,
+ unsigned firstline_ident)
+ {
+ auto paragraphs = pstring_vector_t(text,"\n");
+ pstring ret("");
+
+ for (auto &p : paragraphs)
+ {
+ pstring line = pstring("").rpad(" ", firstline_ident);
+ for (auto &s : pstring_vector_t(p, " "))
+ {
+ if (line.len() + s.len() > width)
+ {
+ ret += line + "\n";
+ line = pstring("").rpad(" ", ident);
+ }
+ line += s + " ";
+ }
+ ret += line + "\n";
+ }
+ return ret;
+ }
+
+ pstring options::help(pstring description, pstring usage,
+ unsigned width, unsigned ident)
+ {
+ pstring ret;
+
+ ret = split_paragraphs(description, width, 0, 0) + "\n";
+ ret += "Usage:\t" + usage + "\n\nOptions:\n";
+
+ for (auto & opt : m_opts )
+ {
+ pstring line = "";
+ if (opt->short_opt() != "")
+ line += " -" + opt->short_opt();
+ if (opt->long_opt() != "")
+ {
+ if (line != "")
+ line += ", ";
+ else
+ line = " ";
+ line += "--" + opt->long_opt();
+ if (opt->has_argument())
+ {
+ line += "=";
+ option_str_limit *ol = dynamic_cast<option_str_limit *>(opt);
+ if (ol)
+ {
+ for (auto &v : ol->limit())
+ {
+ line += v + "|";
+ }
+ line = line.left(line.len() - 1);
+ }
+ else
+ line += "Value";
+ }
+ }
+ line = line.rpad(" ", 20) + " ";
+ if (line.len() > 21)
+ {
+ ret += line + "\n";
+ ret += split_paragraphs(opt->help(), 72, 21, 21);
+ }
+ else
+ ret += split_paragraphs(line + opt->help(), 72, 21, 0);
+ }
+ return ret;
+ }
+
+ option *options::getopt_short(pstring arg)
+ {
+ for (auto & opt : m_opts)
+ {
+ if (opt->short_opt() == arg)
+ return opt;
+ }
+ return nullptr;
+ }
+ option *options::getopt_long(pstring arg)
+ {
+ for (auto & opt : m_opts)
+ {
+ if (opt->long_opt() == arg)
+ return opt;
+ }
+ return nullptr;
+ }
+
+} // namespace plib
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h
index 3ab1adb78c6..6ddac682d66 100644
--- a/src/lib/netlist/plib/poptions.h
+++ b/src/lib/netlist/plib/poptions.h
@@ -27,35 +27,34 @@ class options;
class option
{
public:
- option()
- : m_short(""), m_long(""), m_help(""), m_has_argument(false)
- {}
-
- option(pstring ashort, pstring along, pstring help, bool has_argument, options *parent = nullptr);
+ option();
+ option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument);
- virtual ~option()
- {
- }
+ virtual ~option();
/* no_argument options will be called with "" argument */
- virtual int parse(ATTR_UNUSED pstring argument) { return 0; }
+ virtual int parse(ATTR_UNUSED pstring argument) = 0;
+ pstring short_opt() { return m_short; }
+ pstring long_opt() { return m_long; }
+ pstring help() { return m_help; }
+ bool has_argument() { return m_has_argument ; }
+private:
pstring m_short;
pstring m_long;
pstring m_help;
bool m_has_argument;
-private:
};
class option_str : public option
{
public:
- option_str(pstring ashort, pstring along, pstring defval, pstring help, options *parent = nullptr)
- : option(ashort, along, help, true, parent), m_val(defval)
+ option_str(options &parent, pstring ashort, pstring along, pstring defval, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval)
{}
- virtual int parse(pstring argument) override { m_val = argument; return 0; }
+ virtual int parse(pstring argument) override;
pstring operator ()() { return m_val; }
private:
@@ -65,22 +64,15 @@ private:
class option_str_limit : public option
{
public:
- option_str_limit(pstring ashort, pstring along, pstring defval, pstring limit, pstring help, options *parent = nullptr)
- : option(ashort, along, help, true, parent), m_val(defval), m_limit(limit, ":")
+ option_str_limit(options &parent, pstring ashort, pstring along, pstring defval, pstring limit, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval), m_limit(limit, ":")
{}
- virtual int parse(pstring argument) override
- {
- if (plib::container::contains(m_limit, argument))
- {
- m_val = argument;
- return 0;
- }
- else
- return 1;
- }
+ virtual int parse(pstring argument) override;
pstring operator ()() { return m_val; }
+ const plib::pstring_vector_t &limit() { return m_limit; }
+
private:
pstring m_val;
plib::pstring_vector_t m_limit;
@@ -89,11 +81,11 @@ private:
class option_bool : public option
{
public:
- option_bool(pstring ashort, pstring along, pstring help, options *parent = nullptr)
- : option(ashort, along, help, false, parent), m_val(false)
+ option_bool(options &parent, pstring ashort, pstring along, pstring help)
+ : option(parent, ashort, along, help, false), m_val(false)
{}
- virtual int parse(ATTR_UNUSED pstring argument) override { m_val = true; return 0; }
+ virtual int parse(ATTR_UNUSED pstring argument) override;
bool operator ()() { return m_val; }
private:
@@ -103,16 +95,11 @@ private:
class option_double : public option
{
public:
- option_double(pstring ashort, pstring along, double defval, pstring help, options *parent = nullptr)
- : option(ashort, along, help, true, parent), m_val(defval)
+ option_double(options &parent, pstring ashort, pstring along, double defval, pstring help)
+ : option(parent, ashort, along, help, true), m_val(defval)
{}
- virtual int parse(pstring argument) override
- {
- bool err = false;
- m_val = argument.as_double(&err);
- return (err ? 1 : 0);
- }
+ virtual int parse(pstring argument) override;
double operator ()() { return m_val; }
private:
@@ -123,117 +110,30 @@ class options
{
public:
- options() {}
-
- options(option *o[])
- {
- int i=0;
- while (o[i] != nullptr)
- {
- m_opts.push_back(o[i]);
- i++;
- }
- }
-
- ~options()
- {
- m_opts.clear();
- }
-
- void register_option(option *opt)
- {
- m_opts.push_back(opt);
- }
-
- int parse(int argc, char *argv[])
- {
- m_app = argv[0];
-
- for (int i=1; i<argc; )
- {
- pstring arg(argv[i]);
- option *opt = nullptr;
-
- if (arg.startsWith("--"))
- {
- opt = getopt_long(arg.substr(2));
- }
- else if (arg.startsWith("-"))
- {
- opt = getopt_short(arg.substr(1));
- }
- else
- return i;
- if (opt == nullptr)
- return i;
- if (opt->m_has_argument)
- {
- i++; // FIXME: are there more arguments?
- if (opt->parse(argv[i]) != 0)
- return i - 1;
- }
- else
- opt->parse("");
- i++;
- }
- return argc;
- }
-
- pstring help()
- {
- pstring ret;
-
- for (auto & opt : m_opts )
- {
- pstring line = "";
- if (opt->m_short != "")
- line += " -" + opt->m_short;
- if (opt->m_long != "")
- {
- if (line != "")
- line += ", ";
- else
- line = " ";
- line += "--" + opt->m_long;
- }
- line = line.rpad(" ", 20).cat(opt->m_help);
- ret = ret + line + "\n";
- }
- return ret;
- }
+ options();
+ options(option *o[]);
+
+ ~options();
+
+ void register_option(option *opt);
+ int parse(int argc, char *argv[]);
+
+ pstring help(pstring description, pstring usage,
+ unsigned width = 72, unsigned ident = 20);
+
pstring app() { return m_app; }
private:
+ static pstring split_paragraphs(pstring text, unsigned width, unsigned ident,
+ unsigned firstline_ident);
- option *getopt_short(pstring arg)
- {
- for (auto & opt : m_opts)
- {
- if (opt->m_short == arg)
- return opt;
- }
- return nullptr;
- }
- option *getopt_long(pstring arg)
- {
- for (auto & opt : m_opts)
- {
- if (opt->m_long == arg)
- return opt;
- }
- return nullptr;
- }
+ option *getopt_short(pstring arg);
+ option *getopt_long(pstring arg);
std::vector<option *> m_opts;
pstring m_app;
};
-option::option(pstring ashort, pstring along, pstring help, bool has_argument, options *parent)
-: m_short(ashort), m_long(along), m_help(help), m_has_argument(has_argument)
-{
- if (parent != nullptr)
- parent->register_option(this);
-}
}
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index f6dff95fb12..20573f5bfa5 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -258,7 +258,7 @@ const pstring_t<F> pstring_t<F>::rpad(const pstring_t &ws, const unsigned cnt) c
pstring_t ret(*this);
while (ret.len() < cnt)
ret += ws;
- return pstring_t(ret).substr(0, cnt);
+ return ret;
}
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 5687cd42078..8d753e212c6 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -26,16 +26,17 @@ class tool_options_t : public plib::options
public:
tool_options_t() :
plib::options(),
- opt_ttr ("t", "time_to_run", 1.0, "time to run the emulation (seconds)", this),
- opt_name("n", "name", "", "netlist in file to run; default is first one", this),
- opt_logs("l", "logs", "", "colon separated list of terminals to log", this),
- opt_file("f", "file", "-", "file to process (default is stdin)", this),
- opt_type("y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle", this),
- opt_cmd ("c", "cmd", "run", "run|convert|listdevices|static", this),
- opt_inp( "i", "input", "", "input file to process (default is none)", this),
- opt_verb("v", "verbose", "be verbose - this produces lots of output", this),
- opt_quiet("q", "quiet", "be quiet - no warnings", this),
- opt_help("h", "help", "display help", this)
+ opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"),
+ opt_name(*this, "n", "name", "", "netlist in file to run; default is first one"),
+ opt_logs(*this, "l", "logs", "", "colon separated list of terminals to log"),
+ opt_file(*this, "f", "file", "-", "file to process (default is stdin)"),
+ opt_type(*this, "y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle"),
+ opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static", "run|convert|listdevices|static"),
+ opt_inp(*this, "i", "input", "", "input file to process (default is none)"),
+ opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
+ opt_quiet(*this, "q", "quiet", "be quiet - no warnings"),
+ opt_version(*this, "", "version", "display version and exit"),
+ opt_help(*this, "h", "help", "display help and exit")
{}
plib::option_double opt_ttr;
@@ -43,10 +44,11 @@ public:
plib::option_str opt_logs;
plib::option_str opt_file;
plib::option_str_limit opt_type;
- plib::option_str opt_cmd;
+ plib::option_str_limit opt_cmd;
plib::option_str opt_inp;
plib::option_bool opt_verb;
plib::option_bool opt_quiet;
+ plib::option_bool opt_version;
plib::option_bool opt_help;
};
@@ -92,7 +94,8 @@ public:
{
// read the netlist ...
- m_setup->register_source(std::make_shared<netlist::source_file_t>(filename));
+ m_setup->register_source(plib::make_unique_base<netlist::source_t,
+ netlist::source_file_t>(filename));
m_setup->include(name);
log_setup();
@@ -133,14 +136,9 @@ private:
void usage(tool_options_t &opts)
{
- perr("{}",
- "Usage:\n"
- " nltool --help\n"
- " nltool [options]\n"
- "\n"
- "Where:\n"
- );
- perr("{}\n", opts.help().cstr());
+ pout("{}\n", opts.help(
+ "nltool serves as the Swiss Army knife to run, test and convert netlists.",
+ "nltool [options]").cstr());
}
struct input_t
@@ -207,7 +205,10 @@ std::vector<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
static void run(tool_options_t &opts)
{
netlist_tool_t nt("netlist");
- plib::ticks_t t = plib::ticks();
+ plib::chrono::timer<plib::chrono::system_ticks> t;
+ //plib::perftime_t<plib::exact_ticks> t;
+
+ t.start();
nt.m_opts = &opts;
nt.init();
@@ -222,10 +223,13 @@ static void run(tool_options_t &opts)
std::vector<input_t> *inps = read_input(&nt, opts.opt_inp());
double ttr = opts.opt_ttr();
+ t.stop();
- pout("startup time ==> {1:5.3f}\n", (double) (plib::ticks() - t) / (double) plib::ticks_per_second() );
+ pout("startup time ==> {1:5.3f}\n", t.as_seconds() );
pout("runnning ...\n");
- t = plib::ticks();
+
+ t.reset();
+ t.start();
unsigned pos = 0;
netlist::netlist_time nlt = netlist::netlist_time::zero();
@@ -241,7 +245,9 @@ static void run(tool_options_t &opts)
nt.stop();
plib::pfree(inps);
- double emutime = (double) (plib::ticks() - t) / (double) plib::ticks_per_second();
+ t.stop();
+
+ double emutime = t.as_seconds();
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", ttr, emutime, ttr/emutime*100.0);
}
@@ -273,7 +279,8 @@ static void listdevices()
nt.init();
netlist::factory_list_t &list = nt.setup().factory();
- nt.setup().register_source(std::make_shared<netlist::source_proc_t>("dummy", &netlist_dummy));
+ nt.setup().register_source(plib::make_unique_base<netlist::source_t,
+ netlist::source_proc_t>("dummy", &netlist_dummy));
nt.setup().include("dummy");
nt.setup().start_devices();
@@ -351,7 +358,7 @@ int main(int argc, char *argv[])
tool_options_t opts;
int ret;
- perr("{}", "WARNING: This is Work In Progress! - It may fail anytime\n");
+ //perr("{}", "WARNING: This is Work In Progress! - It may fail anytime\n");
//perr("Update dispatching using method {}\n", pmf_verbose[NL_PMF_TYPE]);
if ((ret = opts.parse(argc, argv)) != argc)
{
@@ -363,7 +370,19 @@ int main(int argc, char *argv[])
if (opts.opt_help())
{
usage(opts);
- return 1;
+ return 0;
+ }
+
+ if (opts.opt_version())
+ {
+ pout(
+ "nltool (netlist) 0.1\n"
+ "Copyright (C) 2016 Couriersud\n"
+ "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n\n"
+ "Written by Couriersud.\n");
+ return 0;
}
pstring cmd = opts.opt_cmd();
diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp
index d822b78d231..0f560cbe62d 100644
--- a/src/lib/netlist/prg/nlwav.cpp
+++ b/src/lib/netlist/prg/nlwav.cpp
@@ -13,21 +13,29 @@ class nlwav_options_t : public plib::options
public:
nlwav_options_t() :
plib::options(),
- opt_inp( "i", "input", "", "input file", this),
- opt_out( "o", "output", "", "output file", this),
- opt_amp( "a", "amp", 10000.0, "amplification after mean correction", this),
- opt_verb("v", "verbose", "be verbose - this produces lots of output", this),
- opt_quiet("q", "quiet", "be quiet - no warnings", this),
- opt_help("h", "help", "display help", this)
+ opt_inp(*this, "i", "input", "", "input file"),
+ opt_out(*this, "o", "output", "", "output file"),
+ opt_amp(*this, "a", "amp", 10000.0, "amplification after mean correction"),
+ opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"),
+ opt_quiet(*this,"q", "quiet", "be quiet - no warnings"),
+ opt_version(*this, "", "version", "display version and exit"),
+ opt_help(*this, "h", "help", "display help and exit")
{}
plib::option_str opt_inp;
plib::option_str opt_out;
plib::option_double opt_amp;
plib::option_bool opt_verb;
plib::option_bool opt_quiet;
+ plib::option_bool opt_version;
plib::option_bool opt_help;
};
+plib::pstdout pout_strm;
+plib::pstderr perr_strm;
+
+plib::pstream_fmt_writer_t pout(pout_strm);
+plib::pstream_fmt_writer_t perr(perr_strm);
+
/* http://de.wikipedia.org/wiki/RIFF_WAVE */
class wav_t
{
@@ -196,26 +204,20 @@ void convert(nlwav_options_t &opts)
//printf("%f %f\n", t, v);
#endif
}
- printf("Mean (low freq filter): %f\n", mean);
- printf("Mean (static): %f\n", means / (double) n);
- printf("Amp + %f\n", 32000.0 / (maxsam- mean));
- printf("Amp - %f\n", -32000.0 / (minsam- mean));
+ pout("Mean (low freq filter): {}\n", mean);
+ pout("Mean (static): {}\n", means / (double) n);
+ pout("Amp + {}\n", 32000.0 / (maxsam- mean));
+ pout("Amp - {}\n", -32000.0 / (minsam- mean));
wo.close();
fo.close();
fin.close();
}
-void usage(nlwav_options_t &opts)
+void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts)
{
- fprintf(stderr,
- "Usage:\n"
- " nltool -help\n"
- " nltool [options]\n"
- "\n"
- "Where:\n"
- );
- fprintf(stderr, "%s\n", opts.help().cstr());
+ fw("{}\n", opts.help("Convert netlist log files into wav files.\n",
+ "nltool [options]").cstr());
}
@@ -226,15 +228,27 @@ int main(int argc, char *argv[])
if ((ret = opts.parse(argc, argv)) != argc)
{
- fprintf(stderr, "Error parsing %s\n", argv[ret]);
- usage(opts);
+ perr("Error parsing {}\n", argv[ret]);
+ usage(perr, opts);
return 1;
}
if (opts.opt_help())
{
- usage(opts);
- return 1;
+ usage(pout, opts);
+ return 0;
+ }
+
+ if (opts.opt_version())
+ {
+ pout(
+ "nlwav (netlist) 0.1\n"
+ "Copyright (C) 2016 Couriersud\n"
+ "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n\n"
+ "Written by Couriersud.\n");
+ return 0;
}
convert(opts);
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 545377cc494..d8a7401018e 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -18,7 +18,7 @@
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
{
pstring pname = devname + "." + name;
- m_pins.insert({pname, plib::make_unique<pin_alias_t>(pname, devname + "." + alias)});
+ m_pins.emplace(pname, plib::make_unique<pin_alias_t>(pname, devname + "." + alias));
}
void nl_convert_base_t::add_ext_alias(const pstring &alias)
@@ -26,7 +26,7 @@ void nl_convert_base_t::add_ext_alias(const pstring &alias)
m_ext_alias.push_back(alias);
}
-void nl_convert_base_t::add_device(std::shared_ptr<dev_t> dev)
+void nl_convert_base_t::add_device(std::unique_ptr<dev_t> dev)
{
for (auto & d : m_devs)
if (d->name() == dev->name())
@@ -34,20 +34,20 @@ void nl_convert_base_t::add_device(std::shared_ptr<dev_t> dev)
out("ERROR: Duplicate device {1} ignored.", dev->name());
return;
}
- m_devs.push_back(dev);
+ m_devs.push_back(std::move(dev));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
{
- add_device(std::make_shared<dev_t>(atype, aname, amodel));
+ add_device(plib::make_unique<dev_t>(atype, aname, amodel));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
{
- add_device(std::make_shared<dev_t>(atype, aname, aval));
+ add_device(plib::make_unique<dev_t>(atype, aname, aval));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
{
- add_device(std::make_shared<dev_t>(atype, aname));
+ add_device(plib::make_unique<dev_t>(atype, aname));
}
void nl_convert_base_t::add_term(pstring netname, pstring termname)
@@ -58,9 +58,9 @@ void nl_convert_base_t::add_term(pstring netname, pstring termname)
net = m_nets[netname].get();
else
{
- auto nets = std::make_shared<net_t>(netname);
+ auto nets = plib::make_unique<net_t>(netname);
net = nets.get();
- m_nets.insert({netname, nets});
+ m_nets.emplace(netname, std::move(nets));
}
/* if there is a pin alias, translate ... */
@@ -84,10 +84,11 @@ void nl_convert_base_t::dump_nl()
net->set_no_export();
}
- std::vector<int> sorted;
- for (unsigned i=0; i < m_devs.size(); i++)
+ std::vector<size_t> sorted;
+ for (size_t i=0; i < m_devs.size(); i++)
sorted.push_back(i);
- std::sort(sorted.begin(), sorted.end(), plib::indexed_compare<std::vector<std::shared_ptr<dev_t>>>(m_devs));
+ std::sort(sorted.begin(), sorted.end(),
+ [&](size_t i1, size_t i2) { return m_devs[i1]->name() < m_devs[i2]->name(); });
for (std::size_t i=0; i<m_devs.size(); i++)
{
diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h
index a2e0dc99ecb..90bae5533eb 100644
--- a/src/lib/netlist/tools/nl_convert.h
+++ b/src/lib/netlist/tools/nl_convert.h
@@ -126,14 +126,14 @@ private:
private:
- void add_device(std::shared_ptr<dev_t> dev);
+ void add_device(std::unique_ptr<dev_t> dev);
plib::postringstream m_buf;
- std::vector<std::shared_ptr<dev_t>> m_devs;
- std::unordered_map<pstring, std::shared_ptr<net_t> > m_nets;
+ std::vector<std::unique_ptr<dev_t>> m_devs;
+ std::unordered_map<pstring, std::unique_ptr<net_t> > m_nets;
std::vector<pstring> m_ext_alias;
- std::unordered_map<pstring, std::shared_ptr<pin_alias_t>> m_pins;
+ std::unordered_map<pstring, std::unique_ptr<pin_alias_t>> m_pins;
static unit_t m_units[];
diff --git a/src/mame/machine/nl_breakout.cpp b/src/mame/machine/nl_breakout.cpp
index 1cfd879c91a..5920e8cf1a2 100644
--- a/src/mame/machine/nl_breakout.cpp
+++ b/src/mame/machine/nl_breakout.cpp
@@ -275,6 +275,7 @@ CIRCUIT_LAYOUT( breakout )
CHIP("H5", 9312)
CHIP("H6", 9310)
CHIP("H7", 7408) //sometimes looks like N7 on schematic
+ //PARAM(H7.USE_DEACTIVATE, 0)
CHIP("H8", 7474)
CHIP("H9", 7474)
@@ -1700,6 +1701,36 @@ CIRCUIT_LAYOUT( breakout )
NET_C(GND, D9.1, D9.2, D9.13, D9.3, D9.4, D9.5)
+ HINT(A3.1.sub, NO_DEACTIVATE)
+ HINT(B6.s3, NO_DEACTIVATE)
+ HINT(C4.s3, NO_DEACTIVATE)
+ HINT(C4.s4, NO_DEACTIVATE)
+ HINT(C5.s3, NO_DEACTIVATE)
+ HINT(C5.s4, NO_DEACTIVATE)
+ HINT(D3.2.sub, NO_DEACTIVATE)
+ HINT(E2.s2, NO_DEACTIVATE)
+ HINT(E3.s2, NO_DEACTIVATE)
+ HINT(E5.s4, NO_DEACTIVATE)
+ HINT(E8.2.sub, NO_DEACTIVATE)
+ HINT(E9.s6, NO_DEACTIVATE)
+ HINT(F5.2.sub, NO_DEACTIVATE)
+ HINT(H2.s1, NO_DEACTIVATE)
+ HINT(H3.s1, NO_DEACTIVATE)
+ HINT(H6.sub, NO_DEACTIVATE)
+ HINT(J3.s4, NO_DEACTIVATE)
+ HINT(J5, NO_DEACTIVATE)
+ HINT(J6.sub, NO_DEACTIVATE)
+ HINT(J8.1, NO_DEACTIVATE)
+ HINT(J8.3, NO_DEACTIVATE)
+ HINT(K4.s4, NO_DEACTIVATE)
+ HINT(M3.s2, NO_DEACTIVATE)
+ HINT(M3.s4, NO_DEACTIVATE)
+ HINT(M4.s2, NO_DEACTIVATE)
+ HINT(M6.sub, NO_DEACTIVATE)
+ HINT(M8.s1, NO_DEACTIVATE)
+ HINT(N6.sub, NO_DEACTIVATE)
+ HINT(N7.s3, NO_DEACTIVATE)
+
CIRCUIT_LAYOUT_END
/*
diff --git a/src/mame/machine/nl_pong.cpp b/src/mame/machine/nl_pong.cpp
index 456448ab067..d03ae825d78 100644
--- a/src/mame/machine/nl_pong.cpp
+++ b/src/mame/machine/nl_pong.cpp
@@ -27,7 +27,6 @@ NETLIST_START(pong_fast)
TTL_INPUT(high, 1)
TTL_INPUT(low, 0)
-#if 1
#if (FAST_CLOCK)
/* abstracting this, performance increases by 60%
* No surprise, the clock is extremely expensive */
@@ -38,12 +37,6 @@ NETLIST_START(pong_fast)
TTL_74107(ic_f6a, xclk, high, high, high)
ALIAS(clk, ic_f6a.Q)
#endif
-#else
- // benchmarking ...
- NETDEV_TTL_CONST(clk, 0)
- MAINCLOCK(xclk)
- PARAM(xclk.FREQ, 7159000.0*2)
-#endif
/* 3V Logic - Just a resistor - the value is not given in schematics */
@@ -577,5 +570,41 @@ NETLIST_START(pong_fast)
NET_C(RV2.2, RV3.2)
ALIAS(videomix, RV3.2)
+#if 1
+ HINT(clk, NO_DEACTIVATE)
+ HINT(ic_e1d, NO_DEACTIVATE)
+ HINT(ic_e1c, NO_DEACTIVATE)
+ HINT(ic_f1.A, NO_DEACTIVATE)
+ HINT(ic_f1.D, NO_DEACTIVATE)
+ HINT(ic_g1d, NO_DEACTIVATE)
+ HINT(ic_h1a, NO_DEACTIVATE)
+ HINT(ic_h1d, NO_DEACTIVATE)
+ HINT(ic_h3b.sub, NO_DEACTIVATE)
+ HINT(ic_g6b.sub, NO_DEACTIVATE)
+ HINT(ic_c2a.sub, NO_DEACTIVATE)
+ HINT(hit_sound, NO_DEACTIVATE)
+ HINT(topbothitsound, NO_DEACTIVATE)
+ HINT(ic_c9b, NO_DEACTIVATE)
+ HINT(ic_b8.D, NO_DEACTIVATE)
+ HINT(ic_b7a, NO_DEACTIVATE)
+ HINT(ic_a7b, NO_DEACTIVATE)
+ HINT(ic_c9a, NO_DEACTIVATE)
+ HINT(ic_a8.D, NO_DEACTIVATE)
+ HINT(ic_b7d, NO_DEACTIVATE)
+ HINT(ic_a7a, NO_DEACTIVATE)
+ HINT(ic_g1a, NO_DEACTIVATE)
+ HINT(ic_c8a.sub, NO_DEACTIVATE)
+ HINT(ic_c8b.sub, NO_DEACTIVATE)
+ HINT(ic_d8b, NO_DEACTIVATE)
+ HINT(ic_d6a.sub, NO_DEACTIVATE)
+ HINT(ic_d6b.sub, NO_DEACTIVATE)
+ HINT(ic_c6a.sub, NO_DEACTIVATE)
+ HINT(ic_c6b.sub, NO_DEACTIVATE)
+ HINT(ic_e5b, NO_DEACTIVATE)
+ HINT(ic_e4c, NO_DEACTIVATE)
+ HINT(ic_d4b, NO_DEACTIVATE)
+ HINT(ic_g1b, NO_DEACTIVATE)
+#endif
+
NETLIST_END()