summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_config.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_config.h')
-rw-r--r--src/lib/netlist/nl_config.h406
1 files changed, 249 insertions, 157 deletions
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 8dad2b36cc2..7306de88cde 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -7,6 +7,9 @@
#ifndef NLCONFIG_H_
#define NLCONFIG_H_
+// Names
+// spell-checker: words Woodbury
+
#include "plib/pconfig.h"
#include "plib/pexception.h"
@@ -15,56 +18,22 @@
///
/// \brief Version - Major.
///
-#define NL_VERSION_MAJOR 0
+#define NL_VERSION_MAJOR 0
///
/// \brief Version - Minor.
///
-#define NL_VERSION_MINOR 14
+#define NL_VERSION_MINOR 14
/// \brief Version - Patch level.
///
-#define NL_VERSION_PATCHLEVEL 0
+#define NL_VERSION_PATCHLEVEL 0
///
/// \addtogroup compiledefine
/// \{
-//============================================================
-// GENERAL
-//============================================================
-
-/// \brief Make use of a memory pool for performance related objects.
-///
-/// Set to 1 to compile netlist with memory allocations from a
-/// linear memory pool. This is based of the assumption that
-/// due to enhanced locality there will be less cache misses.
-/// Your mileage may vary.
-///
-
-#ifndef NL_USE_MEMPOOL
-#define NL_USE_MEMPOOL (1)
-#endif
-
-/// brief default minimum alignment of mempool_arena
-///
-/// 256 is the best compromise between logic applications like MAME
-/// TTL games (e.g. pong) and analog applications like e.g. kidnikik sound.
-///
-/// Best performance for pong is achieved with a value of 16, but this degrades
-/// kidniki performance by ~10%.
-///
-/// More work is needed here.
-#define NL_MEMPOOL_ALIGN (16)
-
-/// \brief Enable queue statistics.
-///
-/// Queue statistics come at a performance cost. Although
-/// the cost is low, we disable them here since they are
-/// only needed during development.
-///
-
-#ifndef NL_USE_QUEUE_STATS
-#define NL_USE_QUEUE_STATS (0)
-#endif
+// -----------------------------------------------------------------------------
+// General
+// -----------------------------------------------------------------------------
/// \brief Compile in academic solvers
///
@@ -78,84 +47,67 @@
/// again. Compiling in all solvers may increase compile
/// time significantly.
///
-
#ifndef NL_USE_ACADEMIC_SOLVERS
-#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)
+ #define NL_USE_ACADEMIC_SOLVERS (1)
#endif
/// \brief Use backward Euler integration
///
/// This will use backward Euler instead of trapezoidal integration.
///
-/// FIXME: Longterm this will become a runtime setting. Only the capacitor model
-/// currently has a trapezoidal version and there is no support currently for
-/// variable capacitors.
-/// The change will have impact on timings since trapezoidal improves timing
-/// accuracy.
-
+/// FIXME: Long term this will become a runtime setting. Only the capacitor
+/// model currently has a trapezoidal version and there is no support currently
+/// for variable capacitors. The change will have impact on timings since
+/// trapezoidal improves timing accuracy.
#ifndef NL_USE_BACKWARD_EULER
-#define NL_USE_BACKWARD_EULER (1)
+ #define NL_USE_BACKWARD_EULER (1) // FIXME: Move to config struct later
#endif
-/// \brief Use the __float128 type for matrix calculations.
+/// \brief Compile with core terminals owned by net_t
///
-/// Defaults to \ref PUSE_FLOAT128
-
-#ifndef NL_USE_FLOAT128
-#define NL_USE_FLOAT128 PUSE_FLOAT128
-#endif
-
-/// \brief Prefer 128bit int type for ptime if supported
+/// 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.
///
-/// Set this to one if you want to use 128 bit int for ptime.
-/// This is about 10% slower on a skylake processor for pongf.
+/// 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.
///
-#ifndef NL_PREFER_INT128
-#define NL_PREFER_INT128 (0)
+/// By default the setting is currently disabled.
+///
+#ifndef NL_USE_INPLACE_CORE_TERMS
+ #define NL_USE_INPLACE_CORE_TERMS (0)
#endif
-/// \brief Support float type for matrix calculations.
+/// \brief Use alternative truth table execution approach
///
-/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
-
-#ifndef NL_USE_FLOAT_MATRIX
-#define NL_USE_FLOAT_MATRIX (NL_USE_ACADEMIC_SOLVERS)
-//#define NL_USE_FLOAT_MATRIX 1
+/// 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 Support long double type for matrix calculations.
+/// \brief Compile matrix solvers using the __float128 type.
///
-/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
-
-#ifndef NL_USE_LONG_DOUBLE_MATRIX
-#define NL_USE_LONG_DOUBLE_MATRIX (NL_USE_ACADEMIC_SOLVERS)
-//#define NL_USE_LONG_DOUBLE_MATRIX 1
+/// Defaults to \ref PUSE_FLOAT128
+#ifndef NL_USE_FLOAT128
+ #define NL_USE_FLOAT128 PUSE_FLOAT128
#endif
-//============================================================
+// -----------------------------------------------------------------------------
// DEBUGGING
-//============================================================
+// -----------------------------------------------------------------------------
/// \brief Enable compile time debugging code
///
#ifndef NL_DEBUG
-#define NL_DEBUG (false)
-//#define NL_DEBUG (true)
+ #define NL_DEBUG (false)
#endif
///
@@ -164,17 +116,56 @@
namespace netlist
{
- // FIXME: need a better solution for global constants.
- struct config
+ // -------------------------------------------------------------------------
+ // GENERAL
+ // -------------------------------------------------------------------------
+
+ struct config_default
{
- //============================================================
+ /// \brief Make use of a memory pool for performance related objects.
+ ///
+ /// Set to 1 to compile netlist with memory allocations from a
+ /// linear memory pool. This is based of the assumption that
+ /// due to enhanced locality there will be less cache misses.
+ /// Your mileage may vary.
+ ///
+ using use_mempool = std::integral_constant<bool, true>;
+
+ /// brief default minimum alignment of mempool_arena
+ ///
+ /// 256 is the best compromise between logic applications like MAME
+ /// TTL games (e.g. pong) and analog applications like e.g. kidniki
+ /// sound.
+ ///
+ /// Best performance for pong is achieved with a value of 16, but this
+ /// degrades kidniki performance by ~10%.
+ ///
+ /// More work is needed here.
+ using mempool_align = std::integral_constant<std::size_t, 16>;
+
+ /// \brief Prefer 128bit int type for ptime if supported
+ ///
+ /// Set this to one if you want to use 128 bit int for ptime.
+ /// This is about 10% slower on a skylake processor for pong.
+ ///
+ using prefer_int128 = std::integral_constant<bool, false>;
+
+ /// \brief Enable queue statistics.
+ ///
+ /// Queue statistics come at a performance cost. Although
+ /// the cost is low, we disable them here since they are
+ /// only needed during development.
+ ///
+ using use_queue_stats = std::integral_constant<bool, false>;
+
+ // ---------------------------------------------------------------------
// Time resolution
- //============================================================
+ // ---------------------------------------------------------------------
/// \brief Resolution as clocks per second for timing
///
- /// Uses 100 pico second resolution. This is aligned to MAME's
- /// attotime resolution.
+ /// Uses 100 picosecond resolution. This is aligned to MAME's
+ /// `attotime` resolution.
///
/// The table below shows the maximum run times depending on
/// time type size and resolution.
@@ -186,15 +177,17 @@ namespace netlist
/// | 63 | 100,000,000,000 | 92,233,720 | 1,068| 2.9 |
/// | 63 | 1,000,000,000,000 | 9,223,372 | 107| 0.3 |
///
- using INTERNAL_RES = std::integral_constant<long long int, 10'000'000'000LL>; // NOLINT
+ using INTERNAL_RES = std::integral_constant<long long int,
+ 10'000'000'000LL>; // NOLINT
/// \brief Recommended clock to be used
///
- /// This is the recommended clock to be used in fixed clock applications limited
- /// to 32 bit clock resolution. The MAME code (netlist.cpp) contains code
- /// illustrating how to deal with remainders if \ref INTERNAL_RES is bigger than
- /// NETLIST_CLOCK.
- using DEFAULT_CLOCK = std::integral_constant<int, 1'000'000'000>; // NOLINT
+ /// This is the recommended clock to be used in fixed clock applications
+ /// limited to 32 bit clock resolution. The MAME code (netlist.cpp)
+ /// contains code illustrating how to deal with remainders if \ref
+ /// INTERNAL_RES is bigger than NETLIST_CLOCK.
+ using DEFAULT_CLOCK = std::integral_constant<int,
+ 1'000'000'000>; // NOLINT
/// \brief Default logic family
///
@@ -202,17 +195,28 @@ namespace netlist
/// \brief Maximum queue size
///
- using MAX_QUEUE_SIZE = std::integral_constant<std::size_t, 1024>; // NOLINT
+ using max_queue_size = std::integral_constant<std::size_t,
+ 1024>; // NOLINT
/// \brief Maximum queue size for solvers
///
- using MAX_SOLVER_QUEUE_SIZE = std::integral_constant<std::size_t, 512>; // NOLINT
+ using max_solver_queue_size = std::integral_constant<std::size_t,
+ 512>; // NOLINT
- using use_float_matrix = std::integral_constant<bool, NL_USE_FLOAT_MATRIX>;
- using use_long_double_matrix = std::integral_constant<bool, NL_USE_LONG_DOUBLE_MATRIX>;
- using use_float128_matrix = std::integral_constant<bool, NL_USE_FLOAT128>;
+ /// \brief Support float type for matrix calculations.
+ ///
+ /// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
+ using use_float_matrix = std::integral_constant<
+ bool, NL_USE_ACADEMIC_SOLVERS>;
+
+ /// \brief Support long double type for matrix calculations.
+ ///
+ /// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
+ using use_long_double_matrix = std::integral_constant<
+ bool, NL_USE_ACADEMIC_SOLVERS>;
- using use_mempool = std::integral_constant<bool, NL_USE_MEMPOOL>;
+ using use_float128_matrix = std::integral_constant<bool,
+ NL_USE_FLOAT128>;
/// \brief Floating point types used
///
@@ -225,6 +229,56 @@ 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.
+ ///
+ /// You can override all netlist build defaults here which are defined
+ /// in \ref config_default.
+ ///
+ 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;
@@ -235,21 +289,34 @@ namespace netlist
///
template <typename FT>
struct fp_constants
- { };
+ {
+ };
/// \brief Specific constants for long double floating point type
///
template <>
struct fp_constants<long double>
{
- static constexpr long double DIODE_MAXDIFF() noexcept { return 1e100L; } // NOLINT
- static constexpr long double DIODE_MAXVOLT() noexcept { return 300.0L; } // NOLINT
-
- static constexpr long double TIMESTEP_MAXDIFF() noexcept { return 1e100L; } // NOLINT
- static constexpr long double TIMESTEP_MINDIV() noexcept { return 1e-60L; } // NOLINT
-
- static constexpr const char * name() noexcept { return "long double"; }
- static constexpr const char * suffix() noexcept { return "L"; }
+ static constexpr long double DIODE_MAXDIFF() noexcept
+ {
+ return 1e100L;
+ } // NOLINT
+ static constexpr long double DIODE_MAXVOLT() noexcept
+ {
+ return 300.0L;
+ } // NOLINT
+
+ static constexpr long double TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e100L;
+ } // NOLINT
+ static constexpr long double TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-60L;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "long double"; }
+ static constexpr const char *suffix() noexcept { return "L"; }
};
/// \brief Specific constants for double floating point type
@@ -257,14 +324,26 @@ namespace netlist
template <>
struct fp_constants<double>
{
- static constexpr double DIODE_MAXDIFF() noexcept { return 1e100; } // NOLINT
- static constexpr double DIODE_MAXVOLT() noexcept { return 300.0; } // NOLINT
-
- static constexpr double TIMESTEP_MAXDIFF() noexcept { return 1e100; } // NOLINT
- static constexpr double TIMESTEP_MINDIV() noexcept { return 1e-60; } // NOLINT
-
- static constexpr const char * name() noexcept { return "double"; }
- static constexpr const char * suffix() noexcept { return ""; }
+ static constexpr double DIODE_MAXDIFF() noexcept
+ {
+ return 1e100;
+ } // NOLINT
+ static constexpr double DIODE_MAXVOLT() noexcept
+ {
+ return 300.0;
+ } // NOLINT
+
+ static constexpr double TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e100;
+ } // NOLINT
+ static constexpr double TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-60;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "double"; }
+ static constexpr const char *suffix() noexcept { return ""; }
};
/// \brief Specific constants for float floating point type
@@ -272,14 +351,26 @@ namespace netlist
template <>
struct fp_constants<float>
{
- static constexpr float DIODE_MAXDIFF() noexcept { return 1e20F; } // NOLINT
- static constexpr float DIODE_MAXVOLT() noexcept { return 90.0F; } // NOLINT
-
- static constexpr float TIMESTEP_MAXDIFF() noexcept { return 1e30F; } // NOLINT
- static constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8F; } // NOLINT
-
- static constexpr const char * name() noexcept { return "float"; }
- static constexpr const char * suffix() noexcept { return "f"; }
+ static constexpr float DIODE_MAXDIFF() noexcept
+ {
+ return 1e20F;
+ } // NOLINT
+ static constexpr float DIODE_MAXVOLT() noexcept
+ {
+ return 90.0F;
+ } // NOLINT
+
+ static constexpr float TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e30F;
+ } // NOLINT
+ static constexpr float TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-8F;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "float"; }
+ static constexpr const char *suffix() noexcept { return "f"; }
};
#if (NL_USE_FLOAT128)
@@ -288,7 +379,7 @@ namespace netlist
template <>
struct fp_constants<FLOAT128>
{
-#if 0
+ #if 0
// MAME compile doesn't support Q
static constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return 1e100Q; }
static constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return 300.0Q; }
@@ -298,30 +389,31 @@ namespace netlist
static constexpr const char * name() noexcept { return "FLOAT128"; }
static constexpr const char * suffix() noexcept { return "Q"; }
-#else
- static constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
- static constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return static_cast<FLOAT128>(300.0L); }
-
- static constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
- static constexpr FLOAT128 TIMESTEP_MINDIV() noexcept { return static_cast<FLOAT128>(1e-60L); }
-
- static constexpr const char * name() noexcept { return "__float128"; }
- static constexpr const char * suffix() noexcept { return "Q"; }
-
-#endif
+ #else
+ static constexpr FLOAT128 DIODE_MAXDIFF() noexcept
+ {
+ return static_cast<FLOAT128>(1e100L);
+ }
+ static constexpr FLOAT128 DIODE_MAXVOLT() noexcept
+ {
+ return static_cast<FLOAT128>(300.0L);
+ }
+
+ static constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept
+ {
+ return static_cast<FLOAT128>(1e100L);
+ }
+ static constexpr FLOAT128 TIMESTEP_MINDIV() noexcept
+ {
+ return static_cast<FLOAT128>(1e-60L);
+ }
+
+ static constexpr const char *name() noexcept { return "__float128"; }
+ static constexpr const char *suffix() noexcept { return "Q"; }
+
+ #endif
};
#endif
} // namespace netlist
-//============================================================
-// Asserts
-//============================================================
-
-#if defined(MAME_DEBUG) || (NL_DEBUG == true)
-#define nl_assert(x) passert_always(x)
-#else
-#define nl_assert(x) do { } while (0)
-#endif
-#define nl_assert_always(x, msg) passert_always_msg(x, msg)
-
#endif // NLCONFIG_H_