summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/netlist/analog/nld_mosfet.cpp12
-rw-r--r--src/lib/netlist/build/cspell.json25
-rw-r--r--src/lib/netlist/build/makefile20
-rw-r--r--src/lib/netlist/core/base_objects.h40
-rw-r--r--src/lib/netlist/core/core_device.h59
-rw-r--r--src/lib/netlist/core/device.h21
-rw-r--r--src/lib/netlist/core/devices.h3
-rw-r--r--src/lib/netlist/core/exec.h25
-rw-r--r--src/lib/netlist/core/logic.h19
-rw-r--r--src/lib/netlist/core/logic_family.h15
-rw-r--r--src/lib/netlist/core/netlist_state.h8
-rw-r--r--src/lib/netlist/core/nets.h351
-rw-r--r--src/lib/netlist/core/object_array.h4
-rw-r--r--src/lib/netlist/core/param.h4
-rw-r--r--src/lib/netlist/core/queue.h20
-rw-r--r--src/lib/netlist/core/setup.h7
-rw-r--r--src/lib/netlist/core/state_var.h5
-rw-r--r--src/lib/netlist/devices/nld_74107.cpp8
-rw-r--r--src/lib/netlist/devices/nld_7474.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7490.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7492.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7493.cpp10
-rw-r--r--src/lib/netlist/devices/nld_ne555.cpp38
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.cpp125
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.h2
-rw-r--r--src/lib/netlist/nl_base.cpp336
-rw-r--r--src/lib/netlist/nl_config.h90
-rw-r--r--src/lib/netlist/nl_parser.cpp964
-rw-r--r--src/lib/netlist/nl_setup.cpp2079
-rw-r--r--src/lib/netlist/nl_setup.h8
-rw-r--r--src/lib/netlist/plib/parray.h8
-rw-r--r--src/lib/netlist/plib/pchrono.h25
-rw-r--r--src/lib/netlist/plib/penum.h2
-rw-r--r--src/lib/netlist/plib/pexception.cpp26
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp2
-rw-r--r--src/lib/netlist/plib/pfmtlog.h86
-rw-r--r--src/lib/netlist/plib/pfunction.cpp14
-rw-r--r--src/lib/netlist/plib/pgsl.h3
-rw-r--r--src/lib/netlist/plib/plists.h142
-rw-r--r--src/lib/netlist/plib/pmain.h2
-rw-r--r--src/lib/netlist/plib/pmatrix_cr.h32
-rw-r--r--src/lib/netlist/plib/pmulti_threading.h4
-rw-r--r--src/lib/netlist/plib/prandom.h2
-rw-r--r--src/lib/netlist/plib/pstate.h4
-rw-r--r--src/lib/netlist/plib/pstream.h2
-rw-r--r--src/lib/netlist/plib/ptime.h4
-rw-r--r--src/lib/netlist/plib/ptimed_queue.h264
-rw-r--r--src/lib/netlist/plib/ptokenizer.cpp2
-rw-r--r--src/lib/netlist/plib/ptypes.h6
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp34
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h10
-rw-r--r--src/lib/netlist/solver/nld_ms_direct_lu.h83
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h8
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp12
-rw-r--r--src/lib/netlist/solver/nld_solver.h2
-rw-r--r--src/lib/netlist/tests/test_penum.cpp14
-rw-r--r--src/lib/netlist/tests/test_precommit.cpp5
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp16
58 files changed, 2691 insertions, 2427 deletions
diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp
index b8d4454d206..46dead610ca 100644
--- a/src/lib/netlist/analog/nld_mosfet.cpp
+++ b/src/lib/netlist/analog/nld_mosfet.cpp
@@ -543,8 +543,8 @@ namespace analog
const nl_fptype gbs = nlconst::zero();
#endif
// exchange controlling nodes if necessary
- const nl_fptype gsource = is_forward ? (gm + gmb) : nlconst::zero();
- const nl_fptype gdrain = is_forward ? nlconst::zero() : (gm + gmb);
+ const nl_fptype gate_source = is_forward ? (gm + gmb) : nlconst::zero();
+ const nl_fptype gate_drain = is_forward ? nlconst::zero() : (gm + gmb);
const nl_fptype IeqDS = (is_forward) ?
Ids - gm * Vgs - gmb * Vbs - gds * Vds
@@ -562,13 +562,13 @@ namespace analog
nl_fptype gGB = nlconst::zero();
nl_fptype gDG = gm;
- nl_fptype gDD = gds + gbd - gdrain;
- const nl_fptype gDS = -gds - gsource;
+ nl_fptype gDD = gds + gbd - gate_drain;
+ const nl_fptype gDS = -gds - gate_source;
const nl_fptype gDB = gmb - gbd;
nl_fptype gSG = -gm;
- const nl_fptype gSD = -gds + gdrain;
- nl_fptype gSS = gbs + gds + gsource;
+ const nl_fptype gSD = -gds + gate_drain;
+ nl_fptype gSS = gbs + gds + gate_source;
const nl_fptype gSB = -gbs - gmb;
nl_fptype gBG = nlconst::zero();
diff --git a/src/lib/netlist/build/cspell.json b/src/lib/netlist/build/cspell.json
index 43e72035b64..f242083ac82 100644
--- a/src/lib/netlist/build/cspell.json
+++ b/src/lib/netlist/build/cspell.json
@@ -31,8 +31,30 @@
"nmos",
"opamp",
"opamps",
- "pmos",
"picosecond",
+ "pmos",
+ // Physics
+ "atto",
+ "centi",
+ "deca",
+ "femto",
+ "giga",
+ "hecto",
+ "peta",
+ "tera",
+ "yocto",
+ "yotta",
+ "zepto",
+ "zetta",
+ // Software
+ "kicad",
+ // C library functions / definitions
+ "feenableexcept",
+ "fedisableexcept",
+ // asm
+ "rdtsc",
+ "rdtscp",
+ "cpuid",
// Specific project terms
"MAME",
"Couriersud",
@@ -43,6 +65,7 @@
"nvcc",
"lfsr",
"gmres",
+ "nlmod_",
// FIXME: Remove everything below here again
// Excluded for now ... Still over 1000 in the log
"plib", // namespace
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index d0b13693686..91ae7140acf 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -49,6 +49,7 @@ TIDY_FLAGSX += -readability-implicit-bool-conversion,
TIDY_FLAGSX += -readability-named-parameter,-readability-function-size,
TIDY_FLAGSX += -llvmlibc-restrict-system-libc-headers,-llvmlibc-implementation-in-namespace,-llvmlibc-callee-namespace,
TIDY_FLAGSX += -modernize-use-nodiscard,
+TIDY_FLAGSX += -modernize-use-auto,
#TIDY_FLAGSX += -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
#TIDY_FLAGSX += -cppcoreguidelines-prefer-member-initializer,
#TIDY_FLAGSX += -modernize-use-transparent-functors,
@@ -103,6 +104,7 @@ MD = @mkdir
RM = @rm
endif
+CSPELL=cspell
PYTHON=@python
TIDY_DB = $(OBJ)/compile_commands.json
@@ -289,10 +291,6 @@ native:
gcc9:
$(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -Wall -pedantic -Wpedantic -fext-numeric-literals -Wsign-compare -Wextra" EXTRALIBS="-lquadmath" OBJ=obj/gcc9
-emsdk:
- emmake $(MAKE) CC=emcc LD=emcc CEXTRAFLAGS="-fexceptions -msimd128" LDEXTRAFLAGS="-s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -fexceptions -msimd128 --emrun --embed-file ../../../mame/machine/nl_pong.cpp@nl_pong.cpp --embed-file ../../../mame/audio/nl_kidniki.cpp@nl_kidniki.cpp" OBJ=obj/emsdk EXESUFFIX=.html
- # LDFLAGS -s ASSERTIONS=1
-
clang:
#$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
$(MAKE) CC=clang++-13 LD=clang++-13 OBJ=obj/clang CEXTRAFLAGS="-march=native \
@@ -343,6 +341,14 @@ mingw-cross:
LDEXTRAFLAGS="-Wl,--subsystem,console -municode" OBJ=obj/mingw-cross \
EXESUFFIX=.exe LIBS=
+#
+# run with emrun --browser chrome nltool.html -c run -t 10 -n kidniki nl_kidniki.cpp
+#
+emsdk:
+ emmake $(MAKE) CC=emcc LD=emcc CEXTRAFLAGS="-fexceptions -msimd128" LDEXTRAFLAGS="-s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -fexceptions -msimd128 --emrun --embed-file ../../../mame/machine/nl_pongf.cpp@nl_pongf.cpp --embed-file ../../../mame/audio/nl_kidniki.cpp@nl_kidniki.cpp" OBJ=obj/emsdk EXESUFFIX=.html
+ # LDFLAGS -s ASSERTIONS=1
+
+
#-------------------------------------------------
# regression tests
#-------------------------------------------------
@@ -365,8 +371,8 @@ doc:
$(DOXYGEN) doxygen.conf
cspell:
- cd .. && cspell -c build/cspell.json --no-color --locale en-GB --relative $(patsubst $(SRC)/%, %, $(ALLHEADERS) ) | sed -e "s/ - Unknown/: error: Unknown/g"
- #cd .. && cspell -c build/cspell.json --no-color --locale en-GB --relative $(patsubst $(SRC)/%, %, $(ALLHEADERS) $(ALLSOURCES)) | sed -e "s/ - Unknown/: error: Unknown/g"
+ #cd .. && cspell -c build/cspell.json --no-color --locale en-GB --relative $(patsubst $(SRC)/%, %, $(ALLHEADERS) ) | sed -e "s/ - Unknown/: error: Unknown/g"
+ cd .. && $(CSPELL) -c build/cspell.json --no-color --locale en-GB --relative $(patsubst $(SRC)/%, %, $(ALLHEADERS) $(ALLSOURCES)) | sed -e "s/ - Unknown/: error: Unknown/g"
#-------------------------------------------------
# depends
@@ -420,7 +426,7 @@ fix_permissions:
srcclean: $(ALLSOURCES) $(ALLHEADERS)
@../../../../srcclean -u $(ALLSOURCES) $(ALLHEADERS)
-precommit: fix_permissions srcclean
+precommit: fix_permissions srcclean all runtests
#-------------------------------------------------
# clang tidy
diff --git a/src/lib/netlist/core/base_objects.h b/src/lib/netlist/core/base_objects.h
index 20fce1c91ca..782d94cf572 100644
--- a/src/lib/netlist/core/base_objects.h
+++ b/src/lib/netlist/core/base_objects.h
@@ -58,8 +58,8 @@ namespace netlist::detail {
static store_type &store() noexcept
{
- static store_type lstore;
- return lstore;
+ static store_type static_store;
+ return static_store;
}
};
@@ -131,8 +131,8 @@ namespace netlist::detail {
netlist_state_t & state() noexcept;
const netlist_state_t & state() const noexcept;
- netlist_t & exec() noexcept { return m_netlist; }
- const netlist_t & exec() const noexcept { return m_netlist; }
+ constexpr netlist_t & exec() noexcept { return m_netlist; }
+ constexpr const netlist_t & exec() const noexcept { return m_netlist; }
// to ease template design
template <typename T, typename... Args>
@@ -192,14 +192,17 @@ namespace netlist::detail {
///
/// All terminals are derived from this class.
///
- class core_terminal_t : public device_object_t,
- public plib::linked_list_t<core_terminal_t>::element_t
+ class core_terminal_t : public device_object_t
+ , public plib::linked_list_t<core_terminal_t, 0>::element_t
+#if NL_USE_INPLACE_CORE_TERMS
+ , public plib::linked_list_t<core_terminal_t, 1>::element_t
+#endif
{
public:
/// \brief Number of signal bits
///
/// Going forward setting this to 8 will allow 8-bit signal
- /// busses to be used in netlist, e.g. for more complex memory
+ /// buses to be used in netlist, e.g. for more complex memory
/// arrangements.
/// Minimum value is 2 here to support tristate output on proxies.
static constexpr const unsigned int INP_BITS = 2;
@@ -240,7 +243,7 @@ namespace netlist::detail {
void clear_net() noexcept { m_net = nullptr; }
constexpr bool has_net() const noexcept { return (m_net != nullptr); }
- net_t & net() const noexcept { return *m_net;}
+ constexpr net_t & net() const noexcept { return *m_net;}
bool is_logic() const noexcept;
bool is_logic_input() const noexcept;
@@ -250,25 +253,26 @@ namespace netlist::detail {
bool is_analog_input() const noexcept;
bool is_analog_output() const noexcept;
- constexpr bool is_state(state_e astate) const noexcept { return (m_state == astate); }
- constexpr const state_e &terminal_state() const noexcept { return m_state; }
- void set_state(state_e astate) noexcept { m_state = astate; }
+ constexpr bool is_state(state_e state) const noexcept { return (m_state == state); }
+ constexpr state_e terminal_state() const noexcept { return m_state; }
+ constexpr void set_state(state_e state) noexcept { m_state = state; }
void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
-#if NL_USE_COPY_INSTEAD_OF_REFERENCE
- void set_copied_input(netlist_sig_t val) noexcept
+ constexpr void set_copied_input([[maybe_unused]] netlist_sig_t val) noexcept
{
- m_Q = val;
+ if constexpr (config::use_copy_instead_of_reference::value)
+ {
+ m_Q_CIR = val;
+ }
}
- state_var_sig m_Q;
-#else
- void set_copied_input([[maybe_unused]] const netlist_sig_t &val) const noexcept { } // NOLINT: static means more message elsewhere
-#endif
void set_delegate(const nl_delegate &delegate) noexcept { m_delegate = delegate; }
const nl_delegate &delegate() const noexcept { return m_delegate; }
void run_delegate() const noexcept { return m_delegate(); }
+ protected:
+ //std::conditional_t<config::use_copy_instead_of_reference::value, state_var_sig, void *> m_Q;
+ state_var_sig m_Q_CIR;
private:
nl_delegate m_delegate;
net_t * m_net;
diff --git a/src/lib/netlist/core/core_device.h b/src/lib/netlist/core/core_device.h
index f7f05427f54..b81835b716e 100644
--- a/src/lib/netlist/core/core_device.h
+++ b/src/lib/netlist/core/core_device.h
@@ -25,35 +25,16 @@ namespace netlist
core_device_t(netlist_state_t &owner, const pstring &name);
core_device_t(core_device_t &owner, const pstring &name);
- PCOPYASSIGNMOVE(core_device_t, delete)
+ core_device_t(const core_device_t &) = delete;
+ core_device_t &operator=(const core_device_t &) = delete;
+ core_device_t(core_device_t &&) noexcept = delete;
+ core_device_t &operator=(core_device_t &&) noexcept = delete;
virtual ~core_device_t() noexcept = default;
- void do_inc_active() noexcept
- {
- gsl_Expects(m_active_outputs >= 0);
-
- if (!m_activate.isnull() && m_hint_deactivate)
- {
- if (++m_active_outputs == 1)
- {
- if (m_stats)
- m_stats->m_stat_inc_active.inc();
- m_activate(true);//inc_active();
- }
- }
- }
+ void do_inc_active() noexcept;
- void do_dec_active() noexcept
- {
- gsl_Expects(m_active_outputs >= 1);
-
- if (!m_activate.isnull() && m_hint_deactivate)
- if (--m_active_outputs == 0)
- {
- m_activate(false); //dec_active();
- }
- }
+ void do_dec_active() noexcept;
void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; }
bool get_hint_deactivate() const noexcept { return m_hint_deactivate; }
@@ -94,11 +75,39 @@ namespace netlist
virtual bool is_time_step() const noexcept { return false; }
private:
+ // FIXME: should this be a state_var?
bool m_hint_deactivate;
state_var_s32 m_active_outputs;
device_arena::unique_ptr<stats_t> m_stats;
};
+ inline void core_device_t::do_inc_active() noexcept
+ {
+ gsl_Expects(m_active_outputs >= 0);
+
+ if (!m_activate.isnull() && m_hint_deactivate)
+ {
+ if (++m_active_outputs == 1)
+ {
+ if (m_stats)
+ m_stats->m_stat_inc_active.inc();
+ m_activate(true);//inc_active();
+ }
+ }
+ }
+
+ inline void core_device_t::do_dec_active() noexcept
+ {
+ gsl_Expects(m_active_outputs >= 1);
+
+ if (!m_activate.isnull() && m_hint_deactivate)
+ if (--m_active_outputs == 0)
+ {
+ m_activate(false); //dec_active();
+ }
+ }
+
+
// -----------------------------------------------------------------------------
// base_device_t
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/core/device.h b/src/lib/netlist/core/device.h
index 74486a2dc80..33a1bdaac35 100644
--- a/src/lib/netlist/core/device.h
+++ b/src/lib/netlist/core/device.h
@@ -33,11 +33,30 @@ namespace netlist
device_t(device_t &owner, const pstring &name,
const pstring &model);
- PCOPYASSIGNMOVE(device_t, delete)
+ device_t(const device_t &) = delete;
+ device_t &operator=(const device_t &) = delete;
+ device_t(device_t &&) noexcept = delete;
+ device_t &operator=(device_t &&) noexcept = delete;
~device_t() noexcept override = default;
protected:
+ template <typename T1, typename T2>
+ void push_two(T1 &term1, netlist_sig_t newQ1, const netlist_time &delay1,
+ T2 &term2, netlist_sig_t newQ2, const netlist_time &delay2) noexcept
+ {
+ if (delay2 < delay1)
+ {
+ term1.push(newQ1, delay1);
+ term2.push(newQ2, delay2);
+ }
+ else
+ {
+ term2.push(newQ2, delay2);
+ term1.push(newQ1, delay1);
+ }
+ }
+
//NETLIB_UPDATE_TERMINALSI() { }
private:
diff --git a/src/lib/netlist/core/devices.h b/src/lib/netlist/core/devices.h
index 52e33b7d96c..07c82be20da 100644
--- a/src/lib/netlist/core/devices.h
+++ b/src/lib/netlist/core/devices.h
@@ -136,6 +136,9 @@ namespace netlist::devices
// -----------------------------------------------------------------------------
// nld_nc_pin
+ //
+ // FIXME: This needs to optimized
+ // The input can be in de-activated state.
// -----------------------------------------------------------------------------
NETLIB_OBJECT(nc_pin)
diff --git a/src/lib/netlist/core/exec.h b/src/lib/netlist/core/exec.h
index 83a41239d91..70786d420e6 100644
--- a/src/lib/netlist/core/exec.h
+++ b/src/lib/netlist/core/exec.h
@@ -27,39 +27,42 @@ namespace netlist
explicit netlist_t(netlist_state_t &state, const pstring &aname);
- PCOPYASSIGNMOVE(netlist_t, delete)
+ netlist_t(const netlist_t &) = delete;
+ netlist_t &operator=(const netlist_t &) = delete;
+ netlist_t(netlist_t &&) noexcept = delete;
+ netlist_t &operator=(netlist_t &&) noexcept = delete;
virtual ~netlist_t() noexcept = default;
// run functions
- const netlist_time_ext &time() const noexcept { return m_time; }
+ constexpr const netlist_time_ext &time() const noexcept { return m_time; }
void process_queue(netlist_time_ext delta) noexcept;
void abort_current_queue_slice() noexcept
{
- qremove(nullptr);
- qpush(m_time, nullptr);
+ queue_remove(nullptr);
+ queue_push(m_time, nullptr);
}
- const detail::queue_t &queue() const noexcept { return m_queue; }
+ constexpr const detail::queue_t &queue() const noexcept { return m_queue; }
template <typename... Args>
- void qpush(Args&&...args) noexcept
+ void queue_push(Args&&...args) noexcept
{
if (config::use_queue_stats::value && m_use_stats)
- m_queue.emplace<false>(std::forward<Args>(args)...); // NOLINT(performance-move-const-arg)
- else
m_queue.emplace<true>(std::forward<Args>(args)...); // NOLINT(performance-move-const-arg)
+ else
+ m_queue.emplace<false>(std::forward<Args>(args)...); // NOLINT(performance-move-const-arg)
}
template <class R>
- void qremove(const R &elem) noexcept
+ void queue_remove(R &&elem) noexcept
{
if (config::use_queue_stats::value && m_use_stats)
- m_queue.remove<true>(elem);
+ m_queue.remove<true>(std::forward<R>(elem));
else
- m_queue.remove<false>(elem);
+ m_queue.remove<false>(std::forward<R>(elem));
}
// Control functions
diff --git a/src/lib/netlist/core/logic.h b/src/lib/netlist/core/logic.h
index fef1f848052..2efa92d8f6d 100644
--- a/src/lib/netlist/core/logic.h
+++ b/src/lib/netlist/core/logic.h
@@ -36,7 +36,7 @@ namespace netlist
{
return plib::downcast<logic_net_t &>(core_terminal_t::net());
}
- const logic_net_t & net() const noexcept
+ constexpr const logic_net_t & net() const noexcept
{
return plib::downcast<const logic_net_t &>(core_terminal_t::net());
}
@@ -52,14 +52,14 @@ namespace netlist
logic_input_t(device_t &dev, const pstring &aname,
nl_delegate delegate);
- const netlist_sig_t &operator()() const noexcept
+ //const netlist_sig_t &operator()() const noexcept
+ constexpr netlist_sig_t operator()() const noexcept
{
gsl_Expects(terminal_state() != STATE_INP_PASSIVE);
- #if NL_USE_COPY_INSTEAD_OF_REFERENCE
- return m_Q;
- #else
- return net().Q();
- #endif
+ if constexpr (config::use_copy_instead_of_reference::value)
+ return m_Q_CIR;
+ else
+ return net().Q();
}
void inactivate() noexcept
@@ -97,6 +97,7 @@ namespace netlist
set_state(STATE_INP_LH);
}
}
+
};
// -----------------------------------------------------------------------------
@@ -120,14 +121,14 @@ namespace netlist
void initial(netlist_sig_t val) noexcept;
- void push(const netlist_sig_t &newQ, const netlist_time &delay) noexcept
+ void push(netlist_sig_t newQ, const netlist_time &delay) noexcept
{
gsl_Expects(delay >= netlist_time::zero());
m_my_net.set_Q_and_push(newQ, delay); // take the shortcut
}
- void set_Q_time(const netlist_sig_t &newQ, const netlist_time_ext &at) noexcept
+ void set_Q_time(netlist_sig_t newQ, const netlist_time_ext &at) noexcept
{
m_my_net.set_Q_time(newQ, at); // take the shortcut
}
diff --git a/src/lib/netlist/core/logic_family.h b/src/lib/netlist/core/logic_family.h
index 5a225a11c3e..7264987b466 100644
--- a/src/lib/netlist/core/logic_family.h
+++ b/src/lib/netlist/core/logic_family.h
@@ -25,7 +25,12 @@ namespace netlist
{
}
- PCOPYASSIGNMOVE(logic_family_desc_t, delete)
+ logic_family_desc_t(const logic_family_desc_t &) = delete;
+ logic_family_desc_t &operator=(const logic_family_desc_t &) = delete;
+
+ // FOXME: Should be move constructible
+ logic_family_desc_t(logic_family_desc_t &&) noexcept = delete;
+ logic_family_desc_t &operator=(logic_family_desc_t &&) noexcept = delete;
virtual ~logic_family_desc_t() noexcept = default;
@@ -76,7 +81,13 @@ namespace netlist
public:
logic_family_t() : m_logic_family(nullptr) {}
logic_family_t(const logic_family_desc_t *d) : m_logic_family(d) {}
- PCOPYASSIGNMOVE(logic_family_t, delete)
+
+ logic_family_t(const logic_family_t &) = delete;
+ logic_family_t &operator=(const logic_family_t &) = delete;
+
+ // FIXME: logic family can be move constructible.
+ logic_family_t(logic_family_t &&) noexcept = delete;
+ logic_family_t &operator=(logic_family_t &&) noexcept = delete;
const logic_family_desc_t *logic_family() const noexcept { return m_logic_family; }
void set_logic_family(const logic_family_desc_t *fam) noexcept { m_logic_family = fam; }
diff --git a/src/lib/netlist/core/netlist_state.h b/src/lib/netlist/core/netlist_state.h
index 5e8ae4567ec..0f0b62f8bee 100644
--- a/src/lib/netlist/core/netlist_state.h
+++ b/src/lib/netlist/core/netlist_state.h
@@ -235,12 +235,12 @@ namespace netlist
/// \brief prior to running free no longer needed resources
///
void free_setup_resources();
-
- std::vector<detail::core_terminal_t *> &core_terms(const detail::net_t &net) noexcept
+#if !(NL_USE_INPLACE_CORE_TERMS)
+ std::vector<detail::core_terminal_t *> &core_terms(const detail::net_t &net)
{
return m_core_terms[&net];
}
-
+#endif
private:
device_arena m_pool; // must be deleted last!
@@ -258,8 +258,10 @@ namespace netlist
devices_collection_type m_devices;
// sole use is to manage lifetime of family objects
family_collection_type m_family_cache;
+#if !(NL_USE_INPLACE_CORE_TERMS)
// all terms for a net
std::unordered_map<const detail::net_t *, std::vector<detail::core_terminal_t *>> m_core_terms;
+#endif
// dummy version
int m_dummy_version;
};
diff --git a/src/lib/netlist/core/nets.h b/src/lib/netlist/core/nets.h
index a121f261a50..280cda2013e 100644
--- a/src/lib/netlist/core/nets.h
+++ b/src/lib/netlist/core/nets.h
@@ -17,13 +17,10 @@
#include "../plib/plists.h"
#include "../plib/pstring.h"
-#ifndef AVOID_NOOP_QUEUE_PUSHES
-#error AVOID_NOOP_QUEUE_PUSHES not defined
-#endif
+#include <algorithm>
namespace netlist
{
-
namespace detail {
// -----------------------------------------------------------------------------
@@ -43,7 +40,10 @@ namespace netlist
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *rail_terminal = nullptr);
- PCOPYASSIGNMOVE(net_t, delete)
+ net_t(const net_t &) = delete;
+ net_t &operator=(const net_t &) = delete;
+ net_t(net_t &&) noexcept = delete;
+ net_t &operator=(net_t &&) noexcept = delete;
virtual ~net_t() noexcept = default;
@@ -55,7 +55,10 @@ namespace netlist
// Any changes below will impact performance.
// -----------------------------------------------------------------------------
- void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
+ constexpr void toggle_new_Q() noexcept
+ {
+ m_new_Q = (m_cur_Q ^ 1);
+ }
void toggle_and_push_to_queue(const netlist_time &delay) noexcept
{
@@ -63,133 +66,28 @@ namespace netlist
push_to_queue(delay);
}
- void push_to_queue(const netlist_time &delay) noexcept
- {
- if (!!is_queued())
- exec().qremove(this);
+ void push_to_queue(const netlist_time &delay) noexcept;
- m_next_scheduled_time = exec().time() + delay;
-#if (AVOID_NOOP_QUEUE_PUSHES)
- m_in_queue = (m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE
- : (m_new_Q != m_cur_Q ? queue_status::QUEUED : queue_status::DELIVERED));
- if (m_in_queue == queue_status::QUEUED)
- exec().qpush(m_next_scheduled_time, this);
- else
- update_inputs();
-#else
- m_in_queue = m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE : queue_status::QUEUED;
- if (m_in_queue == queue_status::QUEUED)
- exec().qpush(m_next_scheduled_time, this);
- else
- update_inputs();
-#endif
+ constexpr bool is_queued() const noexcept
+ {
+ return m_in_queue == queue_status::QUEUED;
}
- constexpr bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
// -----------------------------------------------------------------------------
// Very hot
// -----------------------------------------------------------------------------
template <bool KEEP_STATS>
- void update_devs() noexcept
- {
- gsl_Expects(this->is_rail_net());
-
- m_in_queue = queue_status::DELIVERED; // mark as taken ...
-
- const netlist_sig_t new_Q(m_new_Q);
- const netlist_sig_t cur_Q(m_cur_Q);
-#if (!AVOID_NOOP_QUEUE_PUSHES)
- if (new_Q ^ cur_Q)
-#endif
- {
- const auto mask = (new_Q << core_terminal_t::INP_LH_SHIFT)
- | (cur_Q << core_terminal_t::INP_HL_SHIFT);
- m_cur_Q = new_Q;
-
- if (!KEEP_STATS)
- {
- for (auto &p : m_list_active)
- {
- p.set_copied_input(new_Q);
- if ((p.terminal_state() & mask) != 0)
- p.run_delegate();
- }
- }
- else
- {
- for (auto & p : m_list_active)
- {
- p.set_copied_input(new_Q);
- auto *stats(p.device().stats());
- stats->m_stat_call_count.inc();
- if ((p.terminal_state() & mask))
- {
- auto g(stats->m_stat_total_time.guard());
- p.run_delegate();
- }
- }
- }
- }
- }
+ void update_devs() noexcept;
constexpr const netlist_time_ext &next_scheduled_time() const noexcept { return m_next_scheduled_time; }
- void set_next_scheduled_time(netlist_time_ext next_time) noexcept { m_next_scheduled_time = next_time; }
+ void set_next_scheduled_time(const netlist_time_ext &next_time) noexcept { m_next_scheduled_time = next_time; }
bool is_rail_net() const noexcept { return !(m_rail_terminal == nullptr); }
core_terminal_t & rail_terminal() const noexcept { return *m_rail_terminal; }
- void add_to_active_list(core_terminal_t &term) noexcept
- {
- if (!m_list_active.empty())
- {
- term.set_copied_input(m_cur_Q);
- m_list_active.push_front(&term);
- }
- else
- {
- m_list_active.push_front(&term);
- rail_terminal().device().do_inc_active();
- if (m_in_queue == queue_status::DELAYED_DUE_TO_INACTIVE)
- {
-#if (AVOID_NOOP_QUEUE_PUSHES)
- if (m_next_scheduled_time > exec().time()
- && (m_cur_Q != m_new_Q))
-#else
- if (m_next_scheduled_time > exec().time())
-#endif
- {
- m_in_queue = queue_status::QUEUED; // pending
- exec().qpush(m_next_scheduled_time, this);
- }
- else
- {
- m_in_queue = queue_status::DELIVERED;
- m_cur_Q = m_new_Q;
- }
- update_inputs();
- }
- else
- term.set_copied_input(m_cur_Q);
- }
- }
-
- void remove_from_active_list(core_terminal_t &term) noexcept
- {
- gsl_Expects(!m_list_active.empty());
- m_list_active.remove(&term);
- if (m_list_active.empty())
- {
-#if (AVOID_NOOP_QUEUE_PUSHES)
- if (!!is_queued())
- {
- exec().qremove(this);
- m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
- }
-#endif
- rail_terminal().device().do_dec_active();
- }
- }
+ void add_to_active_list(core_terminal_t &term) noexcept;
+ void remove_from_active_list(core_terminal_t &term) noexcept;
// -----------------------------------------------------------------------------
// setup stuff - cold
@@ -200,17 +98,31 @@ namespace netlist
void rebuild_list(); // rebuild m_list after a load
- //std::vector<core_terminal_t *> &core_terms() noexcept { return state().m_core_terms[this]; }
-
void update_inputs() noexcept
{
-#if NL_USE_COPY_INSTEAD_OF_REFERENCE
- for (auto & term : m_core_terms)
- term->m_Q = m_cur_Q;
-#endif
- // nothing needs to be done if define not set
+ if constexpr (config::use_copy_instead_of_reference::value)
+ {
+ for (auto *term : core_terms_ref())
+ term->set_copied_input(m_cur_Q);
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // net management
+ // -----------------------------------------------------------------------------
+
+ const std::vector<detail::core_terminal_t *> core_terms_copy()
+ {
+ std::vector<detail::core_terminal_t *> ret(core_terms_ref().size());
+ std::copy(core_terms_ref().begin(), core_terms_ref().end(), ret.begin());
+ return ret;
}
+ void remove_terminal(detail::core_terminal_t &term);
+ void remove_all_terminals();
+ void add_terminal(detail::core_terminal_t &terminal);
+
+ bool core_terms_empty() noexcept { return core_terms_ref().empty(); }
protected:
// only used for logic nets
@@ -224,49 +136,188 @@ namespace netlist
}
// only used for logic nets
- void set_Q_and_push(const netlist_sig_t &newQ, const netlist_time &delay) noexcept
+ void set_Q_and_push(netlist_sig_t newQ, const netlist_time &delay) noexcept;
+
+ // only used for logic nets
+ void set_Q_time(netlist_sig_t newQ, const netlist_time_ext &at) noexcept;
+
+
+ private:
+#if NL_USE_INPLACE_CORE_TERMS
+ const plib::linked_list_t<core_terminal_t, 1> &core_terms_ref() const noexcept
{
- gsl_Expects(delay >= netlist_time::zero());
+ return m_core_terms;
+ }
+#else
+ std::vector<detail::core_terminal_t *> &core_terms_ref()
+ {
+ return state().core_terms(*this);
+ }
+#endif
+ state_var<netlist_sig_t> m_new_Q;
+ state_var<netlist_sig_t> m_cur_Q;
+ state_var<queue_status> m_in_queue;
+ // FIXME: this needs to be saved as well
+ plib::linked_list_t<core_terminal_t, 0> m_list_active;
+ state_var<netlist_time_ext> m_next_scheduled_time;
+
+ core_terminal_t * m_rail_terminal;
+#if NL_USE_INPLACE_CORE_TERMS
+ plib::linked_list_t<core_terminal_t, 1> m_core_terms;
+#endif
+ };
+
+ inline void net_t::push_to_queue(const netlist_time &delay) noexcept
+ {
+ if (is_queued())
+ exec().queue_remove(this);
+
+ m_next_scheduled_time = exec().time() + delay;
+ if constexpr (config::avoid_noop_queue_pushes::value)
+ m_in_queue = (m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE
+ : (m_new_Q != m_cur_Q ? queue_status::QUEUED : queue_status::DELIVERED));
+ else
+ m_in_queue = m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE : queue_status::QUEUED;
+
+ if (m_in_queue == queue_status::QUEUED)
+ exec().queue_push(m_next_scheduled_time, this);
+ else
+ update_inputs();
+ }
+
+ template <bool KEEP_STATS>
+ void net_t::update_devs() noexcept
+ {
+ gsl_Expects(this->is_rail_net());
- if (newQ != m_new_Q)
+ m_in_queue = queue_status::DELIVERED; // mark as taken ...
+
+ const netlist_sig_t new_Q(m_new_Q);
+ const netlist_sig_t cur_Q(m_cur_Q);
+ if (config::avoid_noop_queue_pushes::value || ((new_Q ^ cur_Q) != 0))
+ {
+ m_cur_Q = new_Q;
+ const auto mask = (new_Q << core_terminal_t::INP_LH_SHIFT)
+ | (cur_Q << core_terminal_t::INP_HL_SHIFT);
+
+ if (!KEEP_STATS)
{
- m_new_Q = newQ;
- push_to_queue(delay);
+ for (core_terminal_t * p: m_list_active)
+ {
+ p->set_copied_input(new_Q);
+ if ((p->terminal_state() & mask) != 0)
+ p->run_delegate();
+ }
+ }
+ else
+ {
+ for (core_terminal_t * p : m_list_active)
+ {
+ p->set_copied_input(new_Q);
+ auto *stats(p->device().stats());
+ stats->m_stat_call_count.inc();
+ if ((p->terminal_state() & mask))
+ {
+ auto g(stats->m_stat_total_time.guard());
+ p->run_delegate();
+ }
+ }
}
}
+ }
- // only used for logic nets
- void set_Q_time(const netlist_sig_t &newQ, const netlist_time_ext &at) noexcept
+ inline void net_t::add_to_active_list(core_terminal_t &term) noexcept
+ {
+ if (!m_list_active.empty())
{
- gsl_Expects(at >= netlist_time_ext::zero());
-
- if (newQ != m_new_Q)
+ term.set_copied_input(m_cur_Q);
+ m_list_active.push_front(&term);
+ }
+ else
+ {
+ m_list_active.push_front(&term);
+ rail_terminal().device().do_inc_active();
+ if (m_in_queue == queue_status::DELAYED_DUE_TO_INACTIVE)
{
- m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
- m_next_scheduled_time = at;
- m_cur_Q = m_new_Q = newQ;
+ // if we avoid queue pushes we must test if m_cur_Q and m_new_Q are equal
+ if ((!config::avoid_noop_queue_pushes::value || (m_cur_Q != m_new_Q))
+ && (m_next_scheduled_time > exec().time()))
+ {
+ m_in_queue = queue_status::QUEUED; // pending
+ exec().queue_push(m_next_scheduled_time, this);
+ }
+ else
+ {
+ m_in_queue = queue_status::DELIVERED;
+ m_cur_Q = m_new_Q;
+ }
update_inputs();
}
else
+ term.set_copied_input(m_cur_Q);
+ }
+ }
+
+ inline void net_t::remove_from_active_list(core_terminal_t &term) noexcept
+ {
+ gsl_Expects(!m_list_active.empty());
+ m_list_active.remove(&term);
+ if (m_list_active.empty())
+ {
+ if constexpr (true || config::avoid_noop_queue_pushes::value)
{
- m_cur_Q = newQ;
- update_inputs();
+ // All our connected outputs have signalled they no longer
+ // will act on input. We thus remove any potentially queued
+ // events and mark them.
+ // FIXME: May cause regression test to fail - revisit in this case
+ //
+ // This code is definitively needed for the
+ // AVOID_NOOP_QUEUE_PUSHES code path - therefore I left
+ // the if statement in and enabled it for all code paths
+ if (is_queued())
+ {
+ exec().queue_remove(this);
+ m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
+ }
}
+ rail_terminal().device().do_dec_active();
}
+ }
- private:
- state_var<netlist_sig_t> m_new_Q;
- state_var<netlist_sig_t> m_cur_Q;
- state_var<queue_status> m_in_queue;
- plib::linked_list_t<core_terminal_t> m_list_active;
- state_var<netlist_time_ext> m_next_scheduled_time;
+ // only used for logic nets
+ inline void net_t::set_Q_and_push(netlist_sig_t newQ, const netlist_time &delay) noexcept
+ {
+ gsl_Expects(delay >= netlist_time::zero());
- core_terminal_t * m_rail_terminal;
- //std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
+ if (newQ != m_new_Q)
+ {
+ m_new_Q = newQ;
+ push_to_queue(delay);
+ }
+ }
+
+ // only used for logic nets
+ inline void net_t::set_Q_time(netlist_sig_t newQ, const netlist_time_ext &at) noexcept
+ {
+ gsl_Expects(at >= netlist_time_ext::zero());
+
+ if (newQ != m_new_Q)
+ {
+ m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
+ m_next_scheduled_time = at;
+ m_cur_Q = m_new_Q = newQ;
+ update_inputs();
+ }
+ else
+ {
+ m_cur_Q = newQ;
+ update_inputs();
+ }
+ }
- };
} // namespace detail
+
class analog_net_t : public detail::net_t
{
public:
diff --git a/src/lib/netlist/core/object_array.h b/src/lib/netlist/core/object_array.h
index 69528796303..08b66a64990 100644
--- a/src/lib/netlist/core/object_array.h
+++ b/src/lib/netlist/core/object_array.h
@@ -133,7 +133,7 @@ namespace netlist
private:
template <std::size_t P>
- constexpr const value_type &e() const { return (*this)[P](); }
+ constexpr value_type e() const { return (*this)[P](); }
};
template<std::size_t N>
@@ -174,7 +174,7 @@ namespace netlist
}
template<typename T, std::size_t NT>
- void push(const T &v, const std::array<netlist_time, NT> &t)
+ void push(const T &v, const std::array<const netlist_time, NT> &t)
{
static_assert(NT >= N, "Not enough timing entries provided");
diff --git a/src/lib/netlist/core/param.h b/src/lib/netlist/core/param.h
index 52f086cf6f0..388ccebc1ba 100644
--- a/src/lib/netlist/core/param.h
+++ b/src/lib/netlist/core/param.h
@@ -101,8 +101,8 @@ namespace netlist
param_enum_t(core_device_t &device, const pstring &name, T val) noexcept(false);
- T operator()() const noexcept { return m_param; }
- operator T() const noexcept { return m_param; }
+ constexpr T operator()() const noexcept { return m_param; }
+ constexpr operator T() const noexcept { return m_param; }
void set(const T &param) noexcept { set_and_update_param(m_param, param); }
pstring value_string() const override
diff --git a/src/lib/netlist/core/queue.h b/src/lib/netlist/core/queue.h
index d8b95ac86e7..19600f0198c 100644
--- a/src/lib/netlist/core/queue.h
+++ b/src/lib/netlist/core/queue.h
@@ -25,14 +25,6 @@
namespace netlist::detail
{
- // Use timed_queue_heap to use stdc++ heap functions instead of linear processing.
- // This slows down processing by about 35% on a Kaby Lake.
- // template <class A, class T, bool TS>
- // using timed_queue = plib::timed_queue_heap<A, T, TS>;
-
- template <typename A, typename T, bool TS>
- using timed_queue = plib::timed_queue_linear<A, T, TS>;
-
// -----------------------------------------------------------------------------
// queue_t
// -----------------------------------------------------------------------------
@@ -40,19 +32,19 @@ namespace netlist::detail
// We don't need a thread-safe queue currently. Parallel processing of
// solvers will update inputs after parallel processing.
- template <typename A, typename O, bool TS>
+ template <typename A, typename O>
class queue_base :
- public timed_queue<A, plib::queue_entry_t<netlist_time_ext, O *>, false>,
+ public config::timed_queue<A, plib::queue_entry_t<netlist_time_ext, O *>>,
public plib::state_manager_t::callback_t
{
public:
using entry_t = plib::queue_entry_t<netlist_time_ext, O *>;
- using base_queue = timed_queue<A, entry_t, false>;
+ using base_queue = config::timed_queue<A, entry_t>;
using id_delegate = plib::pmfp<std::size_t (const O *)>;
using obj_delegate = plib::pmfp<O * (std::size_t)>;
explicit queue_base(A &arena, std::size_t size, id_delegate get_id, obj_delegate get_obj)
- : timed_queue<A, plib::queue_entry_t<netlist_time_ext, O *>, false>(arena, size)
+ : base_queue(arena, size)
, m_size(0)
, m_times(size)
, m_net_ids(size)
@@ -72,7 +64,7 @@ namespace netlist::detail
void register_state(plib::state_manager_t &manager, const pstring &module) override
{
- manager.save_item(this, m_size, module + "." + "qsize");
+ manager.save_item(this, m_size, module + "." + "size");
manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
}
@@ -103,7 +95,7 @@ namespace netlist::detail
obj_delegate m_obj_by_id;
};
- using queue_t = queue_base<device_arena, net_t, false>;
+ using queue_t = queue_base<device_arena, net_t>;
} // namespace netlist::detail
diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h
index 5171d1428e8..ddf1aa14889 100644
--- a/src/lib/netlist/core/setup.h
+++ b/src/lib/netlist/core/setup.h
@@ -95,7 +95,7 @@ namespace netlist
// need to preserve order of device creation ...
std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
// lifetime control only - can be cleared before run
- std::vector<std::pair<pstring, pstring>> m_defparams;
+ std::vector<std::pair<pstring, pstring>> m_default_params;
std::unordered_map<pstring, bool> m_hints;
factory::list_t m_factory;
};
@@ -188,9 +188,6 @@ namespace netlist
log_type &log() noexcept;
const log_type &log() const noexcept;
- // FIXME: needed from matrix_solver_t
- void add_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false);
-
private:
void resolve_inputs();
@@ -215,7 +212,7 @@ namespace netlist
// net manipulations
- void remove_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false);
+ //void remove_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false);
void move_connections(detail::net_t &net, detail::net_t &dest_net);
void delete_empty_nets();
diff --git a/src/lib/netlist/core/state_var.h b/src/lib/netlist/core/state_var.h
index 7791a8604d6..88f9a072a1f 100644
--- a/src/lib/netlist/core/state_var.h
+++ b/src/lib/netlist/core/state_var.h
@@ -47,7 +47,8 @@ namespace netlist
const pstring &name //!< identifier/name for this state variable
);
- PMOVEASSIGN(state_var, delete)
+ state_var(state_var &&) noexcept = delete;
+ state_var &operator=(state_var &&) noexcept = delete;
//! Destructor.
~state_var() noexcept = default;
@@ -195,7 +196,7 @@ namespace netlist
namespace plib
{
template <typename X>
- struct ptype_traits<netlist::state_var<X>> : ptype_traits<X>
+ struct format_traits<netlist::state_var<X>> : format_traits<X>
{
};
} // namespace plib
diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp
index 4433ba6b98b..1501be4763e 100644
--- a/src/lib/netlist/devices/nld_74107.cpp
+++ b/src/lib/netlist/devices/nld_74107.cpp
@@ -100,6 +100,8 @@ namespace netlist::devices {
NETLIB_HANDLERI(clk)
{
+ const netlist_sig_t J(m_J());
+ const netlist_sig_t K(m_K());
const netlist_sig_t t(m_Q.net().Q());
/*
* J K Q1 Q2 F t Q
@@ -112,12 +114,12 @@ namespace netlist::devices {
* 1 0 0 0 1 1 1
* 1 1 1 0 0 1 0
*/
- if ((m_J() & m_K()) ^ 1)
+ if ((J & K) ^ 1)
m_clk.inactivate();
- newstate(((t ^ 1) & m_J()) | (t & (m_K() ^ 1)));
+ newstate(((t ^ 1) & J) | (t & (K ^ 1)));
}
- void newstate(const netlist_sig_t state)
+ void newstate(const netlist_sig_t state) noexcept
{
m_Q.push(state, D::delay::value(state));
m_QQ.push(state ^ 1, D::delay::value(state ^ 1));
diff --git a/src/lib/netlist/devices/nld_7474.cpp b/src/lib/netlist/devices/nld_7474.cpp
index e1f5027599e..f79d38c5e0f 100644
--- a/src/lib/netlist/devices/nld_7474.cpp
+++ b/src/lib/netlist/devices/nld_7474.cpp
@@ -103,7 +103,7 @@ namespace netlist::devices {
nld_power_pins m_power_pins;
- void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
+ void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ) noexcept
{
// 0: High-to-low 40 ns, 1: Low-to-high 25 ns
static constexpr const std::array<netlist_time, 2> delay = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp
index 1415fc95b13..7bcf1f7b214 100644
--- a/src/lib/netlist/devices/nld_7490.cpp
+++ b/src/lib/netlist/devices/nld_7490.cpp
@@ -56,7 +56,7 @@
namespace netlist::devices {
- static constexpr const std::array<netlist_time, 4> delay =
+ static constexpr const std::array<const netlist_time, 4> delay =
{
NLTIME_FROM_NS(18),
NLTIME_FROM_NS(36) - NLTIME_FROM_NS(18),
diff --git a/src/lib/netlist/devices/nld_7492.cpp b/src/lib/netlist/devices/nld_7492.cpp
index 7d14591b88d..1689ff0dd9d 100644
--- a/src/lib/netlist/devices/nld_7492.cpp
+++ b/src/lib/netlist/devices/nld_7492.cpp
@@ -54,7 +54,7 @@
namespace netlist::devices {
- static constexpr const std::array<netlist_time, 4> delay =
+ static constexpr const std::array<const netlist_time, 4> delay =
{
NLTIME_FROM_NS(18),
NLTIME_FROM_NS(36) - NLTIME_FROM_NS(18),
diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp
index 2b1a01389a4..a6d80fd551b 100644
--- a/src/lib/netlist/devices/nld_7493.cpp
+++ b/src/lib/netlist/devices/nld_7493.cpp
@@ -59,7 +59,7 @@
namespace netlist::devices {
- static constexpr std::array<netlist_time, 3> out_delay { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54) };
+ static constexpr const std::array<const netlist_time, 3> out_delay { NLTIME_FROM_NS(18), NLTIME_FROM_NS(36), NLTIME_FROM_NS(54) };
NETLIB_OBJECT(7493)
{
@@ -67,7 +67,7 @@ namespace netlist::devices {
, m_CLKA(*this, "CLKA", NETLIB_DELEGATE(updA))
, m_CLKB(*this, "CLKB", NETLIB_DELEGATE(updB))
, m_QA(*this, "QA")
- , m_QB(*this, {"QB", "QC", "QD"})
+ , m_QBCD(*this, {"QB", "QC", "QD"})
, m_a(*this, "m_a", 0)
, m_bcd(*this, "m_b", 0)
, m_R1(*this, "R1", NETLIB_DELEGATE(inputs))
@@ -96,7 +96,7 @@ namespace netlist::devices {
m_CLKA.inactivate();
m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40));
- m_QB.push(0, NLTIME_FROM_NS(40));
+ m_QBCD.push(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}
@@ -110,14 +110,14 @@ namespace netlist::devices {
NETLIB_HANDLERI(updB)
{
const auto cnt(++m_bcd &= 0x07);
- m_QB.push(cnt, out_delay);
+ m_QBCD.push(cnt, out_delay);
}
logic_input_t m_CLKA;
logic_input_t m_CLKB;
logic_output_t m_QA;
- object_array_t<logic_output_t, 3> m_QB;
+ object_array_t<logic_output_t, 3> m_QBCD;
state_var<unsigned> m_a;
state_var<unsigned> m_bcd;
diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp
index 5367ed0648e..b6b444fe04d 100644
--- a/src/lib/netlist/devices/nld_ne555.cpp
+++ b/src/lib/netlist/devices/nld_ne555.cpp
@@ -29,7 +29,7 @@ namespace netlist::devices {
, m_last_reset(*this, "m_last_reset", false)
, m_overshoot(*this, "m_overshoot", 0.0)
, m_undershoot(*this, "m_undershoot", 0.0)
- , m_ovlimit(0.0)
+ , m_overshoot_limit(0.0)
{
register_sub_alias("GND", "R3.2"); // Pin 1
register_sub_alias("CONT", "R1.2"); // Pin 5
@@ -56,7 +56,7 @@ namespace netlist::devices {
// Check for astable setup, usually TRIG AND THRES connected. Enable
// overshoot compensation in this case.
if (m_TRIG.net() == m_THRES.net())
- m_ovlimit = nlconst::magic(0.5);
+ m_overshoot_limit = nlconst::magic(0.5);
}
private:
@@ -66,12 +66,12 @@ namespace netlist::devices {
const auto reset = m_RESET();
- const nl_fptype vthresh = clamp_hl(m_R2.P()(), nlconst::magic(0.7), nlconst::magic(1.4));
- const nl_fptype vtrig = clamp_hl(m_R2.N()(), nlconst::magic(0.7), nlconst::magic(1.4));
+ const nl_fptype v_threshold = clamp_hl(m_R2.P()(), nlconst::magic(0.7), nlconst::magic(1.4));
+ const nl_fptype v_trigger = clamp_hl(m_R2.N()(), nlconst::magic(0.7), nlconst::magic(1.4));
// avoid artificial oscillation due to overshoot compensation when
// the control input is used.
- const auto ovlimit = std::min(m_ovlimit, std::max(0.0, (vthresh - vtrig) / 3.0));
+ const auto overshoot_limit = std::min(m_overshoot_limit, std::max(0.0, (v_threshold - v_trigger) / 3.0));
if (!reset && m_last_reset)
{
@@ -80,15 +80,15 @@ namespace netlist::devices {
else
{
#if (NL_USE_BACKWARD_EULER)
- const bool bthresh = (m_THRES() + m_overshoot > vthresh);
- const bool btrig = (m_TRIG() - m_overshoot > vtrig);
+ const bool threshold_exceeded = (m_THRES() + m_overshoot > v_threshold);
+ const bool trigger_exceeded = (m_TRIG() - m_overshoot > v_trigger);
#else
- const bool bthresh = (m_THRES() + m_overshoot > vthresh);
- const bool btrig = (m_TRIG() - m_undershoot > vtrig);
+ const bool threshold_exceeded = (m_THRES() + m_overshoot > v_threshold);
+ const bool trigger_exceeded = (m_TRIG() - m_undershoot > v_trigger);
#endif
- if (!btrig)
+ if (!trigger_exceeded)
m_ff = true;
- else if (bthresh)
+ else if (threshold_exceeded)
{
m_ff = false;
}
@@ -99,11 +99,11 @@ namespace netlist::devices {
if (m_last_out && !out)
{
#if (NL_USE_BACKWARD_EULER)
- m_overshoot += ((m_THRES() - vthresh)) * 2.0;
+ m_overshoot += ((m_THRES() - v_threshold)) * 2.0;
#else
- m_overshoot += ((m_THRES() - vthresh));
+ m_overshoot += ((m_THRES() - v_threshold));
#endif
- m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), ovlimit);
+ m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), overshoot_limit);
//if (this->name() == "IC6_2")
// printf("%f %s %f %f %f\n", exec().time().as_double(), this->name().c_str(), m_overshoot(), m_R2.P()(), m_THRES());
m_RDIS.change_state([this]()
@@ -115,11 +115,11 @@ namespace netlist::devices {
else if (!m_last_out && out)
{
#if (NL_USE_BACKWARD_EULER)
- m_overshoot += (vtrig - m_TRIG()) * 2.0;
- m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), ovlimit);
+ m_overshoot += (v_trigger - m_TRIG()) * 2.0;
+ m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), overshoot_limit);
#else
- m_undershoot += (vtrig - m_TRIG());
- m_undershoot = plib::clamp(m_undershoot(), nlconst::zero(), ovlimit);
+ m_undershoot += (v_trigger - m_TRIG());
+ m_undershoot = plib::clamp(m_undershoot(), nlconst::zero(), overshoot_limit);
#endif
m_RDIS.change_state([this]()
{
@@ -147,7 +147,7 @@ namespace netlist::devices {
state_var<bool> m_last_reset;
state_var<nl_fptype> m_overshoot;
state_var<nl_fptype> m_undershoot;
- nl_fptype m_ovlimit;
+ nl_fptype m_overshoot_limit;
nl_fptype clamp_hl(const nl_fptype v, const nl_fptype a, const nl_fptype b) noexcept
{
diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp
index 8192222c236..0f68517cb1f 100644
--- a/src/lib/netlist/devices/nlid_truthtable.cpp
+++ b/src/lib/netlist/devices/nlid_truthtable.cpp
@@ -41,7 +41,7 @@ namespace netlist::devices {
const pstring &model,
truth_table_t &ttp, const std::vector<pstring> &desc)
: device_t(owner, name, model)
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
, m_state(*this, "m_state", 0)
#endif
, m_ign(*this, "m_ign", 0)
@@ -61,25 +61,26 @@ namespace netlist::devices {
{
int active_outputs = 0;
m_ign = 0;
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state = 0;
#endif
for (std::size_t i = 0; i < m_NI; ++i)
{
m_I[i].activate();
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state |= (m_I[i]() << i);
#endif
}
for (auto &q : m_Q)
- if (q.has_net() && !exec().nl_state().core_terms(q.net()).empty())
- active_outputs++;
+ if (q.has_net())
+ if (!q.net().core_terms_empty())
+ active_outputs++;
set_active_outputs(active_outputs);
}
NETLIB_HANDLERI(inputs)
{
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state = 0;
for (std::size_t i = 0; i < m_NI; ++i)
{
@@ -89,7 +90,7 @@ namespace netlist::devices {
process<true>();
}
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
template <std::size_t N>
void update_N() noexcept
{
@@ -122,7 +123,7 @@ namespace netlist::devices {
if (doOUT)
{
-#if !USE_TT_ALTERNATIVE
+#if !NL_USE_TT_ALTERNATIVE
for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
if (ign & 1)
I->activate();
@@ -150,7 +151,7 @@ namespace netlist::devices {
}
const type_t output_state(m_ttp.m_out_state[new_state]);
- type_t out(output_state & m_outmask);
+ const type_t out(output_state & m_outmask);
m_ign = output_state >> m_NO;
@@ -171,7 +172,7 @@ namespace netlist::devices {
for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
if (ign & 1)
I->inactivate();
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state = new_state;
#endif
}
@@ -195,7 +196,7 @@ namespace netlist::devices {
plib::static_vector<logic_input_t, m_NI> m_I;
plib::static_vector<logic_output_t, m_NO> m_Q;
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
state_var<type_t> m_state;
#endif
state_var<type_t> m_ign;
@@ -214,18 +215,18 @@ namespace netlist::devices {
{
using type = T;
- pbitset() noexcept : m_bs(0) { }
- pbitset(T v) noexcept : m_bs(v) { }
+ constexpr pbitset() noexcept : m_bs(0) { }
+ constexpr pbitset(T v) noexcept : m_bs(v) { }
- pbitset &set() noexcept { *this = all_bits(); return *this; }
- pbitset &set(std::size_t bit) noexcept { m_bs |= (static_cast<T>(1) << bit); return *this; }
- pbitset &reset() noexcept { *this = no_bits(); return *this; }
- pbitset &reset(std::size_t bit) noexcept { m_bs &= ~(static_cast<T>(1) << bit); return *this; }
+ constexpr pbitset &set() noexcept { *this = all_bits(); return *this; }
+ constexpr pbitset &set(std::size_t bit) noexcept { m_bs |= (static_cast<T>(1) << bit); return *this; }
+ constexpr pbitset &reset() noexcept { *this = no_bits(); return *this; }
+ constexpr pbitset &reset(std::size_t bit) noexcept { m_bs &= ~(static_cast<T>(1) << bit); return *this; }
- pbitset flip() const noexcept { return pbitset(~m_bs); }
- pbitset flip(std::size_t bit) const noexcept { return pbitset(m_bs ^ (static_cast<T>(1) << bit)); }
+ constexpr pbitset flip() const noexcept { return pbitset(~m_bs); }
+ constexpr pbitset flip(std::size_t bit) const noexcept { return pbitset(m_bs ^ (static_cast<T>(1) << bit)); }
- std::size_t count() const noexcept
+ constexpr std::size_t count() const noexcept
{
std::size_t ret(0);
for (T v = m_bs; v != 0; v = v >> 1)
@@ -236,8 +237,8 @@ namespace netlist::devices {
}
constexpr bool test(const std::size_t bit) const { return ((m_bs >> bit) & 1) == 1; }
- operator T&() noexcept { return m_bs; }
- operator const T&() const noexcept { return m_bs; }
+ constexpr operator T&() noexcept { return m_bs; }
+ constexpr operator const T&() const noexcept { return m_bs; }
constexpr T as_uint() const noexcept { return m_bs; }
constexpr bool all() const noexcept { return *this == all_bits(); }
@@ -254,7 +255,7 @@ namespace netlist::devices {
///
/// \returns pbitset
///
- pbitset expand_and(pbitset b) const noexcept
+ constexpr pbitset expand_and(pbitset b) const noexcept
{
pbitset ret;
T v( m_bs);
@@ -271,8 +272,8 @@ namespace netlist::devices {
return ret;
}
- static constexpr pbitset all_bits() noexcept { return pbitset(~static_cast<T>(0)); }
- static constexpr pbitset no_bits() noexcept{ return pbitset(static_cast<T>(0)); }
+ static constexpr const pbitset all_bits() noexcept { return pbitset(~static_cast<T>(0)); }
+ static constexpr const pbitset no_bits() noexcept{ return pbitset(static_cast<T>(0)); }
private:
T m_bs;
};
@@ -285,12 +286,12 @@ namespace netlist::devices {
struct packed_int
{
- packed_int(void *data, std::size_t bits) noexcept
+ constexpr packed_int(void *data, std::size_t bits) noexcept
: m_data(data)
, m_size(bits)
{}
- void set(size_t pos, std::uint_least64_t val) noexcept
+ constexpr void set(size_t pos, std::uint_least64_t val) noexcept
{
switch (m_size)
{
@@ -302,7 +303,7 @@ namespace netlist::devices {
}
}
- std::uint_least64_t operator[] (size_t pos) const noexcept
+ constexpr std::uint_least64_t operator[] (size_t pos) const noexcept
{
switch (m_size)
{
@@ -315,7 +316,7 @@ namespace netlist::devices {
}
}
- std::uint_least64_t mask() const noexcept
+ constexpr std::uint_least64_t mask() const noexcept
{
switch (m_size)
{
@@ -346,7 +347,7 @@ namespace netlist::devices {
{
}
- void parse(const std::vector<pstring> &truthtable);
+ void parse(const std::vector<pstring> &truth_table);
private:
void parse_line(unsigned cur, std::vector<pstring> list,
@@ -382,7 +383,7 @@ namespace netlist::devices {
std::vector<pstring> outputs(plib::psplit(io[1], ','));
nl_assert_always(outputs.size() == m_NO, "output count wrong");
-#if !USE_TT_ALTERNATIVE
+#if !NL_USE_TT_ALTERNATIVE
for (std::size_t i=0; i < m_NI; i++)
{
inout[i] = plib::trim(inout[i]);
@@ -393,18 +394,18 @@ namespace netlist::devices {
{
inout[i] = plib::trim(inout[i]);
}
- if (0 < m_NI) m_I.emplace(0, *this, inout[0]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<0>, this));
- if (1 < m_NI) m_I.emplace(1, *this, inout[1]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<1>, this));
- if (2 < m_NI) m_I.emplace(2, *this, inout[2]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<2>, this));
- if (3 < m_NI) m_I.emplace(3, *this, inout[3]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<3>, this));
- if (4 < m_NI) m_I.emplace(4, *this, inout[4]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<4>, this));
- if (5 < m_NI) m_I.emplace(5, *this, inout[5]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<5>, this));
- if (6 < m_NI) m_I.emplace(6, *this, inout[6]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<6>, this));
- if (7 < m_NI) m_I.emplace(7, *this, inout[7]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<7>, this));
- if (8 < m_NI) m_I.emplace(8, *this, inout[8]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<8>, this));
- if (9 < m_NI) m_I.emplace(9, *this, inout[9]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<9>, this));
- if (10 < m_NI) m_I.emplace(10, *this, inout[10]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<10>, this));
- if (11 < m_NI) m_I.emplace(11, *this, inout[11]); //# nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<11>, this));
+ if (0 < m_NI) m_I.emplace_back(*this, inout[0], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<0>, this));
+ if (1 < m_NI) m_I.emplace_back(*this, inout[1], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<1>, this));
+ if (2 < m_NI) m_I.emplace_back(*this, inout[2], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<2>, this));
+ if (3 < m_NI) m_I.emplace_back(*this, inout[3], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<3>, this));
+ if (4 < m_NI) m_I.emplace_back(*this, inout[4], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<4>, this));
+ if (5 < m_NI) m_I.emplace_back(*this, inout[5], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<5>, this));
+ if (6 < m_NI) m_I.emplace_back(*this, inout[6], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<6>, this));
+ if (7 < m_NI) m_I.emplace_back(*this, inout[7], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<7>, this));
+ if (8 < m_NI) m_I.emplace_back(*this, inout[8], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<8>, this));
+ if (9 < m_NI) m_I.emplace_back(*this, inout[9], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<9>, this));
+ if (10 < m_NI) m_I.emplace_back(*this, inout[10], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<10>, this));
+ if (11 < m_NI) m_I.emplace_back(*this, inout[11], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<11>, this));
#endif
for (std::size_t i=0; i < m_NO; i++)
{
@@ -437,20 +438,20 @@ namespace netlist::devices {
{
using tt_type = nld_truth_table_t<m_NI, m_NO>;
- if (!m_ttbl)
+ if (!m_table)
{
- m_ttbl = plib::make_unique<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t>(pool);
+ m_table = plib::make_unique<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t>(pool);
truth_table_parser desc_s(m_NO, m_NI,
- packed_int(m_ttbl->m_out_state.data(), sizeof(m_ttbl->m_out_state[0]) * 8),
- m_ttbl->m_timing_index.data(), m_ttbl->m_timing_nt.data());
+ packed_int(m_table->m_out_state.data(), sizeof(m_table->m_out_state[0]) * 8),
+ m_table->m_timing_index.data(), m_table->m_timing_nt.data());
desc_s.parse(m_desc);
}
- return plib::make_unique<tt_type>(pool, anetlist, name, m_family_name, *m_ttbl, m_desc);
+ return plib::make_unique<tt_type>(pool, anetlist, name, m_family_name, *m_table, m_desc);
}
private:
- device_arena::unique_ptr<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t> m_ttbl;
+ device_arena::unique_ptr<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t> m_table;
};
tt_bitset truth_table_parser::calculate_ignored_inputs(tt_bitset state) const
@@ -562,13 +563,13 @@ namespace netlist::devices {
}
}
- void truth_table_parser::parse(const std::vector<pstring> &truthtable)
+ void truth_table_parser::parse(const std::vector<pstring> &truth_table)
{
unsigned line = 0;
- pstring ttline(truthtable[line]);
+ pstring tt_line(truth_table[line]);
line++;
- ttline = truthtable[line];
+ tt_line = truth_table[line];
line++;
for (unsigned j=0; j < m_size; j++)
@@ -577,9 +578,9 @@ namespace netlist::devices {
for (int j=0; j < 16; j++)
m_timing_nt[j] = netlist_time::zero();
- while (!ttline.empty())
+ while (!tt_line.empty())
{
- std::vector<pstring> io(plib::psplit(ttline,'|'));
+ std::vector<pstring> io(plib::psplit(tt_line,'|'));
// checks
nl_assert_always(io.size() == 3, "io.count mismatch");
std::vector<pstring> inout(plib::psplit(io[0], ','));
@@ -590,7 +591,7 @@ namespace netlist::devices {
nl_assert_always(times.size() == m_NO, "timing count not matching");
tt_bitset val = 0;
- std::vector<uint_least8_t> tindex;
+ std::vector<uint_least8_t> indexes;
//
// FIXME: evaluation of outputs should be done in parse_line to
@@ -610,14 +611,14 @@ namespace netlist::devices {
while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t)
k++;
m_timing_nt[k] = t;
- tindex.push_back(k); //[j] = k;
+ indexes.push_back(k); //[j] = k;
}
- parse_line(0, inout, 0 , val, tindex);
- if (line < truthtable.size())
- ttline = truthtable[line];
+ parse_line(0, inout, 0 , val, indexes);
+ if (line < truth_table.size())
+ tt_line = truth_table[line];
else
- ttline = "";
+ tt_line = "";
line++;
}
@@ -666,9 +667,9 @@ namespace netlist::factory {
}
#define ENTRYY(n, m, s) case (n * 100 + m): \
- { using xtype = devices::netlist_factory_truth_table_t<n, m>; \
+ { using dev_type = devices::netlist_factory_truth_table_t<n, m>; \
auto cs=s; \
- ret = plib::make_unique<xtype, host_arena>(desc.name, std::move(cs)); } \
+ ret = plib::make_unique<dev_type, host_arena>(desc.name, std::move(cs)); } \
break
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h
index a7e4d7a327d..83f9679e70b 100644
--- a/src/lib/netlist/devices/nlid_truthtable.h
+++ b/src/lib/netlist/devices/nlid_truthtable.h
@@ -12,8 +12,6 @@
#include "../nl_setup.h"
#include "nl_factory.h"
-#define USE_TT_ALTERNATIVE (0)
-
namespace netlist::factory {
class truth_table_base_element_t : public factory::element_t
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 6441b91c287..c60162efb0c 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -25,23 +25,9 @@ namespace netlist
{
// ----------------------------------------------------------------------------------------
- // callbacks_t
+ // detail::core_terminal_t
// ----------------------------------------------------------------------------------------
- // ----------------------------------------------------------------------------------------
- // queue_t
- // ----------------------------------------------------------------------------------------
-
- // ----------------------------------------------------------------------------------------
- // device_object_t
- // ----------------------------------------------------------------------------------------
-
- detail::device_object_t::device_object_t(core_device_t *dev, const pstring &aname)
- : object_t(aname)
- , m_device(dev)
- {
- }
-
detail::terminal_type detail::core_terminal_t::type() const noexcept(false)
{
if (dynamic_cast<const terminal_t *>(this) != nullptr)
@@ -58,6 +44,16 @@ namespace netlist
//return terminal_type::TERMINAL; // please compiler
}
+ // ----------------------------------------------------------------------------------------
+ // detail::device_object_t
+ // ----------------------------------------------------------------------------------------
+
+ detail::device_object_t::device_object_t(core_device_t *dev, const pstring &aname)
+ : object_t(aname)
+ , m_device(dev)
+ {
+ }
+
netlist_state_t &detail::device_object_t::state() noexcept
{
return m_device->state();
@@ -69,7 +65,7 @@ namespace netlist
}
// ----------------------------------------------------------------------------------------
- // netlist_object_t
+ // detail::netlist_object_t
// ----------------------------------------------------------------------------------------
netlist_state_t & detail::netlist_object_t::state() noexcept
@@ -100,8 +96,47 @@ namespace netlist
state.save(*this, m_time, aname, "m_time");
}
+ void netlist_t::reset()
+ {
+ log().debug("Searching for main clock\n");
+ m_main_clock = m_state.get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+
+ log().debug("Searching for solver\n");
+ m_solver = m_state.get_single_device<devices::NETLIB_NAME(solver)>("solver");
+
+ // Don't reset time
+ //m_time = netlist_time_ext::zero();
+ m_queue.clear();
+ if (m_main_clock != nullptr)
+ m_main_clock->m_Q.net().set_next_scheduled_time(m_time);
+ //if (m_solver != nullptr)
+ // m_solver->reset();
+
+ m_state.reset();
+ }
+
+ void netlist_t::stop()
+ {
+ log().debug("Printing statistics ...\n");
+ print_stats();
+ log().debug("Stopping solver device ...\n");
+ if (m_solver != nullptr)
+ m_solver->stop();
+ }
+
+ void netlist_t::print_stats() const
+ {
+ if (m_use_stats)
+ {
+ netlist_state_t::stats_info si{m_queue, m_stat_mainloop, m_perf_out_processed};
+ m_state.print_stats(si);
+ }
+ log().verbose("Current pool memory allocated: {1:12} kB", nl_state().pool().cur_alloc() >> 10);
+ log().verbose("Maximum pool memory allocated: {1:12} kB", nl_state().pool().max_alloc() >> 10);
+ }
+
// ----------------------------------------------------------------------------------------
- // netlist_t
+ // netlist_state_t
// ----------------------------------------------------------------------------------------
netlist_state_t::netlist_state_t(const pstring &name,
@@ -137,8 +172,8 @@ namespace netlist
m_setup->parser().add_include<plib::psource_str_t>("devices/net_lib.h", content);
#if 1
NETLIST_NAME(base_lib)(m_setup->parser());
- //m_setup->parser().register_source<source_pattern_t>("../macro/modules/nlmod_{1}.cpp");
- //m_setup->parser().register_source<source_pattern_t>("../macro/nlm_{1}.cpp");
+ //#m_setup->parser().register_source<source_pattern_t>("../macro/modules/nlmod_{1}.cpp");
+ //#m_setup->parser().register_source<source_pattern_t>("../macro/nlm_{1}.cpp");
#else
#if 1
pstring dir = "src/lib/netlist/";
@@ -166,25 +201,25 @@ namespace netlist
m_lib = std::move(lib);
}
-
- void netlist_t::stop()
- {
- log().debug("Printing statistics ...\n");
- print_stats();
- log().debug("Stopping solver device ...\n");
- if (m_solver != nullptr)
- m_solver->stop();
- }
-
std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
{
+ // special case for queue end processing items
+ if (net == nullptr)
+ return std::numeric_limits<std::size_t>::max() - 1;
+
for (std::size_t i = 0; i < m_nets.size(); i++)
if (m_nets[i].get() == net)
return i;
+
return std::numeric_limits<std::size_t>::max();
}
+
detail::net_t *netlist_state_t::net_by_id(std::size_t id) const
{
+ // special case for queue end processing items
+ if (id == std::numeric_limits<std::size_t>::max() - 1)
+ return nullptr;
+
return m_nets[id].get();
}
@@ -274,25 +309,6 @@ namespace netlist
return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR, NL_VERSION_PATCHLEVEL);
}
- void netlist_t::reset()
- {
- log().debug("Searching for main clock\n");
- m_main_clock = m_state.get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
-
- log().debug("Searching for solver\n");
- m_solver = m_state.get_single_device<devices::NETLIB_NAME(solver)>("solver");
-
- // Don't reset time
- //m_time = netlist_time_ext::zero();
- m_queue.clear();
- if (m_main_clock != nullptr)
- m_main_clock->m_Q.net().set_next_scheduled_time(m_time);
- //if (m_solver != nullptr)
- // m_solver->reset();
-
- m_state.reset();
- }
-
void netlist_state_t::free_setup_resources()
{
m_setup = nullptr;
@@ -339,7 +355,7 @@ namespace netlist
for (auto &n : m_nets)
{
n->update_inputs(); // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- for (auto & term : core_terms(*n))
+ for (detail::core_terminal_t * term : n->core_terms_copy())
{
if (!plib::container::contains(t, &term->delegate()))
{
@@ -370,17 +386,6 @@ namespace netlist
}
- void netlist_t::print_stats() const
- {
- if (m_use_stats)
- {
- netlist_state_t::stats_info si{m_queue, m_stat_mainloop, m_perf_out_processed};
- m_state.print_stats(si);
- }
- log().verbose("Current pool memory allocated: {1:12} kB", nl_state().pool().cur_alloc() >> 10);
- log().verbose("Maximum pool memory allocated: {1:12} kB", nl_state().pool().max_alloc() >> 10);
- }
-
void netlist_state_t::print_stats(stats_info &si) const
{
std::vector<size_t> index;
@@ -431,7 +436,7 @@ namespace netlist
/ gsl::narrow<plib::pperftime_t<true>::type>(200000);
log().verbose("Queue Pushes {1:15}", si.m_queue.m_prof_call());
- log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sortmove());
+ log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sort_move());
log().verbose("Queue Removes {1:15}", si.m_queue.m_prof_remove());
log().verbose("");
@@ -476,6 +481,19 @@ namespace netlist
return ret;
}
+ nlparse_t &netlist_state_t::parser() { return m_setup->parser(); }
+ const nlparse_t &netlist_state_t::parser() const { return m_setup->parser(); }
+
+ void netlist_state_t::remove_device(core_device_t *dev)
+ {
+ for (auto it = m_devices.begin(); it != m_devices.end(); it++)
+ if (it->second.get() == dev)
+ {
+ m_state.remove_save_items(dev);
+ m_devices.erase(it);
+ return;
+ }
+ }
// ----------------------------------------------------------------------------------------
// core_device_t
@@ -525,7 +543,7 @@ namespace netlist
pstring alias = this->name() + "." + name;
// everything already fully qualified
- state().parser().register_alias_nofqn(alias, term.name());
+ state().parser().register_alias_no_fqn(alias, term.name());
}
void base_device_t::register_sub_alias(const pstring &name, const pstring &aliased)
@@ -534,7 +552,7 @@ namespace netlist
pstring aliased_fqn = this->name() + "." + aliased;
// everything already fully qualified
- state().parser().register_alias_nofqn(alias, aliased_fqn);
+ state().parser().register_alias_no_fqn(alias, aliased_fqn);
}
void base_device_t::connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2)
@@ -600,6 +618,16 @@ namespace netlist
}
// ----------------------------------------------------------------------------------------
+ // analog_t
+ // ----------------------------------------------------------------------------------------
+
+ analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state,
+ nl_delegate delegate)
+ : core_terminal_t(dev, aname, state, delegate)
+ {
+ }
+
+ // ----------------------------------------------------------------------------------------
// net_t
// ----------------------------------------------------------------------------------------
@@ -614,12 +642,22 @@ namespace netlist
props::add(this, props::value_type());
}
+ bool detail::net_t::is_logic() const noexcept
+ {
+ return dynamic_cast<const logic_net_t *>(this) != nullptr;
+ }
+
+ bool detail::net_t::is_analog() const noexcept
+ {
+ return dynamic_cast<const analog_net_t *>(this) != nullptr;
+ }
+
void detail::net_t::rebuild_list()
{
// rebuild m_list
m_list_active.clear();
- for (auto & term : exec().nl_state().core_terms(*this))
+ for (core_terminal_t * term : core_terms_ref())
if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
{
m_list_active.push_back(term);
@@ -627,7 +665,6 @@ namespace netlist
}
}
-
void detail::net_t::reset() noexcept
{
m_next_scheduled_time = exec().time();
@@ -644,7 +681,7 @@ namespace netlist
// rebuild m_list and reset terminals to active or analog out state
m_list_active.clear();
- for (core_terminal_t *ct : exec().nl_state().core_terms(*this))
+ for (core_terminal_t * ct : core_terms_copy())
{
ct->reset();
if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
@@ -653,6 +690,63 @@ namespace netlist
}
}
+#if NL_USE_INPLACE_CORE_TERMS
+ void detail::net_t::remove_terminal(detail::core_terminal_t &term)
+ {
+ m_core_terms.remove(&term);
+ }
+
+ void detail::net_t::remove_all_terminals()
+ {
+ m_core_terms.clear();
+ }
+
+ void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
+ {
+ for (detail::core_terminal_t * t : m_core_terms)
+ if (t == &terminal)
+ {
+ state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ }
+
+ terminal.set_net(this);
+
+ m_core_terms.push_back(&terminal);
+ }
+
+#else
+ void detail::net_t::remove_terminal(detail::core_terminal_t &term)
+ {
+ //net.core_terms().remove(p);
+ for (auto pp = state().core_terms(*this).begin(); pp != state().core_terms(*this).end(); pp++)
+ if (*pp == &term)
+ {
+ state().core_terms(*this).erase(pp);
+ break;
+ }
+ }
+
+ void detail::net_t::remove_all_terminals()
+ {
+ state().core_terms(*this).clear();
+ }
+
+ void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
+ {
+ for (detail::core_terminal_t * t : state().core_terms(*this))
+ if (t == &terminal)
+ {
+ state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ }
+
+ terminal.set_net(this);
+
+ state().core_terms(*this).push_back(&terminal);
+ }
+#endif
+
// ----------------------------------------------------------------------------------------
// logic_net_t
// ----------------------------------------------------------------------------------------
@@ -678,6 +772,7 @@ namespace netlist
net_t::reset();
m_cur_Analog = nlconst::zero();
}
+
// ----------------------------------------------------------------------------------------
// core_terminal_t
// ----------------------------------------------------------------------------------------
@@ -685,19 +780,46 @@ namespace netlist
detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname,
const state_e state, nl_delegate delegate)
: device_object_t(&dev, dev.name() + "." + aname)
- #if NL_USE_COPY_INSTEAD_OF_REFERENCE
- , m_Q(*this, "m_Q", 0)
- #endif
+ , m_Q_CIR(*this, "m_Q", 0)
, m_delegate(delegate)
, m_net(nullptr)
, m_state(*this, "m_state", state)
{
}
- analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state,
- nl_delegate delegate)
- : core_terminal_t(dev, aname, state, delegate)
+ bool detail::core_terminal_t::is_logic() const noexcept
+ {
+ return dynamic_cast<const logic_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_logic_input() const noexcept
+ {
+ return dynamic_cast<const logic_input_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_logic_output() const noexcept
+ {
+ return dynamic_cast<const logic_output_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_tristate_output() const noexcept
{
+ return dynamic_cast<const tristate_output_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_analog() const noexcept
+ {
+ return dynamic_cast<const analog_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_analog_input() const noexcept
+ {
+ return dynamic_cast<const analog_input_t *>(this) != nullptr;
+ }
+
+ bool detail::core_terminal_t::is_analog_output() const noexcept
+ {
+ return dynamic_cast<const analog_output_t *>(this) != nullptr;
}
// ----------------------------------------------------------------------------------------
@@ -764,7 +886,6 @@ namespace netlist
state().setup().register_term(*this);
}
-
// ----------------------------------------------------------------------------------------
// logic_output_t
// ----------------------------------------------------------------------------------------
@@ -787,6 +908,7 @@ namespace netlist
// -----------------------------------------------------------------------------
// tristate_output_t
// -----------------------------------------------------------------------------
+
tristate_output_t::tristate_output_t(device_t &dev, const pstring &aname, bool force_logic)
: logic_output_t(dev, aname)
, m_last_logic(dev, name() + "." + "m_last_logic", 1) // force change
@@ -862,7 +984,6 @@ namespace netlist
}
-
pstring param_t::get_initial(const core_device_t *dev, bool *found) const
{
pstring res = dev->state().setup().get_initial_param_val(this->name(), "");
@@ -915,76 +1036,11 @@ namespace netlist
return state().setup().models().get_model(str()).value(entity);
}
-
plib::istream_uptr param_data_t::stream()
{
return device().state().parser().get_data_stream(str());
}
- bool detail::core_terminal_t::is_logic() const noexcept
- {
- return dynamic_cast<const logic_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_logic_input() const noexcept
- {
- return dynamic_cast<const logic_input_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_logic_output() const noexcept
- {
- return dynamic_cast<const logic_output_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_tristate_output() const noexcept
- {
- return dynamic_cast<const tristate_output_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_analog() const noexcept
- {
- return dynamic_cast<const analog_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_analog_input() const noexcept
- {
- return dynamic_cast<const analog_input_t *>(this) != nullptr;
- }
-
- bool detail::core_terminal_t::is_analog_output() const noexcept
- {
- return dynamic_cast<const analog_output_t *>(this) != nullptr;
- }
-
-
- bool detail::net_t::is_logic() const noexcept
- {
- return dynamic_cast<const logic_net_t *>(this) != nullptr;
- }
-
- bool detail::net_t::is_analog() const noexcept
- {
- return dynamic_cast<const analog_net_t *>(this) != nullptr;
- }
-
- // ----------------------------------------------------------------------------------------
- // netlist_state_t
- // ----------------------------------------------------------------------------------------
-
- nlparse_t &netlist_state_t::parser() { return m_setup->parser(); }
- const nlparse_t &netlist_state_t::parser() const { return m_setup->parser(); }
-
- void netlist_state_t::remove_device(core_device_t *dev)
- {
- for (auto it = m_devices.begin(); it != m_devices.end(); it++)
- if (it->second.get() == dev)
- {
- m_state.remove_save_items(dev);
- m_devices.erase(it);
- return;
- }
- }
-
// ----------------------------------------------------------------------------------------
// netlist_t
//
@@ -998,7 +1054,7 @@ namespace netlist
{
netlist_time_ext stop(m_time + delta);
- qpush(stop, nullptr);
+ queue_push(stop, nullptr);
if (m_main_clock == nullptr)
{
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 1559589606d..c19fe296aa7 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -51,19 +51,6 @@
#define NL_USE_ACADEMIC_SOLVERS (1)
#endif
-/// \brief Store input values in logic_terminal_t.
-///
-/// Set to 1 to store values in logic_terminal_t instead of
-/// accessing them indirectly by pointer from logic_net_t.
-/// This approach is stricter and should identify bugs in
-/// the netlist core faster.
-/// By default it is disabled since it is not as fast as
-/// the default approach. It is up to 20% slower.
-///
-#ifndef NL_USE_COPY_INSTEAD_OF_REFERENCE
-#define NL_USE_COPY_INSTEAD_OF_REFERENCE (0) // FIXME: Move to config struct later
-#endif
-
/// \brief Use backward Euler integration
///
/// This will use backward Euler instead of trapezoidal integration.
@@ -77,6 +64,35 @@
#define NL_USE_BACKWARD_EULER (1) // FIXME: Move to config struct later
#endif
+/// \brief Compile with core terminals owned by net_t
+///
+/// Set to 1 to enable that net_t owns core terminal collection.
+/// In addition, this approach will use plib::list_t so that the doubled linked
+/// list pointers are part of the core_terminal_t.
+///
+/// This approach requires that terminals at each point in time are only owned
+/// by one net. The approach helped to identify bugs. Since the approach
+/// involves that containers are located in different locations, it needs a
+/// pre-processor define.
+///
+/// By default the setting is currently disabled.
+///
+#ifndef NL_USE_INPLACE_CORE_TERMS
+#define NL_USE_INPLACE_CORE_TERMS (0)
+#endif
+
+/// \brief Use alternative truth table execution approach
+///
+/// Enabling this will define a separate truth table execution approach which
+/// will use a separate delegate for each input. This approach needs more
+/// refinement yet. It works, but is not as fast as the standard approach.
+///
+/// Unfortunately this has to be macro since it needs another member variable.
+///
+#ifndef NL_USE_TT_ALTERNATIVE
+#define NL_USE_TT_ALTERNATIVE (0)
+#endif
+
/// \brief Compile matrix solvers using the __float128 type.
///
/// Defaults to \ref PUSE_FLOAT128
@@ -84,15 +100,6 @@
#define NL_USE_FLOAT128 PUSE_FLOAT128
#endif
-/// \brief Avoid unnecessary queue pushes
-///
-/// Enable the setting below to avoid queue pushes were at execution
-/// no action will be taken. This is academically cleaner, but slower than
-/// allowing this to happen and filter it during during "process".
-/// This is used in core/nets.h
-#ifndef AVOID_NOOP_QUEUE_PUSHES
-#define AVOID_NOOP_QUEUE_PUSHES (0) // FIXME: Move to config struct later
-#endif
//============================================================
// DEBUGGING
@@ -216,6 +223,42 @@ namespace netlist
/// FIXME: More work needed. Review magic numbers.
///
using fptype = double;
+
+ /// \brief Store input values in logic_terminal_t.
+ ///
+ /// Set to 1 to store values in logic_terminal_t instead of
+ /// accessing them indirectly by pointer from logic_net_t.
+ /// This approach is stricter and should identify bugs in
+ /// the netlist core faster. The approach needs
+ /// NL_USE_INPLACE_CORE_TERMS enabled to achieve some performance.
+ ///
+ /// By default it is disabled since it is not as fast as
+ /// the default approach. It is ~20% slower.
+ ///
+ using use_copy_instead_of_reference = std::integral_constant<bool, false>;
+
+ /// \brief Avoid unnecessary queue pushes
+ ///
+ /// Enable the setting below to avoid queue pushes were at execution
+ /// no action will be taken. This is academically cleaner, but
+ /// ~6% slower than allowing this to happen and filter it during
+ /// during "process".
+ ///
+ using avoid_noop_queue_pushes = std::integral_constant<bool, false>;
+
+ /// \brief Which sorted queue to use
+ ///
+ /// Use timed_queue_heap to use stdc++ heap functions instead of the
+ /// linear processing queue. This slows down execution by about 35%
+ /// on a Kaby Lake.
+ ///
+ /// The default is the linear queue.
+
+ // template <class A, class T>
+ // using timed_queue = plib::timed_queue_heap<A, T>;
+
+ template <typename A, typename T>
+ using timed_queue = plib::timed_queue_linear<A, T>;
};
/// \brief Netlist configuration.
@@ -225,6 +268,9 @@ namespace netlist
///
struct config : public config_default
{
+ //using mempool_align = std::integral_constant<std::size_t, 32>;
+ //using avoid_noop_queue_pushes = std::integral_constant<bool, true>;
+ //using use_copy_instead_of_reference = std::integral_constant<bool, true>;
};
using nl_fptype = config::fptype;
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 507ecea0aa7..02c7d11f2b2 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -8,577 +8,575 @@
namespace netlist
{
-// ----------------------------------------------------------------------------------------
-// A netlist parser
-// ----------------------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------------------
+ // A netlist parser
+ // ----------------------------------------------------------------------------------------
-void parser_t::verror(const pstring &msg)
-{
- m_setup.log().fatal("{1}", msg);
- throw nl_exception(plib::pfmt("{1}")(msg));
-}
+ void parser_t::verror(const pstring &msg)
+ {
+ m_setup.log().fatal("{1}", msg);
+ throw nl_exception(plib::pfmt("{1}")(msg));
+ }
-parser_t::parser_t(nlparse_t &setup)
- : m_setup(setup)
- , m_cur_local(nullptr)
-{
- m_tokenizer.identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-$@")
- .number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers
- .whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
- .comment("/*", "*/", "//");
- m_tok_paren_left = m_tokenizer.register_token("(");
- m_tok_paren_right = m_tokenizer.register_token(")");
- m_tok_comma = m_tokenizer.register_token(",");
-
- m_tok_static = m_tokenizer.register_token("static");
- m_tok_ALIAS = m_tokenizer.register_token("ALIAS");
- m_tok_DIPPINS = m_tokenizer.register_token("DIPPINS");
- m_tok_NET_C = m_tokenizer.register_token("NET_C");
- m_tok_FRONTIER = m_tokenizer.register_token("OPTIMIZE_FRONTIER");
- m_tok_PARAM = m_tokenizer.register_token("PARAM");
- m_tok_DEFPARAM = m_tokenizer.register_token("DEFPARAM");
- m_tok_HINT = m_tokenizer.register_token("HINT");
- m_tok_NET_MODEL = m_tokenizer.register_token("NET_MODEL");
- m_tok_NET_REGISTER_DEV = m_tokenizer.register_token("NET_REGISTER_DEV");
- m_tok_INCLUDE = m_tokenizer.register_token("INCLUDE");
- m_tok_LOCAL_SOURCE = m_tokenizer.register_token("LOCAL_SOURCE");
- m_tok_LOCAL_LIB_ENTRY = m_tokenizer.register_token("LOCAL_LIB_ENTRY");
- m_tok_EXTERNAL_LIB_ENTRY = m_tokenizer.register_token("EXTERNAL_LIB_ENTRY");
- m_tok_SUBMODEL = m_tokenizer.register_token("SUBMODEL");
- m_tok_NETLIST_START = m_tokenizer.register_token("NETLIST_START");
- m_tok_NETLIST_END = m_tokenizer.register_token("NETLIST_END");
- m_tok_NETLIST_EXTERNAL = m_tokenizer.register_token("NETLIST_EXTERNAL");
- m_tok_EXTERNAL_SOURCE = m_tokenizer.register_token("EXTERNAL_SOURCE");
- m_tok_TRUTHTABLE_START = m_tokenizer.register_token("TRUTHTABLE_START");
- m_tok_TRUTHTABLE_END = m_tokenizer.register_token("TRUTHTABLE_END");
- m_tok_TRUTHTABLE_ENTRY = m_tokenizer.register_token("TRUTHTABLE_ENTRY");
- m_tok_TT_HEAD = m_tokenizer.register_token("TT_HEAD");
- m_tok_TT_LINE = m_tokenizer.register_token("TT_LINE");
- m_tok_TT_FAMILY = m_tokenizer.register_token("TT_FAMILY");
-
- m_tokenizer.register_token("RES_R");
- m_tokenizer.register_token("RES_K");
- m_tokenizer.register_token("RES_M");
- m_tokenizer.register_token("CAP_U");
- m_tokenizer.register_token("CAP_N");
- m_tokenizer.register_token("CAP_P");
-
-}
-
-bool parser_t::parse(plib::istream_uptr &&strm, const pstring &nlname)
-{
- token_store_t tokstor;
- parse_tokens(std::move(strm), tokstor);
- return parse(tokstor, nlname);
-}
+ parser_t::parser_t(nlparse_t &setup)
+ : m_setup(setup)
+ , m_cur_local(nullptr)
+ {
+ m_tokenizer.identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-$@")
+ .number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers
+ .whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
+ .comment("/*", "*/", "//");
+ m_tok_paren_left = m_tokenizer.register_token("(");
+ m_tok_paren_right = m_tokenizer.register_token(")");
+ m_tok_comma = m_tokenizer.register_token(",");
+
+ m_tok_static = m_tokenizer.register_token("static");
+ m_tok_ALIAS = m_tokenizer.register_token("ALIAS");
+ m_tok_DIPPINS = m_tokenizer.register_token("DIPPINS");
+ m_tok_NET_C = m_tokenizer.register_token("NET_C");
+ m_tok_FRONTIER = m_tokenizer.register_token("OPTIMIZE_FRONTIER");
+ m_tok_PARAM = m_tokenizer.register_token("PARAM");
+ m_tok_DEFPARAM = m_tokenizer.register_token("DEFPARAM");
+ m_tok_HINT = m_tokenizer.register_token("HINT");
+ m_tok_NET_MODEL = m_tokenizer.register_token("NET_MODEL");
+ m_tok_NET_REGISTER_DEV = m_tokenizer.register_token("NET_REGISTER_DEV");
+ m_tok_INCLUDE = m_tokenizer.register_token("INCLUDE");
+ m_tok_LOCAL_SOURCE = m_tokenizer.register_token("LOCAL_SOURCE");
+ m_tok_LOCAL_LIB_ENTRY = m_tokenizer.register_token("LOCAL_LIB_ENTRY");
+ m_tok_EXTERNAL_LIB_ENTRY = m_tokenizer.register_token("EXTERNAL_LIB_ENTRY");
+ m_tok_SUBMODEL = m_tokenizer.register_token("SUBMODEL");
+ m_tok_NETLIST_START = m_tokenizer.register_token("NETLIST_START");
+ m_tok_NETLIST_END = m_tokenizer.register_token("NETLIST_END");
+ m_tok_NETLIST_EXTERNAL = m_tokenizer.register_token("NETLIST_EXTERNAL");
+ m_tok_EXTERNAL_SOURCE = m_tokenizer.register_token("EXTERNAL_SOURCE");
+ m_tok_TRUTHTABLE_START = m_tokenizer.register_token("TRUTHTABLE_START");
+ m_tok_TRUTHTABLE_END = m_tokenizer.register_token("TRUTHTABLE_END");
+ m_tok_TRUTHTABLE_ENTRY = m_tokenizer.register_token("TRUTHTABLE_ENTRY");
+ m_tok_TT_HEAD = m_tokenizer.register_token("TT_HEAD");
+ m_tok_TT_LINE = m_tokenizer.register_token("TT_LINE");
+ m_tok_TT_FAMILY = m_tokenizer.register_token("TT_FAMILY");
+
+ m_tokenizer.register_token("RES_R");
+ m_tokenizer.register_token("RES_K");
+ m_tokenizer.register_token("RES_M");
+ m_tokenizer.register_token("CAP_U");
+ m_tokenizer.register_token("CAP_N");
+ m_tokenizer.register_token("CAP_P");
-void parser_t::parse_tokens(plib::istream_uptr &&strm, token_store_t &tokstor)
-{
- plib::putf8_reader u8reader(strm.release_stream());
- m_tokenizer.append_to_store(&u8reader, tokstor);
-}
+ }
-bool parser_t::parse(const token_store_t &tokstor, const pstring &nlname)
-{
- set_token_source(&tokstor);
+ bool parser_t::parse(plib::istream_uptr &&strm, const pstring &nlname)
+ {
+ token_store_t tokstor;
+ parse_tokens(std::move(strm), tokstor);
+ return parse(tokstor, nlname);
+ }
- bool in_nl = false;
+ void parser_t::parse_tokens(plib::istream_uptr &&strm, token_store_t &tokstor)
+ {
+ plib::putf8_reader u8reader(strm.release_stream());
+ m_tokenizer.append_to_store(&u8reader, tokstor);
+ }
- while (true)
+ bool parser_t::parse(const token_store_t &tokstor, const pstring &nlname)
{
- // FIXME: line numbers in cached local netlists are wrong
- // need to process raw tokens here.
- token_t token = get_token_raw();
- if (token.is_type(token_type::ENDOFFILE))
- {
- return false;
- }
+ set_token_source(&tokstor);
+
+ bool in_nl = false;
- if (token.is(m_tok_NETLIST_END) || token.is(m_tok_TRUTHTABLE_END))
+ while (true)
{
- if (!in_nl)
- error (MF_PARSER_UNEXPECTED_1(token.str()));
- else
+ // FIXME: line numbers in cached local netlists are wrong
+ // need to process raw tokens here.
+ token_t token = get_token_raw();
+ if (token.is_type(token_type::ENDOFFILE))
{
- in_nl = false;
+ return false;
}
- require_token(m_tok_paren_left);
- require_token(m_tok_paren_right);
- m_cur_local->push_back(token);
- m_cur_local->push_back(token_t(m_tok_paren_left));
- m_cur_local->push_back(token_t(m_tok_paren_right));
+ if (token.is(m_tok_NETLIST_END) || token.is(m_tok_TRUTHTABLE_END))
+ {
+ if (!in_nl)
+ error (MF_PARSER_UNEXPECTED_1(token.str()));
+ else
+ {
+ in_nl = false;
+ }
+ require_token(m_tok_paren_left);
+ require_token(m_tok_paren_right);
+
+ m_cur_local->push_back(token);
+ m_cur_local->push_back(token_t(m_tok_paren_left));
+ m_cur_local->push_back(token_t(m_tok_paren_right));
- }
- else if (token.is(m_tok_NETLIST_START) || token.is(m_tok_TRUTHTABLE_START))
- {
- if (in_nl)
- error (MF_PARSER_UNEXPECTED_1(token.str()));
- require_token(m_tok_paren_left);
- token_t name = get_token();
- if (token.is(m_tok_NETLIST_START) && (name.str() == nlname || nlname.empty()))
+ }
+ else if (token.is(m_tok_NETLIST_START) || token.is(m_tok_TRUTHTABLE_START))
+ {
+ if (in_nl)
+ error (MF_PARSER_UNEXPECTED_1(token.str()));
+ require_token(m_tok_paren_left);
+ token_t name = get_token();
+ if (token.is(m_tok_NETLIST_START) && (name.str() == nlname || nlname.empty()))
+ {
+ require_token(m_tok_paren_right);
+ parse_netlist();
+ return true;
+ }
+ if (token.is(m_tok_TRUTHTABLE_START) && name.str() == nlname)
+ {
+ net_truth_table_start(nlname);
+ return true;
+ }
+
+ // create a new cached local store
+ m_local.emplace(name.str(), token_store_t());
+ m_cur_local = &m_local[name.str()];
+ auto sl = location();
+ auto li = plib::pfmt("# {1} \"{2}\"")(sl.line(), sl.file_name());
+
+ m_cur_local->push_back(token_t(token_type::LINEMARKER, li));
+ m_cur_local->push_back(token);
+ m_cur_local->push_back(token_t(m_tok_paren_left));
+ m_cur_local->push_back(name);
+ //m_cur_local->push_back(token_t(m_tok_paren_right));
+ in_nl = true;
+ }
+ // FIXME: do we really need this going forward ? there should be no need
+ // for NETLIST_EXTERNAL in netlist files
+ else if (token.is(m_tok_NETLIST_EXTERNAL))
{
+ if (in_nl)
+ error (MF_UNEXPECTED_NETLIST_EXTERNAL());
+ require_token(m_tok_paren_left);
+ token_t name = get_token();
require_token(m_tok_paren_right);
- parse_netlist();
- return true;
}
- if (token.is(m_tok_TRUTHTABLE_START) && name.str() == nlname)
+ else if (!in_nl)
{
- net_truth_table_start(nlname);
- return true;
+ if (!token.is(m_tok_static) && !token.is_type(token_type::SOURCELINE)
+ && !token.is_type(token_type::LINEMARKER))
+ error(MF_EXPECTED_NETLIST_START_1(token.str()));
+ }
+ else
+ {
+ m_cur_local->push_back(token);
}
-
- // create a new cached local store
- m_local.emplace(name.str(), token_store_t());
- m_cur_local = &m_local[name.str()];
- auto sl = location();
- auto li = plib::pfmt("# {1} \"{2}\"")(sl.line(), sl.file_name());
-
- m_cur_local->push_back(token_t(token_type::LINEMARKER, li));
- m_cur_local->push_back(token);
- m_cur_local->push_back(token_t(m_tok_paren_left));
- m_cur_local->push_back(name);
- //m_cur_local->push_back(token_t(m_tok_paren_right));
- in_nl = true;
- }
- // FIXME: do we really need this going forward ? there should be no need
- // for NETLIST_EXTERNAL in netlist files
- else if (token.is(m_tok_NETLIST_EXTERNAL))
- {
- if (in_nl)
- error (MF_UNEXPECTED_NETLIST_EXTERNAL());
- require_token(m_tok_paren_left);
- token_t name = get_token();
- require_token(m_tok_paren_right);
- }
- else if (!in_nl)
- {
- if (!token.is(m_tok_static) && !token.is_type(token_type::SOURCELINE)
- && !token.is_type(token_type::LINEMARKER))
- error(MF_EXPECTED_NETLIST_START_1(token.str()));
- }
- else
- {
- m_cur_local->push_back(token);
}
}
-}
-void parser_t::parse_netlist()
-{
- while (true)
+ void parser_t::parse_netlist()
{
- token_t token = get_token();
-
- if (token.is_type(token_type::ENDOFFILE))
- error (MF_UNEXPECTED_END_OF_FILE());
-
- m_setup.log().debug("Parser: Device: {1}\n", token.str());
-
- if (token.is(m_tok_ALIAS))
- net_alias();
- else if (token.is(m_tok_DIPPINS))
- dip_pins();
- else if (token.is(m_tok_NET_C))
- net_c();
- else if (token.is(m_tok_FRONTIER))
- frontier();
- else if (token.is(m_tok_PARAM))
- netdev_param();
- else if (token.is(m_tok_DEFPARAM))
- netdev_default_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))
- net_sub_model();
- else if (token.is(m_tok_INCLUDE))
- net_include();
- else if (token.is(m_tok_LOCAL_SOURCE))
- net_local_source();
- else if (token.is(m_tok_EXTERNAL_SOURCE))
- net_external_source();
- else if (token.is(m_tok_LOCAL_LIB_ENTRY))
- net_lib_entry(true);
- else if (token.is(m_tok_EXTERNAL_LIB_ENTRY))
- net_lib_entry(false);
- else if (token.is(m_tok_TRUTHTABLE_ENTRY))
- {
- require_token(m_tok_paren_left);
- pstring name(get_identifier());
- register_local_as_source(name);
- m_setup.include(name);
- require_token(m_tok_paren_right);
- }
- else if (token.is(m_tok_NET_REGISTER_DEV))
- {
- net_register_dev();
- }
- else if (token.is(m_tok_NETLIST_END))
+ while (true)
{
- netdev_netlist_end();
- return;
+ token_t token = get_token();
+
+ if (token.is_type(token_type::ENDOFFILE))
+ error (MF_UNEXPECTED_END_OF_FILE());
+
+ m_setup.log().debug("Parser: Device: {1}\n", token.str());
+
+ if (token.is(m_tok_ALIAS))
+ net_alias();
+ else if (token.is(m_tok_DIPPINS))
+ dip_pins();
+ else if (token.is(m_tok_NET_C))
+ net_c();
+ else if (token.is(m_tok_FRONTIER))
+ frontier();
+ else if (token.is(m_tok_PARAM))
+ netdev_param();
+ else if (token.is(m_tok_DEFPARAM))
+ netdev_default_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))
+ net_sub_model();
+ else if (token.is(m_tok_INCLUDE))
+ net_include();
+ else if (token.is(m_tok_LOCAL_SOURCE))
+ net_local_source();
+ else if (token.is(m_tok_EXTERNAL_SOURCE))
+ net_external_source();
+ else if (token.is(m_tok_LOCAL_LIB_ENTRY))
+ net_lib_entry(true);
+ else if (token.is(m_tok_EXTERNAL_LIB_ENTRY))
+ net_lib_entry(false);
+ else if (token.is(m_tok_TRUTHTABLE_ENTRY))
+ {
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ register_local_as_source(name);
+ m_setup.include(name);
+ require_token(m_tok_paren_right);
+ }
+ else if (token.is(m_tok_NET_REGISTER_DEV))
+ {
+ net_register_dev();
+ }
+ else if (token.is(m_tok_NETLIST_END))
+ {
+ netdev_netlist_end();
+ return;
+ }
+ else if (!token.is_type(token_type::IDENTIFIER))
+ error(MF_EXPECTED_IDENTIFIER_GOT_1(token.str()));
+ else
+ device(token.str());
}
- else if (!token.is_type(token_type::IDENTIFIER))
- error(MF_EXPECTED_IDENTIFIER_GOT_1(token.str()));
- else
- device(token.str());
}
-}
-void parser_t::net_lib_entry(bool is_local)
-{
- require_token(m_tok_paren_left);
- pstring name(get_identifier());
+ void parser_t::net_lib_entry(bool is_local)
+ {
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
- if (is_local)
- register_local_as_source(name);
- else if (m_local.find(name) != m_local.end())
- error(MF_EXTERNAL_SOURCE_IS_LOCAL_1(name));
+ if (is_local)
+ register_local_as_source(name);
+ else if (m_local.find(name) != m_local.end())
+ error(MF_EXTERNAL_SOURCE_IS_LOCAL_1(name));
- // FIXME: Need to pass in parameter definition FIXME: get line number right
- m_setup.register_lib_entry(name, "", location());
- require_token(m_tok_paren_right);
-}
+ // FIXME: Need to pass in parameter definition FIXME: get line number right
+ m_setup.register_lib_entry(name, "", location());
+ require_token(m_tok_paren_right);
+ }
-void parser_t::net_truth_table_start(const pstring &nlname)
-{
- bool head_found(false);
-
- // parse remaining parameters
- require_token(m_tok_comma);
- long ni = get_number_long();
- require_token(m_tok_comma);
- long no = get_number_long();
- require_token(m_tok_comma);
- pstring def_param = get_string();
- require_token(m_tok_paren_right);
-
- netlist::tt_desc desc;
- desc.name = nlname;
- desc.ni = gsl::narrow<unsigned long>(ni);
- desc.no = gsl::narrow<unsigned long>(no);
- desc.family = "";
-
- while (true)
+ void parser_t::net_truth_table_start(const pstring &nlname)
{
- token_t token = get_token();
+ bool head_found(false);
+
+ // parse remaining parameters
+ require_token(m_tok_comma);
+ long ni = get_number_long();
+ require_token(m_tok_comma);
+ long no = get_number_long();
+ require_token(m_tok_comma);
+ pstring def_param = get_string();
+ require_token(m_tok_paren_right);
- if (token.is(m_tok_TT_HEAD))
- {
- require_token(m_tok_paren_left);
- desc.desc.push_back(get_string());
- require_token(m_tok_paren_right);
- head_found = true;
- }
- else if (token.is(m_tok_TT_LINE))
- {
- if (!head_found)
- error(MF_TT_LINE_WITHOUT_HEAD());
- require_token(m_tok_paren_left);
- desc.desc.push_back(get_string());
- require_token(m_tok_paren_right);
- }
- else if (token.is(m_tok_TT_FAMILY))
- {
- require_token(m_tok_paren_left);
- desc.family = get_string();
- require_token(m_tok_paren_right);
- }
- else
+ netlist::tt_desc desc;
+ desc.name = nlname;
+ desc.ni = gsl::narrow<unsigned long>(ni);
+ desc.no = gsl::narrow<unsigned long>(no);
+ desc.family = "";
+
+ while (true)
{
- require_token(token, m_tok_TRUTHTABLE_END);
- require_token(m_tok_paren_left);
- require_token(m_tok_paren_right);
- // FIXME: proper location
- m_setup.truth_table_create(desc, def_param, location());
- return;
+ token_t token = get_token();
+
+ if (token.is(m_tok_TT_HEAD))
+ {
+ require_token(m_tok_paren_left);
+ desc.desc.push_back(get_string());
+ require_token(m_tok_paren_right);
+ head_found = true;
+ }
+ else if (token.is(m_tok_TT_LINE))
+ {
+ if (!head_found)
+ error(MF_TT_LINE_WITHOUT_HEAD());
+ require_token(m_tok_paren_left);
+ desc.desc.push_back(get_string());
+ require_token(m_tok_paren_right);
+ }
+ else if (token.is(m_tok_TT_FAMILY))
+ {
+ require_token(m_tok_paren_left);
+ desc.family = get_string();
+ require_token(m_tok_paren_right);
+ }
+ else
+ {
+ require_token(token, m_tok_TRUTHTABLE_END);
+ require_token(m_tok_paren_left);
+ require_token(m_tok_paren_right);
+ // FIXME: proper location
+ m_setup.truth_table_create(desc, def_param, location());
+ return;
+ }
}
}
-}
-void parser_t::netdev_netlist_end()
-{
- // don't do much
- require_token(m_tok_paren_left);
- require_token(m_tok_paren_right);
-}
-
-void parser_t::net_model()
-{
- require_token(m_tok_paren_left);
- pstring model = get_string();
- m_setup.register_model(model);
- require_token(m_tok_paren_right);
-}
+ void parser_t::netdev_netlist_end()
+ {
+ // don't do much
+ require_token(m_tok_paren_left);
+ require_token(m_tok_paren_right);
+ }
-void parser_t::net_sub_model()
-{
- require_token(m_tok_paren_left);
- pstring model(get_identifier());
- require_token(m_tok_comma);
- pstring name = get_identifier();
- require_token(m_tok_paren_right);
-
- m_setup.namespace_push(name);
- m_setup.include(model);
- m_setup.namespace_pop();
-}
-
-void parser_t::frontier()
-{
- require_token(m_tok_paren_left);
- // don't do much
- pstring attachat = get_identifier();
- require_token(m_tok_comma);
- auto tok = get_token();
- auto r_IN = stringify_expression(tok);
- require_token(tok, m_tok_comma);
- tok = get_token();
- auto r_OUT = stringify_expression(tok);
- require_token(tok, m_tok_paren_right);
-
- m_setup.register_frontier(attachat, r_IN, r_OUT);
-}
-
-void parser_t::net_include()
-{
- require_token(m_tok_paren_left);
- pstring name(get_identifier());
- require_token(m_tok_paren_right);
+ void parser_t::net_model()
+ {
+ require_token(m_tok_paren_left);
+ pstring model = get_string();
+ m_setup.register_model(model);
+ require_token(m_tok_paren_right);
+ }
- m_setup.include(name);
-}
+ void parser_t::net_sub_model()
+ {
+ require_token(m_tok_paren_left);
+ pstring model(get_identifier());
+ require_token(m_tok_comma);
+ pstring name = get_identifier();
+ require_token(m_tok_paren_right);
-void parser_t::net_local_source()
-{
- // This directive is only for hardcoded netlists. Ignore it here.
- require_token(m_tok_paren_left);
- pstring name(get_identifier());
- require_token(m_tok_paren_right);
+ m_setup.namespace_push(name);
+ m_setup.include(model);
+ m_setup.namespace_pop();
+ }
- register_local_as_source(name);
-}
+ void parser_t::frontier()
+ {
+ require_token(m_tok_paren_left);
+ // don't do much
+ pstring attach_at = get_identifier();
+ require_token(m_tok_comma);
+ auto tok = get_token();
+ auto r_IN = stringify_expression(tok);
+ require_token(tok, m_tok_comma);
+ tok = get_token();
+ auto r_OUT = stringify_expression(tok);
+ require_token(tok, m_tok_paren_right);
-void parser_t::register_local_as_source(const pstring &name)
-{
- auto p = m_local.find(name);
- if (p != m_local.end())
- m_setup.register_source<source_token_t>(name, p->second);
- else
- error(MF_LOCAL_SOURCE_NOT_FOUND_1(name));
-}
-
-void parser_t::net_external_source()
-{
- // This directive is only for hardcoded netlists. Ignore it here.
- require_token(m_tok_paren_left);
- pstring name(get_identifier());
- require_token(m_tok_paren_right);
+ m_setup.register_frontier(attach_at, r_IN, r_OUT);
+ }
-}
+ void parser_t::net_include()
+ {
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ require_token(m_tok_paren_right);
-void parser_t::net_alias()
-{
- require_token(m_tok_paren_left);
- pstring alias = get_identifier_or_number();
+ m_setup.include(name);
+ }
- require_token(m_tok_comma);
+ void parser_t::net_local_source()
+ {
+ // This directive is only for hardcoded netlists. Ignore it here.
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ require_token(m_tok_paren_right);
- pstring out = get_identifier();
+ register_local_as_source(name);
+ }
- require_token(m_tok_paren_right);
+ void parser_t::register_local_as_source(const pstring &name)
+ {
+ auto p = m_local.find(name);
+ if (p != m_local.end())
+ m_setup.register_source<source_token_t>(name, p->second);
+ else
+ error(MF_LOCAL_SOURCE_NOT_FOUND_1(name));
+ }
- m_setup.log().debug("Parser: Alias: {1} {2}\n", alias, out);
- m_setup.register_alias(alias, out);
-}
+ void parser_t::net_external_source()
+ {
+ // This directive is only for hardcoded netlists. Ignore it here.
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ require_token(m_tok_paren_right);
-void parser_t::net_c()
-{
- require_token(m_tok_paren_left);
- pstring first = get_identifier();
- require_token(m_tok_comma);
+ }
- while (true)
+ void parser_t::net_alias()
{
- pstring t1 = get_identifier();
- m_setup.register_link(first , t1);
- m_setup.log().debug("Parser: Connect: {1} {2}\n", first, t1);
- token_t n = get_token();
- if (n.is(m_tok_paren_right))
- break;
- if (!n.is(m_tok_comma))
- error(MF_EXPECTED_COMMA_OR_RP_1(n.str()));
- }
+ require_token(m_tok_paren_left);
+ pstring alias = get_identifier_or_number();
-}
+ require_token(m_tok_comma);
-void parser_t::dip_pins()
-{
- std::vector<pstring> pins;
+ pstring out = get_identifier();
- require_token(m_tok_paren_left);
- pins.push_back(get_identifier());
- require_token(m_tok_comma);
+ require_token(m_tok_paren_right);
- while (true)
+ m_setup.log().debug("Parser: Alias: {1} {2}\n", alias, out);
+ m_setup.register_alias(alias, out);
+ }
+
+ void parser_t::net_c()
{
- pstring t1 = get_identifier();
- pins.push_back(t1);
- token_t n = get_token();
- if (n.is(m_tok_paren_right))
- break;
- if (!n.is(m_tok_comma))
- error(MF_EXPECTED_COMMA_OR_RP_1(n.str()));
+ require_token(m_tok_paren_left);
+ pstring first = get_identifier();
+ require_token(m_tok_comma);
+
+ while (true)
+ {
+ pstring t1 = get_identifier();
+ m_setup.register_link(first , t1);
+ m_setup.log().debug("Parser: Connect: {1} {2}\n", first, t1);
+ token_t n = get_token();
+ if (n.is(m_tok_paren_right))
+ break;
+ if (!n.is(m_tok_comma))
+ error(MF_EXPECTED_COMMA_OR_RP_1(n.str()));
+ }
+
}
- if ((pins.size() % 2) == 1)
- error(MF_DIPPINS_EQUAL_NUMBER_1(pins[0]));
- std::size_t n = pins.size();
- for (std::size_t i = 0; i < n / 2; i++)
+
+ void parser_t::dip_pins()
{
- m_setup.register_alias(plib::pfmt("{1}")(i+1), pins[i*2]);
- m_setup.register_alias(plib::pfmt("{1}")(n-i), pins[i*2 + 1]);
+ std::vector<pstring> pins;
+
+ require_token(m_tok_paren_left);
+ pins.push_back(get_identifier());
+ require_token(m_tok_comma);
+
+ while (true)
+ {
+ pstring t1 = get_identifier();
+ pins.push_back(t1);
+ token_t n = get_token();
+ if (n.is(m_tok_paren_right))
+ break;
+ if (!n.is(m_tok_comma))
+ error(MF_EXPECTED_COMMA_OR_RP_1(n.str()));
+ }
+ if ((pins.size() % 2) == 1)
+ error(MF_DIPPINS_EQUAL_NUMBER_1(pins[0]));
+ std::size_t n = pins.size();
+ for (std::size_t i = 0; i < n / 2; i++)
+ {
+ m_setup.register_alias(plib::pfmt("{1}")(i+1), pins[i*2]);
+ m_setup.register_alias(plib::pfmt("{1}")(n-i), pins[i*2 + 1]);
+ }
}
-}
-void parser_t::netdev_param()
-{
- require_token(m_tok_paren_left);
- pstring param(get_identifier());
- require_token(m_tok_comma);
- token_t tok = get_token();
- if (tok.is_type(token_type::STRING))
+ void parser_t::netdev_param()
{
- m_setup.log().debug("Parser: Param: {1} {2}\n", param, tok.str());
- m_setup.register_param(param, tok.str());
- require_token(m_tok_paren_right);
+ require_token(m_tok_paren_left);
+ pstring param(get_identifier());
+ require_token(m_tok_comma);
+ token_t tok = get_token();
+ if (tok.is_type(token_type::STRING))
+ {
+ m_setup.log().debug("Parser: Param: {1} {2}\n", param, tok.str());
+ m_setup.register_param(param, tok.str());
+ require_token(m_tok_paren_right);
+ }
+ else
+ {
+ auto val = stringify_expression(tok);
+ m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
+ m_setup.register_param(param, val);
+ require_token(tok, m_tok_paren_right);
+ }
}
- else
+
+ void parser_t::netdev_default_param()
{
- auto val = stringify_expression(tok);
- m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
- m_setup.register_param(param, val);
- require_token(tok, m_tok_paren_right);
+ require_token(m_tok_paren_left);
+ pstring param(get_identifier());
+ require_token(m_tok_comma);
+ token_t tok = get_token();
+ if (tok.is_type(token_type::STRING))
+ {
+ m_setup.log().debug("Parser: DefParam: {1} {2}\n", param, tok.str());
+ m_setup.register_default_param(param, tok.str());
+ require_token(m_tok_paren_right);
+ }
+ else
+ {
+ auto val = stringify_expression(tok);
+ m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
+ m_setup.register_default_param(param, val);
+ require_token(tok, m_tok_paren_right);
+ }
}
-}
-void parser_t::netdev_default_param()
-{
- require_token(m_tok_paren_left);
- pstring param(get_identifier());
- require_token(m_tok_comma);
- token_t tok = get_token();
- if (tok.is_type(token_type::STRING))
+ void parser_t::netdev_hint()
{
- m_setup.log().debug("Parser: DefParam: {1} {2}\n", param, tok.str());
- m_setup.register_defparam(param, tok.str());
+ require_token(m_tok_paren_left);
+ pstring id(get_identifier());
+ require_token(m_tok_comma);
+ pstring hint(get_identifier());
+ m_setup.register_hint(id, ".HINT_" + hint);
require_token(m_tok_paren_right);
}
- else
+
+ void parser_t::net_register_dev()
{
- auto val = stringify_expression(tok);
- m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
- m_setup.register_defparam(param, val);
- require_token(tok, m_tok_paren_right);
+ require_token(m_tok_paren_left);
+ pstring type(get_identifier());
+ require_token(m_tok_comma);
+ pstring name(get_identifier());
+ require_token(m_tok_paren_right);
+
+ m_setup.register_dev(type, name);
}
-}
-void parser_t::netdev_hint()
-{
- require_token(m_tok_paren_left);
- pstring id(get_identifier());
- require_token(m_tok_comma);
- pstring hint(get_identifier());
- m_setup.register_hint(id, ".HINT_" + hint);
- require_token(m_tok_paren_right);
-}
-
-void parser_t::net_register_dev()
-{
- require_token(m_tok_paren_left);
- pstring type(get_identifier());
- require_token(m_tok_comma);
- pstring name(get_identifier());
- require_token(m_tok_paren_right);
+ void parser_t::device(const pstring &dev_type)
+ {
+ std::vector<pstring> params;
- m_setup.register_dev(type, name);
-}
+ require_token(m_tok_paren_left);
+ pstring devname(get_identifier());
-void parser_t::device(const pstring &dev_type)
-{
- std::vector<pstring> params;
+ m_setup.log().debug("Parser: IC: {1}\n", devname);
- require_token(m_tok_paren_left);
- pstring devname(get_identifier());
+ auto tok(get_token());
- m_setup.log().debug("Parser: IC: {1}\n", devname);
+ while (tok.is(m_tok_comma))
+ {
+ tok = get_token();
+ if (tok.is_type(token_type::STRING))
+ {
+ params.push_back(tok.str());
+ tok = get_token();
+ }
+ else
+ {
+ auto value = stringify_expression(tok);
+ params.push_back(value);
+ }
+ }
+
+ require_token(tok, m_tok_paren_right);
+ m_setup.register_dev(dev_type, devname, params);
+ }
- auto tok(get_token());
+ // ----------------------------------------------------------------------------------------
+ // private
+ // ----------------------------------------------------------------------------------------
- while (tok.is(m_tok_comma))
+ pstring parser_t::stringify_expression(token_t &tok)
{
- tok = get_token();
- if (/*tok.is_type(token_type::IDENTIFIER) ||*/ tok.is_type(token_type::STRING))
+ int pc(0);
+ pstring ret;
+ while (!tok.is(m_tok_comma))
{
- params.push_back(tok.str());
+ if (tok.is(m_tok_paren_left))
+ pc++;
+ else if (tok.is(m_tok_paren_right))
+ {
+ if (pc<=0)
+ break;
+ pc--;
+ }
+ ret += tok.str();
tok = get_token();
}
- else
- {
- auto value = stringify_expression(tok);
- params.push_back(value);
- }
+ return ret;
}
- require_token(tok, m_tok_paren_right);
- m_setup.register_dev(dev_type, devname, params);
-}
-
+ // ----------------------------------------------------------------------------------------
+ // source_token_t
+ // ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// private
-// ----------------------------------------------------------------------------------------
-
-pstring parser_t::stringify_expression(token_t &tok)
-{
- int pc(0);
- pstring ret;
- while (!tok.is(m_tok_comma))
+ bool source_token_t::parse(nlparse_t &setup, const pstring &name)
{
- if (tok.is(m_tok_paren_left))
- pc++;
- else if (tok.is(m_tok_paren_right))
+ if (name == m_name)
{
- if (pc<=0)
- break;
- pc--;
+ auto ret = setup.parse_tokens(m_store, name);
+ return ret;
}
- ret += tok.str();
- tok = get_token();
- }
- return ret;
-}
-// ----------------------------------------------------------------------------------------
-// source_token_t
-// ----------------------------------------------------------------------------------------
+ return false;
+ }
-bool source_token_t::parse(nlparse_t &setup, const pstring &name)
-{
- if (name == m_name)
+ plib::istream_uptr source_token_t::stream([[maybe_unused]] const pstring &name)
{
- auto ret = setup.parse_tokens(m_store, name);
- return ret;
+ return plib::istream_uptr();
}
- return false;
-}
-
-plib::istream_uptr source_token_t::stream([[maybe_unused]] const pstring &name)
-{
- return plib::istream_uptr();
-}
-
-
} // namespace netlist
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index b98ed123a7b..d8040258568 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -35,7 +35,7 @@ namespace netlist
{
pstring alias_fqn = build_fqn(alias);
pstring out_fqn = build_fqn(out);
- register_alias_nofqn(alias_fqn, out_fqn);
+ register_alias_no_fqn(alias_fqn, out_fqn);
}
void nlparse_t::register_dip_alias_arr(const pstring &terms)
@@ -70,7 +70,7 @@ namespace netlist
void nlparse_t::register_dev(const pstring &classname, const pstring &name,
const std::vector<pstring> &params_and_connections,
- factory::element_t **felem)
+ factory::element_t **factory_element)
{
auto *f = factory().factory_by_name(classname);
@@ -98,25 +98,25 @@ namespace netlist
if (!params_and_connections.empty())
{
- auto ptok(params_and_connections.begin());
- auto ptok_end(params_and_connections.end());
+ auto token_ptr(params_and_connections.begin());
+ auto token_end(params_and_connections.end());
for (const pstring &tp : parameter_list)
{
if (plib::startsWith(tp, "+"))
{
- if (ptok == ptok_end)
+ if (token_ptr == token_end)
{
auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
//break;
}
- pstring output_name = *ptok;
+ pstring output_name = *token_ptr;
log().debug("Link: {1} {2}", tp, output_name);
register_link(name + "." + tp.substr(1), output_name);
- ++ptok;
+ ++token_ptr;
}
else if (plib::startsWith(tp, "@"))
{
@@ -127,30 +127,30 @@ namespace netlist
}
else
{
- if (ptok == params_and_connections.end())
+ if (token_ptr == token_end)
{
auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
}
- pstring paramfq = name + "." + tp;
+ pstring fully_qualified_name = name + "." + tp;
- log().debug("Default parameter: {1}\n", paramfq);
+ log().debug("Default parameter: {1}\n", fully_qualified_name);
- register_param(paramfq, *ptok);
+ register_param(fully_qualified_name, *token_ptr);
- ++ptok;
+ ++token_ptr;
}
}
- if (ptok != params_and_connections.end())
+ if (token_ptr != params_and_connections.end())
{
MF_PARAM_COUNT_EXCEEDED_2 err(name, params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
}
}
- if (felem != nullptr)
- *felem = f;
+ if (factory_element != nullptr)
+ *factory_element = f;
}
void nlparse_t::register_hint(const pstring &object_name, const pstring &hint_name)
@@ -240,7 +240,7 @@ namespace netlist
{
if (idx->second.find("$(") == pstring::npos)
{
- //* There may be reason ... so make it an INFO
+ // There may be reason ... so make it an INFO
log().info(MI_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn,
idx->second, val));
}
@@ -248,7 +248,7 @@ namespace netlist
}
}
- void nlparse_t::register_defparam(const pstring &name, const pstring &def)
+ void nlparse_t::register_default_param(const pstring &name, const pstring &def)
{
// strip " from stringified strings
pstring val(def);
@@ -256,7 +256,7 @@ namespace netlist
val = def.substr(1, def.length() - 2);
// Replace "@." with the current namespace
val = plib::replace_all(val, "@.", namespace_prefix());
- m_abstract.m_defparams.emplace_back(namespace_prefix() + name, val);
+ m_abstract.m_default_params.emplace_back(namespace_prefix() + name, val);
}
factory::list_t &nlparse_t::factory() noexcept
@@ -284,17 +284,17 @@ namespace netlist
register_param(frontier_name + ".RIN", r_IN);
register_param(frontier_name + ".ROUT", r_OUT);
register_link(frontier_name + ".G", "GND");
- pstring attfn = build_fqn(attach);
+ pstring attach_fully_qualified_name = build_fqn(attach);
pstring front_fqn = build_fqn(frontier_name);
bool found = false;
for (auto & link : m_abstract.m_links)
{
- if (link.first == attfn)
+ if (link.first == attach_fully_qualified_name)
{
link.first = front_fqn + ".I";
found = true;
}
- else if (link.second == attfn)
+ else if (link.second == attach_fully_qualified_name)
{
link.second = front_fqn + ".I";
found = true;
@@ -329,7 +329,7 @@ namespace netlist
return namespace_prefix() + obj_name;
}
- void nlparse_t::register_alias_nofqn(const pstring &alias, const pstring &out)
+ void nlparse_t::register_alias_no_fqn(const pstring &alias, const pstring &out)
{
if (!m_abstract.m_alias.insert({alias, out}).second)
{
@@ -414,12 +414,12 @@ namespace netlist
void nlparse_t::remove_connections(const pstring &pin)
{
// FIXME: check use_cases - remove_connections may be dead
- pstring pinfn = build_fqn(pin);
+ pstring pin_fully_qualified_name = build_fqn(pin);
bool found = false;
for (auto link = m_abstract.m_links.begin(); link != m_abstract.m_links.end(); )
{
- if ((link->first == pinfn) || (link->second == pinfn))
+ if ((link->first == pin_fully_qualified_name) || (link->second == pin_fully_qualified_name))
{
log().verbose("removing connection: {1} <==> {2}\n", link->first, link->second);
link = m_abstract.m_links.erase(link);
@@ -451,7 +451,6 @@ namespace netlist
}
}
-
// ----------------------------------------------------------------------------------------
// Sources
// ----------------------------------------------------------------------------------------
@@ -469,1294 +468,1268 @@ namespace netlist
// setup_t
// ----------------------------------------------------------------------------------------
+ setup_t::setup_t(netlist_state_t &nlstate)
+ : m_abstract(nlstate.log())
+ , m_parser(nlstate.log(), m_abstract)
+ , m_nlstate(nlstate)
+ , m_models(m_abstract.m_models) // FIXME : parse abstract_t only
+ , m_netlist_params(nullptr)
+ , m_proxy_cnt(0)
+ {
+ }
-setup_t::setup_t(netlist_state_t &nlstate)
- : m_abstract(nlstate.log())
- , m_parser(nlstate.log(), m_abstract)
- , m_nlstate(nlstate)
- , m_models(m_abstract.m_models) // FIXME : parse abstract_t only
- , m_netlist_params(nullptr)
- , m_proxy_cnt(0)
-{
-}
-
-pstring setup_t::termtype_as_str(detail::core_terminal_t &in)
-{
- switch (in.type())
+ pstring setup_t::termtype_as_str(detail::core_terminal_t &in)
{
- case detail::terminal_type::TERMINAL:
- return "TERMINAL";
- case detail::terminal_type::INPUT:
- return "INPUT";
- case detail::terminal_type::OUTPUT:
- return "OUTPUT";
+ switch (in.type())
+ {
+ case detail::terminal_type::TERMINAL:
+ return "TERMINAL";
+ case detail::terminal_type::INPUT:
+ return "INPUT";
+ case detail::terminal_type::OUTPUT:
+ return "OUTPUT";
+ }
+ return "Error"; // Tease gcc
}
- return "Error"; // Tease gcc
-}
-pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) const
-{
- // When `get_intial_param_val` is called the parameter `<name>` is already registered
- // and the value `(value_string())` is set to the default value, e.g. "74XX"
- // If thus `$(IC5E.A.MODEL)` is given for `name=="IC5E.A.MODEL"` `value_string()` below
- // will return the default.
- // FIXME: It may be more explicit and stable to test if pattern==name and return
- // `def` in this case.
-
- auto i = m_abstract.m_param_values.find(name);
- auto found_pat(false);
- pstring v = (i == m_abstract.m_param_values.end()) ? def : i->second;
-
- do
- {
- found_pat = false;
- auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"})));
- std::size_t p(0);
- v = "";
- while (p < sp.size())
- {
- if (sp[p] == "$(")
+ pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) const
+ {
+ // When `get_intial_param_val` is called the parameter `<name>` is already registered
+ // and the value `(value_string())` is set to the default value, e.g. "74XX"
+ // If thus `$(IC5E.A.MODEL)` is given for `name=="IC5E.A.MODEL"` `value_string()` below
+ // will return the default.
+ // FIXME: It may be more explicit and stable to test if pattern==name and return
+ // `def` in this case.
+
+ auto i = m_abstract.m_param_values.find(name);
+ auto found_pat(false);
+ pstring v = (i == m_abstract.m_param_values.end()) ? def : i->second;
+
+ do
+ {
+ found_pat = false;
+ auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"})));
+ std::size_t p(0);
+ v = "";
+ while (p < sp.size())
{
- p++;
- pstring r;
- while (p < sp.size() && sp[p] != ")")
- r += sp[p++];
- p++;
- auto k = m_params.find(r);
- if (k != m_params.end())
+ if (sp[p] == "$(")
{
- v = v + k->second.param().value_string();
- found_pat = true;
+ p++;
+ pstring r;
+ while (p < sp.size() && sp[p] != ")")
+ r += sp[p++];
+ p++;
+ auto k = m_params.find(r);
+ if (k != m_params.end())
+ {
+ v = v + k->second.param().value_string();
+ found_pat = true;
+ }
+ else
+ {
+ // pass - on
+ v = v + "$(" + r + ")";
+ }
}
else
- {
- // pass - on
- v = v + "$(" + r + ")";
- }
+ v += sp[p++];
}
- else
- v += sp[p++];
- }
- } while (found_pat);
+ } while (found_pat);
- return v;
-}
+ return v;
+ }
-void setup_t::register_term(detail::core_terminal_t &term)
-{
- log().debug("{1} {2}\n", termtype_as_str(term), term.name());
- if (!m_terminals.insert({term.name(), &term}).second)
+ void setup_t::register_term(detail::core_terminal_t &term)
{
- log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
- throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
+ log().debug("{1} {2}\n", termtype_as_str(term), term.name());
+ if (!m_terminals.insert({term.name(), &term}).second)
+ {
+ log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
+ throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
+ }
}
-}
-void setup_t::register_term(terminal_t &term, terminal_t *other_term, const std::array<terminal_t *, 2> &splitter_terms)
-{
- this->register_term(term);
- m_connected_terminals.insert({&term, {other_term, splitter_terms[0], splitter_terms[1], nullptr}});
-}
+ void setup_t::register_term(terminal_t &term, terminal_t *other_term, const std::array<terminal_t *, 2> &splitter_terms)
+ {
+ this->register_term(term);
+ m_connected_terminals.insert({&term, {other_term, splitter_terms[0], splitter_terms[1], nullptr}});
+ }
-void setup_t::register_param_t(param_t &param)
-{
- if (!m_params.insert({param.name(), param_ref_t(param.device(), param)}).second)
+ void setup_t::register_param_t(param_t &param)
{
- log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
- throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
+ if (!m_params.insert({param.name(), param_ref_t(param.device(), param)}).second)
+ {
+ log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
+ throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
+ }
}
-}
-pstring setup_t::resolve_alias(const pstring &name) const
-{
- pstring temp = name;
- pstring ret;
+ pstring setup_t::resolve_alias(const pstring &name) const
+ {
+ pstring temp = name;
+ pstring ret;
- // FIXME: Detect endless loop
- do {
- ret = temp;
- auto p = m_abstract.m_alias.find(ret);
- temp = (p != m_abstract.m_alias.end() ? p->second : "");
- } while (!temp.empty() && temp != ret);
+ // FIXME: Detect endless loop
+ do {
+ ret = temp;
+ auto p = m_abstract.m_alias.find(ret);
+ temp = (p != m_abstract.m_alias.end() ? p->second : "");
+ } while (!temp.empty() && temp != ret);
- log().debug("{1}==>{2}\n", name, ret);
- return ret;
-}
+ log().debug("{1}==>{2}\n", name, ret);
+ return ret;
+ }
-pstring setup_t::de_alias(const pstring &alias) const
-{
- pstring temp = alias;
- pstring ret;
+ pstring setup_t::de_alias(const pstring &alias) const
+ {
+ pstring temp = alias;
+ pstring ret;
- // FIXME: Detect endless loop
- do {
- ret = temp;
- temp = "";
- for (const auto &e : m_abstract.m_alias)
- {
- // FIXME: this will resolve first one found
- if (e.second == ret)
+ // FIXME: Detect endless loop
+ do {
+ ret = temp;
+ temp = "";
+ for (const auto &e : m_abstract.m_alias)
{
- temp = e.first;
- break;
+ // FIXME: this will resolve first one found
+ if (e.second == ret)
+ {
+ temp = e.first;
+ break;
+ }
}
- }
- } while (!temp.empty() && temp != ret);
+ } while (!temp.empty() && temp != ret);
- log().debug("{1}==>{2}\n", alias, ret);
- return ret;
-}
+ log().debug("{1}==>{2}\n", alias, ret);
+ return ret;
+ }
-std::vector<pstring> setup_t::get_terminals_for_device_name(const pstring &devname) const
-{
- std::vector<pstring> terms;
- for (const auto & t : m_terminals)
+ std::vector<pstring> setup_t::get_terminals_for_device_name(const pstring &devname) const
{
- if (plib::startsWith(t.second->name(), devname))
+ std::vector<pstring> terms;
+ for (const auto & t : m_terminals)
{
- pstring tn(t.second->name().substr(devname.length()+1));
- if (tn.find('.') == pstring::npos)
- terms.push_back(tn);
+ if (plib::startsWith(t.second->name(), devname))
+ {
+ pstring tn(t.second->name().substr(devname.length()+1));
+ if (tn.find('.') == pstring::npos)
+ terms.push_back(tn);
+ }
}
- }
- for (const auto & t : m_abstract.m_alias)
- {
- if (plib::startsWith(t.first, devname))
+ for (const auto & t : m_abstract.m_alias)
{
- pstring tn(t.first.substr(devname.length()+1));
- if (tn.find('.') == pstring::npos)
+ if (plib::startsWith(t.first, devname))
{
- terms.push_back(tn);
- pstring resolved = resolve_alias(t.first);
- if (resolved != t.first)
+ pstring tn(t.first.substr(devname.length()+1));
+ if (tn.find('.') == pstring::npos)
{
- auto found = std::find(terms.begin(), terms.end(), resolved.substr(devname.length()+1));
- if (found!=terms.end())
- terms.erase(found);
+ terms.push_back(tn);
+ pstring resolved = resolve_alias(t.first);
+ if (resolved != t.first)
+ {
+ auto found = std::find(terms.begin(), terms.end(), resolved.substr(devname.length()+1));
+ if (found!=terms.end())
+ terms.erase(found);
+ }
}
}
}
+ return terms;
}
- return terms;
-}
-detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) const
-{
- const pstring &tname = resolve_alias(terminal_in);
- auto ret = m_terminals.find(tname);
- // look for default
- if (ret == m_terminals.end())
+ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) const
{
- // look for ".Q" std output
- ret = m_terminals.find(tname + ".Q");
- }
-
- detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
+ const pstring &tname = resolve_alias(terminal_in);
+ auto ret = m_terminals.find(tname);
+ // look for default
+ if (ret == m_terminals.end())
+ {
+ // look for ".Q" std output
+ ret = m_terminals.find(tname + ".Q");
+ }
- if (term == nullptr && required)
- {
- log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
- throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
- }
- if (term != nullptr)
- {
- log().debug("Found input {1}\n", tname);
- }
+ detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
- return term;
-}
+ if (term == nullptr && required)
+ {
+ log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
+ throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
+ }
+ if (term != nullptr)
+ {
+ log().debug("Found input {1}\n", tname);
+ }
-detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
- detail::terminal_type atype, bool required) const
-{
- const pstring &tname = resolve_alias(terminal_in);
- auto ret = m_terminals.find(tname);
- // look for default
- if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT)
- {
- // look for ".Q" std output
- ret = m_terminals.find(tname + ".Q");
+ return term;
}
- if (ret == m_terminals.end() && required)
- {
- log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
- throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
- }
- detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
- if (term != nullptr && term->type() != atype)
+ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
+ detail::terminal_type atype, bool required) const
{
- if (required)
+ const pstring &tname = resolve_alias(terminal_in);
+ auto ret = m_terminals.find(tname);
+ // look for default
+ if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT)
+ {
+ // look for ".Q" std output
+ ret = m_terminals.find(tname + ".Q");
+ }
+ if (ret == m_terminals.end() && required)
{
- log().fatal(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
- throw nl_exception(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
+ log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
+ throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
}
+ detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
- term = nullptr;
- }
- if (term != nullptr)
- log().debug("Found input {1}\n", tname);
+ if (term != nullptr && term->type() != atype)
+ {
+ if (required)
+ {
+ log().fatal(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
+ throw nl_exception(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
+ }
- return term;
-}
+ term = nullptr;
+ }
+ if (term != nullptr)
+ log().debug("Found input {1}\n", tname);
-param_ref_t setup_t::find_param(const pstring &param_in) const
-{
- const pstring resolved_param_name(resolve_alias(param_in));
- auto ret(m_params.find(resolved_param_name));
- if (ret == m_params.end())
+ return term;
+ }
+
+ param_ref_t setup_t::find_param(const pstring &param_in) const
{
- log().fatal(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
- throw nl_exception(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
+ const pstring resolved_param_name(resolve_alias(param_in));
+ auto ret(m_params.find(resolved_param_name));
+ if (ret == m_params.end())
+ {
+ log().fatal(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
+ throw nl_exception(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
+ }
+ return ret->second;
}
- return ret->second;
-}
+ //NOLINTNEXTLINE(misc-no-recursion)
+ devices::nld_base_proxy *setup_t::get_d_a_proxy(const detail::core_terminal_t &out)
+ {
+ gsl_Expects(out.is_logic());
-//NOLINTNEXTLINE(misc-no-recursion)
-devices::nld_base_proxy *setup_t::get_d_a_proxy(const detail::core_terminal_t &out)
-{
- gsl_Expects(out.is_logic());
+ const auto &out_cast = dynamic_cast<const logic_output_t &>(out);
+ auto iter_proxy(m_proxies.find(&out));
- const auto &out_cast = dynamic_cast<const logic_output_t &>(out);
- auto iter_proxy(m_proxies.find(&out));
+ if (iter_proxy != m_proxies.end())
+ return iter_proxy->second;
- if (iter_proxy != m_proxies.end())
- return iter_proxy->second;
+ // create a new one ...
+ pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt);
+ auto new_proxy =
+ out_cast.logic_family()->create_d_a_proxy(m_nlstate, x, &out_cast);
+ m_proxy_cnt++;
+ // connect all existing terminals to new net
- // create a new one ...
- pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt);
- auto new_proxy =
- out_cast.logic_family()->create_d_a_proxy(m_nlstate, x, &out_cast);
- m_proxy_cnt++;
- // connect all existing terminals to new net
+ // Get a copy first
+ auto temp_terminals(out.net().core_terms_copy());
+ // remove all terminals from out.net()
+ out.net().remove_all_terminals();
- for (auto & p : nlstate().core_terms(out.net()))
- {
- p->clear_net(); // de-link from all nets ...
- if (!connect(new_proxy->proxy_term(), *p))
+ for (detail::core_terminal_t * p : temp_terminals)
{
- log().fatal(MF_CONNECTING_1_TO_2(
- new_proxy->proxy_term().name(), (*p).name()));
- throw nl_exception(MF_CONNECTING_1_TO_2(
- new_proxy->proxy_term().name(), (*p).name()));
+ p->clear_net(); // de-link from all nets ...
+ if (!connect(new_proxy->proxy_term(), *p))
+ {
+ log().fatal(MF_CONNECTING_1_TO_2(
+ new_proxy->proxy_term().name(), (*p).name()));
+ throw nl_exception(MF_CONNECTING_1_TO_2(
+ new_proxy->proxy_term().name(), (*p).name()));
+ }
}
- }
- nlstate().core_terms(out.net()).clear();
- add_terminal(out.net(), new_proxy->in());
+ out.net().add_terminal(new_proxy->in());
- auto *proxy(new_proxy.get());
- if (!m_proxies.insert({&out, proxy}).second)
- throw nl_exception(MF_DUPLICATE_PROXY_1(out.name()));
+ auto *proxy(new_proxy.get());
+ if (!m_proxies.insert({&out, proxy}).second)
+ throw nl_exception(MF_DUPLICATE_PROXY_1(out.name()));
- m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
- return proxy;
-
-}
+ m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
+ return proxy;
+ }
-//NOLINTNEXTLINE(misc-no-recursion)
-devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
-{
- gsl_Expects(inp.is_logic());
+ //NOLINTNEXTLINE(misc-no-recursion)
+ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
+ {
+ gsl_Expects(inp.is_logic());
- const auto &incast = dynamic_cast<const logic_input_t &>(inp);
+ const auto &logic_input_terminal = dynamic_cast<const logic_input_t &>(inp);
- auto iter_proxy(m_proxies.find(&inp));
+ auto iter_proxy(m_proxies.find(&inp));
- if (iter_proxy != m_proxies.end())
- return iter_proxy->second;
+ if (iter_proxy != m_proxies.end())
+ return iter_proxy->second;
- log().debug("connect_terminal_input: connecting proxy\n");
- auto new_proxy = incast.logic_family()->create_a_d_proxy(m_nlstate,
- plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt), &incast);
+ log().debug("connect_terminal_input: connecting proxy\n");
+ auto new_proxy =
+ logic_input_terminal.logic_family()->create_a_d_proxy(m_nlstate,
+ plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt),
+ &logic_input_terminal);
- auto *ret(new_proxy.get());
+ auto *ret(new_proxy.get());
- if (!m_proxies.insert({&inp, ret}).second)
- throw nl_exception(MF_DUPLICATE_PROXY_1(inp.name()));
+ if (!m_proxies.insert({&inp, ret}).second)
+ throw nl_exception(MF_DUPLICATE_PROXY_1(inp.name()));
- m_proxy_cnt++;
+ m_proxy_cnt++;
- // connect all existing terminals to new net
+ // connect all existing terminals to new net
- if (inp.has_net())
- {
- for (detail::core_terminal_t * p : nlstate().core_terms(inp.net()))
+ if (inp.has_net())
{
- // inp may already belongs to the logic net. Thus skip it here.
- // It will be removed by the clear further down.
- if (p != &inp)
+ auto temp_terminals(inp.net().core_terms_copy());
+
+ inp.net().remove_all_terminals();
+
+ for (detail::core_terminal_t * p : temp_terminals)
{
- p->clear_net(); // de-link from all nets ...
- if (!connect(ret->proxy_term(), *p))
+ // inp may already belongs to the logic net. Thus skip it here.
+ // It will be removed by the clear further down.
+ if (p != &inp)
{
- log().fatal(MF_CONNECTING_1_TO_2(
- ret->proxy_term().name(), (*p).name()));
- throw nl_exception(MF_CONNECTING_1_TO_2(
- ret->proxy_term().name(), (*p).name()));
+ p->clear_net(); // de-link from all nets ...
+ if (!connect(ret->proxy_term(), *p))
+ {
+ log().fatal(MF_CONNECTING_1_TO_2(
+ ret->proxy_term().name(), (*p).name()));
+ throw nl_exception(MF_CONNECTING_1_TO_2(
+ ret->proxy_term().name(), (*p).name()));
+ }
}
}
}
- nlstate().core_terms(inp.net()).clear(); // clear the list
+ inp.clear_net();
+ ret->out().net().add_terminal(inp);
+ m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
+ return ret;
}
- inp.clear_net();
- add_terminal(ret->out().net(), inp);
- m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
- return ret;
-}
-detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term)
-{
- if (term.is_logic())
+ detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term)
{
- const auto &out = dynamic_cast<const logic_t &>(term);
- auto iter_proxy(m_proxies.find(&out));
- if (iter_proxy != m_proxies.end())
- return iter_proxy->second->proxy_term();
+ if (term.is_logic())
+ {
+ const auto &out = dynamic_cast<const logic_t &>(term);
+ auto iter_proxy(m_proxies.find(&out));
+ if (iter_proxy != m_proxies.end())
+ return iter_proxy->second->proxy_term();
+ }
+ return term;
}
- return term;
-}
-
-//NOLINTNEXTLINE(misc-no-recursion)
-void setup_t::merge_nets(detail::net_t &this_net, detail::net_t &other_net)
-{
- log().debug("merging nets ...\n");
- if (&other_net == &this_net)
+ //NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::merge_nets(detail::net_t &this_net, detail::net_t &other_net)
{
- log().warning(MW_CONNECTING_1_TO_ITSELF(this_net.name()));
- return; // Nothing to do
- }
+ log().debug("merging nets ...\n");
+ if (&other_net == &this_net)
+ {
+ log().warning(MW_CONNECTING_1_TO_ITSELF(this_net.name()));
+ return; // Nothing to do
+ }
- if (this_net.is_rail_net() && other_net.is_rail_net())
- {
- log().fatal(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
- throw nl_exception(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
- }
+ if (this_net.is_rail_net() && other_net.is_rail_net())
+ {
+ log().fatal(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
+ throw nl_exception(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
+ }
- if (other_net.is_rail_net())
- {
- log().debug("other net is a rail net\n");
- merge_nets(other_net, this_net);
- }
- else
- {
- move_connections(other_net, this_net);
+ if (other_net.is_rail_net())
+ {
+ log().debug("other net is a rail net\n");
+ merge_nets(other_net, this_net);
+ }
+ else
+ {
+ move_connections(other_net, this_net);
+ }
}
-}
-
-//NOLINTNEXTLINE(misc-no-recursion)
-void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out)
-{
- if (out.is_analog() && in.is_logic())
+ //NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out)
{
- auto *proxy = get_a_d_proxy(in);
+ if (out.is_analog() && in.is_logic())
+ {
+ auto *proxy = get_a_d_proxy(in);
- add_terminal(out.net(), proxy->proxy_term());
- }
- else if (out.is_logic() && in.is_analog())
- {
- devices::nld_base_proxy *proxy = get_d_a_proxy(out);
+ out.net().add_terminal(proxy->proxy_term());
+ }
+ else if (out.is_logic() && in.is_analog())
+ {
+ devices::nld_base_proxy *proxy = get_d_a_proxy(out);
- connect_terminals(proxy->proxy_term(), in);
- //proxy->out().net().register_con(in);
- }
- else
- {
- if (in.has_net())
- merge_nets(out.net(), in.net());
+ connect_terminals(proxy->proxy_term(), in);
+ //proxy->out().net().register_con(in);
+ }
else
- add_terminal(out.net(), in);
+ {
+ if (in.has_net())
+ merge_nets(out.net(), in.net());
+ else
+ out.net().add_terminal(in);
+ }
}
-}
-
-//NOLINTNEXTLINE(misc-no-recursion)
-void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp)
-{
- if (inp.is_analog())
+ //NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp)
{
- connect_terminals(inp, term);
- }
- else if (inp.is_logic())
- {
- log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(),
- inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?", term.name());
- auto *proxy = get_a_d_proxy(inp);
+ if (inp.is_analog())
+ {
+ connect_terminals(inp, term);
+ }
+ else if (inp.is_logic())
+ {
+ log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(),
+ inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?", term.name());
+ auto *proxy = get_a_d_proxy(inp);
- //out.net().register_con(proxy->proxy_term());
- connect_terminals(term, proxy->proxy_term());
+ //out.net().register_con(proxy->proxy_term());
+ connect_terminals(term, proxy->proxy_term());
+ }
+ else
+ {
+ log().fatal(MF_OBJECT_INPUT_TYPE_1(inp.name()));
+ throw nl_exception(MF_OBJECT_INPUT_TYPE_1(inp.name()));
+ }
}
- else
- {
- log().fatal(MF_OBJECT_INPUT_TYPE_1(inp.name()));
- throw nl_exception(MF_OBJECT_INPUT_TYPE_1(inp.name()));
- }
-}
-
-//NOLINTNEXTLINE(misc-no-recursion)
-void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &out)
-{
- if (out.is_analog())
+ //NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &out)
{
- log().debug("connect_terminal_output: {1} {2}\n", in.name(), out.name());
- // no proxy needed, just merge existing terminal net
- if (in.has_net())
+ if (out.is_analog())
{
- if (&out.net() != &in.net())
- merge_nets(out.net(), in.net());
+ log().debug("connect_terminal_output: {1} {2}\n", in.name(), out.name());
+ // no proxy needed, just merge existing terminal net
+ if (in.has_net())
+ {
+ if (&out.net() != &in.net())
+ merge_nets(out.net(), in.net());
+ else
+ // Only an info - some ICs (CD4538) connect pins internally to GND
+ // and the schematics again externally. This will cause this warning.
+ // FIXME: Add a hint to suppress the warning.
+ log().info(MI_CONNECTING_1_TO_2_SAME_NET(in.name(), out.name(), in.net().name()));
+ }
else
- // Only an info - some ICs (CD4538) connect pins internally to GND
- // and the schematics again externally. This will cause this warning.
- // FIXME: Add a hint to suppress the warning.
- log().info(MI_CONNECTING_1_TO_2_SAME_NET(in.name(), out.name(), in.net().name()));
+ out.net().add_terminal(in);
}
- else
- add_terminal(out.net(), in);
- }
- else if (out.is_logic())
- {
- log().debug("connect_terminal_output: connecting proxy\n");
- devices::nld_base_proxy *proxy = get_d_a_proxy(out);
+ else if (out.is_logic())
+ {
+ log().debug("connect_terminal_output: connecting proxy\n");
+ devices::nld_base_proxy *proxy = get_d_a_proxy(out);
- connect_terminals(proxy->proxy_term(), in);
- }
- else
- {
- log().fatal(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
- throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
+ connect_terminals(proxy->proxy_term(), in);
+ }
+ else
+ {
+ log().fatal(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
+ throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
+ }
}
-}
-void setup_t::connect_terminals(detail::core_terminal_t &t1,detail::core_terminal_t &t2)
-{
- if (t1.has_net() && t2.has_net())
- {
- log().debug("T2 and T1 have net\n");
- merge_nets(t1.net(), t2.net());
- }
- else if (t2.has_net())
- {
- log().debug("T2 has net\n");
- add_terminal(t2.net(), t1);
- }
- else if (t1.has_net())
+ void setup_t::connect_terminals(detail::core_terminal_t &t1,detail::core_terminal_t &t2)
{
- log().debug("T1 has net\n");
- add_terminal(t1.net(), t2);
- }
- else
- {
- log().debug("adding analog net ...\n");
- // FIXME: Nets should have a unique name
- auto anet = plib::make_owned<analog_net_t>(nlstate().pool(), m_nlstate,"net." + t1.name());
- auto *anetp = anet.get();
- m_nlstate.register_net(std::move(anet));
- t1.set_net(anetp);
- add_terminal(*anetp, t2);
- add_terminal(*anetp, t1);
+ if (t1.has_net() && t2.has_net())
+ {
+ log().debug("T2 and T1 have net\n");
+ merge_nets(t1.net(), t2.net());
+ }
+ else if (t2.has_net())
+ {
+ log().debug("T2 has net\n");
+ t2.net().add_terminal(t1);
+ }
+ else if (t1.has_net())
+ {
+ log().debug("T1 has net\n");
+ t1.net().add_terminal(t2);
+ }
+ else
+ {
+ log().debug("adding analog net ...\n");
+ // FIXME: Nets should have a unique name
+ auto new_net_uptr = plib::make_owned<analog_net_t>(nlstate().pool(), m_nlstate,"net." + t1.name());
+ auto *new_net_ptr = new_net_uptr.get();
+ m_nlstate.register_net(std::move(new_net_uptr));
+ t1.set_net(new_net_ptr);
+ new_net_ptr->add_terminal(t2);
+ new_net_ptr->add_terminal(t1);
+ }
}
-}
-//NOLINTNEXTLINE(misc-no-recursion)
-bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
-{
- bool ret = false;
- if (t1.has_net())
+ //NOLINTNEXTLINE(misc-no-recursion)
+ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
{
- if (t1.net().is_rail_net())
- ret = connect(t2, t1.net().rail_terminal());
- if (!ret)
+ bool ret = false;
+ if (t1.has_net())
{
- for (auto & t : nlstate().core_terms(t1.net()))
+ if (t1.net().is_rail_net())
+ ret = connect(t2, t1.net().rail_terminal());
+ if (!ret)
{
- if (t->is_type(detail::terminal_type::TERMINAL))
- ret = connect(t2, *t);
- if (ret)
- break;
+ for (detail::core_terminal_t * t : t1.net().core_terms_copy())
+ {
+ if (t->is_type(detail::terminal_type::TERMINAL))
+ ret = connect(t2, *t);
+ if (ret)
+ break;
+ }
}
}
- }
- if (!ret && t2.has_net())
- {
- if (t2.net().is_rail_net())
- ret = connect(t1, t2.net().rail_terminal());
- if (!ret)
+ if (!ret && t2.has_net())
{
- for (auto & t : nlstate().core_terms(t2.net()))
+ if (t2.net().is_rail_net())
+ ret = connect(t1, t2.net().rail_terminal());
+ if (!ret)
{
- if (t->is_type(detail::terminal_type::TERMINAL))
- ret = connect(t1, *t);
- if (ret)
- break;
+ for (detail::core_terminal_t * t : t2.net().core_terms_copy())
+ {
+ if (t->is_type(detail::terminal_type::TERMINAL))
+ ret = connect(t1, *t);
+ if (ret)
+ break;
+ }
}
}
+ return ret;
}
- return ret;
-}
-
-//NOLINTNEXTLINE(misc-no-recursion)
-bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in)
-{
- log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name());
- detail::core_terminal_t &t1 = resolve_proxy(t1_in);
- detail::core_terminal_t &t2 = resolve_proxy(t2_in);
- bool ret = true;
-
- if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT))
+ //NOLINTNEXTLINE(misc-no-recursion)
+ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in)
{
- if (t2.has_net() && t2.net().is_rail_net())
+ log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name());
+ detail::core_terminal_t &t1 = resolve_proxy(t1_in);
+ detail::core_terminal_t &t2 = resolve_proxy(t2_in);
+ bool ret = true;
+
+ if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT))
{
- log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
- throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
+ if (t2.has_net() && t2.net().is_rail_net())
+ {
+ log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
+ throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
+ }
+ connect_input_output(t2, t1);
}
- connect_input_output(t2, t1);
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT))
- {
- if (t1.has_net() && t1.net().is_rail_net())
+ else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT))
{
- log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
- throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
+ if (t1.has_net() && t1.net().is_rail_net())
+ {
+ log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
+ throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
+ }
+ connect_input_output(t1, t2);
}
- connect_input_output(t1, t2);
- }
- else if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::OUTPUT))
- {
- connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2);
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::INPUT))
- {
- connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2));
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT))
- {
- ret = connect_input_input(t1, t2);
- }
- else
- {
- ret = false;
- }
- return ret;
-}
-
-void setup_t::resolve_inputs()
-{
- log().verbose("Resolving inputs ...");
-
- // Netlist can directly connect input to input.
- // We therefore first park connecting inputs and retry
- // after all other terminals were connected.
-
- unsigned tries = m_netlist_params->m_max_link_loops();
-#if 0
- // This code fails for some netlists when the element at position 0
- // is deleted. It will fail somewhere deep in std::pair releasing
- // std::string called from erase.
- //
- // One example is the this netlist:
- //
- // #include "netlist/devices/net_lib.h"
- // NETLIST_START(charge_discharge)
- // SOLVER(solver, 48000) // Fixed frequency solver
- // CLOCK(I, 200) // 200 Hz clock as input, TTL logic output
- // RES(R, RES_K(1))
- // CAP(C, CAP_U(1))
- //
- // NET_C(I.Q, R.1)
- // NET_C(R.2, C.1)
- // NET_C(C.2, GND)
- //
- // ALIAS(O, R.2) // Output O == C.1 == R.2
- // // NETLIST_END()
- //
- // Just save the net list as /tmp/test1.cpp, run
- // ./nltool --cmd=run -t 0.05 -l O -l I /tmp/test1.cpp
- // and see it crash with this code enabled.
- //
- // g++-7 (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0
- //
- while (!m_links.empty() && tries > 0)
- {
- auto li = m_links.begin();
- while (li != m_links.end())
+ else if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::TERMINAL))
{
- const pstring t1s = li->first;
- const pstring t2s = li->second;
- detail::core_terminal_t *t1 = find_terminal(t1s);
- detail::core_terminal_t *t2 = find_terminal(t2s);
-
- if (connect(*t1, *t2))
- li = m_links.erase(li);
- else
- li++;
+ connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1);
}
- tries--;
- }
-#else
- while (!m_abstract.m_links.empty() && tries > 0)
- {
- for (std::size_t i = 0; i < m_abstract.m_links.size(); )
+ else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::OUTPUT))
{
- const pstring t1s(m_abstract.m_links[i].first);
- const pstring t2s(m_abstract.m_links[i].second);
- detail::core_terminal_t *t1 = find_terminal(t1s);
- detail::core_terminal_t *t2 = find_terminal(t2s);
- if (connect(*t1, *t2))
- m_abstract.m_links.erase(m_abstract.m_links.begin() + plib::narrow_cast<std::ptrdiff_t>(i));
- else
- i++;
+ connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2);
}
- tries--;
- }
-#endif
- if (tries == 0)
- {
- for (auto & link : m_abstract.m_links)
- log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first), de_alias(link.second)));
-
- log().fatal(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
- throw nl_exception(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
- }
-
- log().verbose("deleting empty nets ...");
-
- // delete empty nets
-
- delete_empty_nets();
-
- bool err(false);
-
- log().verbose("looking for terminals not connected ...");
- for (auto & i : m_terminals)
- {
- detail::core_terminal_t *term = i.second;
- const pstring name_da = de_alias(term->name());
- bool is_nc_pin(dynamic_cast< devices::NETLIB_NAME(nc_pin) *>(&term->device()) != nullptr);
- bool is_nc_flagged(false);
-
- auto hnc = m_abstract.m_hints.find(name_da + sHINT_NC);
- if (hnc != m_abstract.m_hints.end())
+ else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::TERMINAL))
{
- hnc->second = true; // mark as used
- is_nc_flagged = true;
+ connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1);
}
-
- if (term->has_net() && is_nc_pin)
+ else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::INPUT))
{
- log().error(ME_NC_PIN_1_WITH_CONNECTIONS(name_da));
- err = true;
+ connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2);
}
- else if (is_nc_pin)
+ else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::TERMINAL))
{
- /* ignore */
+ connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2));
}
- else if (!term->has_net())
+ else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT))
{
- log().error(ME_TERMINAL_1_WITHOUT_NET(name_da));
- err = true;
+ ret = connect_input_input(t1, t2);
}
- else if (nlstate().core_terms(term->net()).empty())
+ else
{
- if (term->is_logic_input())
- log().warning(MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da));
- else if (term->is_logic_output())
+ ret = false;
+ }
+ return ret;
+ }
+
+ void setup_t::resolve_inputs()
+ {
+ log().verbose("Resolving inputs ...");
+
+ // Netlist can directly connect input to input.
+ // We therefore first park connecting inputs and retry
+ // after all other terminals were connected.
+
+ unsigned tries = m_netlist_params->m_max_link_loops();
+ #if 0
+ // This code fails for some netlists when the element at position 0
+ // is deleted. It will fail somewhere deep in std::pair releasing
+ // std::string called from erase.
+ //
+ // One example is the this netlist:
+ //
+ // #include "netlist/devices/net_lib.h"
+ // NETLIST_START(charge_discharge)
+ // SOLVER(solver, 48000) // Fixed frequency solver
+ // CLOCK(I, 200) // 200 Hz clock as input, TTL logic output
+ // RES(R, RES_K(1))
+ // CAP(C, CAP_U(1))
+ //
+ // NET_C(I.Q, R.1)
+ // NET_C(R.2, C.1)
+ // NET_C(C.2, GND)
+ //
+ // ALIAS(O, R.2) // Output O == C.1 == R.2
+ // // NETLIST_END()
+ //
+ // Just save the net list as /tmp/test1.cpp, run
+ // ./nltool --cmd=run -t 0.05 -l O -l I /tmp/test1.cpp
+ // and see it crash with this code enabled.
+ //
+ // g++-7 (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0
+ //
+ while (!m_links.empty() && tries > 0)
+ {
+ auto li = m_links.begin();
+ while (li != m_links.end())
{
- if (!is_nc_flagged)
- log().info(MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ const pstring t1s = li->first;
+ const pstring t2s = li->second;
+ detail::core_terminal_t *t1 = find_terminal(t1s);
+ detail::core_terminal_t *t2 = find_terminal(t2s);
+
+ if (connect(*t1, *t2))
+ li = m_links.erase(li);
+ else
+ li++;
}
- else if (term->is_analog_output())
+ tries--;
+ }
+ #else
+ while (!m_abstract.m_links.empty() && tries > 0)
+ {
+ for (std::size_t i = 0; i < m_abstract.m_links.size(); )
{
- if (!is_nc_flagged)
- log().info(MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ const pstring t1s(m_abstract.m_links[i].first);
+ const pstring t2s(m_abstract.m_links[i].second);
+ detail::core_terminal_t *t1 = find_terminal(t1s);
+ detail::core_terminal_t *t2 = find_terminal(t2s);
+ if (connect(*t1, *t2))
+ m_abstract.m_links.erase(m_abstract.m_links.begin() + plib::narrow_cast<std::ptrdiff_t>(i));
+ else
+ i++;
}
- else
- log().warning(MW_TERMINAL_1_WITHOUT_CONNECTIONS(name_da));
+ tries--;
}
- }
+ #endif
+ if (tries == 0)
+ {
+ for (auto & link : m_abstract.m_links)
+ log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first), de_alias(link.second)));
- log().verbose("checking tristate consistency ...");
- for (auto & i : m_terminals)
- {
- detail::core_terminal_t *term = i.second;
- if (term->is_tristate_output())
+ log().fatal(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
+ throw nl_exception(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
+ }
+
+ log().verbose("deleting empty nets ...");
+
+ // delete empty nets
+
+ delete_empty_nets();
+
+ bool err(false);
+
+ log().verbose("looking for terminals not connected ...");
+ for (auto & i : m_terminals)
{
- const auto &tri(dynamic_cast<tristate_output_t &>(*term));
- // check if we are connected to a proxy
- const auto iter_proxy(m_proxies.find(&tri));
+ detail::core_terminal_t *term = i.second;
+ const pstring name_da = de_alias(term->name());
+ bool is_nc_pin(dynamic_cast< devices::NETLIB_NAME(nc_pin) *>(&term->device()) != nullptr);
+ bool is_nc_flagged(false);
+
+ auto hnc = m_abstract.m_hints.find(name_da + sHINT_NC);
+ if (hnc != m_abstract.m_hints.end())
+ {
+ hnc->second = true; // mark as used
+ is_nc_flagged = true;
+ }
- if (iter_proxy == m_proxies.end() && !tri.is_force_logic())
+ if (term->has_net() && is_nc_pin)
{
- log().error(ME_TRISTATE_NO_PROXY_FOUND_2(term->name(), term->device().name()));
+ log().error(ME_NC_PIN_1_WITH_CONNECTIONS(name_da));
err = true;
}
- else if (iter_proxy != m_proxies.end() && tri.is_force_logic())
+ else if (is_nc_pin)
+ {
+ // ignore
+ }
+ else if (!term->has_net())
{
- log().error(ME_TRISTATE_PROXY_FOUND_2(term->name(), term->device().name()));
+ log().error(ME_TERMINAL_1_WITHOUT_NET(name_da));
err = true;
}
+ else if (term->net().core_terms_empty())
+ {
+ if (term->is_logic_input())
+ log().warning(MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da));
+ else if (term->is_logic_output())
+ {
+ if (!is_nc_flagged)
+ log().info(MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ }
+ else if (term->is_analog_output())
+ {
+ if (!is_nc_flagged)
+ log().info(MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ }
+ else
+ log().warning(MW_TERMINAL_1_WITHOUT_CONNECTIONS(name_da));
+ }
}
- }
- if (err)
- {
- log().fatal(MF_TERMINALS_WITHOUT_NET());
- throw nl_exception(MF_TERMINALS_WITHOUT_NET());
- }
-}
+ log().verbose("checking tristate consistency ...");
+ for (auto & i : m_terminals)
+ {
+ detail::core_terminal_t *term = i.second;
+ if (term->is_tristate_output())
+ {
+ const auto &tri(dynamic_cast<tristate_output_t &>(*term));
+ // check if we are connected to a proxy
+ const auto iter_proxy(m_proxies.find(&tri));
-void setup_t::add_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false)
-{
- for (auto &t : nlstate().core_terms(net))
- if (t == &terminal)
+ if (iter_proxy == m_proxies.end() && !tri.is_force_logic())
+ {
+ log().error(ME_TRISTATE_NO_PROXY_FOUND_2(term->name(), term->device().name()));
+ err = true;
+ }
+ else if (iter_proxy != m_proxies.end() && tri.is_force_logic())
+ {
+ log().error(ME_TRISTATE_PROXY_FOUND_2(term->name(), term->device().name()));
+ err = true;
+ }
+ }
+ }
+ if (err)
{
- log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(net.name(), t->name()));
- throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(net.name(), t->name()));
+ log().fatal(MF_TERMINALS_WITHOUT_NET());
+ throw nl_exception(MF_TERMINALS_WITHOUT_NET());
}
- terminal.set_net(&net);
-
- nlstate().core_terms(net).push_back(&terminal);
-}
-
-void setup_t::remove_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false)
-{
- if (plib::container::contains(nlstate().core_terms(net), &terminal))
- {
- terminal.set_net(nullptr);
- plib::container::remove(nlstate().core_terms(net), &terminal);
}
- else
+
+ void setup_t::move_connections(detail::net_t &net, detail::net_t &dest_net)
{
- log().fatal(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), net.name()));
- throw nl_exception(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), net.name()));
- }
-}
+ auto temp(net.core_terms_copy());
-void setup_t::move_connections(detail::net_t &net, detail::net_t &dest_net)
-{
- for (auto &ct : nlstate().core_terms(net))
- add_terminal(dest_net, *ct);
- nlstate().core_terms(net).clear();
-}
+ net.remove_all_terminals();
+ for (detail::core_terminal_t * ct : temp)
+ {
+ dest_net.add_terminal(*ct);
+ }
+ }
+ log_type &setup_t::log() noexcept { return m_nlstate.log(); }
+ const log_type &setup_t::log() const noexcept { return m_nlstate.log(); }
-log_type &setup_t::log() noexcept { return m_nlstate.log(); }
-const log_type &setup_t::log() const noexcept { return m_nlstate.log(); }
+ // ----------------------------------------------------------------------------------------
+ // Models
+ // ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// Models
-// ----------------------------------------------------------------------------------------
+ //NOLINTNEXTLINE(misc-no-recursion)
+ void models_t::model_parse(const pstring &model_in, map_t &map)
+ {
+ pstring model = model_in;
+ std::size_t pos = 0;
+ pstring key;
+ while (true)
+ {
+ pos = model.find('(');
+ if (pos != pstring::npos) break;
-//NOLINTNEXTLINE(misc-no-recursion)
-void models_t::model_parse(const pstring &model_in, map_t &map)
-{
- pstring model = model_in;
- std::size_t pos = 0;
- pstring key;
+ key = plib::ucase(model);
+ auto i = m_models.find(key);
+ if (i == m_models.end())
+ {
+ throw nl_exception(MF_MODEL_NOT_FOUND(pstring("xx") + model));
+ }
- while (true)
- {
- pos = model.find('(');
- if (pos != pstring::npos) break;
+ model = i->second;
+ }
+ pstring base_model = plib::left(model, pos);
- key = plib::ucase(model);
- auto i = m_models.find(key);
- if (i == m_models.end())
+ if (base_model == "_")
+ map["COREMODEL"] = key;
+ else
{
- throw nl_exception(MF_MODEL_NOT_FOUND(pstring("xx") + model));
+ auto i = m_models.find(base_model);
+ if (i != m_models.end())
+ model_parse(base_model, map);
+ else
+ throw nl_exception(MF_MODEL_NOT_FOUND(model_in));
}
- model = i->second;
- }
- pstring xmodel = plib::left(model, pos);
+ pstring remainder = plib::trim(model.substr(pos + 1));
+ if (!plib::endsWith(remainder, ")"))
+ throw nl_exception(MF_MODEL_ERROR_1(model));
+ // FIMXE: Not optimal
+ remainder = plib::left(remainder, remainder.length() - 1);
- if (xmodel == "_")
- map["COREMODEL"] = key;
- else
- {
- auto i = m_models.find(xmodel);
- if (i != m_models.end())
- model_parse(xmodel, map);
- else
- throw nl_exception(MF_MODEL_NOT_FOUND(model_in));
+ const auto pairs(plib::psplit(remainder,' ', true));
+ for (const pstring &pe : pairs)
+ {
+ auto pose = pe.find('=');
+ if (pose == pstring::npos)
+ throw nl_exception(MF_MODEL_ERROR_ON_PAIR_1(model));
+ map[plib::ucase(plib::left(pe, pose))] = pe.substr(pose + 1);
+ }
}
- pstring remainder = plib::trim(model.substr(pos + 1));
- if (!plib::endsWith(remainder, ")"))
- throw nl_exception(MF_MODEL_ERROR_1(model));
- // FIMXE: Not optimal
- remainder = plib::left(remainder, remainder.length() - 1);
-
- const auto pairs(plib::psplit(remainder,' ', true));
- for (const pstring &pe : pairs)
+ pstring models_t::model_t::model_string(const map_t &map)
{
- auto pose = pe.find('=');
- if (pose == pstring::npos)
- throw nl_exception(MF_MODEL_ERROR_ON_PAIR_1(model));
- map[plib::ucase(plib::left(pe, pose))] = pe.substr(pose + 1);
- }
-}
+ // operator [] has no const implementation
+ pstring ret = map.at("COREMODEL") + "(";
+ for (const auto & i : map)
+ ret += (i.first + '=' + i.second + ' ');
-pstring models_t::model_t::model_string(const map_t &map)
-{
- // operator [] has no const implementation
- pstring ret = map.at("COREMODEL") + "(";
- for (const auto & i : map)
- ret += (i.first + '=' + i.second + ' ');
-
- return ret + ")";
-}
-
-models_t::model_t models_t::get_model(const pstring &model)
-{
- map_t &map = m_cache[model];
-
- if (map.empty())
- model_parse(model , map);
+ return ret + ")";
+ }
- return { model, map };
-}
+ models_t::model_t models_t::get_model(const pstring &model)
+ {
+ map_t &map = m_cache[model];
-pstring models_t::model_t::value_str(const pstring &entity) const
-{
- if (entity != plib::ucase(entity))
- throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(m_map)));
- const auto it(m_map.find(entity));
- if ( it == m_map.end())
- throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map)));
+ if (map.empty())
+ model_parse(model , map);
- return it->second;
-}
+ return { model, map };
+ }
-nl_fptype models_t::model_t::value(const pstring &entity) const
-{
- pstring tmp = value_str(entity);
-
- nl_fptype factor = nlconst::one();
- auto p = std::next(tmp.begin(), plib::narrow_cast<pstring::difference_type>(tmp.length() - 1));
- switch (*p)
- {
- case 'M': factor = nlconst::magic(1e6); break; // NOLINT
- case 'k':
- case 'K': factor = nlconst::magic(1e3); break; // NOLINT
- case 'm': factor = nlconst::magic(1e-3); break; // NOLINT
- case 'u': factor = nlconst::magic(1e-6); break; // NOLINT
- case 'n': factor = nlconst::magic(1e-9); break; // NOLINT
- case 'p': factor = nlconst::magic(1e-12); break; // NOLINT
- case 'f': factor = nlconst::magic(1e-15); break; // NOLINT
- case 'a': factor = nlconst::magic(1e-18); break; // NOLINT
- default:
- if (*p < '0' || *p > '9')
- throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity));
- }
- if (factor != nlconst::one())
- tmp = plib::left(tmp, tmp.length() - 1);
- // FIXME: check for errors
- bool err(false);
- auto val = plib::pstonum_ne<nl_fptype>(tmp, err);
- if (err)
- throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", m_model));
- return val * factor;
-}
-
-
-// FIXME: all this belongs elsewhere
-
-PENUM(family_type,
- CUSTOM,
- TTL,
- MOS,
- CMOS,
- NMOS,
- PMOS)
-
-class logic_family_std_proxy_t : public logic_family_desc_t
-{
-public:
- logic_family_std_proxy_t(family_type ft)
- : m_family_type(ft)
+ pstring models_t::model_t::value_str(const pstring &entity) const
{
+ if (entity != plib::ucase(entity))
+ throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(m_map)));
+ const auto it(m_map.find(entity));
+ if ( it == m_map.end())
+ throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map)));
+
+ return it->second;
}
- // FIXME: create proxies based on family type (far future)
- device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist,
- const pstring &name, const logic_output_t *proxied) const override
+ nl_fptype models_t::model_t::value(const pstring &entity) const
{
- switch(m_family_type)
+ pstring tmp = value_str(entity);
+
+ nl_fptype factor = nlconst::one();
+ auto p = std::next(tmp.begin(), plib::narrow_cast<pstring::difference_type>(tmp.length() - 1));
+ switch (*p)
{
- case family_type::CUSTOM:
- case family_type::TTL:
- case family_type::MOS:
- case family_type::CMOS:
- case family_type::NMOS:
- case family_type::PMOS:
- return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ case 'M': factor = nlconst::magic(1e6); break; // NOLINT
+ case 'k':
+ case 'K': factor = nlconst::magic(1e3); break; // NOLINT
+ case 'm': factor = nlconst::magic(1e-3); break; // NOLINT
+ case 'u': factor = nlconst::magic(1e-6); break; // NOLINT
+ case 'n': factor = nlconst::magic(1e-9); break; // NOLINT
+ case 'p': factor = nlconst::magic(1e-12); break; // NOLINT
+ case 'f': factor = nlconst::magic(1e-15); break; // NOLINT
+ case 'a': factor = nlconst::magic(1e-18); break; // NOLINT
+ default:
+ if (*p < '0' || *p > '9')
+ throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity));
}
- return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ if (factor != nlconst::one())
+ tmp = plib::left(tmp, tmp.length() - 1);
+ // FIXME: check for errors
+ bool err(false);
+ auto val = plib::pstonum_ne<nl_fptype>(tmp, err);
+ if (err)
+ throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", m_model));
+ return val * factor;
}
- device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override
- {
- switch(m_family_type)
+ // ----------------------------------------------------------------------------------------
+ // logic_family_std_proxy_t
+ //
+ // FIXME: all this belongs elsewhere
+ // ----------------------------------------------------------------------------------------
+ PENUM(family_type,
+ CUSTOM,
+ TTL,
+ MOS,
+ CMOS,
+ NMOS,
+ PMOS)
+
+ class logic_family_std_proxy_t : public logic_family_desc_t
+ {
+ public:
+ logic_family_std_proxy_t(family_type ft)
+ : m_family_type(ft)
+ {
+ }
+
+ // FIXME: create proxies based on family type (far future)
+ device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist,
+ const pstring &name, const logic_output_t *proxied) const override
+ {
+ switch(m_family_type)
+ {
+ case family_type::CUSTOM:
+ case family_type::TTL:
+ case family_type::MOS:
+ case family_type::CMOS:
+ case family_type::NMOS:
+ case family_type::PMOS:
+ return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ }
+ return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ }
+
+ device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override
+ {
+ switch(m_family_type)
+ {
+ case family_type::CUSTOM:
+ case family_type::TTL:
+ case family_type::MOS:
+ case family_type::CMOS:
+ case family_type::NMOS:
+ case family_type::PMOS:
+ return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
+ return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
+ private:
+ family_type m_family_type;
+ };
+
+ /// \brief Class representing the logic families.
+ ///
+ /// This is the model representation of the logic families. This is a
+ /// netlist specific model. Examples give values for TTL family
+ ///
+ //
+ /// |NL? |name |parameter |units| TTL |
+ /// |:--:|:-----|:----------------------------------------------------------|:----|------:|
+ /// | Y |IVL |Input voltage low threshold relative to supply voltage | |1.0e-14|
+ /// | Y |IVH |Input voltage high threshold relative to supply voltage | | 0|
+ /// | Y |OVL |Output voltage minimum voltage relative to supply voltage | |1.0e-14|
+ /// | Y |OVL |Output voltage maximum voltage relative to supply voltage | |1.0e-14|
+ /// | Y |ORL |Output output resistance for logic 0 | | 0|
+ /// | Y |ORH |Output output resistance for logic 1 | | 0|
+ ///
+ class family_model_t
+ {
+ public:
+ template <typename P>
+ family_model_t(P &model)
+ : m_TYPE(model, "TYPE")
+ , m_IVL(model, "IVL")
+ , m_IVH(model, "IVH")
+ , m_OVL(model, "OVL")
+ , m_OVH(model, "OVH")
+ , m_ORL(model, "ORL")
+ , m_ORH(model, "ORH")
+ {}
+
+ param_model_t::value_str_t m_TYPE; //!< Family type (TTL, CMOS, ...)
+ param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage
+ param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage
+ param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage
+ param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage
+ param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
+ param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
+ };
+
+ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
+ {
+ family_type ft(family_type::CUSTOM);
+
+ auto mod(m_models.get_model(model));
+ family_model_t modv(mod);
+
+ if (!ft.set_from_string(modv.m_TYPE()))
+ throw nl_exception(MF_UNKNOWN_FAMILY_TYPE_1(modv.m_TYPE(), model));
+
+ auto it = m_nlstate.family_cache().find(model);
+ if (it != m_nlstate.family_cache().end())
+ return it->second.get();
+
+ auto ret = plib::make_unique<logic_family_std_proxy_t, host_arena>(ft);
+
+ ret->m_low_threshold_PCNT = modv.m_IVL();
+ ret->m_high_threshold_PCNT = modv.m_IVH();
+ ret->m_low_VO = modv.m_OVL();
+ ret->m_high_VO = modv.m_OVH();
+ ret->m_R_low = modv.m_ORL();
+ ret->m_R_high = modv.m_ORH();
+
+ switch (ft)
{
case family_type::CUSTOM:
case family_type::TTL:
+ case family_type::NMOS:
+ ret->m_vcc = "VCC";
+ ret->m_gnd = "GND";
+ break;
case family_type::MOS:
case family_type::CMOS:
- case family_type::NMOS:
case family_type::PMOS:
- return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
- }
- return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
- }
-private:
- family_type m_family_type;
-};
-
-
-/// \brief Class representing the logic families.
-///
-/// This is the model representation of the logic families. This is a
-/// netlist specific model. Examples give values for TTL family
-///
-//
-/// |NL? |name |parameter |units| TTL |
-/// |:--:|:-----|:----------------------------------------------------------|:----|------:|
-/// | Y |IVL |Input voltage low threshold relative to supply voltage | |1.0e-14|
-/// | Y |IVH |Input voltage high threshold relative to supply voltage | | 0|
-/// | Y |OVL |Output voltage minimum voltage relative to supply voltage | |1.0e-14|
-/// | Y |OVL |Output voltage maximum voltage relative to supply voltage | |1.0e-14|
-/// | Y |ORL |Output output resistance for logic 0 | | 0|
-/// | Y |ORH |Output output resistance for logic 1 | | 0|
-///
-class family_model_t
-{
-public:
- template <typename P>
- family_model_t(P &model)
- : m_TYPE(model, "TYPE")
- , m_IVL(model, "IVL")
- , m_IVH(model, "IVH")
- , m_OVL(model, "OVL")
- , m_OVH(model, "OVH")
- , m_ORL(model, "ORL")
- , m_ORH(model, "ORH")
- {}
-
- param_model_t::value_str_t m_TYPE; //!< Family type (TTL, CMOS, ...)
- param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage
- param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage
- param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage
- param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage
- param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
- param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
-};
-
-
-const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
-{
- family_type ft(family_type::CUSTOM);
-
- auto mod(m_models.get_model(model));
- family_model_t modv(mod);
+ ret->m_vcc = "VDD";
+ ret->m_gnd = "VSS";
+ break;
+ }
- if (!ft.set_from_string(modv.m_TYPE()))
- throw nl_exception(MF_UNKNOWN_FAMILY_TYPE_1(modv.m_TYPE(), model));
+ auto *retp = ret.get();
- auto it = m_nlstate.family_cache().find(model);
- if (it != m_nlstate.family_cache().end())
- return it->second.get();
+ m_nlstate.family_cache().emplace(model, std::move(ret));
- auto ret = plib::make_unique<logic_family_std_proxy_t, host_arena>(ft);
+ return retp;
+ }
- ret->m_low_threshold_PCNT = modv.m_IVL();
- ret->m_high_threshold_PCNT = modv.m_IVH();
- ret->m_low_VO = modv.m_OVL();
- ret->m_high_VO = modv.m_OVH();
- ret->m_R_low = modv.m_ORL();
- ret->m_R_high = modv.m_ORH();
+ // ----------------------------------------------------------------------------------------
+ // Device handling
+ // ----------------------------------------------------------------------------------------
- switch (ft)
+ void setup_t::delete_empty_nets()
{
- case family_type::CUSTOM:
- case family_type::TTL:
- case family_type::NMOS:
- ret->m_vcc = "VCC";
- ret->m_gnd = "GND";
- break;
- case family_type::MOS:
- case family_type::CMOS:
- case family_type::PMOS:
- ret->m_vcc = "VDD";
- ret->m_gnd = "VSS";
- break;
+ m_nlstate.nets().erase(
+ std::remove_if(m_nlstate.nets().begin(), m_nlstate.nets().end(),
+ [](device_arena::owned_ptr<detail::net_t> &net)
+ {
+ if (net->core_terms_empty())
+ {
+ // FIXME: need to remove from state->m_core_terms as well.
+ net->state().log().verbose("Deleting net {1} ...", net->name());
+ net->state().run_state_manager().remove_save_items(net.get());
+ return true;
+ }
+ return false;
+ }), m_nlstate.nets().end());
}
- auto *retp = ret.get();
+ // ----------------------------------------------------------------------------------------
+ // Run preparation
+ // ----------------------------------------------------------------------------------------
- m_nlstate.family_cache().emplace(model, std::move(ret));
+ void setup_t::prepare_to_run()
+ {
+ pstring env_log_setting = plib::util::environment("NL_LOGS", "");
- return retp;
-}
+ if (!env_log_setting.empty())
+ {
+ const auto list_of_logs(plib::psplit(env_log_setting, ':'));
+ m_parser.register_dynamic_log_devices(list_of_logs);
+ }
-// ----------------------------------------------------------------------------------------
-// Device handling
-// ----------------------------------------------------------------------------------------
+ // create default parameters first!
-void setup_t::delete_empty_nets()
-{
- m_nlstate.nets().erase(
- std::remove_if(m_nlstate.nets().begin(), m_nlstate.nets().end(),
- [](device_arena::owned_ptr<detail::net_t> &net)
- {
- if (net->state().core_terms(*net).empty())
- {
- // FIXME: need to remove from state->m_core_terms as well.
- net->state().log().verbose("Deleting net {1} ...", net->name());
- net->state().run_state_manager().remove_save_items(net.get());
- return true;
- }
- return false;
- }), m_nlstate.nets().end());
-}
+ for (auto & e : m_abstract.m_default_params)
+ {
+ auto param(plib::make_unique<param_str_t, host_arena>(nlstate(), e.first, e.second));
+ register_param_t(*param);
+ m_defparam_lifetime.push_back(std::move(param));
+ }
-// ----------------------------------------------------------------------------------------
-// Run preparation
-// ----------------------------------------------------------------------------------------
+ // make sure the solver and parameters are started first!
-void setup_t::prepare_to_run()
-{
- pstring env_log_setting = plib::util::environment("NL_LOGS", "");
+ for (auto & e : m_abstract.m_device_factory)
+ {
+ if ( m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ || m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ m_nlstate.register_device(e.first, e.second->make_device(nlstate().pool(), m_nlstate, e.first));
+ }
+ }
- if (!env_log_setting.empty())
- {
- const auto loglist(plib::psplit(env_log_setting, ':'));
- m_parser.register_dynamic_log_devices(loglist);
- }
+ log().debug("Searching for solver and parameters ...\n");
- // create defparams first!
+ auto *solver = m_nlstate.get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ m_netlist_params = m_nlstate.get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
- for (auto & e : m_abstract.m_defparams)
- {
- auto param(plib::make_unique<param_str_t, host_arena>(nlstate(), e.first, e.second));
- register_param_t(*param);
- m_defparam_lifetime.push_back(std::move(param));
- }
+ // set default model parameters
- // make sure the solver and parameters are started first!
+ // FIXME: this is not optimal
+ m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
+ m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
- for (auto & e : m_abstract.m_device_factory)
- {
- if ( m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- || m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ // create devices
+
+ log().debug("Creating devices ...\n");
+ for (auto & e : m_abstract.m_device_factory)
{
- m_nlstate.register_device(e.first, e.second->make_device(nlstate().pool(), m_nlstate, e.first));
+ if ( !m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ && !m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate, e.first);
+ m_nlstate.register_device(dev->name(), std::move(dev));
+ }
}
- }
- log().debug("Searching for solver and parameters ...\n");
+ int error_count(0);
- auto *solver = m_nlstate.get_single_device<devices::NETLIB_NAME(solver)>("solver");
- m_netlist_params = m_nlstate.get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+ const bool use_deactivate = m_netlist_params->m_use_deactivate();
- // set default model parameters
+ for (auto &d : m_nlstate.devices())
+ {
+ auto p = m_abstract.m_hints.find(d.second->name() + sHINT_NO_DEACTIVATE);
+ if (p != m_abstract.m_hints.end())
+ {
+ p->second = true; // mark as used
+ d.second->set_hint_deactivate(false);
+ }
+ else
+ d.second->set_hint_deactivate(use_deactivate);
+ }
- // FIXME: this is not optimal
- m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
- m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
+ if (error_count > 0)
+ {
+ log().fatal(MF_ERRORS_FOUND(error_count));
+ throw nl_exception(MF_ERRORS_FOUND(error_count));
+ }
- // create devices
+ // resolve inputs
+ resolve_inputs();
- log().debug("Creating devices ...\n");
- for (auto & e : m_abstract.m_device_factory)
- {
- if ( !m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- && !m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ log().verbose("looking for two terms connected to rail nets ...");
+ for (auto & t : m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>())
{
- auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate, e.first);
- m_nlstate.register_device(dev->name(), std::move(dev));
+ if (t->N().net().is_rail_net() && t->P().net().is_rail_net())
+ {
+ log().info(MI_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3(
+ t->name(), t->N().net().name(), t->P().net().name()));
+ // The following would remove internal devices in e.g. MOSFETs as well.
+ #if 0
+ remove_terminal(t->setup_N().net(), t->setup_N());
+ remove_terminal(t->setup_P().net(), t->setup_P());
+ m_nlstate.remove_device(t);
+ #endif
+ }
}
- }
- int error_count(0);
+ log().verbose("looking for unused hints ...");
+ for (auto &h : m_abstract.m_hints)
+ {
+ if (!h.second)
+ {
+ log().fatal(MF_UNUSED_HINT_1(h.first));
+ throw nl_exception(MF_UNUSED_HINT_1(h.first));
+ }
+ }
- const bool use_deactivate = m_netlist_params->m_use_deactivate();
+ log().verbose("initialize solver ...\n");
- for (auto &d : m_nlstate.devices())
- {
- auto p = m_abstract.m_hints.find(d.second->name() + sHINT_NO_DEACTIVATE);
- if (p != m_abstract.m_hints.end())
+ if (solver == nullptr)
{
- p->second = true; // mark as used
- d.second->set_hint_deactivate(false);
+ for (auto &p : m_nlstate.nets())
+ if (p->is_analog())
+ {
+ log().fatal(MF_NO_SOLVER());
+ throw nl_exception(MF_NO_SOLVER());
+ }
}
else
- d.second->set_hint_deactivate(use_deactivate);
- }
-
- if (error_count > 0)
- {
- log().fatal(MF_ERRORS_FOUND(error_count));
- throw nl_exception(MF_ERRORS_FOUND(error_count));
- }
-
- // resolve inputs
- resolve_inputs();
+ solver->post_start();
- log().verbose("looking for two terms connected to rail nets ...");
- for (auto & t : m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>())
- {
- if (t->N().net().is_rail_net() && t->P().net().is_rail_net())
+ error_count = 0;
+ log().debug("Looking for unknown parameters ...\n");
+ for (auto &p : m_abstract.m_param_values)
{
- log().info(MI_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3(
- t->name(), t->N().net().name(), t->P().net().name()));
- // The following would remove internal devices in e.g. MOSFETs as well.
-#if 0
- remove_terminal(t->setup_N().net(), t->setup_N());
- remove_terminal(t->setup_P().net(), t->setup_P());
- m_nlstate.remove_device(t);
-#endif
+ auto f = m_params.find(p.first);
+ if (f == m_params.end())
+ {
+ log().error(ME_UNKNOWN_PARAMETER(p.first));
+ error_count++;
+ }
+ }
+ if (error_count > 0)
+ {
+ log().fatal(MF_ERRORS_FOUND(error_count));
+ throw nl_exception(MF_ERRORS_FOUND(error_count));
}
- }
- log().verbose("looking for unused hints ...");
- for (auto &h : m_abstract.m_hints)
- {
- if (!h.second)
+ for (auto &n : m_nlstate.nets())
{
- log().fatal(MF_UNUSED_HINT_1(h.first));
- throw nl_exception(MF_UNUSED_HINT_1(h.first));
+ for (detail::core_terminal_t * term : n->core_terms_copy())
+ if (term->delegate().isnull())
+ {
+ log().fatal(MF_DELEGATE_NOT_SET_1(term->name()));
+ throw nl_exception(MF_DELEGATE_NOT_SET_1(term->name()));
+ }
+ n->rebuild_list();
}
}
- log().verbose("initialize solver ...\n");
+ // ----------------------------------------------------------------------------------------
+ // base sources
+ // ----------------------------------------------------------------------------------------
- if (solver == nullptr)
+ bool source_netlist_t::parse(nlparse_t &setup, const pstring &name)
{
- for (auto &p : m_nlstate.nets())
- if (p->is_analog())
- {
- log().fatal(MF_NO_SOLVER());
- throw nl_exception(MF_NO_SOLVER());
- }
+ auto strm(stream(name));
+ return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) : false;
}
- else
- solver->post_start();
- error_count = 0;
- log().debug("Looking for unknown parameters ...\n");
- for (auto &p : m_abstract.m_param_values)
+ plib::istream_uptr source_string_t::stream([[maybe_unused]] const pstring &name)
{
- auto f = m_params.find(p.first);
- if (f == m_params.end())
- {
- log().error(ME_UNKNOWN_PARAMETER(p.first));
- error_count++;
- }
- }
- if (error_count > 0)
- {
- log().fatal(MF_ERRORS_FOUND(error_count));
- throw nl_exception(MF_ERRORS_FOUND(error_count));
+ plib::istream_uptr ret(std::make_unique<std::istringstream>(putf8string(m_str)), name);
+ ret->imbue(std::locale::classic());
+ return ret;
}
- for (auto &n : m_nlstate.nets())
+ plib::istream_uptr source_mem_t::stream([[maybe_unused]] const pstring &name)
{
- for (auto & term : m_nlstate.core_terms(*n))
- if (term->delegate().isnull())
- {
- log().fatal(MF_DELEGATE_NOT_SET_1(term->name()));
- throw nl_exception(MF_DELEGATE_NOT_SET_1(term->name()));
- }
- n->rebuild_list();
+ plib::istream_uptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary), name);
+ ret->imbue(std::locale::classic());
+ return ret;
}
-}
-// ----------------------------------------------------------------------------------------
-// base sources
-// ----------------------------------------------------------------------------------------
-
-bool source_netlist_t::parse(nlparse_t &setup, const pstring &name)
-{
- auto strm(stream(name));
- return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) : false;
-}
-
-plib::istream_uptr source_string_t::stream([[maybe_unused]] const pstring &name)
-{
- plib::istream_uptr ret(std::make_unique<std::istringstream>(putf8string(m_str)), name);
- ret->imbue(std::locale::classic());
- return ret;
-}
-
-plib::istream_uptr source_mem_t::stream([[maybe_unused]] const pstring &name)
-{
- plib::istream_uptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary), name);
- ret->imbue(std::locale::classic());
- return ret;
-}
-
-plib::istream_uptr source_file_t::stream([[maybe_unused]] const pstring &name)
-{
- auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename));
- if (f->is_open())
+ plib::istream_uptr source_file_t::stream([[maybe_unused]] const pstring &name)
{
- return { std::move(f), m_filename };
- }
+ auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename));
+ if (f->is_open())
+ {
+ return { std::move(f), m_filename };
+ }
- return plib::istream_uptr();
-}
+ return plib::istream_uptr();
+ }
-plib::istream_uptr source_pattern_t::stream([[maybe_unused]] const pstring &name)
-{
- pstring filename = plib::pfmt(m_pattern)(m_force_lowercase ? plib::lcase(name) : name);
- auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(filename));
- if (f->is_open())
+ plib::istream_uptr source_pattern_t::stream([[maybe_unused]] const pstring &name)
{
- return { std::move(f), filename };
+ pstring filename = plib::pfmt(m_pattern)(m_force_lowercase ? plib::lcase(name) : name);
+ auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(filename));
+ if (f->is_open())
+ {
+ return { std::move(f), filename };
+ }
+
+ return plib::istream_uptr();
}
- return plib::istream_uptr();
-}
+ bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
+ {
+ if (name == m_setup_func_name)
+ {
+ m_setup_func(setup);
+ return true;
+ }
+ return false;
+ }
-bool source_proc_t::parse(nlparse_t &setup, const pstring &name)
-{
- if (name == m_setup_func_name)
+ plib::istream_uptr source_proc_t::stream([[maybe_unused]] const pstring &name)
{
- m_setup_func(setup);
- return true;
+ return plib::istream_uptr();
}
- return false;
-}
-
-plib::istream_uptr source_proc_t::stream([[maybe_unused]] const pstring &name)
-{
- return plib::istream_uptr();
-}
-
} // namespace netlist
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 14eaf90d95e..d22b78c3703 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -55,7 +55,7 @@
setup.register_param(NET_STR(name), NET_STR(val));
#define DEFPARAM(name, val) \
- setup.register_defparam(NET_STR(name), NET_STR(val));
+ setup.register_default_param(NET_STR(name), NET_STR(val));
#define HINT(name, val) \
setup.register_hint(# name , ".HINT_" # val);
@@ -168,7 +168,7 @@ namespace netlist
void register_model(const pstring &model_in);
void register_alias(const pstring &alias, const pstring &out);
- void register_alias_nofqn(const pstring &alias, const pstring &out);
+ void register_alias_no_fqn(const pstring &alias, const pstring &out);
void register_dip_alias_arr(const pstring &terms);
// last argument only needed by nltool
@@ -181,7 +181,7 @@ namespace netlist
register_dev(classname, name, std::vector<pstring>());
}
- void register_hint(const pstring &objname, const pstring &hint_name);
+ void register_hint(const pstring &object_name, const pstring &hint_name);
void register_link(const pstring &sin, const pstring &sout);
void register_link_arr(const pstring &terms);
@@ -191,7 +191,7 @@ namespace netlist
void register_param(const pstring &param, const pstring &value);
// DEFPARAM support
- void register_defparam(const pstring &name, const pstring &def);
+ void register_default_param(const pstring &name, const pstring &def);
template <typename T>
std::enable_if_t<plib::is_arithmetic<T>::value>
diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h
index b07a533a22d..94bb424998c 100644
--- a/src/lib/netlist/plib/parray.h
+++ b/src/lib/netlist/plib/parray.h
@@ -123,13 +123,13 @@ namespace plib {
~parray() noexcept = default;
- base_type &as_base() noexcept { return m_a; }
+ constexpr base_type &as_base() noexcept { return m_a; }
constexpr size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); }
constexpr size_type max_size() const noexcept { return base_type::max_size(); }
- bool empty() const noexcept { return size() == 0; }
+ constexpr bool empty() const noexcept { return size() == 0; }
constexpr reference operator[](size_type i) noexcept
{
@@ -140,8 +140,8 @@ namespace plib {
return m_a[i];
}
- pointer data() noexcept { return m_a.data(); }
- const_pointer data() const noexcept { return m_a.data(); }
+ constexpr pointer data() noexcept { return m_a.data(); }
+ constexpr const_pointer data() const noexcept { return m_a.data(); }
private:
PALIGNAS_VECTOROPT()
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index e245e955665..1c2e4b13057 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -37,8 +37,8 @@ namespace plib {
using ret_type = R;
static ret_type per_second() noexcept
{
- static ret_type persec = 0;
- if (persec == 0)
+ static ret_type per_second = 0;
+ if (per_second == 0)
{
ret_type x = 0;
system_ticks::type t = system_ticks::start();
@@ -48,9 +48,9 @@ namespace plib {
e = system_ticks::stop();
} while (e - t < system_ticks::per_second() / 100 );
x += T :: stop();
- persec = (ret_type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
+ per_second = (ret_type)(double)((double) x * (double) system_ticks::per_second() / double (e - t));
}
- return persec;
+ return per_second;
}
};
@@ -163,11 +163,11 @@ namespace plib {
template<bool enabled_>
struct counter
{
- counter() : m_count(0) { }
+ constexpr counter() : m_count(0) { }
using type = uint_least64_t;
- type operator()() const noexcept { return m_count; }
- void inc() noexcept { ++m_count; }
- void reset() noexcept { m_count = 0; }
+ constexpr type operator()() const noexcept { return m_count; }
+ constexpr void inc() noexcept { ++m_count; }
+ constexpr void reset() noexcept { m_count = 0; }
constexpr static bool enabled = enabled_;
private:
type m_count;
@@ -178,8 +178,8 @@ namespace plib {
{
using type = uint_least64_t;
constexpr type operator()() const noexcept { return 0; }
- void inc() const noexcept { }
- void reset() const noexcept { }
+ constexpr void inc() const noexcept { }
+ constexpr void reset() const noexcept { }
constexpr static bool enabled = false;
};
@@ -189,7 +189,7 @@ namespace plib {
{
using type = typename T::type;
using ctype = uint_least64_t;
- constexpr static bool enabled = enabled_;
+ constexpr static const bool enabled = enabled_;
struct guard_t
{
@@ -210,7 +210,7 @@ namespace plib {
constexpr type operator()() const { return m_time; }
- void reset() noexcept { m_time = 0; m_count = 0; }
+ constexpr void reset() noexcept { m_time = 0; m_count = 0; }
constexpr type average() const noexcept { return (m_count == 0) ? 0 : m_time / m_count; }
constexpr type total() const noexcept { return m_time; }
constexpr ctype count() const noexcept { return m_count; }
@@ -221,7 +221,6 @@ namespace plib {
constexpr guard_t guard() noexcept { return guard_t(*this); }
- // pause must be followed by cont(inue)
void stop() noexcept { m_time += T::stop(); }
void start() noexcept { m_time -= T::start(); }
diff --git a/src/lib/netlist/plib/penum.h b/src/lib/netlist/plib/penum.h
index 2e9bf322072..5a1db765ba0 100644
--- a/src/lib/netlist/plib/penum.h
+++ b/src/lib/netlist/plib/penum.h
@@ -32,7 +32,7 @@ namespace plib
struct ename : public plib::penum_base { \
enum E { __VA_ARGS__ }; \
constexpr ename (const E &v) : m_v(v) { } \
- template <typename T> explicit constexpr ename(const T &val) { m_v = static_cast<E>(val); } \
+ template <typename T> explicit constexpr ename(const T &val) : m_v(static_cast<E>(val)) { } \
bool set_from_string (const pstring &s) { \
int f = from_string_int(strings(), s); \
if (f>=0) { m_v = static_cast<E>(f); return true; } \
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
index 61cb9480301..260fa908bf0 100644
--- a/src/lib/netlist/plib/pexception.cpp
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -28,7 +28,7 @@ namespace plib {
}
catch (...)
{
- /* ignore */
+ // ignore
}
std::terminate();
}
@@ -45,7 +45,7 @@ namespace plib {
}
catch (...)
{
- /* ignore */
+ // ignore
}
std::terminate();
}
@@ -106,17 +106,17 @@ namespace plib {
//FIXME: mingw needs to be compiled with `-fnon-call-exceptions`
- fp_signal_enabler::fp_signal_enabler(unsigned fpexceptions)
+ fp_signal_enabler::fp_signal_enabler(unsigned fp_exceptions)
{
#if HAS_FEENABLE_EXCEPT
if (m_enable)
{
int b = 0;
- if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
- if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
- if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
- if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
- if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
+ if (fp_exceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
+ if (fp_exceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
+ if (fp_exceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
+ if (fp_exceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
+ if (fp_exceptions & plib::FP_INVALID) b = b | FE_INVALID;
if ((b & m_last_enabled) != b)
m_last_enabled = feenableexcept(b);
}
@@ -124,11 +124,11 @@ namespace plib {
if (m_enable)
{
int b = _EM_DENORMAL | _EM_INEXACT | _EM_ZERODIVIDE | _EM_UNDERFLOW | _EM_OVERFLOW | _EM_INVALID;
- if (fpexceptions & plib::FP_INEXACT) b &= ~_EM_INEXACT;
- if (fpexceptions & plib::FP_DIVBYZERO) b &= ~_EM_ZERODIVIDE;
- if (fpexceptions & plib::FP_UNDERFLOW) b &= ~_EM_UNDERFLOW;
- if (fpexceptions & plib::FP_OVERFLOW) b &= ~_EM_OVERFLOW;
- if (fpexceptions & plib::FP_INVALID) b &= ~_EM_INVALID;
+ if (fp_exceptions & plib::FP_INEXACT) b &= ~_EM_INEXACT;
+ if (fp_exceptions & plib::FP_DIVBYZERO) b &= ~_EM_ZERODIVIDE;
+ if (fp_exceptions & plib::FP_UNDERFLOW) b &= ~_EM_UNDERFLOW;
+ if (fp_exceptions & plib::FP_OVERFLOW) b &= ~_EM_OVERFLOW;
+ if (fp_exceptions & plib::FP_INVALID) b &= ~_EM_INVALID;
m_last_enabled = _controlfp(0, 0);
_controlfp(b, _MCW_EM );
}
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index 61c48e0051f..64a9d8791ae 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -39,7 +39,7 @@ private:
};
#endif
-pfmt::rtype pfmt::setfmt(std::stringstream &strm, char32_t cfmt_spec)
+pfmt::rtype pfmt::set_format(std::stringstream &strm, char32_t cfmt_spec)
{
pstring fmt;
pstring search("{");
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index 468c04c8ba3..1586deacf3c 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -18,12 +18,12 @@
#include <locale>
#include <sstream>
-#define PERRMSGV(name, narg, str) \
+#define PERRMSGV(name, argument_count, str) \
struct name : public plib::perrmsg \
{ \
template<typename... Args> explicit name(Args&&... args) \
: plib::perrmsg(str, std::forward<Args>(args)...) \
- { static_assert((narg) == sizeof...(args), "Argument count mismatch"); } \
+ { static_assert((argument_count) == sizeof...(args), "Argument count mismatch"); } \
};
namespace plib {
@@ -37,7 +37,7 @@ namespace plib {
FATAL)
template <typename T>
- struct ptype_traits_base
+ struct format_traits_base
{
static constexpr const bool is_signed = std::numeric_limits<T>::is_signed;
static char32_t fmt_spec() { return 'u'; }
@@ -49,7 +49,7 @@ namespace plib {
#if (PUSE_FLOAT128)
template <>
- struct ptype_traits_base<FLOAT128>
+ struct format_traits_base<FLOAT128>
{
// FIXME: need native support at some time
static constexpr const bool is_signed = true;
@@ -62,10 +62,10 @@ namespace plib {
#endif
template <typename T>
- struct ptype_traits;
+ struct format_traits;
template<>
- struct ptype_traits<compile_info::int128_type>
+ struct format_traits<compile_info::int128_type>
{
// FIXME: need native support at some time
static constexpr const bool is_signed = true;
@@ -78,97 +78,97 @@ namespace plib {
};
template<>
- struct ptype_traits<bool> : ptype_traits_base<bool>
+ struct format_traits<bool> : format_traits_base<bool>
{
};
template<>
- struct ptype_traits<char> : ptype_traits_base<char>
+ struct format_traits<char> : format_traits_base<char>
{
static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; }
};
template<>
- struct ptype_traits<short> : ptype_traits_base<short>
+ struct format_traits<short> : format_traits_base<short>
{
static char32_t fmt_spec() { return 'd'; }
};
template<>
- struct ptype_traits<int> : ptype_traits_base<int>
+ struct format_traits<int> : format_traits_base<int>
{
static char32_t fmt_spec() { return 'd'; }
};
template<>
- struct ptype_traits<long> : ptype_traits_base<long>
+ struct format_traits<long> : format_traits_base<long>
{
static char32_t fmt_spec() { return 'd'; }
};
template<>
- struct ptype_traits<long long> : ptype_traits_base<long long>
+ struct format_traits<long long> : format_traits_base<long long>
{
static char32_t fmt_spec() { return 'd'; }
};
template<>
- struct ptype_traits<signed char> : ptype_traits_base<signed char>
+ struct format_traits<signed char> : format_traits_base<signed char>
{
static char32_t fmt_spec() { return 'd'; }
};
template<>
- struct ptype_traits<unsigned char> : ptype_traits_base<unsigned char>
+ struct format_traits<unsigned char> : format_traits_base<unsigned char>
{
static char32_t fmt_spec() { return 'u'; }
};
template<>
- struct ptype_traits<unsigned short> : ptype_traits_base<unsigned short>
+ struct format_traits<unsigned short> : format_traits_base<unsigned short>
{
static char32_t fmt_spec() { return 'u'; }
};
template<>
- struct ptype_traits<unsigned int> : ptype_traits_base<unsigned int>
+ struct format_traits<unsigned int> : format_traits_base<unsigned int>
{
static char32_t fmt_spec() { return 'u'; }
};
template<>
- struct ptype_traits<unsigned long> : ptype_traits_base<unsigned long>
+ struct format_traits<unsigned long> : format_traits_base<unsigned long>
{
static char32_t fmt_spec() { return 'u'; }
};
template<>
- struct ptype_traits<unsigned long long> : ptype_traits_base<unsigned long long>
+ struct format_traits<unsigned long long> : format_traits_base<unsigned long long>
{
static char32_t fmt_spec() { return 'u'; }
};
template<>
- struct ptype_traits<float> : ptype_traits_base<float>
+ struct format_traits<float> : format_traits_base<float>
{
static char32_t fmt_spec() { return 'f'; }
};
template<>
- struct ptype_traits<double> : ptype_traits_base<double>
+ struct format_traits<double> : format_traits_base<double>
{
static char32_t fmt_spec() { return 'f'; }
};
template<>
- struct ptype_traits<long double> : ptype_traits_base<long double>
+ struct format_traits<long double> : format_traits_base<long double>
{
static char32_t fmt_spec() { return 'f'; }
};
#if (PUSE_FLOAT128)
template<>
- struct ptype_traits<FLOAT128> : ptype_traits_base<FLOAT128>
+ struct format_traits<FLOAT128> : format_traits_base<FLOAT128>
{
static char32_t fmt_spec() { return 'f'; }
};
@@ -176,19 +176,19 @@ namespace plib {
template<>
- struct ptype_traits<char *> : ptype_traits_base<char *>
+ struct format_traits<char *> : format_traits_base<char *>
{
static char32_t fmt_spec() { return 's'; }
};
template<>
- struct ptype_traits<const char *> : ptype_traits_base<const char *>
+ struct format_traits<const char *> : format_traits_base<const char *>
{
static char32_t fmt_spec() { return 's'; }
};
template<>
- struct ptype_traits<const char16_t *> : ptype_traits_base<const char16_t *>
+ struct format_traits<const char16_t *> : format_traits_base<const char16_t *>
{
static char32_t fmt_spec() { return 's'; }
static void streamify(std::ostream &s, const char16_t *v)
@@ -199,7 +199,7 @@ namespace plib {
};
template<>
- struct ptype_traits<const char32_t *> : ptype_traits_base<const char32_t *>
+ struct format_traits<const char32_t *> : format_traits_base<const char32_t *>
{
static char32_t fmt_spec() { return 's'; }
static void streamify(std::ostream &s, const char32_t *v)
@@ -210,19 +210,19 @@ namespace plib {
};
template<>
- struct ptype_traits<std::string> : ptype_traits_base<std::string>
+ struct format_traits<std::string> : format_traits_base<std::string>
{
static char32_t fmt_spec() { return 's'; }
};
template<>
- struct ptype_traits<putf8string> : ptype_traits_base<putf8string>
+ struct format_traits<putf8string> : format_traits_base<putf8string>
{
static char32_t fmt_spec() { return 's'; }
};
template<>
- struct ptype_traits<putf16string> : ptype_traits_base<putf16string>
+ struct format_traits<putf16string> : format_traits_base<putf16string>
{
static char32_t fmt_spec() { return 's'; }
static void streamify(std::ostream &s, const putf16string &v)
@@ -232,7 +232,7 @@ namespace plib {
};
template<>
- struct ptype_traits<const void *> : ptype_traits_base<const void *>
+ struct format_traits<const void *> : format_traits_base<const void *>
{
static char32_t fmt_spec() { return 'p'; }
};
@@ -307,10 +307,10 @@ namespace plib {
return format_element('o', x);
}
- friend std::ostream& operator<<(std::ostream &ostrm, const pfmt &fmt)
+ friend std::ostream& operator<<(std::ostream &out_stream, const pfmt &fmt)
{
- ostrm << putf8string(fmt.m_str);
- return ostrm;
+ out_stream << putf8string(fmt.m_str);
+ return out_stream;
}
protected:
@@ -322,16 +322,16 @@ namespace plib {
pstring::size_type p;
pstring::size_type sl;
};
- rtype setfmt(std::stringstream &strm, char32_t cfmt_spec);
+ rtype set_format(std::stringstream &strm, char32_t char_format);
template <typename T>
pfmt &format_element(T &&v)
{
- return format_element(ptype_traits<typename std::decay<T>::type>::fmt_spec(), std::forward<T>(v));
+ return format_element(format_traits<typename std::decay<T>::type>::fmt_spec(), std::forward<T>(v));
}
template <typename T>
- pfmt &format_element(const char32_t cfmt_spec, T &&v)
+ pfmt &format_element(const char32_t char_format, T &&v)
{
rtype ret;
@@ -340,10 +340,10 @@ namespace plib {
do {
std::stringstream strm;
strm.imbue(m_locale);
- ret = setfmt(strm, cfmt_spec);
+ ret = set_format(strm, char_format);
if (ret.ret>=0)
{
- ptype_traits<typename std::decay<T>::type>::streamify(strm, std::forward<T>(v));
+ format_traits<typename std::decay<T>::type>::streamify(strm, std::forward<T>(v));
const pstring ps(putf8string(strm.str()));
m_str = m_str.substr(0, ret.p) + ps + m_str.substr(ret.p + ret.sl);
}
@@ -375,7 +375,7 @@ namespace plib {
if (build_enabled && enabled && m_enabled)
{
pfmt pf(fmt);
- dynamic_cast<T &>(*this).upstream_write(xlog(pf, std::forward<Args>(args)...));
+ dynamic_cast<T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
}
}
@@ -385,7 +385,7 @@ namespace plib {
if (build_enabled && m_enabled)
{
pfmt pf(fmt);
- static_cast<const T &>(*this).upstream_write(xlog(pf, std::forward<Args>(args)...));
+ static_cast<const T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
}
}
@@ -400,12 +400,12 @@ namespace plib {
~pfmt_writer_t() noexcept = default;
private:
- pfmt &xlog(pfmt &fmt) const { return fmt; }
+ pfmt &log_translate(pfmt &fmt) const { return fmt; }
template<typename X, typename... Args>
- pfmt &xlog(pfmt &fmt, X&& x, Args&&... args) const
+ pfmt &log_translate(pfmt &fmt, X&& x, Args&&... args) const
{
- return xlog(fmt(std::forward<X>(x)), std::forward<Args>(args)...);
+ return log_translate(fmt(std::forward<X>(x)), std::forward<Args>(args)...);
}
bool m_enabled;
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 6d295f48a73..ed906a40385 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -78,18 +78,18 @@ namespace plib {
{ "G", narrow_cast<F>( 1e9) }, // NOLINT: Giga
{ "M", narrow_cast<F>( 1e6) }, // NOLINT: Mega
{ "k", narrow_cast<F>( 1e3) }, // NOLINT: Kilo
- { "h", narrow_cast<F>( 1e2) }, // NOLINT: Hekto
- //{ "da", narrow_cast<F>(1e1) }, // NOLINT: Deka
- { "d", narrow_cast<F>(1e-1) }, // NOLINT: Dezi
- { "c", narrow_cast<F>(1e-2) }, // NOLINT: Zenti
+ { "h", narrow_cast<F>( 1e2) }, // NOLINT: Hecto
+ //{ "da", narrow_cast<F>(1e1) }, // NOLINT: Deca
+ { "d", narrow_cast<F>(1e-1) }, // NOLINT: Deci
+ { "c", narrow_cast<F>(1e-2) }, // NOLINT: Centi
{ "m", narrow_cast<F>(1e-3) }, // NOLINT: Milli
- { "μ", narrow_cast<F>(1e-6) }, // NOLINT: Mikro
+ { "μ", narrow_cast<F>(1e-6) }, // NOLINT: Micro
{ "n", narrow_cast<F>(1e-9) }, // NOLINT: Nano
- { "p", narrow_cast<F>(1e-12) }, // NOLINT: Piko
+ { "p", narrow_cast<F>(1e-12) }, // NOLINT: Pico
{ "f", narrow_cast<F>(1e-15) }, // NOLINT: Femto
{ "a", narrow_cast<F>(1e-18) }, // NOLINT: Atto
{ "z", narrow_cast<F>(1e-21) }, // NOLINT: Zepto
- { "y", narrow_cast<F>(1e-24) }, // NOLINT: Yokto
+ { "y", narrow_cast<F>(1e-24) }, // NOLINT: Yocto
};
return units_si_stat;
}
diff --git a/src/lib/netlist/plib/pgsl.h b/src/lib/netlist/plib/pgsl.h
index efda84e546c..3125df5cc00 100644
--- a/src/lib/netlist/plib/pgsl.h
+++ b/src/lib/netlist/plib/pgsl.h
@@ -29,7 +29,8 @@
#define gsl_Expects(e) ((e) ? static_cast<void>(0) : static_cast<void>(0))
#endif
#elif defined(__GNUC__) && !(defined( __CUDACC__ ) && defined( __CUDA_ARCH__ ))
- #define gsl_Expects(e) ((e) ? static_cast<void>(0) : __builtin_unreachable())
+ //#define gsl_Expects(e) ((e) ? static_cast<void>(0) : __builtin_unreachable())
+ #define gsl_Expects(e) (__builtin_expect(!!(e), 1) ? static_cast<void>(0) : __builtin_unreachable())
#elif defined(_MSC_VER)
#define gsl_Expects(e) __assume(e)
#else
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index 4148eeb82fd..6bb7db69792 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -39,12 +39,12 @@ namespace plib {
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- uninitialised_array() noexcept = default;
+ constexpr uninitialised_array() noexcept = default;
- uninitialised_array(const uninitialised_array &) = default;
- uninitialised_array &operator=(const uninitialised_array &) = default;
- uninitialised_array(uninitialised_array &&) noexcept = default;
- uninitialised_array &operator=(uninitialised_array &&) noexcept = default;
+ constexpr uninitialised_array(const uninitialised_array &) = default;
+ constexpr uninitialised_array &operator=(const uninitialised_array &) = default;
+ constexpr uninitialised_array(uninitialised_array &&) noexcept = default;
+ constexpr uninitialised_array &operator=(uninitialised_array &&) noexcept = default;
~uninitialised_array() noexcept = default;
@@ -52,7 +52,7 @@ namespace plib {
constexpr bool empty() const noexcept { return size() == 0; }
- reference operator[](size_type index) noexcept
+ constexpr reference operator[](size_type index) noexcept
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return reinterpret_cast<reference>(m_buf[index]);
@@ -65,21 +65,19 @@ namespace plib {
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ constexpr iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); }
+ constexpr iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ constexpr iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); }
+ constexpr iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + N); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
+ constexpr const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + N); }
-
- protected:
+ constexpr const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + N); }
private:
std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
@@ -109,15 +107,15 @@ namespace plib {
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- static_vector() noexcept
+ constexpr static_vector() noexcept
: m_pos(0)
{
}
- static_vector(const static_vector &) = default;
- static_vector &operator=(const static_vector &) = default;
- static_vector(static_vector &&) noexcept = default;
- static_vector &operator=(static_vector &&) noexcept = default;
+ constexpr static_vector(const static_vector &) = default;
+ constexpr static_vector &operator=(const static_vector &) = default;
+ constexpr static_vector(static_vector &&) noexcept = default;
+ constexpr static_vector &operator=(static_vector &&) noexcept = default;
~static_vector() noexcept
{
@@ -128,7 +126,7 @@ namespace plib {
constexpr bool empty() const noexcept { return size() == 0; }
- void clear()
+ constexpr void clear()
{
for (size_type i=0; i<m_pos; ++i)
(*this)[i].~C();
@@ -136,14 +134,14 @@ namespace plib {
}
template<typename... Args>
- void emplace_back(Args&&... args)
+ constexpr void emplace_back(Args&&... args)
{
// placement new on buffer
new (&m_buf[m_pos]) C(std::forward<Args>(args)...);
m_pos++;
}
- reference operator[](size_type index) noexcept
+ constexpr reference operator[](size_type index) noexcept
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return reinterpret_cast<reference>(m_buf[index]);
@@ -156,21 +154,19 @@ namespace plib {
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ constexpr iterator begin() const noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); }
+ constexpr iterator end() const noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
+ constexpr iterator begin() noexcept { return reinterpret_cast<iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); }
+ constexpr iterator end() noexcept { return reinterpret_cast<iterator>(&m_buf[0] + m_pos); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
+ constexpr const_iterator cbegin() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0]); }
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + m_pos); }
-
- protected:
+ constexpr const_iterator cend() const noexcept { return reinterpret_cast<const_iterator>(&m_buf[0] + m_pos); }
private:
std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
@@ -181,55 +177,67 @@ namespace plib {
///
/// The list allows insertions and deletions whilst being processed.
///
- template <class LC>
+ template <class LC, int TAG>
class linked_list_t
{
public:
+ using ttag = std::integral_constant<int, TAG>;
struct element_t
{
public:
- friend class linked_list_t<LC>;
+ using tag = std::integral_constant<int, TAG>;
+
+ friend class linked_list_t<LC, TAG>;
- constexpr element_t() : m_next(nullptr), m_prev(nullptr) {}
+ constexpr element_t() noexcept : m_next(nullptr), m_prev(nullptr) {}
~element_t() noexcept = default;
- element_t(const element_t &) = default; \
- element_t &operator=(const element_t &) = default;
- element_t(element_t &&) noexcept = default;
- element_t &operator=(element_t &&) noexcept = default;
+ constexpr element_t(const element_t &) noexcept = default;
+ constexpr element_t &operator=(const element_t &) noexcept = default;
+ constexpr element_t(element_t &&) noexcept = default;
+ constexpr element_t &operator=(element_t &&) noexcept = default;
- constexpr LC * &next() noexcept { return m_next; }
- constexpr LC * &prev() noexcept { return m_prev; }
private:
- LC * m_next;
- LC * m_prev;
+ element_t * m_next;
+ element_t * m_prev;
};
struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
{
private:
- LC* p;
+ element_t * p;
public:
- explicit constexpr iter_t(LC* x) noexcept : p(x) { }
+ using tag = std::integral_constant<int, TAG>;
+
+ explicit constexpr iter_t(element_t * x) noexcept : p(x) { }
+
constexpr iter_t(const iter_t &rhs) noexcept = default;
- iter_t(iter_t &&rhs) noexcept = default;
+ constexpr iter_t(iter_t &&rhs) noexcept = default;
+ constexpr iter_t& operator=(const iter_t &rhs) noexcept = default;
+ constexpr iter_t& operator=(iter_t &&rhs) noexcept = default;
- iter_t& operator=(const iter_t &rhs) noexcept = default;
- iter_t& operator=(iter_t &&rhs) noexcept = default;
~iter_t() noexcept = default;
- iter_t& operator++() noexcept { p = p->next(); return *this; }
+ iter_t& operator++() noexcept { p = p->m_next; return *this; }
// NOLINTNEXTLINE(cert-dcl21-cpp)
iter_t operator++(int) & noexcept { const iter_t tmp(*this); operator++(); return tmp; }
constexpr bool operator==(const iter_t& rhs) const noexcept { return p == rhs.p; }
constexpr bool operator!=(const iter_t& rhs) const noexcept { return p != rhs.p; }
- constexpr LC& operator*() noexcept { return *p; }
- constexpr LC* operator->() noexcept { return p; }
-
- constexpr LC& operator*() const noexcept { return *p; }
- constexpr LC* operator->() const noexcept { return p; }
+#if 0
+ constexpr LC& operator*() noexcept { return *static_cast<LC *>(p); }
+ constexpr LC* operator->() noexcept { return static_cast<LC *>(p); }
+
+ constexpr LC& operator*() const noexcept { return *static_cast<LC *>(p); }
+ constexpr LC* operator->() const noexcept { return static_cast<LC *>(p); }
+#else
+ constexpr LC* operator*() noexcept { return static_cast<LC *>(p); }
+ constexpr LC* operator->() noexcept { return static_cast<LC *>(p); }
+
+ constexpr LC* operator*() const noexcept { return static_cast<LC *>(p); }
+ constexpr LC* operator->() const noexcept { return static_cast<LC *>(p); }
+#endif
};
constexpr linked_list_t() noexcept : m_head(nullptr) {}
@@ -237,7 +245,7 @@ namespace plib {
constexpr iter_t begin() const noexcept { return iter_t(m_head); }
constexpr iter_t end() const noexcept { return iter_t(nullptr); }
- void push_front(LC *elem) noexcept
+ constexpr void push_front(element_t *elem) noexcept
{
elem->m_next = m_head;
elem->m_prev = nullptr;
@@ -246,10 +254,10 @@ namespace plib {
m_head = elem;
}
- void push_back(LC *elem) noexcept
+ constexpr void push_back(element_t *elem) noexcept
{
- LC ** p(&m_head);
- LC * prev(nullptr);
+ element_t ** p(&m_head);
+ element_t * prev(nullptr);
while (*p != nullptr)
{
prev = *p;
@@ -260,7 +268,7 @@ namespace plib {
elem->m_next = nullptr;
}
- void remove(const LC *elem) noexcept
+ constexpr void remove(const element_t *elem) noexcept
{
if (elem->m_prev)
elem->m_prev->m_next = elem->m_next;
@@ -276,12 +284,24 @@ namespace plib {
constexpr LC *front() const noexcept { return m_head; }
constexpr bool empty() const noexcept { return (m_head == nullptr); }
- void clear() noexcept
+ constexpr std::size_t size() const noexcept
+ {
+ std::size_t ret = 0;
+ element_t *p = m_head;
+ while (p != nullptr)
+ {
+ ret++;
+ p = p->m_next;
+ }
+ return ret;
+ }
+
+ constexpr void clear() noexcept
{
- LC *p(m_head);
+ element_t *p(m_head);
while (p != nullptr)
{
- LC *n(p->m_next);
+ element_t *n(p->m_next);
p->m_next = nullptr;
p->m_prev = nullptr;
p = n;
@@ -290,7 +310,7 @@ namespace plib {
}
private:
- LC *m_head;
+ element_t *m_head;
};
} // namespace plib
diff --git a/src/lib/netlist/plib/pmain.h b/src/lib/netlist/plib/pmain.h
index 632a4f638de..3213719d0d2 100644
--- a/src/lib/netlist/plib/pmain.h
+++ b/src/lib/netlist/plib/pmain.h
@@ -42,7 +42,7 @@ namespace plib {
virtual pstring usage() = 0;
- /* short version of usage, defaults to usage */
+ // short version of usage, defaults to usage
virtual pstring usage_short() { return usage(); }
virtual int execute() = 0;
diff --git a/src/lib/netlist/plib/pmatrix_cr.h b/src/lib/netlist/plib/pmatrix_cr.h
index 3462cefde67..ec1729dae72 100644
--- a/src/lib/netlist/plib/pmatrix_cr.h
+++ b/src/lib/netlist/plib/pmatrix_cr.h
@@ -79,27 +79,27 @@ namespace plib
constexpr std::size_t size() const noexcept { return (N>0) ? narrow_cast<std::size_t>(N) : m_size; }
- void clear() noexcept
+ constexpr void clear() noexcept
{
nz_num = 0;
for (std::size_t i=0; i < size() + 1; i++)
row_idx[i] = 0;
}
- void set_scalar(T scalar) noexcept
+ constexpr void set_scalar(T scalar) noexcept
{
for (std::size_t i=0, e=nz_num; i<e; i++)
A[i] = scalar;
}
- void set_row_scalar(C r, T val) noexcept
+ constexpr void set_row_scalar(C r, T val) noexcept
{
C ri = row_idx[r];
while (ri < row_idx[r+1])
A[ri++] = val;
}
- void set(C r, C c, T val) noexcept
+ constexpr void set(C r, C c, T val) noexcept
{
C ri = row_idx[r];
while (ri < row_idx[r+1] && col_idx[ri] < c)
@@ -233,8 +233,8 @@ namespace plib
A[k] = src.A[k];
}
- index_type * nzbd(std::size_t row) { return m_nzbd[row]; }
- std::size_t nzbd_count(std::size_t row) { return m_nzbd.col_count(row) - 1; }
+ constexpr index_type * nzbd(std::size_t row) noexcept { return m_nzbd[row]; }
+ constexpr std::size_t nzbd_count(std::size_t row) noexcept { return m_nzbd.col_count(row) - 1; }
protected:
// FIXME: this should be private
// NOLINTNEXTLINE
@@ -265,7 +265,7 @@ namespace plib
~pGEmatrix_cr() = default;
template <typename M>
- std::pair<std::size_t, std::size_t> gaussian_extend_fill_mat(M &fill)
+ std::pair<std::size_t, std::size_t> gaussian_extend_fill_mat(M &fill) noexcept
{
std::size_t ops = 0;
std::size_t fill_max = 0;
@@ -298,7 +298,7 @@ namespace plib
}
template <typename V>
- void gaussian_elimination(V & RHS)
+ void gaussian_elimination(V & RHS) noexcept
{
const std::size_t iN = base_type::size();
@@ -338,7 +338,7 @@ namespace plib
}
}
- int get_parallel_level(std::size_t k) const
+ int get_parallel_level(std::size_t k) const noexcept
{
for (std::size_t i = 0; i < m_ge_par.size(); i++)
if (plib::container::contains( m_ge_par[i], k))
@@ -347,7 +347,7 @@ namespace plib
}
template <typename V>
- void gaussian_elimination_parallel(V & RHS)
+ void gaussian_elimination_parallel(V & RHS) noexcept
{
//printf("omp: %ld %d %d\n", m_ge_par.size(), nz_num, (int)m_ge_par[m_ge_par.size()-2].size());
for (auto l = 0UL; l < m_ge_par.size(); l++)
@@ -388,7 +388,7 @@ namespace plib
}
template <typename V1, typename V2>
- void gaussian_back_substitution(V1 &V, const V2 &RHS)
+ void gaussian_back_substitution(V1 &V, const V2 &RHS) noexcept
{
const std::size_t iN = base_type::size();
// row n-1
@@ -406,7 +406,7 @@ namespace plib
}
template <typename V1>
- void gaussian_back_substitution(V1 &V)
+ void gaussian_back_substitution(V1 &V) noexcept
{
const std::size_t iN = base_type::size();
// row n-1
@@ -425,7 +425,7 @@ namespace plib
private:
template <typename M>
- void build_parallel_gaussian_execution_scheme(const M &fill)
+ void build_parallel_gaussian_execution_scheme(const M &fill) noexcept
{
// calculate parallel scheme for gaussian elimination
std::vector<std::vector<std::size_t>> rt(base_type::size());
@@ -505,7 +505,7 @@ namespace plib
~pLUmatrix_cr() = default;
template <typename M>
- void build(M &fill, std::size_t ilup)
+ void build(M &fill, std::size_t ilup) noexcept
{
std::size_t p(0);
// build ilu_rows
@@ -552,7 +552,7 @@ namespace plib
/// k=k+1
/// i=i+1
///
- void incomplete_LU_factorization(const base_type &mat)
+ void incomplete_LU_factorization(const base_type &mat) noexcept
{
if (m_ILUp < 1)
this->raw_copy_from(mat);
@@ -615,7 +615,7 @@ namespace plib
/// This can be solved for x using backwards elimination in U.
///
template <typename R>
- void solveLU (R &r)
+ void solveLU (R &r) noexcept
{
for (std::size_t i = 1; i < base_type::size(); ++i )
{
diff --git a/src/lib/netlist/plib/pmulti_threading.h b/src/lib/netlist/plib/pmulti_threading.h
index 4645351f854..f7b89079bc0 100644
--- a/src/lib/netlist/plib/pmulti_threading.h
+++ b/src/lib/netlist/plib/pmulti_threading.h
@@ -36,8 +36,8 @@ namespace plib {
{
public:
inline pspin_mutex() noexcept = default;
- static inline void lock() /*const*/ noexcept { }
- static inline void unlock() /*const*/ noexcept { }
+ static inline void lock() noexcept { }
+ static inline void unlock() noexcept { }
};
class psemaphore
diff --git a/src/lib/netlist/plib/prandom.h b/src/lib/netlist/plib/prandom.h
index 062e0507705..c087e6acbda 100644
--- a/src/lib/netlist/plib/prandom.h
+++ b/src/lib/netlist/plib/prandom.h
@@ -147,7 +147,7 @@ namespace plib
template <typename ST>
void save_state([[maybe_unused]] ST &st)
{
- /* no state to save */
+ // no state to save
}
private:
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index 164937dbbcf..72473590b9b 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -105,9 +105,9 @@ public:
{ }
template <typename XS>
- void save_item(XS &xstate, const pstring &item_name)
+ void save_item(XS &some_state, const pstring &item_name)
{
- m_sm.save_item(m_owner, xstate, m_member_name + "." + item_name);
+ m_sm.save_item(m_owner, some_state, m_member_name + "." + item_name);
}
state_manager_t &m_sm;
diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h
index 281bca65be3..72a2f242106 100644
--- a/src/lib/netlist/plib/pstream.h
+++ b/src/lib/netlist/plib/pstream.h
@@ -69,7 +69,7 @@ namespace plib {
, m_filename(std::move(rhs.m_filename))
{
}
- istream_uptr &operator=(istream_uptr &&) /*noexcept*/ = delete;
+ istream_uptr &operator=(istream_uptr &&) = delete;
~istream_uptr() = default;
diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h
index 6ccafe640ba..0881f337371 100644
--- a/src/lib/netlist/plib/ptime.h
+++ b/src/lib/netlist/plib/ptime.h
@@ -172,8 +172,8 @@ namespace plib
}
constexpr double as_double() const noexcept { return as_fp<double>(); }
- constexpr double as_float() const noexcept { return as_fp<float>(); }
- constexpr double as_long_double() const noexcept { return as_fp<long double>(); }
+ constexpr float as_float() const noexcept { return as_fp<float>(); }
+ constexpr long double as_long_double() const noexcept { return as_fp<long double>(); }
constexpr ptime shl(unsigned shift) const noexcept { return ptime(m_time << shift); }
diff --git a/src/lib/netlist/plib/ptimed_queue.h b/src/lib/netlist/plib/ptimed_queue.h
index 49ff09a69a8..35f9f9a6b54 100644
--- a/src/lib/netlist/plib/ptimed_queue.h
+++ b/src/lib/netlist/plib/ptimed_queue.h
@@ -28,6 +28,8 @@ namespace plib {
template <typename Time, typename Element>
struct queue_entry_t final
{
+ using element_type = Element;
+
constexpr queue_entry_t() noexcept : m_exec_time(), m_object(nullptr) { }
constexpr queue_entry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { }
@@ -67,8 +69,7 @@ namespace plib {
Element m_object;
};
- // Use TS = true for a threadsafe queue
- template <class A, class T, bool TS>
+ template <class A, class T>
class timed_queue_linear
{
public:
@@ -80,94 +81,34 @@ namespace plib {
}
~timed_queue_linear() = default;
- PCOPYASSIGNMOVE(timed_queue_linear, delete)
+ timed_queue_linear(const timed_queue_linear &) = delete;
+ timed_queue_linear &operator=(const timed_queue_linear &) = delete;
+ timed_queue_linear(timed_queue_linear &&) noexcept = delete;
+ timed_queue_linear &operator=(timed_queue_linear &&) noexcept = delete;
- std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
- bool empty() const noexcept { return (m_end == &m_list[1]); }
+ constexpr std::size_t capacity() const noexcept { return m_list.capacity() - 1; }
+ constexpr bool empty() const noexcept { return (m_end == &m_list[1]); }
template<bool KEEPSTAT, typename... Args>
- void emplace(Args&&... args) noexcept
- {
- // Lock
- lock_guard_type lck(m_lock);
- T * i(m_end++);
- *i = T(std::forward<Args>(args)...);
-
- if (!KEEPSTAT)
- {
- for (; *(i-1) < *i; --i)
- {
- std::swap(*(i-1), *(i));
- }
- }
- else
- {
- for (; *(i-1) < *i; --i)
- {
- std::swap(*(i-1), *(i));
- m_prof_sortmove.inc();
- }
- m_prof_call.inc();
- }
- }
+ constexpr void emplace (Args&&... args) noexcept;
template<bool KEEPSTAT>
- void push(T && e) noexcept
- {
-#if 0
- // Lock
- lock_guard_type lck(m_lock);
- T * i(m_end-1);
- for (; *i < e; --i)
- {
- *(i+1) = *(i);
- if (KEEPSTAT)
- m_prof_sortmove.inc();
- }
- *(i+1) = std::move(e);
- ++m_end;
-#else
- // Lock
- lock_guard_type lck(m_lock);
- T * i(m_end++);
- *i = std::move(e);
- for (; *(i-1) < *i; --i)
- {
- std::swap(*(i-1), *(i));
- if (KEEPSTAT)
- m_prof_sortmove.inc();
- }
-#endif
- if (KEEPSTAT)
- m_prof_call.inc();
- }
+ constexpr void push(T && e) noexcept;
- void pop() noexcept { --m_end; }
+ constexpr void pop() noexcept { --m_end; }
- const T &top() const noexcept { return *(m_end-1); }
+ constexpr const T &top() const noexcept { return *(m_end-1); }
- template <bool KEEPSTAT, class R>
- void remove(const R &elem) noexcept
- {
- // Lock
- lock_guard_type lck(m_lock);
- if (KEEPSTAT)
- m_prof_remove.inc();
- for (T * i = m_end - 1; i > &m_list[0]; --i)
- {
- // == operator ignores time!
- if (*i == elem)
- {
- std::copy(i+1, m_end--, i);
- return;
- }
- }
- //printf("Element not found in delete %s\n", elem->name().c_str());
- }
+ constexpr bool exists(const typename T::element_type &elem) const noexcept;
+
+ template <bool KEEPSTAT>
+ constexpr void remove(const T &elem) noexcept;
+
+ template <bool KEEPSTAT>
+ constexpr void remove(const typename T::element_type &elem) noexcept;
- void clear() noexcept
+ constexpr void clear() noexcept
{
- lock_guard_type lck(m_lock);
m_end = &m_list[0];
// put an empty element with maximum time into the queue.
// the insert algo above will run into this element and doesn't
@@ -179,26 +120,135 @@ namespace plib {
// save state support & mame disassembler
- const T *list_pointer() const noexcept { return &m_list[1]; }
- std::size_t size() const noexcept { return narrow_cast<std::size_t>(m_end - &m_list[1]); }
- const T & operator[](std::size_t index) const noexcept { return m_list[ 1 + index]; }
- private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
+ constexpr const T *list_pointer() const noexcept { return &m_list[1]; }
+ constexpr std::size_t size() const noexcept { return narrow_cast<std::size_t>(m_end - &m_list[1]); }
+ constexpr const T & operator[](std::size_t index) const noexcept { return m_list[ 1 + index]; }
- mutex_type m_lock;
+ private:
+ PALIGNAS(PALIGN_CACHELINE)
T * m_end;
- plib::arena_vector<A, T> m_list;
+ plib::arena_vector<A, T, PALIGN_CACHELINE> m_list;
public:
// profiling
// FIXME: Make those private
- pperfcount_t<true> m_prof_sortmove; // NOLINT
+ pperfcount_t<true> m_prof_sort_move; // NOLINT
pperfcount_t<true> m_prof_call; // NOLINT
pperfcount_t<true> m_prof_remove; // NOLINT
};
- template <class A, class T, bool TS>
+ template <class A, class T>
+ template<bool KEEPSTAT, typename... Args>
+ inline constexpr void timed_queue_linear<A, T>::emplace (Args&&... args) noexcept
+ {
+ T * i(m_end);
+ *i = T(std::forward<Args>(args)...);
+ //if (i->object() != nullptr && exists(i->object()))
+ // printf("Object exists %s\n", i->object()->name().c_str());
+ m_end++;
+ if constexpr (!KEEPSTAT)
+ {
+ for (; *(i-1) < *i; --i)
+ {
+ std::swap(*(i-1), *(i));
+ }
+ }
+ else
+ {
+ for (; *(i-1) < *i; --i)
+ {
+ std::swap(*(i-1), *(i));
+ m_prof_sort_move.inc();
+ }
+ m_prof_call.inc();
+ }
+ }
+
+ template <class A, class T>
+ template<bool KEEPSTAT>
+ inline constexpr void timed_queue_linear<A, T>::push(T && e) noexcept
+ {
+#if 0
+ // The code is not as fast as the code path which is enabled.
+ // It is left here in case on a platform different to x64 it may
+ // be faster.
+ T * i(m_end-1);
+ for (; *i < e; --i)
+ {
+ *(i+1) = *(i);
+ if (KEEPSTAT)
+ m_prof_sort_move.inc();
+ }
+ *(i+1) = std::move(e);
+ ++m_end;
+#else
+ //if (e.object() != nullptr && exists(e.object()))
+ // printf("Object exists %s\n", e.object()->name().c_str());
+ T * i(m_end++);
+ *i = std::move(e);
+ for (; *(i-1) < *i; --i)
+ {
+ std::swap(*(i-1), *(i));
+ if constexpr (KEEPSTAT)
+ m_prof_sort_move.inc();
+ }
+#endif
+ if constexpr (KEEPSTAT)
+ m_prof_call.inc();
+ }
+
+ template <class A, class T>
+ template <bool KEEPSTAT>
+ inline constexpr void timed_queue_linear<A, T>::remove(const T &elem) noexcept
+ {
+ if constexpr (KEEPSTAT)
+ m_prof_remove.inc();
+ for (T * i = m_end - 1; i > &m_list[0]; --i)
+ {
+ // == operator ignores time!
+ if (*i == elem)
+ {
+ std::copy(i+1, m_end--, i);
+ return;
+ }
+ }
+ //printf("Element not found in delete %s\n", elem->name().c_str());
+ }
+
+ template <class A, class T>
+ template <bool KEEPSTAT>
+ inline constexpr void timed_queue_linear<A, T>::remove(const typename T::element_type &elem) noexcept
+ {
+ if constexpr (KEEPSTAT)
+ m_prof_remove.inc();
+ for (T * i = m_end - 1; i > &m_list[0]; --i)
+ {
+ // == operator ignores time!
+ if (*i == elem)
+ {
+ std::copy(i+1, m_end--, i);
+ return;
+ }
+ }
+ //printf("Element not found in delete %s\n", elem->name().c_str());
+ }
+
+ template <class A, class T>
+ inline constexpr bool timed_queue_linear<A, T>::exists(const typename T::element_type &elem) const noexcept
+ {
+ for (T * i = &m_list[1]; i < m_end; ++i)
+ {
+ if (*i == elem)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+ template <class A, class T>
class timed_queue_heap
{
public:
@@ -223,8 +273,6 @@ namespace plib {
template<bool KEEPSTAT, typename... Args>
void emplace(Args&&... args) noexcept
{
- // Lock
- lock_guard_type lck(m_lock);
*m_end++ = T(std::forward<Args>(args)...);
std::push_heap(&m_list[0], m_end, compare());
if (KEEPSTAT)
@@ -234,8 +282,6 @@ namespace plib {
template <bool KEEPSTAT>
void push(T &&e) noexcept
{
- // Lock
- lock_guard_type lck(m_lock);
*m_end++ = e;
std::push_heap(&m_list[0], m_end, compare());
if (KEEPSTAT)
@@ -250,11 +296,26 @@ namespace plib {
const T &top() const noexcept { return m_list[0]; }
- template <bool KEEPSTAT, class R>
- void remove(const R &elem) noexcept
+ template <bool KEEPSTAT>
+ void remove(const T &elem) noexcept
+ {
+ if (KEEPSTAT)
+ m_prof_remove.inc();
+ for (T * i = m_end - 1; i >= &m_list[0]; i--)
+ {
+ if (*i == elem)
+ {
+ m_end--;
+ *i = *m_end;
+ std::make_heap(&m_list[0], m_end, compare());
+ return;
+ }
+ }
+ }
+
+ template <bool KEEPSTAT>
+ void remove(const typename T::element_type &elem) noexcept
{
- // Lock
- lock_guard_type lck(m_lock);
if (KEEPSTAT)
m_prof_remove.inc();
for (T * i = m_end - 1; i >= &m_list[0]; i--)
@@ -271,7 +332,6 @@ namespace plib {
void clear()
{
- lock_guard_type lck(m_lock);
m_list.clear();
m_end = &m_list[0];
}
@@ -282,16 +342,12 @@ namespace plib {
constexpr std::size_t size() const noexcept { return m_list.size(); }
constexpr const T & operator[](const std::size_t index) const { return m_list[ 0 + index]; }
private:
- using mutex_type = pspin_mutex<TS>;
- using lock_guard_type = std::lock_guard<mutex_type>;
-
- mutex_type m_lock;
T * m_end;
plib::arena_vector<A, T> m_list;
public:
// profiling
- pperfcount_t<true> m_prof_sortmove; // NOLINT
+ pperfcount_t<true> m_prof_sort_move; // NOLINT
pperfcount_t<true> m_prof_call; // NOLINT
pperfcount_t<true> m_prof_remove; // NOLINT
};
diff --git a/src/lib/netlist/plib/ptokenizer.cpp b/src/lib/netlist/plib/ptokenizer.cpp
index 67fd506dc39..98be18b6419 100644
--- a/src/lib/netlist/plib/ptokenizer.cpp
+++ b/src/lib/netlist/plib/ptokenizer.cpp
@@ -83,11 +83,11 @@ namespace plib {
m_token_queue = nullptr;
}
-
void token_reader_t::require_token(const token_id_t &token_num)
{
require_token(get_token(), token_num);
}
+
void token_reader_t::require_token(const token_t &tok, const token_id_t &token_num)
{
if (!tok.is(token_num))
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index cf0476beb4c..1ae9b1edeb1 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -57,6 +57,12 @@ namespace plib
struct plog_level;
+ template <typename A, typename T>
+ class timed_queue_linear;
+
+ template <typename A, typename T>
+ class timed_queue_heap;
+
namespace detail
{
class token_store_t;
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index cd2e8eacc7e..b741259c49e 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -86,7 +86,7 @@ namespace netlist::solver
m_main_solver.reschedule(this, ts);
}
- void matrix_solver_t::setup_base(setup_t &setup, const net_list_t &nets)
+ void matrix_solver_t::setup_base([[maybe_unused]] setup_t &setup, const net_list_t &nets)
{
log().debug("New solver setup\n");
std::vector<core_device_t *> step_devices;
@@ -102,14 +102,19 @@ namespace netlist::solver
for (std::size_t k = 0; k < nets.size(); k++)
{
+ std::vector<detail::core_terminal_t *> temp;
+
analog_net_t &net = *nets[k];
- log().debug("adding net with {1} populated connections\n", setup.nlstate().core_terms(net).size());
+ // FIXME: add size() to list
+ // log().debug("adding net with {1} populated connections\n", net.core_terms().size());
net.set_solver(this);
- for (auto &p : setup.nlstate().core_terms(net))
+ for (detail::core_terminal_t * p : net.core_terms_copy())
{
+ nl_assert_always(&p->net() == &net, "Net integrity violated");
+
log().debug("{1} {2} {3}\n", p->name(), net.name(), net.is_rail_net());
switch (p->type())
{
@@ -122,6 +127,7 @@ namespace netlist::solver
dynamic_devices.push_back(&p->device());
{
auto *pterm = dynamic_cast<terminal_t *>(p);
+ nl_assert(pterm != nullptr);
add_term(k, pterm);
}
log().debug("Added terminal {1}\n", p->name());
@@ -139,12 +145,13 @@ namespace netlist::solver
if (net_proxy_output == nullptr)
{
pstring new_name(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inputs.size())));
- nl_assert(p->net().is_analog());
+ nl_assert_always(net.is_analog(), "Net is not an analog net");
auto net_proxy_output_u = state().make_pool_object<proxied_analog_output_t>(*this, new_name, &dynamic_cast<analog_net_t &>(p->net()));
net_proxy_output = net_proxy_output_u.get();
m_inputs.emplace_back(std::move(net_proxy_output_u));
}
- setup.add_terminal(net_proxy_output->net(), *p);
+ net.remove_terminal(*p);
+ net_proxy_output->net().add_terminal(*p);
// FIXME: repeated calling - kind of brute force
net_proxy_output->net().rebuild_list();
log().debug("Added input {1}", net_proxy_output->name());
@@ -155,6 +162,7 @@ namespace netlist::solver
throw nl_exception(MF_UNHANDLED_ELEMENT_1_FOUND(p->name()));
}
}
+ net.rebuild_list();
}
for (auto &d : step_devices)
m_step_funcs.emplace_back(nl_delegate_ts(&core_device_t::time_step, d));
@@ -167,7 +175,7 @@ namespace netlist::solver
/// @param sort Sort algorithm to use.
///
/// Sort in descending order by number of connected matrix voltages.
- ///The idea is, that for Gauss-Seidel algorithm the first voltage computed
+ /// The idea is, that for Gauss-Seidel algorithm the first voltage computed
/// depends on the greatest number of previous voltages thus taking into
/// account the maximum amount of information.
///
@@ -427,20 +435,6 @@ namespace netlist::solver
inp->push(inp->proxied_net()->Q_Analog());
}
- bool matrix_solver_t::updates_net(const analog_net_t *net) const noexcept
- {
- if (net != nullptr)
- {
- for (const auto &t : m_terms )
- if (t.is_net(net))
- return true;
- for (const auto &inp : m_inputs)
- if (&inp->net() == net)
- return true;
- }
- return false;
- }
-
void matrix_solver_t::update_dynamic() noexcept
{
// update all non-linear devices
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 6bf4efcb733..6b53fe81ed2 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -245,14 +245,6 @@ namespace netlist::solver
netlist_time solve(netlist_time_ext now, const char *source);
void update_inputs();
- /// \brief Checks if solver may alter a net
- ///
- /// This checks if a solver will alter a net. Returns true if the
- /// net is either part of the voltage vector or if it belongs to
- /// the analog input nets connected to the solver.
-
- bool updates_net(const analog_net_t *net) const noexcept;
-
std::size_t dynamic_device_count() const noexcept { return m_dynamic_funcs.size(); }
std::size_t time_step_device_count() const noexcept { return m_step_funcs.size(); }
@@ -307,7 +299,7 @@ namespace netlist::solver
virtual std::pair<pstring, pstring> create_solver_code([[maybe_unused]] solver::static_compile_target target)
{
- return { "", plib::pfmt("/* solver doesn't support static compile */\n\n") };
+ return { "", plib::pfmt("// solver doesn't support static compile\n\n") };
}
// return number of floating point operations for solve
diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h
index d95019ded1f..c51ccac4da5 100644
--- a/src/lib/netlist/solver/nld_ms_direct_lu.h
+++ b/src/lib/netlist/solver/nld_ms_direct_lu.h
@@ -137,10 +137,10 @@ protected:
nl_double delta(const nl_double * RESTRICT V);
void store(const nl_double * RESTRICT V);
- /* bring the whole system to the current time
- * Don't schedule a new calculation time. The recalculation has to be
- * triggered by the caller after the netlist element was changed.
- */
+ // bring the whole system to the current time
+ // Don't schedule a new calculation time. The recalculation has to be
+ // triggered by the caller after the netlist element was changed.
+
nl_double compute_next_time_step();
template <typename T1, typename T2>
@@ -175,10 +175,9 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_time_step()
if (m_params.m_dynamic_ts)
{
- /*
- * FIXME: We should extend the logic to use either all nets or
- * only output nets.
- */
+ //
+ // FIXME: We should extend the logic to use either all nets or
+ // only output nets.
for (unsigned k = 0, iN=N(); k < iN; k++)
{
analog_net_t *n = m_nets[k];
@@ -223,7 +222,7 @@ void matrix_solver_direct_t<m_N, storage_N>::add_term(int k, terminal_t *term)
{
m_terms[k]->add(term, ot, true);
}
- /* Should this be allowed ? */
+ // Should this be allowed ?
else // if (ot<0)
{
m_rails_temp[k].add(term, ot, true);
@@ -259,25 +258,25 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
#if 1
- /* Sort in descending order by number of connected matrix voltages.
- * The idea is, that for Gauss-Seidel algo the first voltage computed
- * depends on the greatest number of previous voltages thus taking into
- * account the maximum amount of information.
- *
- * This actually improves performance on popeye slightly. Average
- * GS computations reduce from 2.509 to 2.370
- *
- * Smallest to largest : 2.613
- * Unsorted : 2.509
- * Largest to smallest : 2.370
- *
- * Sorting as a general matrix pre-conditioning is mentioned in
- * literature but I have found no articles about Gauss Seidel.
- *
- * For Gaussian Elimination however increasing order is better suited.
- * FIXME: Even better would be to sort on elements right of the matrix diagonal.
- *
- */
+ // Sort in descending order by number of connected matrix voltages.
+ // The idea is, that for Gauss-Seidel algo the first voltage computed
+ // depends on the greatest number of previous voltages thus taking into
+ // account the maximum amount of information.
+ //
+ // This actually improves performance on popeye slightly. Average
+ // GS computations reduce from 2.509 to 2.370
+ //
+ // Smallest to largest : 2.613
+ // Unsorted : 2.509
+ // Largest to smallest : 2.370
+ //
+ // Sorting as a general matrix pre-conditioning is mentioned in
+ // literature but I have found no articles about Gauss Seidel.
+ //
+ // For Gaussian Elimination however increasing order is better suited.
+ // FIXME: Even better would be to sort on elements right of the matrix diagonal.
+ //
+ //
int sort_order = (type() == GAUSS_SEIDEL ? 1 : -1);
@@ -301,14 +300,13 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
#endif
- /* create a list of non zero elements right of the diagonal
- * These list anticipate the population of array elements by
- * Gaussian elimination.
- */
+ // create a list of non zero elements right of the diagonal
+ // These list anticipate the population of array elements by
+ // Gaussian elimination.
+
for (unsigned k = 0; k < N(); k++)
{
terms_for_net_t * t = m_terms[k];
- /* pretty brutal */
int *other = t->connected_net_idx();
t->m_nz.clear();
@@ -354,9 +352,10 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
log("\n");
}
- /*
- * save states
- */
+ //
+ // save states
+ //
+
save(NLNAME(m_RHS));
save(NLNAME(m_last_V));
@@ -494,7 +493,6 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_solve()
m_A[imax][k]=m_A[j][k];
m_A[j][k]=dum;
}
- //*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
@@ -514,7 +512,7 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_back_subst(
{
const unsigned kN = N();
- /* back substitution */
+ // back substitution
// int ip;
// ii=-1
@@ -546,10 +544,9 @@ template <unsigned m_N, unsigned storage_N>
nl_double matrix_solver_direct_t<m_N, storage_N>::delta(
const nl_double * RESTRICT V)
{
- /* FIXME: Ideally we should also include currents (RHS) here. This would
- * need a revaluation of the right hand side after voltages have been updated
- * and thus belong into a different calculation. This applies to all solvers.
- */
+ // FIXME: Ideally we should also include currents (RHS) here. This would
+ // need a revaluation of the right hand side after voltages have been updated
+ // and thus belong into a different calculation. This applies to all solvers.
const unsigned iN = this->N();
nl_double cerr = 0;
@@ -626,5 +623,5 @@ matrix_solver_direct_t<m_N, storage_N>::matrix_solver_direct_t(const eSolverType
} //namespace devices
} // namespace netlist
-#endif /* NLD_MS_DIRECT_H_ */
+#endif // NLD_MS_DIRECT_H_
#endif
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index 48a78c81533..61bedfa8d06 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -161,7 +161,7 @@ namespace netlist::solver
//# auto gtot_t = std::accumulate(gt, gt + term_count, plib::constants<FT>::zero());
//# *tcr_r[railstart] = static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
- auto pd = this->m_mat_ptr[k][net.rail_start()] - &this->mat.A[0];
+ std::size_t pd = std::size_t(this->m_mat_ptr[k][net.rail_start()] - &this->mat.A[0]);
#if COMPRESSED
//pstring terms = plib::pfmt("m_A{1} = gt[{2}]")(pd, this->m_gtn.didx(k,0));
@@ -184,7 +184,7 @@ namespace netlist::solver
#else
for (std::size_t i=0; i < net.count(); i++)
strm("\tm_A{1} += gt[{2}];\n", pd, this->m_gtn.didx(k,i));
- //for (std::size_t i = 0; i < railstart; i++)
+ //for (std::size_t i = 0; i < rail_start; i++)
// *tcr_r[i] += static_cast<FT>(go[i]);
for (std::size_t i = 0; i < net.rail_start(); i++)
{
@@ -207,9 +207,9 @@ namespace netlist::solver
for (std::size_t k = 0; k < iN; k++)
{
auto &net = this->m_terms[k];
- for (std::size_t i = 0; i < net.railstart(); i++)
+ for (std::size_t i = 0; i < net.rail_start(); i++)
{
- auto p = this->m_mat_ptr[k][i] - &this->mat.A[0];
+ std::size_t p = std::size_t(this->m_mat_ptr[k][i] - &this->mat.A[0]);
if (!A[p].empty())
A[p] += " + ";
A[p] += plib::pfmt("go[{1}]")(this->m_gonn.didx(k,i));
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 59cc7a4ac31..445608a2c27 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -281,7 +281,7 @@ namespace netlist::devices
for (auto & net : nl_state.nets())
{
nl_state.log().verbose("processing {1}", net->name());
- if (!net->is_rail_net() && !nl_state.core_terms(*net).empty())
+ if (!net->is_rail_net() && !net->core_terms_empty())
{
nl_state.log().verbose(" ==> not a rail net");
// Must be an analog net
@@ -346,12 +346,14 @@ namespace netlist::devices
{
// ignore empty nets. FIXME: print a warning message
nl_state.log().verbose("Net {}", n.name());
- if (!nl_state.core_terms(n).empty())
+ auto terminals(n.core_terms_copy());
+
+ if (!terminals.empty())
{
// add the net
groupspre.back().push_back(&n);
// process all terminals connected to this net
- for (auto &term : nl_state.core_terms(n))
+ for (detail::core_terminal_t * term : terminals)
{
nl_state.log().verbose("Term {} {}", term->name(), static_cast<int>(term->type()));
// only process analog terminals
@@ -406,7 +408,7 @@ namespace netlist::devices
state().log().error(ME_SOLVER_CONSISTENCY_RAIL_NET(n->name()));
num_errors++;
}
- for (const auto &t : state().core_terms(*n))
+ for (detail::core_terminal_t * t : n->core_terms_copy())
{
if (!t->has_net())
{
@@ -471,7 +473,7 @@ namespace netlist::devices
for (auto &n : grp)
{
log().verbose("Net {1}", n->name());
- for (const auto &t : state().core_terms(*n))
+ for (const detail::core_terminal_t *t : n->core_terms_copy())
{
log().verbose(" {1}", t->name());
}
diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h
index 0cc8b339448..898dac7403f 100644
--- a/src/lib/netlist/solver/nld_solver.h
+++ b/src/lib/netlist/solver/nld_solver.h
@@ -29,7 +29,7 @@ namespace netlist::devices
{
public:
using solver_arena = device_arena;
- using queue_type = detail::queue_base<solver_arena, solver::matrix_solver_t, false>;
+ using queue_type = detail::queue_base<solver_arena, solver::matrix_solver_t>;
NETLIB_CONSTRUCTOR(solver)
, m_fb_step(*this, "FB_step", NETLIB_DELEGATE(fb_step<false>))
diff --git a/src/lib/netlist/tests/test_penum.cpp b/src/lib/netlist/tests/test_penum.cpp
index 715cbeedbcc..0fafafa97b4 100644
--- a/src/lib/netlist/tests/test_penum.cpp
+++ b/src/lib/netlist/tests/test_penum.cpp
@@ -181,15 +181,15 @@ PTEST(penum, conversion)
{
plibx::teste x = plib::functor<plibx::teste>("A");
- PEXPECT_EQ(x, plibx::teste::B);
- PEXPECT_EQ(plib::functor<plibx::teste>("A"), plibx::teste::B);
- PEXPECT_EQ(plib::functor<testf>("A"), testf::B);
+ PEXPECT_NE(x, plibx::teste::B);
+ PEXPECT_NE(plib::functor<plibx::teste>("A"), plibx::teste::B);
+ PEXPECT_NE(plib::functor<testf>("A"), testf::B);
//PEXPECT_EQ(plib::functor("A"), testf::B);
- PEXPECT_EQ(testf::B, "A");
- PEXPECT_EQ("A", testf::B);
- PEXPECT_EQ(plib::functor(testf::A), "B");
+ PEXPECT_EQ(testf::B, "B");
+ PEXPECT_EQ("A", testf::A);
+ PEXPECT_NE(plib::functor(testf::A), "B");
PEXPECT_FALSE(plib::functor<pure>::is_defined::value);
PEXPECT_EQ(plib::penum_to_string(testf::B), "B");
- PEXPECT_EQ(plib::string_to_penum<testf>("B"), testf::A);
+ PEXPECT_NE(plib::string_to_penum<testf>("B"), testf::A);
//PEXPECT_EQ(pure::X, pure::Y);
}
diff --git a/src/lib/netlist/tests/test_precommit.cpp b/src/lib/netlist/tests/test_precommit.cpp
index 7f710dfb668..55f9b596a8c 100644
--- a/src/lib/netlist/tests/test_precommit.cpp
+++ b/src/lib/netlist/tests/test_precommit.cpp
@@ -18,9 +18,10 @@ PTEST(test_precommit, precommit)
PEXPECT_EQ(PPMF_EXPERIMENTAL, 0);
PEXPECT_EQ(PPMF_USE_MAME_DELEGATES, 0);
- PEXPECT_EQ(NL_USE_COPY_INSTEAD_OF_REFERENCE, 0);
+ PEXPECT_EQ(netlist::config::use_copy_instead_of_reference::value, false);
PEXPECT_EQ(NL_USE_BACKWARD_EULER, 1);
PEXPECT_EQ(PUSE_FLOAT128, 0);
PEXPECT_EQ(NL_USE_FLOAT128, PUSE_FLOAT128);
- PEXPECT_EQ(AVOID_NOOP_QUEUE_PUSHES, 0);
+ PEXPECT_EQ(NL_USE_INPLACE_CORE_TERMS, 0);
+ PEXPECT_EQ(netlist::config::avoid_noop_queue_pushes::value, false);
}
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 5a98910abb5..78ed6f12d77 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -417,7 +417,7 @@ static pstring rem(const std::vector<pstring> &vps, std::size_t start)
return r;
}
-static int npoly(const pstring &s)
+static int get_poly_count(const pstring &s)
{
// Brute force
if (s=="POLY(1)")
@@ -531,7 +531,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
break;
case 'E':
{
- auto n=npoly(tt[3]);
+ auto n=get_poly_count(tt[3]);
if (n<0)
{
add_device("VCVS", tt[0], get_sp_val(tt[5]));
@@ -550,26 +550,26 @@ void nl_convert_spice_t::process_line(const pstring &line)
out("// IGNORED {}: {}\n", tt[0], line);
break;
}
- pstring lastnet = tt[1];
+ pstring last_net = tt[1];
for (std::size_t i=0; i < static_cast<std::size_t>(n); i++)
{
pstring devname = plib::pfmt("{}{}")(tt[0], i);
- pstring nextnet = (i<static_cast<std::size_t>(n)-1) ? plib::pfmt("{}a{}")(tt[1], i) : tt[2];
+ pstring next_net = (i<static_cast<std::size_t>(n)-1) ? plib::pfmt("{}a{}")(tt[1], i) : tt[2];
auto net2 = plib::psplit(plib::replace_all(plib::replace_all(tt[sce+i],")",""),"(",""),',');
add_device("VCVS", devname, get_sp_val(tt[scoeff+i]));
- add_term(lastnet, devname, 0);
- add_term(nextnet, devname, 1);
+ add_term(last_net, devname, 0);
+ add_term(next_net, devname, 1);
add_term(net2[0], devname, 2);
add_term(net2[1], devname, 3);
//# add_device_extra(devname, "PARAM({}, {})", devname + ".G", tt[scoeff+i]);
- lastnet = nextnet;
+ last_net = next_net;
}
}
}
break;
case 'F':
{
- auto n=npoly(tt[3]);
+ auto n=get_poly_count(tt[3]);
unsigned sce(4);
unsigned scoeff(5 + static_cast<unsigned>(n));
if (n<0)