diff options
author | couriersud <couriersud@gmx.org> | 2017-04-06 00:03:59 +0200 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2017-04-09 00:04:10 +0200 |
commit | 49d50c3045a71a75566ad4322bf2195b2adba0c2 (patch) | |
tree | ee1e5f74c8f4fbf04d896d6703e7a4c43bbc8f31 /src/lib/netlist | |
parent | 3f9f4eedcfc2757567d8bc46bd8e6f7850348683 (diff) |
Netlist code refactoring:
- more use of c++ features
- some CRTP in pfmtlog
- demangled code for truthtables
- use more constexpr
- rewrite main loop
- use default constructors and assignment operators were applicable.
- optimized 7448 and 9316
All of this has decreased startup time by approx. 25% to 30%. Complex
netlists like pong or kidniki are parsed, analyzed and constructed in
around 15 ms. Run performance has increased by about 5%.
All in all not to bad. A game like pong uses a clock of 7 MHz (after
division by 2). Thats 14 MHz clock invocations. Running at over 200%, 28
MHz. On a 3.9 GHz Machine about 140 cycles/clock change.
[Couriersud]
Diffstat (limited to 'src/lib/netlist')
37 files changed, 472 insertions, 446 deletions
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp index 676042850ad..f54c2b3e68f 100644 --- a/src/lib/netlist/analog/nlid_twoterm.cpp +++ b/src/lib/netlist/analog/nlid_twoterm.cpp @@ -38,7 +38,7 @@ generic_diode::generic_diode(device_t &dev, pstring name) void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin) { - static const double csqrt2 = std::sqrt(2.0); + static constexpr double csqrt2 = 1.414213562373095048801688724209; //std::sqrt(2.0); m_Is = Is; m_logIs = std::log(Is); m_n = n; diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index d996d5dfd51..f2aa515e82d 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -200,14 +200,15 @@ maketree: $(sort $(OBJDIRS)) .PHONY: clang clang-5 mingw doc clang: - $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" + $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-march=native -Weverything -Werror -override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" clang-5: - $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" + $(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors" # # Mostly done: -Wno-weak-vtables -Wno-cast-align # FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors +# FIXME: -Winconsistent-missing-destructor-override : c++ community has diverging opinions on this https://github.com/isocpp/CppCoreGuidelines/issues/721 # FIXME: -Wunreachable-code : False warnings, this a documented clang bug: https://llvm.org/bugs/show_bug.cgi?id=28994 mingw: diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index 3521bd744ba..4c32235f6fc 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -15,11 +15,13 @@ //#define NL_AUTO_DEVICES 1 +#define SOLVER(name, freq) \ + NET_REGISTER_DEV(SOLVER, name) \ + PARAM(name.FREQ, freq) + #ifdef NL_AUTO_DEVICES #include "nld_devinc.h" -#include "solver/nld_solver.h" - #include "macro/nlm_cd4xxx.h" #include "macro/nlm_ttl74xx.h" #include "macro/nlm_opamp.h" @@ -29,10 +31,6 @@ #else -#define SOLVER(name, freq) \ - NET_REGISTER_DEV(SOLVER, name) \ - PARAM(name.FREQ, freq) - #include "nld_system.h" #include "nld_2102A.h" diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp index 7f9e6087c91..c5a12a15fb4 100644 --- a/src/lib/netlist/devices/nld_74107.cpp +++ b/src/lib/netlist/devices/nld_74107.cpp @@ -13,8 +13,8 @@ namespace netlist namespace devices { - static const netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) }; - static const netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) }; + static constexpr netlist_time delay_107[2] = { NLTIME_FROM_NS(16), NLTIME_FROM_NS(25) }; + static constexpr netlist_time delay_107A[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(15) }; NETLIB_OBJECT(74107A) { diff --git a/src/lib/netlist/devices/nld_74161.cpp b/src/lib/netlist/devices/nld_74161.cpp index af6d212820b..5eb711fb456 100644 --- a/src/lib/netlist/devices/nld_74161.cpp +++ b/src/lib/netlist/devices/nld_74161.cpp @@ -5,8 +5,6 @@ * */ -#define MAXCNT 15 - #include "nld_74161.h" #include "../nl_base.h" @@ -14,6 +12,9 @@ namespace netlist { namespace devices { + + static constexpr const unsigned MAXCNT = 15; + NETLIB_OBJECT(74161) { NETLIB_CONSTRUCTOR(74161) @@ -84,7 +85,7 @@ namespace netlist } // FIXME: Timing - static const netlist_time delay[4] = + static constexpr netlist_time delay[4] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(40), @@ -108,9 +109,7 @@ namespace netlist } else if (m_ENABLET() && m_ENABLEP()) { - ++m_cnt; - if (m_cnt > MAXCNT) - m_cnt = 0; + ++m_cnt &= MAXCNT; } } diff --git a/src/lib/netlist/devices/nld_74175.cpp b/src/lib/netlist/devices/nld_74175.cpp index f8524caeb6d..1393c4dc79b 100644 --- a/src/lib/netlist/devices/nld_74175.cpp +++ b/src/lib/netlist/devices/nld_74175.cpp @@ -92,8 +92,8 @@ namespace netlist } }; - const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) }; - const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) }; + constexpr const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) }; + constexpr const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) }; NETLIB_RESET(74175_sub) { diff --git a/src/lib/netlist/devices/nld_74192.cpp b/src/lib/netlist/devices/nld_74192.cpp index 0884ab74880..1af605d4776 100644 --- a/src/lib/netlist/devices/nld_74192.cpp +++ b/src/lib/netlist/devices/nld_74192.cpp @@ -5,8 +5,6 @@ * */ -#define MAXCNT 9 - #include "nld_74192.h" #include "../nl_base.h" @@ -14,6 +12,9 @@ namespace netlist { namespace devices { + + static constexpr const unsigned MAXCNT = 9; + NETLIB_OBJECT(74192_subABCD) { NETLIB_CONSTRUCTOR(74192_subABCD) @@ -109,7 +110,7 @@ namespace netlist } // FIXME: Timing - static const netlist_time delay[4] = + static constexpr netlist_time delay[4] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(40), @@ -133,8 +134,7 @@ namespace netlist { if (m_CD() && !m_last_CU && m_CU()) { - ++m_cnt; - if (m_cnt > MAXCNT) + if (++m_cnt > MAXCNT) m_cnt = 0; } if (m_CU() && !m_last_CD && m_CD()) diff --git a/src/lib/netlist/devices/nld_74193.cpp b/src/lib/netlist/devices/nld_74193.cpp index 9d29175dae9..55d18f3dc1b 100644 --- a/src/lib/netlist/devices/nld_74193.cpp +++ b/src/lib/netlist/devices/nld_74193.cpp @@ -5,8 +5,6 @@ * */ -#define MAXCNT 15 - #include "nld_74193.h" #include "../nl_base.h" @@ -14,6 +12,8 @@ namespace netlist { namespace devices { + static constexpr const unsigned MAXCNT = 15; + NETLIB_OBJECT(74193) { NETLIB_CONSTRUCTOR(74193) @@ -87,7 +87,7 @@ namespace netlist } // FIXME: Timing - static const netlist_time delay[4] = + static constexpr netlist_time delay[4] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(40), @@ -112,9 +112,7 @@ namespace netlist { if (m_CD() && !m_last_CU && m_CU()) { - ++m_cnt; - if (m_cnt > MAXCNT) - m_cnt = 0; + ++m_cnt &= MAXCNT; } if (m_CU() && !m_last_CD && m_CD()) { diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 9353c758bbc..cc2e60f23b7 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -38,7 +38,6 @@ namespace netlist public: void update_outputs(unsigned v); - static const uint_fast8_t tab7448[16][7]; logic_input_t m_A; logic_input_t m_B; @@ -134,6 +133,28 @@ namespace netlist #else +#define BITS7(b6,b5,b4,b3,b2,b1,b0) (b6<<6) | (b5<<5) | (b4<<4) | (b3<<3) | (b2<<2) | (b1<<1) | (b0<<0) + + static constexpr uint8_t tab7448[16] = + { + BITS7( 1, 1, 1, 1, 1, 1, 0 ), /* 00 - not blanked ! */ + BITS7( 0, 1, 1, 0, 0, 0, 0 ), /* 01 */ + BITS7( 1, 1, 0, 1, 1, 0, 1 ), /* 02 */ + BITS7( 1, 1, 1, 1, 0, 0, 1 ), /* 03 */ + BITS7( 0, 1, 1, 0, 0, 1, 1 ), /* 04 */ + BITS7( 1, 0, 1, 1, 0, 1, 1 ), /* 05 */ + BITS7( 0, 0, 1, 1, 1, 1, 1 ), /* 06 */ + BITS7( 1, 1, 1, 0, 0, 0, 0 ), /* 07 */ + BITS7( 1, 1, 1, 1, 1, 1, 1 ), /* 08 */ + BITS7( 1, 1, 1, 0, 0, 1, 1 ), /* 09 */ + BITS7( 0, 0, 0, 1, 1, 0, 1 ), /* 10 */ + BITS7( 0, 0, 1, 1, 0, 0, 1 ), /* 11 */ + BITS7( 0, 1, 0, 0, 0, 1, 1 ), /* 12 */ + BITS7( 1, 0, 0, 1, 0, 1, 1 ), /* 13 */ + BITS7( 0, 0, 0, 1, 1, 1, 1 ), /* 14 */ + BITS7( 0, 0, 0, 0, 0, 0, 0 ), /* 15 */ + }; + NETLIB_UPDATE(7448) { if (!m_BIQ() || (m_BIQ() && !m_LTQ())) @@ -157,9 +178,7 @@ namespace netlist m_C.activate(); m_B.activate(); m_A.activate(); - unsigned v; - - v = (m_A() << 0) | (m_B() << 1) | (m_C() << 2) | (m_D() << 3); + unsigned v = (m_A() << 0) | (m_B() << 1) | (m_C() << 2) | (m_D() << 3); if ((!m_RBIQ() && (v==0))) v = 15; update_outputs(v); @@ -183,31 +202,13 @@ namespace netlist { // max transfer time is 100 NS */ - for (std::size_t i=0; i<7; i++) - m_Q[i].push(tab7448[v][i], NLTIME_FROM_NS(100)); + uint8_t t = tab7448[v]; + for (std::size_t i = 0; i < 7; i++) + m_Q[i].push((t >> (6-i)) & 1, NLTIME_FROM_NS(100)); m_state = v; } } - const uint_fast8_t NETLIB_NAME(7448)::tab7448[16][7] = - { - { 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */ - { 0, 1, 1, 0, 0, 0, 0 }, /* 01 */ - { 1, 1, 0, 1, 1, 0, 1 }, /* 02 */ - { 1, 1, 1, 1, 0, 0, 1 }, /* 03 */ - { 0, 1, 1, 0, 0, 1, 1 }, /* 04 */ - { 1, 0, 1, 1, 0, 1, 1 }, /* 05 */ - { 0, 0, 1, 1, 1, 1, 1 }, /* 06 */ - { 1, 1, 1, 0, 0, 0, 0 }, /* 07 */ - { 1, 1, 1, 1, 1, 1, 1 }, /* 08 */ - { 1, 1, 1, 0, 0, 1, 1 }, /* 09 */ - { 0, 0, 0, 1, 1, 0, 1 }, /* 10 */ - { 0, 0, 1, 1, 0, 0, 1 }, /* 11 */ - { 0, 1, 0, 0, 0, 1, 1 }, /* 12 */ - { 1, 0, 0, 1, 0, 1, 1 }, /* 13 */ - { 0, 0, 0, 1, 1, 1, 1 }, /* 14 */ - { 0, 0, 0, 0, 0, 0, 0 }, /* 15 */ - }; #endif NETLIB_DEVICE_IMPL(7448) diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp index 7c547f05dbd..13e69c6aa31 100644 --- a/src/lib/netlist/devices/nld_7490.cpp +++ b/src/lib/netlist/devices/nld_7490.cpp @@ -78,7 +78,7 @@ namespace netlist m_last_B = 0; } - static const netlist_time delay[4] = + static C14CONSTEXPR const netlist_time delay[4] = { 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 bc6989d5cb5..78b75e9e326 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -51,7 +51,7 @@ namespace netlist { if (m_reset) { - m_bcd = (m_bcd + 1) & 0x07; + ++m_bcd &= static_cast<std::uint8_t>(0x07); m_QD.push((m_bcd >> 2) & 1, out_delay3); m_QC.push((m_bcd >> 1) & 1, out_delay2); m_QB.push(m_bcd & 1, out_delay); @@ -69,9 +69,9 @@ namespace netlist logic_output_t m_QC; logic_output_t m_QD; - state_var<netlist_sig_t> m_reset; - state_var<netlist_sig_t> m_a; - state_var_u8 m_bcd; + state_var_sig m_reset; + state_var_sig m_a; + state_var_sig m_bcd; }; NETLIB_OBJECT_DERIVED(7493_dip, 7493) diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 0c45f6dde51..ad752adb605 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -180,8 +180,8 @@ namespace netlist else { m_cnt = m_ABCD->read_ABCD(); - update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); } } diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 61ae427a2a8..58085f04c77 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -8,22 +8,22 @@ #include "nld_9316.h" #include "../nl_base.h" -#define MAXCNT 15 - namespace netlist { namespace devices { + static constexpr const unsigned MAXCNT = 15; + NETLIB_OBJECT(9316) { NETLIB_CONSTRUCTOR(9316) - , m_CLK(*this, "CLK", NETLIB_DELEGATE(9316, clk)) , m_cnt(*this, "m_cnt", 0) - , m_ENP(*this, "ENP") + , m_CLK(*this, "CLK", NETLIB_DELEGATE(9316, clk)) , m_ENT(*this, "ENT") - , m_CLRQ(*this, "CLRQ") , m_LOADQ(*this, "LOADQ") + , m_ENP(*this, "ENP") + , m_CLRQ(*this, "CLRQ") , m_A(*this, "A", NETLIB_DELEGATE(9316, noop)) , m_B(*this, "B", NETLIB_DELEGATE(9316, noop)) , m_C(*this, "C", NETLIB_DELEGATE(9316, noop)) @@ -36,20 +36,20 @@ namespace netlist { } + private: NETLIB_RESETI(); NETLIB_UPDATEI(); NETLIB_HANDLERI(clk); NETLIB_HANDLERI(noop) { } - protected: + state_var<unsigned> m_cnt; logic_input_t m_CLK; - state_var<unsigned> m_cnt; + logic_input_t m_ENT; + logic_input_t m_LOADQ; logic_input_t m_ENP; - logic_input_t m_ENT; logic_input_t m_CLRQ; - logic_input_t m_LOADQ; logic_input_t m_A; logic_input_t m_B; @@ -64,7 +64,7 @@ namespace netlist private: - void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay) + void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay) noexcept { m_QA.push((cnt >> 0) & 1, out_delay); m_QB.push((cnt >> 1) & 1, out_delay); @@ -77,22 +77,22 @@ namespace netlist { NETLIB_CONSTRUCTOR_DERIVED(9316_dip, 9316) { - register_subalias("1", m_CLRQ); - register_subalias("2", m_CLK); - register_subalias("3", m_A); - register_subalias("4", m_B); - register_subalias("5", m_C); - register_subalias("6", m_D); - register_subalias("7", m_ENP); - // register_subalias("8", ); -. GND - - register_subalias("9", m_LOADQ); - register_subalias("10", m_ENT); - register_subalias("11", m_QD); - register_subalias("12", m_QC); - register_subalias("13", m_QB); - register_subalias("14", m_QA); - register_subalias("15", m_RC); + register_subalias("1", "CLRQ"); + register_subalias("2", "CLK"); + register_subalias("3", "A"); + register_subalias("4", "B"); + register_subalias("5", "C"); + register_subalias("6", "D"); + register_subalias("7", "ENP"); + // register_subalias("8", "); -. GND + + register_subalias("9", "LOADQ"); + register_subalias("10", "ENT"); + register_subalias("11", "QD"); + register_subalias("12", "QC"); + register_subalias("13", "QB"); + register_subalias("14", "QA"); + register_subalias("15", "RC"); // register_subalias("16", ); -. VCC } }; @@ -107,37 +107,48 @@ namespace netlist { if (m_LOADQ()) { - m_cnt = (m_cnt < MAXCNT ? m_cnt + 1 : 0); - update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); - m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + ++m_cnt &= MAXCNT; + //m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + if (m_cnt == MAXCNT) + { + m_RC.push(m_ENT(), NLTIME_FROM_NS(27)); + update_outputs_all(MAXCNT, NLTIME_FROM_NS(20)); + } + else if (m_cnt == 0) + { + m_RC.push(0, NLTIME_FROM_NS(27)); + update_outputs_all(0, NLTIME_FROM_NS(20)); + } + else + update_outputs_all(m_cnt, NLTIME_FROM_NS(20)); } else { m_cnt = (m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0); - m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); update_outputs_all(m_cnt, NLTIME_FROM_NS(22)); } } NETLIB_UPDATE(9316) { - const netlist_sig_t clrq = m_CLRQ(); + const netlist_sig_t CLRQ(m_CLRQ()); + const netlist_sig_t ENT(m_ENT()); - if (((m_LOADQ() ^ 1) | (m_ENT() & m_ENP())) & clrq) + if (((m_LOADQ() ^ 1) || (ENT && m_ENP())) && CLRQ) { m_CLK.activate_lh(); - m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } else { m_CLK.inactivate(); - if (!clrq && (m_cnt>0)) + if (!CLRQ && (m_cnt>0)) { - update_outputs_all(0, NLTIME_FROM_NS(36)); m_cnt = 0; + update_outputs_all(m_cnt, NLTIME_FROM_NS(36)); } - m_RC.push(m_ENT() & (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } + m_RC.push(ENT && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index 1b57b9c8ece..e97ae41e437 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -72,7 +72,7 @@ namespace netlist m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0); m_inc = netlist_time::from_double(1.0 / m_FREQ()); if (m_FREQ() < 24000 || m_FREQ() > 56000) - log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ()); + log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ()); m_shift = 0x1ffff; m_is_timestep = m_RV.m_P.net().solver()->is_timestep(); @@ -82,7 +82,7 @@ namespace netlist { m_inc = netlist_time::from_double(1.0 / m_FREQ()); if (m_FREQ() < 24000 || m_FREQ() > 56000) - log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ()); + log().warning(MW_1_FREQUENCY_OUTSIDE_OF_SPECS_1, m_FREQ()); } NETLIB_UPDATE(MM5837_dip) diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index aaa181911ba..98793c657d2 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -46,8 +46,9 @@ namespace netlist NETLIB_UPDATE(extclock) { m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off); - m_cnt = (m_cnt + 1) % m_size; m_off = netlist_time::zero(); + if (++m_cnt >= m_size) + m_cnt = 0; } // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index a04b49c2440..92fb91d627c 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -155,7 +155,7 @@ namespace netlist logic_input_t m_feedback; logic_output_t m_Q; - state_var<std::uint8_t> m_cnt; + state_var_u8 m_cnt; std::uint8_t m_size; state_var<netlist_time> m_off; netlist_time m_inc[32]; diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 58c1ed65390..bf7d03fe3d7 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -122,7 +122,7 @@ namespace netlist } } - uint_least64_t mask() const { return (static_cast<uint_least64_t>(1) << m_size) - 1; } + uint_least64_t mask() const { return static_cast<uint_least64_t>(-1); } private: void *m_data; @@ -140,7 +140,7 @@ namespace netlist { } - void parse(const std::vector<pstring> &desc, uint_least64_t disabled_ignore); + void parse(const std::vector<pstring> &desc); private: void parseline(unsigned cur, std::vector<pstring> list, @@ -209,11 +209,12 @@ namespace netlist m_ign = 0; - truthtable_parser desc_s(m_NO, m_NI, &m_ttp->m_initialized, - packed_int(m_ttp->m_outs, sizeof(m_ttp->m_outs[0]) * 8), - m_ttp->m_timing, m_ttp->m_timing_nt); - - desc_s.parse(desc, disabled_ignore * 0); +#if 0 + for (size_t i=0; i<m_size; i++) + { + m_ttp.m_outs[i] &= ~(disabled_ignore << m_NO); + } +#endif #if 0 printf("%s\n", name().c_str()); for (int j=0; j < m_size; j++) @@ -240,7 +241,12 @@ namespace netlist plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override { typedef nld_truthtable_t<m_NI, m_NO> tt_type; - return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, &m_ttbl, m_desc); + truthtable_parser desc_s(m_NO, m_NI, &m_ttbl.m_initialized, + packed_int(m_ttbl.m_outs, sizeof(m_ttbl.m_outs[0]) * 8), + m_ttbl.m_timing, m_ttbl.m_timing_nt); + + desc_s.parse(m_desc); + return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, m_ttbl, m_desc); } private: typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl; @@ -356,7 +362,7 @@ void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list, } } -void truthtable_parser::parse(const std::vector<pstring> &truthtable, uint_least64_t disabled_ignore) +void truthtable_parser::parse(const std::vector<pstring> &truthtable) { unsigned line = 0; @@ -446,7 +452,7 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable, uint_least { if (m_outs[i] == m_outs.mask()) throw nl_exception(plib::pfmt("truthtable: found element not set {1}\n").x(i) ); - m_outs.set(i, m_outs[i] | ((ign[i] & ~disabled_ignore) << m_NO));; + m_outs.set(i, m_outs[i] | (ign[i] << m_NO));; } *m_initialized = true; diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index 1eeef1a6386..84f49f7c305 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -14,16 +14,16 @@ #include "../nl_base.h" #include "../plib/putil.h" -#define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \ - class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT> \ - { \ - public: \ - template <class C> \ - NETLIB_NAME(cname)(C &owner, const pstring &name) \ +#define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \ + class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT> \ + { \ + public: \ + template <class C> \ + NETLIB_NAME(cname)(C &owner, const pstring &name) \ : nld_truthtable_t<nIN, nOUT>(owner, name, family_TTL(), &m_ttbl, m_desc) { } \ - private: \ - static truthtable_t m_ttbl; \ - static std::vector<pstring> m_desc; \ + private: \ + static truthtable_t m_ttbl; \ + static std::vector<pstring> m_desc; \ } @@ -32,22 +32,31 @@ namespace netlist namespace devices { +#if 0 + template<unsigned bits> struct uint_for_size { typedef uint_least32_t type; }; + template<unsigned bits> + struct need_bytes_for_bits + { + enum { value = 4 }; + }; +#else template<unsigned bits> struct need_bytes_for_bits { enum { value = - bits <= 8 ? 1 : - bits <= 16 ? 2 : - bits <= 32 ? 4 : - 8 + bits <= 8 ? 1 : + bits <= 16 ? 2 : + bits <= 32 ? 4 : + 8 }; }; template<unsigned bits> struct uint_for_size; - template<> struct uint_for_size<1> { typedef uint_least8_t type; }; + template<> struct uint_for_size<1> { typedef uint_least8_t type; }; template<> struct uint_for_size<2> { typedef uint_least16_t type; }; template<> struct uint_for_size<4> { typedef uint_least32_t type; }; template<> struct uint_for_size<8> { typedef uint_least64_t type; }; +#endif template<std::size_t m_NI, std::size_t m_NO> NETLIB_OBJECT(truthtable_t) @@ -74,8 +83,9 @@ namespace netlist }; template <class C> - nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam, - truthtable_t *ttp, const std::vector<pstring> &desc) + nld_truthtable_t(C &owner, const pstring &name, + const logic_family_desc_t *fam, + truthtable_t &ttp, const std::vector<pstring> &desc) : device_t(owner, name) , m_fam(*this, fam) , m_ign(*this, "m_ign", 0) @@ -91,10 +101,10 @@ namespace netlist { m_active = 0; m_ign = 0; - for (std::size_t i = 0; i < m_NI; i++) - m_I[i].activate(); - for (std::size_t i=0; i<m_NO;i++) - if (this->m_Q[i].has_net() && this->m_Q[i].net().num_cons()>0) + for (auto &i : m_I) + i.activate(); + for (auto &q : m_Q) + if (q.has_net() && q.net().num_cons() > 0) m_active++; } @@ -137,14 +147,14 @@ namespace netlist private: template<bool doOUT> - inline void process() + void process() { - netlist_time mt = netlist_time::zero(); + netlist_time mt(netlist_time::zero()); - type_t nstate = 0; + type_t nstate(0); if (m_NI > 1) { - type_t ign = m_ign; + type_t ign(m_ign); if (!doOUT) for (std::size_t i = 0; i < m_NI; i++) { @@ -166,31 +176,28 @@ namespace netlist if (!doOUT) { nstate |= m_I[0](); - mt = std::max(this->m_I[0].net().time(), mt); + //mt = std::max(this->m_I[0].net().time(), mt); + mt = this->m_I[0].net().time(); } else nstate |= m_I[0](); } - const type_t outstate = m_ttp->m_outs[nstate]; - type_t out = outstate & m_outmask; + const type_t outstate(m_ttp.m_outs[nstate]); + type_t out(outstate & m_outmask); m_ign = outstate >> m_NO; - const std::size_t timebase = nstate * m_NO; + const std::size_t timebase(nstate * m_NO); + const auto *t(&m_ttp.m_timing[timebase]); + const auto *tim = m_ttp.m_timing_nt; if (doOUT) - { - auto *t = &m_ttp->m_timing[timebase]; - for (std::size_t i = 0; i < m_NO; ++i) - m_Q[i].push((out >> i) & 1, m_ttp->m_timing_nt[t[i]]); - } + for (std::size_t i = 0; i < m_NO; out >>= 1, ++i) + m_Q[i].push(out & 1, tim[t[i]]); else - { - auto *t = &m_ttp->m_timing[timebase]; - for (std::size_t i = 0; i < m_NO; ++i) - m_Q[i].set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[t[i]]); - } + for (std::size_t i = 0; i < m_NO; out >>= 1, ++i) + m_Q[i].set_Q_time(out & 1, mt + tim[t[i]]); if (m_NI > 1) { @@ -204,7 +211,7 @@ namespace netlist /* FIXME: check width */ state_var<type_t> m_ign; state_var_s32 m_active; - truthtable_t * m_ttp; + const truthtable_t &m_ttp; }; class netlist_base_factory_truthtable_t : public factory::element_t diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 4be3042d6d5..75e448427e7 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -193,7 +193,7 @@ void detail::queue_t::on_post_load() // ---------------------------------------------------------------------------------------- detail::object_t::object_t(const pstring &aname) - : m_name(aname) + : m_name(plib::make_unique<pstring>(aname)) { } @@ -203,7 +203,7 @@ detail::object_t::~object_t() const pstring &detail::object_t::name() const { - return m_name; + return *m_name; } // ---------------------------------------------------------------------------------------- @@ -246,7 +246,7 @@ netlist_t::netlist_t(const pstring &aname) , m_solver(nullptr) , m_params(nullptr) , m_name(aname) - , m_log(this) + , m_log(*this) , m_lib(nullptr) , m_state() { @@ -263,7 +263,7 @@ netlist_t::~netlist_t() m_devices.clear(); } -nl_double netlist_t::gmin() const +nl_double netlist_t::gmin() const NL_NOEXCEPT { return solver()->gmin(); } @@ -549,8 +549,8 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT } else { - logic_net_t &mc_net = m_mainclock->m_Q.net(); - const netlist_time inc = m_mainclock->m_inc; + logic_net_t &mc_net(m_mainclock->m_Q.net()); + const netlist_time inc(m_mainclock->m_inc); netlist_time mc_time(mc_net.time()); detail::queue_t::entry_t e; @@ -639,7 +639,7 @@ void netlist_t::print_stats() const } } -core_device_t *netlist_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) +core_device_t *netlist_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const { core_device_t *ret = nullptr; for (auto &d : m_devices) @@ -692,7 +692,7 @@ void core_device_t::set_default_delegate(detail::core_terminal_t &term) term.m_delegate.set(&core_device_t::update, this); } -plib::plog_base<NL_DEBUG> &core_device_t::log() +plib::plog_base<netlist_t, NL_DEBUG> &core_device_t::log() { return netlist().log(); } @@ -782,9 +782,8 @@ detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) , m_new_Q(*this, "m_new_Q", 0) , m_cur_Q (*this, "m_cur_Q", 0) , m_in_queue(*this, "m_in_queue", QS_DELIVERED) - , m_time(*this, "m_time", netlist_time::zero()) , m_active(*this, "m_active", 0) - , m_cur_Analog(*this, "m_cur_Analog", 0.0) + , m_time(*this, "m_time", netlist_time::zero()) , m_railterminal(mr) { } @@ -796,8 +795,8 @@ detail::net_t::~net_t() void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT { - ++m_active; m_list_active.push_front(&term); + ++m_active; nl_assert(m_active <= static_cast<int>(num_cons())); if (m_active == 1) { @@ -807,7 +806,7 @@ void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT if (m_time > netlist().time()) { m_in_queue = QS_QUEUED; /* pending */ - netlist().queue().push(queue_t::entry_t(m_time, this)); + netlist().queue().push({m_time, this}); } else { @@ -842,27 +841,12 @@ void detail::net_t::rebuild_list() m_active = cnt; } -void detail::net_t::update_devs() NL_NOEXCEPT +void detail::net_t::process(unsigned Mask) { - nl_assert(this->isRailNet()); - - const uint8_t masks[4] = - { - 0, - core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE, - core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE, - 0 - }; - - const auto mask = masks[ (m_cur_Q << 1) | m_new_Q ]; - - m_cur_Q = m_new_Q; - m_in_queue = QS_DELIVERED; /* mark as taken ... */ - for (auto & p : m_list_active) { p.device().m_stat_call_count.inc(); - if ((p.state() & mask) != 0) + if ((p.state() & Mask) != 0) { p.device().m_stat_total_time.start(); p.m_delegate(); @@ -871,6 +855,30 @@ void detail::net_t::update_devs() NL_NOEXCEPT } } +void detail::net_t::update_devs() NL_NOEXCEPT +{ + nl_assert(this->isRailNet()); + + const unsigned mask((m_new_Q << core_terminal_t::INP_LH_SHIFT) + | (m_cur_Q<<core_terminal_t::INP_HL_SHIFT)); + + m_in_queue = QS_DELIVERED; /* mark as taken ... */ + + switch (mask) + { + case core_terminal_t::STATE_INP_HL: + m_cur_Q = m_new_Q; + process(core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE); + break; + case core_terminal_t::STATE_INP_LH: + m_cur_Q = m_new_Q; + process(core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE); + break; + default: + break; + } +} + void detail::net_t::reset() { m_time = netlist_time::zero(); @@ -879,7 +887,11 @@ void detail::net_t::reset() m_new_Q = 0; m_cur_Q = 0; - m_cur_Analog = 0.0; + + analog_net_t *p = dynamic_cast<analog_net_t *>(this); + + if (p != nullptr) + p->m_cur_Analog = 0.0; /* rebuild m_list */ @@ -951,6 +963,7 @@ logic_net_t::~logic_net_t() analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr) : net_t(nl, aname, mr) + , m_cur_Analog(*this, "m_cur_Analog", 0.0) , m_solver(nullptr) { } @@ -1204,11 +1217,7 @@ param_double_t::param_double_t(device_t &device, const pstring &name, const doub m_param = device.setup().get_initial_param_val(this->name(),val); netlist().save(*this, m_param, "m_param"); } -#if 0 -param_double_t::~param_double_t() -{ -} -#endif + param_int_t::param_int_t(device_t &device, const pstring &name, const int val) : param_t(device, name) { @@ -1216,12 +1225,6 @@ param_int_t::param_int_t(device_t &device, const pstring &name, const int val) netlist().save(*this, m_param, "m_param"); } -#if 0 -param_int_t::~param_int_t() -{ -} -#endif - param_logic_t::param_logic_t(device_t &device, const pstring &name, const bool val) : param_t(device, name) { @@ -1229,12 +1232,6 @@ param_logic_t::param_logic_t(device_t &device, const pstring &name, const bool v netlist().save(*this, m_param, "m_param"); } -#if 0 -param_logic_t::~param_logic_t() -{ -} -#endif - param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val) : param_t(device, name) { @@ -1242,12 +1239,6 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val) //netlist().save(*this, m_param, "m_param"); } -#if 0 -param_ptr_t::~param_ptr_t() -{ -} -#endif - void param_model_t::changed() { netlist().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name()); diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 74faabef3b6..63eb469db8b 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -171,16 +171,16 @@ class NETLIB_NAME(name) : public device_t #endif #define nl_assert_always(x, msg) do { if (!(x)) throw nl_exception(plib::pfmt("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}")(msg)(__FILE__)(__LINE__)(#x)); } while (0) -// ----------------------------------------------------------------------------- -// forward definitions -// ----------------------------------------------------------------------------- - //============================================================ // Namespace starts //============================================================ namespace netlist { + // ----------------------------------------------------------------------------- + // forward definitions + // ----------------------------------------------------------------------------- + namespace devices { class matrix_solver_t; @@ -203,6 +203,16 @@ namespace netlist class net_t; } + class logic_output_t; + class logic_input_t; + class analog_net_t; + class logic_net_t; + class net_t; + class setup_t; + class netlist_t; + class core_device_t; + class device_t; + //============================================================ // Exceptions //============================================================ @@ -224,16 +234,6 @@ namespace netlist virtual ~nl_exception(); }; - class logic_output_t; - class logic_input_t; - class analog_net_t; - class logic_net_t; - class net_t; - class setup_t; - class netlist_t; - class core_device_t; - class device_t; - /*! Logic families descriptors are used to create proxy devices. * The logic family describes the analog capabilities of logic devices, * inputs and outputs. @@ -318,23 +318,24 @@ namespace netlist const T &value //!< Initial value after construction ); //! Copy Constructor. - state_var(const state_var &rhs) NL_NOEXCEPT = default; + constexpr state_var(const state_var &rhs) noexcept = default; //! Move Constructor. - state_var(state_var &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs.m_value); } + constexpr state_var(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of a state var. - state_var &operator=(const state_var &rhs) NL_NOEXCEPT { m_value = rhs.m_value; return *this; } + C14CONSTEXPR state_var &operator=(const state_var &rhs) noexcept = default; //! Assignment move operator to assign value of a state var. - state_var &operator=(state_var &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs.m_value); return *this; } + C14CONSTEXPR state_var &operator=(state_var &&rhs) noexcept = default; //! Assignment operator to assign value of type T. - state_var &operator=(const T &rhs) NL_NOEXCEPT { m_value = rhs; return *this; } + C14CONSTEXPR state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; } //! Assignment move operator to assign value of type T. - state_var &operator=(T &&rhs) NL_NOEXCEPT { std::swap(m_value, rhs); return *this; } + C14CONSTEXPR state_var &operator=(T &&rhs) noexcept { std::swap(m_value, rhs); return *this; } //! Return value of state variable. - operator T & () NL_NOEXCEPT { return m_value; } + C14CONSTEXPR operator T & () noexcept { return m_value; } //! Return const value of state variable. - constexpr operator const T & () const NL_NOEXCEPT { return m_value; } - T * ptr() NL_NOEXCEPT { return &m_value; } - constexpr T * ptr() const NL_NOEXCEPT{ return &m_value; } + constexpr operator const T & () const noexcept { return m_value; } + C14CONSTEXPR T * ptr() noexcept { return &m_value; } + constexpr const T * ptr() const noexcept{ return &m_value; } + private: T m_value; }; @@ -357,7 +358,7 @@ namespace netlist state_var(const state_var &rhs) NL_NOEXCEPT = default; //! Move Constructor. state_var(state_var &&rhs) NL_NOEXCEPT = default; - state_var &operator=(const state_var &rhs) NL_NOEXCEPT { m_value = rhs.m_value; return *this; } + state_var &operator=(const state_var &rhs) NL_NOEXCEPT = default; state_var &operator=(const T &rhs) NL_NOEXCEPT { m_value = rhs; return *this; } T & operator[](const std::size_t i) NL_NOEXCEPT { return m_value[i]; } constexpr T & operator[](const std::size_t i) const NL_NOEXCEPT { return m_value[i]; } @@ -378,6 +379,8 @@ namespace netlist using state_var_u32 = state_var<std::uint32_t>; /*! predefined state variable type for int32_t */ using state_var_s32 = state_var<std::int32_t>; + /*! predefined state variable type for sig_t */ + using state_var_sig = state_var<netlist_sig_t>; // ----------------------------------------------------------------------------- // object_t @@ -414,18 +417,18 @@ namespace netlist ~object_t(); // only childs should be destructible private: - pstring m_name; + std::unique_ptr<pstring> m_name; }; struct detail::netlist_ref { - explicit netlist_ref(netlist_t &nl) : m_netlist(nl) { } + explicit constexpr netlist_ref(netlist_t &nl) : m_netlist(nl) { } - netlist_t & netlist() NL_NOEXCEPT { return m_netlist; } - const netlist_t & netlist() const NL_NOEXCEPT { return m_netlist; } + C14CONSTEXPR netlist_t & netlist() NL_NOEXCEPT { return m_netlist; } + constexpr const netlist_t & netlist() const NL_NOEXCEPT { return m_netlist; } protected: - ~netlist_ref() {} // prohibit polymorphic destruction + ~netlist_ref() = default; // prohibit polymorphic destruction private: netlist_t & m_netlist; @@ -450,16 +453,18 @@ namespace netlist * \param name string holding the name of the device */ device_object_t(core_device_t &dev, const pstring &name); + /*! returns reference to owning device. * \returns reference to owning device. */ - core_device_t &device() const NL_NOEXCEPT { return m_device; } + core_device_t &device() NL_NOEXCEPT { return m_device; } + const core_device_t &device() const NL_NOEXCEPT { return m_device; } /*! The netlist owning the owner of this object. * \returns reference to netlist object. */ - netlist_t &netlist(); - const netlist_t &netlist() const; + netlist_t &netlist() NL_NOEXCEPT; + const netlist_t &netlist() const NL_NOEXCEPT; private: core_device_t & m_device; @@ -486,11 +491,15 @@ namespace netlist using list_t = std::vector<core_terminal_t *>; + static constexpr const unsigned INP_HL_SHIFT = 0; + static constexpr const unsigned INP_LH_SHIFT = 1; + static constexpr const unsigned INP_ACTIVE_SHIFT = 2; + enum state_e { STATE_INP_PASSIVE = 0, - STATE_INP_ACTIVE = 1, - STATE_INP_HL = 2, - STATE_INP_LH = 4, + STATE_INP_HL = (1 << INP_HL_SHIFT), + STATE_INP_LH = (1 << INP_LH_SHIFT), + STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT), STATE_OUT = 128, STATE_BIDIR = 256 }; @@ -519,9 +528,9 @@ namespace netlist bool is_logic() const NL_NOEXCEPT; bool is_analog() const NL_NOEXCEPT; - bool is_state(const state_e astate) const NL_NOEXCEPT { return (m_state == astate); } - state_e state() const NL_NOEXCEPT { return m_state; } - void set_state(const state_e astate) NL_NOEXCEPT { m_state = astate; } + bool is_state(const state_e &astate) const NL_NOEXCEPT { return (m_state == astate); } + const state_e &state() const NL_NOEXCEPT { return m_state; } + void set_state(const state_e &astate) NL_NOEXCEPT { m_state = astate; } void reset(); @@ -560,17 +569,17 @@ namespace netlist nl_double operator ()() const NL_NOEXCEPT; - void set(const nl_double G) NL_NOEXCEPT + void set(const nl_double &G) NL_NOEXCEPT { set(G,G, 0.0); } - void set(const nl_double GO, const nl_double GT) NL_NOEXCEPT + void set(const nl_double &GO, const nl_double >) NL_NOEXCEPT { set(GO, GT, 0.0); } - void set(const nl_double GO, const nl_double GT, const nl_double I) NL_NOEXCEPT + void set(const nl_double &GO, const nl_double >, const nl_double &I) NL_NOEXCEPT { set_ptr(m_Idr1, I); set_ptr(m_go1, GO); @@ -590,7 +599,7 @@ namespace netlist terminal_t *m_otherterm; private: - void set_ptr(nl_double *ptr, const nl_double val) NL_NOEXCEPT + void set_ptr(nl_double *ptr, const nl_double &val) NL_NOEXCEPT { if (ptr != nullptr && *ptr != val) { @@ -709,13 +718,13 @@ namespace netlist void toggle_new_Q() NL_NOEXCEPT { m_new_Q = (m_cur_Q ^ 1); } - void toggle_and_push_to_queue(const netlist_time delay) NL_NOEXCEPT + void toggle_and_push_to_queue(const netlist_time &delay) NL_NOEXCEPT { toggle_new_Q(); push_to_queue(delay); } - void push_to_queue(const netlist_time delay) NL_NOEXCEPT; + void push_to_queue(const netlist_time &delay) NL_NOEXCEPT; bool is_queued() const NL_NOEXCEPT { return m_in_queue == QS_QUEUED; } void update_devs() NL_NOEXCEPT; @@ -723,8 +732,8 @@ namespace netlist const netlist_time &time() const NL_NOEXCEPT { return m_time; } void set_time(const netlist_time &ntime) NL_NOEXCEPT { m_time = ntime; } - bool isRailNet() const { return !(m_railterminal == nullptr); } - core_terminal_t & railterminal() const { return *m_railterminal; } + bool isRailNet() const NL_NOEXCEPT { return !(m_railterminal == nullptr); } + core_terminal_t & railterminal() const NL_NOEXCEPT { return *m_railterminal; } std::size_t num_cons() const NL_NOEXCEPT { return m_core_terms.size(); } @@ -748,18 +757,15 @@ namespace netlist state_var<netlist_sig_t> m_new_Q; state_var<netlist_sig_t> m_cur_Q; state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ - - state_var<netlist_time> m_time; state_var_s32 m_active; - state_var<nl_double> m_cur_Analog; + state_var<netlist_time> m_time; private: plib::linkedlist_t<core_terminal_t> m_list_active; core_terminal_t * m_railterminal; - public: - + void process(unsigned Mask); }; class logic_net_t : public detail::net_t @@ -772,7 +778,7 @@ namespace netlist netlist_sig_t Q() const NL_NOEXCEPT { return m_cur_Q; } void initial(const netlist_sig_t val) NL_NOEXCEPT { m_cur_Q = m_new_Q = val; } - void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT + void set_Q_and_push(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT { if (newQ != m_new_Q ) { @@ -780,7 +786,7 @@ namespace netlist push_to_queue(delay); } } - void set_Q_and_push_force(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT + void set_Q_and_push_force(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT { if (newQ != m_new_Q || is_queued()) { @@ -789,7 +795,7 @@ namespace netlist } } - void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT + void set_Q_time(const netlist_sig_t newQ, const netlist_time &at) NL_NOEXCEPT { if (newQ != m_new_Q) { @@ -815,19 +821,22 @@ namespace netlist using list_t = std::vector<analog_net_t *>; + friend class net_t; + analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); virtual ~analog_net_t(); - nl_double Q_Analog() const { return m_cur_Analog; } - void set_Q_Analog(const nl_double &v) { m_cur_Analog = v; } - nl_double *Q_Analog_state_ptr() { return m_cur_Analog.ptr(); } + nl_double Q_Analog() const NL_NOEXCEPT { return m_cur_Analog; } + void set_Q_Analog(const nl_double v) NL_NOEXCEPT { m_cur_Analog = v; } + nl_double *Q_Analog_state_ptr() NL_NOEXCEPT { return m_cur_Analog.ptr(); } //FIXME: needed by current solver code - devices::matrix_solver_t *solver() const { return m_solver; } - void set_solver(devices::matrix_solver_t *solver) { m_solver = solver; } + devices::matrix_solver_t *solver() const NL_NOEXCEPT { return m_solver; } + void set_solver(devices::matrix_solver_t *solver) NL_NOEXCEPT { m_solver = solver; } private: + state_var<nl_double> m_cur_Analog; devices::matrix_solver_t *m_solver; }; @@ -844,17 +853,17 @@ namespace netlist void initial(const netlist_sig_t val); - void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT + void push(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT { m_my_net.set_Q_and_push(newQ, delay); // take the shortcut } - void push_force(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT + void push_force(const netlist_sig_t newQ, const netlist_time &delay) NL_NOEXCEPT { m_my_net.set_Q_and_push_force(newQ, delay); // take the shortcut } - void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT + void set_Q_time(const netlist_sig_t newQ, const netlist_time &at) NL_NOEXCEPT { m_my_net.set_Q_time(newQ, at); // take the shortcut } @@ -928,7 +937,7 @@ namespace netlist { public: param_logic_t(device_t &device, const pstring &name, const bool val); - bool operator()() const NL_NOEXCEPT { return m_param; } + const bool &operator()() const NL_NOEXCEPT { return m_param; } void setTo(const bool ¶m) { set(m_param, param); } private: bool m_param; @@ -938,7 +947,7 @@ namespace netlist { public: param_int_t(device_t &device, const pstring &name, const int val); - int operator()() const NL_NOEXCEPT { return m_param; } + const int &operator()() const NL_NOEXCEPT { return m_param; } void setTo(const int ¶m) { set(m_param, param); } private: int m_param; @@ -948,7 +957,7 @@ namespace netlist { public: param_double_t(device_t &device, const pstring &name, const double val); - double operator()() const NL_NOEXCEPT { return m_param; } + const double &operator()() const NL_NOEXCEPT { return m_param; } void setTo(const double ¶m) { set(m_param, param); } private: double m_param; @@ -960,7 +969,7 @@ namespace netlist param_str_t(device_t &device, const pstring &name, const pstring &val); virtual ~param_str_t(); - const pstring operator()() const NL_NOEXCEPT { return Value(); } + const pstring &operator()() const NL_NOEXCEPT { return Value(); } void setTo(const pstring ¶m) NL_NOEXCEPT { if (m_param != param) @@ -972,7 +981,7 @@ namespace netlist } protected: virtual void changed(); - pstring Value() const NL_NOEXCEPT { return m_param; } + const pstring &Value() const NL_NOEXCEPT { return m_param; } private: pstring m_param; }; @@ -985,13 +994,13 @@ namespace netlist { public: value_t(param_model_t ¶m, const pstring &name) + : m_value(param.model_value(name)) { - m_value = param.model_value(name); } - double operator()() const { return m_value; } - operator double() const { return m_value; } + const double &operator()() const NL_NOEXCEPT { return m_value; } + operator const double&() const NL_NOEXCEPT { return m_value; } private: - double m_value; + const double m_value; }; friend class value_t; @@ -1032,7 +1041,7 @@ namespace netlist param_rom_t(device_t &device, const pstring &name); - const ST & operator[] (std::size_t n) { return m_data[n]; } + const ST & operator[] (std::size_t n) NL_NOEXCEPT { return m_data[n]; } protected: virtual void changed() override { @@ -1102,7 +1111,7 @@ namespace netlist update(); } - plib::plog_base<NL_DEBUG> &log(); + plib::plog_base<netlist_t, NL_DEBUG> &log(); public: virtual void timestep(ATTR_UNUSED const nl_double st) { } @@ -1203,7 +1212,7 @@ namespace netlist // ----------------------------------------------------------------------------- - class netlist_t : public plib::plog_dispatch_intf, private plib::nocopyassignmove + class netlist_t : private plib::nocopyassignmove { public: @@ -1212,14 +1221,14 @@ namespace netlist /* run functions */ - const netlist_time time() const NL_NOEXCEPT { return m_time; } + const netlist_time &time() const NL_NOEXCEPT { return m_time; } devices::NETLIB_NAME(solver) *solver() const NL_NOEXCEPT { return m_solver; } /* never use this in constructors! */ - nl_double gmin() const; + nl_double gmin() const NL_NOEXCEPT; void process_queue(const netlist_time &delta) NL_NOEXCEPT; - void abort_current_queue_slice() { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); } + void abort_current_queue_slice() NL_NOEXCEPT { m_queue.retime(detail::queue_t::entry_t(m_time, nullptr)); } /* Control functions */ @@ -1241,7 +1250,7 @@ namespace netlist std::size_t find_net_id(const detail::net_t *net) const; template<class device_class> - std::vector<device_class *> get_device_list() + std::vector<device_class *> get_device_list() const { std::vector<device_class *> tmp; for (auto &d : m_devices) @@ -1260,7 +1269,7 @@ namespace netlist } template<class C> - C *get_single_device(const pstring &classname) + C *get_single_device(const pstring &classname) const { return dynamic_cast<C *>(get_single_device(classname, check_class<C>)); } @@ -1268,8 +1277,8 @@ namespace netlist /* logging and name */ pstring name() const { return m_name; } - plib::plog_base<NL_DEBUG> &log() { return m_log; } - const plib::plog_base<NL_DEBUG> &log() const { return m_log; } + plib::plog_base<netlist_t, NL_DEBUG> &log() { return m_log; } + const plib::plog_base<netlist_t, NL_DEBUG> &log() const { return m_log; } /* state related */ @@ -1295,6 +1304,9 @@ namespace netlist // FIXME: sort rebuild_lists out void rebuild_lists(); /* must be called after post_load ! */ + /* logging callback */ + virtual void vlog(const plib::plog_level &l, const pstring &ls) const = 0; + protected: void print_stats() const; @@ -1305,7 +1317,7 @@ namespace netlist static pstring from_utf8(const char *c) { return pstring(c, pstring::UTF8); } static pstring from_utf8(const pstring &c) { return c; } - core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)); + core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const; /* mostly rw */ netlist_time m_time; @@ -1319,7 +1331,7 @@ namespace netlist pstring m_name; std::unique_ptr<setup_t> m_setup; - plib::plog_base<NL_DEBUG> m_log; + plib::plog_base<netlist_t, NL_DEBUG> m_log; std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists plib::state_manager_t m_state; @@ -1349,6 +1361,7 @@ namespace netlist this->emplace(i, dev, pstring(names.p[i], pstring::UTF8)); } }; + // ----------------------------------------------------------------------------- // inline implementations // ----------------------------------------------------------------------------- @@ -1400,7 +1413,7 @@ namespace netlist } } - inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT + inline void detail::net_t::push_to_queue(const netlist_time &delay) NL_NOEXCEPT { if ((num_cons() != 0)) { @@ -1455,12 +1468,12 @@ namespace netlist } } - inline netlist_t &detail::device_object_t::netlist() + inline netlist_t &detail::device_object_t::netlist() NL_NOEXCEPT { return m_device.netlist(); } - inline const netlist_t &detail::device_object_t::netlist() const + inline const netlist_t &detail::device_object_t::netlist() const NL_NOEXCEPT { return m_device.netlist(); } @@ -1481,8 +1494,6 @@ namespace netlist for (std::size_t i=0; i<N; i++) m_value[i] = value; } - - } namespace plib diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index 76406ab6bee..c5026e6b081 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -20,6 +20,7 @@ #include <thread> #include <mutex> #include <algorithm> +#include <utility> // ---------------------------------------------------------------------------------------- // timed queue @@ -54,22 +55,11 @@ namespace netlist { constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { } constexpr pqentry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { } - constexpr pqentry_t(const pqentry_t &e) noexcept : m_exec_time(e.m_exec_time), m_object(e.m_object) { } - pqentry_t(pqentry_t &&e) noexcept { swap(e); } ~pqentry_t() = default; - - pqentry_t& operator=(pqentry_t && other) noexcept - { - swap(other); - return *this; - } - - pqentry_t& operator=(const pqentry_t &other) noexcept - { - pqentry_t t(other); - swap(t); - return *this; - } + constexpr pqentry_t(const pqentry_t &e) noexcept = default; + constexpr pqentry_t(pqentry_t &&e) = default; + pqentry_t& operator=(pqentry_t && other) noexcept = default; + pqentry_t& operator=(const pqentry_t &other) noexcept = default; void swap(pqentry_t &other) noexcept { @@ -120,10 +110,10 @@ namespace netlist { /* Lock */ tqlock lck(m_lock); - T * i = m_end; + T * i(m_end); for (; QueueOp::less(*(i - 1), e); --i) { - *(i) = *(i-1); + *(i) = std::move(*(i-1)); m_prof_sortmove.inc(); } *i = std::move(e); @@ -139,12 +129,12 @@ namespace netlist { /* Lock */ tqlock lck(m_lock); - for (T * i = m_end - 1; i > &m_list[0]; i--) + for (T * i = m_end - 1; i > &m_list[0]; --i) { if (QueueOp::equal(*i, elem)) { - m_end--; - for (;i < m_end; i++) + --m_end; + for (;i < m_end; ++i) *i = std::move(*(i+1)); return; } @@ -155,7 +145,7 @@ namespace netlist { /* Lock */ tqlock lck(m_lock); - for (T * i = m_end - 1; i > &m_list[0]; i--) + for (T * i = m_end - 1; i > &m_list[0]; --i) { if (QueueOp::equal(*i, elem)) // partial equal! { @@ -163,12 +153,12 @@ namespace netlist while (QueueOp::less(*(i-1), *i)) { std::swap(*(i-1), *i); - i--; + --i; } while (i < m_end && QueueOp::less(*i, *(i+1))) { std::swap(*(i+1), *i); - i++; + ++i; } return; } @@ -189,9 +179,9 @@ namespace netlist // save state support & mame disasm - constexpr const T *listptr() const { return &m_list[1]; } + constexpr const T *listptr() const noexcept { return &m_list[1]; } constexpr std::size_t size() const noexcept { return static_cast<std::size_t>(m_end - &m_list[1]); } - constexpr const T & operator[](const std::size_t index) const { return m_list[ 1 + index]; } + constexpr const T & operator[](const std::size_t index) const noexcept { return m_list[ 1 + index]; } private: #if HAS_OPENMP && USE_OPENMP using tqmutex = pspin_mutex<true>; @@ -217,7 +207,7 @@ namespace netlist struct compare { - bool operator()(const T &a, const T &b) { return QueueOp::less(b,a); } + constexpr bool operator()(const T &a, const T &b) const { return QueueOp::less(b,a); } }; explicit timed_queue(const std::size_t list_size) diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index b29b26aa320..4685a13c354 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -8,6 +8,7 @@ #include "nl_parser.h" #include "nl_factory.h" #include "nl_errstr.h" +#include "nl_base.h" namespace netlist { diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 0d290c8dfcf..65745d86459 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -763,11 +763,11 @@ void setup_t::start_devices() } } -plib::plog_base<NL_DEBUG> &setup_t::log() +plib::plog_base<netlist_t, NL_DEBUG> &setup_t::log() { return netlist().log(); } -const plib::plog_base<NL_DEBUG> &setup_t::log() const +const plib::plog_base<netlist_t, NL_DEBUG> &setup_t::log() const { return netlist().log(); } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 4aa883fbf32..d0359928711 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -288,8 +288,8 @@ namespace netlist /* helper - also used by nltool */ const pstring resolve_alias(const pstring &name) const; - plib::plog_base<NL_DEBUG> &log(); - const plib::plog_base<NL_DEBUG> &log() const; + plib::plog_base<netlist_t, NL_DEBUG> &log(); + const plib::plog_base<netlist_t, NL_DEBUG> &log() const; std::vector<std::pair<pstring, factory::element_t *>> m_device_factory; diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h index 6d6cb509ae5..7c81f890e07 100644 --- a/src/lib/netlist/nl_time.h +++ b/src/lib/netlist/nl_time.h @@ -37,40 +37,34 @@ namespace netlist using mult_type = std::uint64_t; constexpr ptime() noexcept : m_time(0) {} - constexpr ptime(const ptime &rhs) noexcept : m_time(rhs.m_time) { } - constexpr ptime(ptime &&rhs) noexcept : m_time(rhs.m_time) { } + + constexpr ptime(const ptime &rhs) noexcept = default; + constexpr ptime(ptime &&rhs) noexcept = default; + C14CONSTEXPR ptime &operator=(const ptime &rhs) noexcept = default; + C14CONSTEXPR ptime &operator=(ptime &&rhs) noexcept = default; constexpr explicit ptime(const double t) = delete; //: m_time((internal_type) ( t * (double) resolution)) { } constexpr explicit ptime(const internal_type &nom, const internal_type &den) noexcept : m_time(nom * (RES / den)) { } - ptime &operator=(const ptime &rhs) noexcept { ptime t(rhs); std::swap(m_time, t.m_time); return *this; } - ptime &operator=(ptime &&rhs) noexcept { std::swap(this->m_time, rhs.m_time); return *this; } - - ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; } - ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; } - ptime operator*=(const mult_type &factor) noexcept { m_time *= static_cast<internal_type>(factor); return *this; } + C14CONSTEXPR ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; } + C14CONSTEXPR ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; } + C14CONSTEXPR ptime &operator*=(const mult_type &factor) noexcept { m_time *= static_cast<internal_type>(factor); return *this; } - friend ptime operator-(const ptime &lhs, const ptime &rhs) noexcept + friend C14CONSTEXPR ptime operator-(ptime lhs, const ptime &rhs) noexcept { - ptime t(lhs); - t -= rhs; - return t; + return lhs -= rhs; } - friend ptime operator+(const ptime &lhs, const ptime &rhs) noexcept + friend C14CONSTEXPR ptime operator+(ptime lhs, const ptime &rhs) noexcept { - ptime t(lhs); - t += rhs; - return t; + return lhs += rhs; } - friend ptime operator*(const ptime &lhs, const mult_type &factor) noexcept + friend C14CONSTEXPR ptime operator*(ptime lhs, const mult_type &factor) noexcept { - ptime t(lhs); - t *= factor; - return t; + return lhs *= factor; } friend constexpr mult_type operator/(const ptime &lhs, const ptime &rhs) noexcept @@ -111,18 +105,17 @@ namespace netlist constexpr internal_type as_raw() const noexcept { return m_time; } constexpr double as_double() const noexcept { - return static_cast<double>(m_time) - / static_cast<double>(RES); + return static_cast<double>(m_time) / static_cast<double>(RES); } // for save states .... - internal_type *get_internaltype_ptr() noexcept { return &m_time; } + C14CONSTEXPR internal_type *get_internaltype_ptr() noexcept { return &m_time; } - static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } - static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C(1000000)); } - static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C(1000)); } - static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); } - static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); } + static constexpr ptime from_nsec(const internal_type &ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } + static constexpr ptime from_usec(const internal_type &us) noexcept { return ptime(us, UINT64_C(1000000)); } + static constexpr ptime from_msec(const internal_type &ms) noexcept { return ptime(ms, UINT64_C(1000)); } + static constexpr ptime from_hz(const internal_type &hz) noexcept { return ptime(1 , hz); } + static constexpr ptime from_raw(const internal_type &raw) noexcept { return ptime(raw); } static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(RES)), RES); } static constexpr ptime zero() noexcept { return ptime(0, RES); } diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 3a2cb00e9e4..20828451b33 100755 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -12,20 +12,45 @@ * Define this for more accurate measurements if you processor supports * RDTSCP. */ +#ifndef PHAS_RDTSCP #define PHAS_RDTSCP (1) +#endif /* * Define this to use accurate timing measurements. Only works * if PHAS_RDTSCP == 1 */ +#ifndef PUSE_ACCURATE_STATS #define PUSE_ACCURATE_STATS (1) +#endif /* * Set this to one if you want to use 128 bit int for ptime. * This is for tests only. */ +#ifndef PHAS_INT128 #define PHAS_INT128 (0) +#endif + +/*============================================================ + * Check for CPP Version + * + * C++11: __cplusplus is 201103L. + * C++14: __cplusplus is 201402L. + * c++17/c++1z__cplusplus is 201703L. + * + *============================================================*/ + +#if __cplusplus == 201103L +#define C14CONSTEXPR +#elif __cplusplus == 201402L +#define C14CONSTEXPR constexpr +#elif __cplusplus == 201703L +#define C14CONSTEXPR constexpr +#else +#error "C++ version not supported" +#endif #ifndef PHAS_INT128 #define PHAS_INT128 (0) diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h index bbbe78b18db..4827081b754 100644 --- a/src/lib/netlist/plib/pexception.h +++ b/src/lib/netlist/plib/pexception.h @@ -26,6 +26,7 @@ public: virtual ~pexception() noexcept; const pstring &text() { return m_text; } + const char* what() const noexcept override { return m_text.c_str(); } private: pstring m_text; @@ -91,12 +92,12 @@ public: virtual ~fpexception_e() noexcept; }; -static const unsigned FP_INEXACT = 0x0001; -static const unsigned FP_DIVBYZERO = 0x0002; -static const unsigned FP_UNDERFLOW = 0x0004; -static const unsigned FP_OVERFLOW = 0x0008; -static const unsigned FP_INVALID = 0x00010; -static const unsigned FP_ALL = 0x0001f; +static constexpr unsigned FP_INEXACT = 0x0001; +static constexpr unsigned FP_DIVBYZERO = 0x0002; +static constexpr unsigned FP_UNDERFLOW = 0x0004; +static constexpr unsigned FP_OVERFLOW = 0x0008; +static constexpr unsigned FP_INVALID = 0x00010; +static constexpr unsigned FP_ALL = 0x0001f; /* * Catch SIGFPE on linux for debugging purposes. diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index ac4f0f6f046..b8b5fcb3b91 100755 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -17,11 +17,6 @@ namespace plib { -plog_dispatch_intf::~plog_dispatch_intf() -{ -} - - pfmt &pfmt::format_element(const char *l, const unsigned cfmt_spec, ...) { va_list ap; @@ -56,7 +51,7 @@ pfmt &pfmt::format_element(const char *l, const unsigned cfmt_spec, ...) if (p1 != pstring::npos) { sl = p1 - p + 1; - fmt += m_str.substr(p+1, p1 - p - 2); + fmt += m_str.substr(p+1, p1 - p - 1); } } } diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 030de5d1fc5..9b7a85d8d8d 100755 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -152,6 +152,8 @@ public: { } + pfmt(const pfmt &rhs) : m_str(rhs.m_str), m_arg(rhs.m_arg) { } + ~pfmt() { } @@ -189,6 +191,7 @@ public: { return format_element(ptype_traits<T>::size_spec(), 'o', x); } + protected: pfmt &format_element(const char *l, const unsigned fmt_spec, ...); @@ -199,9 +202,7 @@ private: unsigned m_arg; }; -class plog_dispatch_intf; - -template <bool build_enabled = true> +template <class T, bool build_enabled = true> class pfmt_writer_t : plib::nocopyassignmove { public: @@ -212,7 +213,10 @@ public: void log(const pstring & fmt, Args&&... args) const { if (build_enabled && enabled && m_enabled) - vdowrite(xlog(pfmt(fmt), std::forward<Args>(args)...)); + { + pfmt pf(fmt); + static_cast<T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...)); + } } template<typename... Args> @@ -221,7 +225,7 @@ public: if (build_enabled && m_enabled) { pfmt pf(fmt); - vdowrite(xlog(pf, std::forward<Args>(args)...)); + static_cast<const T *>(this)->vdowrite(xlog(pf, std::forward<Args>(args)...)); } } @@ -234,7 +238,6 @@ public: protected: ~pfmt_writer_t() { } - virtual void vdowrite(const pstring &ls) const = 0; private: pfmt &xlog(pfmt &fmt) const { return fmt; } @@ -249,36 +252,30 @@ private: }; -template <plog_level::E L, bool build_enabled = true> -class plog_channel : public pfmt_writer_t<build_enabled> +template <class T, plog_level::E L, bool build_enabled = true> +class plog_channel : public pfmt_writer_t<plog_channel<T, L, build_enabled>, build_enabled> { + friend class pfmt_writer_t<plog_channel<T, L, build_enabled>, build_enabled>; public: - explicit plog_channel(plog_dispatch_intf *b) : pfmt_writer_t<build_enabled>(), m_base(b) { } - virtual ~plog_channel() { } + explicit plog_channel(T &b) : pfmt_writer_t<plog_channel, build_enabled>(), m_base(b) { } + ~plog_channel() { } protected: - virtual void vdowrite(const pstring &ls) const override; + void vdowrite(const pstring &ls) const + { + m_base.vlog(L, ls); + } private: - plog_dispatch_intf *m_base; -}; - -class plog_dispatch_intf -{ - template<plog_level::E, bool> friend class plog_channel; - -public: - virtual ~plog_dispatch_intf(); -protected: - virtual void vlog(const plog_level &l, const pstring &ls) const = 0; + T &m_base; }; -template<bool debug_enabled> +template<class T, bool debug_enabled> class plog_base { public: - explicit plog_base(plog_dispatch_intf *proxy) + explicit plog_base(T &proxy) : debug(proxy), info(proxy), verbose(proxy), @@ -288,22 +285,17 @@ public: {} virtual ~plog_base() {} - plog_channel<plog_level::DEBUG, debug_enabled> debug; - plog_channel<plog_level::INFO> info; - plog_channel<plog_level::VERBOSE> verbose; - plog_channel<plog_level::WARNING> warning; - plog_channel<plog_level::ERROR> error; - plog_channel<plog_level::FATAL> fatal; + plog_channel<T, plog_level::DEBUG, debug_enabled> debug; + plog_channel<T, plog_level::INFO> info; + plog_channel<T, plog_level::VERBOSE> verbose; + plog_channel<T, plog_level::WARNING> warning; + plog_channel<T, plog_level::ERROR> error; + plog_channel<T, plog_level::FATAL> fatal; }; - -template <plog_level::E L, bool build_enabled> -void plog_channel<L, build_enabled>::vdowrite(const pstring &ls) const -{ - m_base->vlog(L, ls); -} - } +template<typename T> +plib::pfmt& operator<<(plib::pfmt &p, T&& val) { return p(std::forward<T>(val)); } #endif /* PSTRING_H_ */ diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index 5957de7ea13..7ec517255c8 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -38,7 +38,7 @@ public: { public: - static const std::size_t npos = static_cast<std::size_t>(-1); + static constexpr std::size_t npos = static_cast<std::size_t>(-1); token_id_t() : m_id(npos) {} explicit token_id_t(const std::size_t id) : m_id(id) {} diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h index 1c18328a374..ff280322d5c 100644 --- a/src/lib/netlist/plib/ppmf.h +++ b/src/lib/netlist/plib/ppmf.h @@ -213,8 +213,8 @@ namespace plib { using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args); return (reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...); } - bool is_set() { return m_func != nullptr; } - generic_function get_function() const { return m_func; } + bool is_set() noexcept { return m_func != nullptr; } + generic_function get_function() const noexcept { return m_func; } private: generic_function m_func; }; @@ -246,8 +246,8 @@ namespace plib { return this->call(m_obj, std::forward<Targs>(args)...); } - generic_class *object() const { return m_obj; } - bool has_object() const { return m_obj != nullptr; } + generic_class *object() const noexcept { return m_obj; } + bool has_object() const noexcept { return m_obj != nullptr; } private: generic_class *m_obj; }; diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index f78e6655f48..3e9ee99cba0 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -360,15 +360,15 @@ private: postream &m_strm; }; -class putf8_fmt_writer : public pfmt_writer_t<>, public putf8_writer +class putf8_fmt_writer : public pfmt_writer_t<putf8_fmt_writer>, public putf8_writer { public: explicit putf8_fmt_writer(postream &strm); virtual ~putf8_fmt_writer() override; -protected: - virtual void vdowrite(const pstring &ls) const override; +//protected: + void vdowrite(const pstring &ls) const; private: }; diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index 9462d81a122..63f53f791cb 100755 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -18,6 +18,42 @@ // strings in std:: which I would consider usuable for the use-cases I encounter. // ---------------------------------------------------------------------------------------- +template <typename T> +class pstring_const_iterator final +{ +public: + + typedef typename T::ref_value_type value_type; + + typedef value_type const *pointer; + typedef value_type const &reference; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + typedef typename T::string_type string_type; + typedef typename T::traits_type traits_type; + + pstring_const_iterator() noexcept : p() { } + explicit constexpr pstring_const_iterator(const typename string_type::const_iterator &x) noexcept : p(x) { } + pstring_const_iterator(const pstring_const_iterator &rhs) noexcept = default; + pstring_const_iterator(pstring_const_iterator &&rhs) noexcept = default; + pstring_const_iterator &operator=(const pstring_const_iterator &rhs) noexcept = default; + pstring_const_iterator &operator=(pstring_const_iterator &&rhs) noexcept = default; + + pstring_const_iterator& operator++() noexcept { p += static_cast<difference_type>(traits_type::codelen(&(*p))); return *this; } + pstring_const_iterator operator++(int) noexcept { pstring_const_iterator tmp(*this); operator++(); return tmp; } + + bool operator==(const pstring_const_iterator& rhs) const noexcept { return p == rhs.p; } + bool operator!=(const pstring_const_iterator& rhs) const noexcept { return p != rhs.p; } + + reference operator*() const noexcept { return *reinterpret_cast<pointer>(&(*p)); } + pointer operator->() const noexcept { return reinterpret_cast<pointer>(&(*p)); } + +private: + template <typename G> friend struct pstring_t; + typename string_type::const_iterator p; +}; + + template <typename F> struct pstring_t { @@ -118,40 +154,9 @@ public: return *this; } - class const_iterator final - { - public: - - typedef ref_value_type value_type; - - typedef value_type const *pointer; - typedef value_type const &reference; - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - - const_iterator() noexcept : p() { } - explicit constexpr const_iterator(const typename string_type::const_iterator &x) noexcept : p(x) { } - const_iterator(const const_iterator &rhs) noexcept = default; - const_iterator(const_iterator &&rhs) noexcept = default; - const_iterator &operator=(const const_iterator &rhs) noexcept = default; - const_iterator &operator=(const_iterator &&rhs) noexcept = default; - - const_iterator& operator++() noexcept { p += static_cast<difference_type>(traits_type::codelen(&(*p))); return *this; } - const_iterator operator++(int) noexcept { const_iterator tmp(*this); operator++(); return tmp; } - - bool operator==(const const_iterator& rhs) const noexcept { return p == rhs.p; } - bool operator!=(const const_iterator& rhs) const noexcept { return p != rhs.p; } - - reference operator*() const noexcept { return *reinterpret_cast<pointer>(&(*p)); } - pointer operator->() const noexcept { return reinterpret_cast<pointer>(&(*p)); } - - private: - template <typename G> friend struct pstring_t; - typename string_type::const_iterator p; - }; - // no non-const const_iterator for now - typedef const_iterator iterator; + typedef pstring_const_iterator<pstring_t> iterator; + typedef pstring_const_iterator<pstring_t> const_iterator; iterator begin() { return iterator(m_str.begin()); } iterator end() { return iterator(m_str.end()); } diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index cca0fbe2741..c69fb55a8e3 100755 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -417,7 +417,7 @@ void tool_app_t::static_compile() void tool_app_t::mac_out(const pstring &s, const bool cont) { - static const unsigned RIGHT = 72; + static constexpr unsigned RIGHT = 72; if (cont) { unsigned adj = 0; diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index 835a808c1c9..7ea9a57ece2 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -36,7 +36,7 @@ namespace netlist #if TEST_PARALLEL #define MAXTHR 10 -static const int num_thr = 3; +static constexpr int num_thr = 3; struct thr_intf { @@ -165,7 +165,7 @@ protected: private: //static const std::size_t m_pitch = (((storage_N + 1) + 0) / 1) * 1; - static const std::size_t m_pitch = (((storage_N + 1) + 7) / 8) * 8; + static constexpr std::size_t m_pitch = (((storage_N + 1) + 7) / 8) * 8; //static const std::size_t m_pitch = (((storage_N + 1) + 15) / 16) * 16; //static const std::size_t m_pitch = (((storage_N + 1) + 31) / 32) * 32; #if (NL_USE_DYNAMIC_ALLOCATION) diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index 0d6607d9527..c759d135725 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -92,7 +92,7 @@ protected: nl_double m_last_RHS[storage_N]; // right hand side - contains currents private: - static const std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; + static constexpr std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; nl_ext_double m_A[storage_N][m_pitch]; nl_ext_double m_Ainv[storage_N][m_pitch]; nl_ext_double m_W[storage_N][m_pitch]; @@ -218,7 +218,7 @@ void matrix_solver_sm_t<m_N, storage_N>::LE_compute_x( template <std::size_t m_N, std::size_t storage_N> unsigned matrix_solver_sm_t<m_N, storage_N>::solve_non_dynamic(const bool newton_raphson) { - static const bool incremental = true; + static constexpr bool incremental = true; static unsigned cnt = 0; const auto iN = N(); diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 3e6c7a1fe17..ed110c01c7b 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -97,7 +97,7 @@ protected: nl_double m_last_RHS[storage_N]; // right hand side - contains currents private: - static const std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; + static constexpr std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8; nl_ext_double m_A[storage_N][m_pitch]; nl_ext_double m_Ainv[storage_N][m_pitch]; nl_ext_double m_W[storage_N][m_pitch]; |