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.h472
1 files changed, 393 insertions, 79 deletions
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index f2005602443..7306de88cde 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -1,105 +1,419 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*!
- *
- * \file nl_config.h
- *
- */
+
+/// \file nl_config.h
+///
#ifndef NLCONFIG_H_
#define NLCONFIG_H_
+// Names
+// spell-checker: words Woodbury
+
#include "plib/pconfig.h"
+#include "plib/pexception.h"
-//============================================================
-// SETUP
-//============================================================
-
-
-//============================================================
-// GENERAL
-//============================================================
-
-/*! 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 USE_MEMPOOL
-#define USE_MEMPOOL (1)
-#endif
+#include <type_traits>
-/*! 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 USE_QUEUE_STATS
-#define USE_QUEUE_STATS (0)
-#endif
+///
+/// \brief Version - Major.
+///
+#define NL_VERSION_MAJOR 0
+///
+/// \brief Version - Minor.
+///
+#define NL_VERSION_MINOR 14
+/// \brief Version - Patch level.
+///
+#define NL_VERSION_PATCHLEVEL 0
+
+///
+/// \addtogroup compiledefine
+/// \{
+
+// -----------------------------------------------------------------------------
+// General
+// -----------------------------------------------------------------------------
-/*! 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 5% slower.
- *
- */
-#ifndef USE_COPY_INSTEAD_OF_REFERENCE
-#define USE_COPY_INSTEAD_OF_REFERENCE (0)
+/// \brief Compile in academic solvers
+///
+/// Set to 0 to disable compiling the following solvers:
+///
+/// Sherman-Morrison, Woodbury, SOR and GMRES
+///
+/// In addition, compilation of FLOAT, LONGDOUBLE and FLOATQ128 matrix
+/// solvers will be disabled.
+/// GMRES may be added to productive solvers in the future
+/// again. Compiling in all solvers may increase compile
+/// time significantly.
+///
+#ifndef NL_USE_ACADEMIC_SOLVERS
+ #define NL_USE_ACADEMIC_SOLVERS (1)
#endif
-/*
- * FIXME: Using truthtable is a lot slower than the explicit device
- * in breakout. Performance drops by 20%. This can be fixed by
- * setting param USE_DEACTIVATE for the device.
- */
+/// \brief Use backward Euler integration
+///
+/// This will use backward Euler instead of trapezoidal integration.
+///
+/// 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) // FIXME: Move to config struct later
+#endif
-#define USE_TRUTHTABLE_7448 (0)
+/// \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
-/*
- * FIXME: The truthtable implementation of 74107 (JK-Flipflop)
- * is included for educational purposes to demonstrate how
- * to implement state holding devices as truthtables.
- * It will completely nuke performance for pong.
- */
+/// \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
-#define USE_TRUTHTABLE_74107 (0)
+/// \brief Compile matrix solvers using the __float128 type.
+///
+/// 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
-//============================================================
-// Time resolution
-//============================================================
+///
+/// \}
+///
+
+namespace netlist
+{
+ // -------------------------------------------------------------------------
+ // 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 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.
+ ///
+ /// | Bits | Res | Seconds | Days | Years |
+ /// | ====-| ===-| =======-| ====-| =====-|
+ /// | 63 | 1,000,000,000 | 9,223,372,037 | 106,752| 292.3 |
+ /// | 63 | 10,000,000,000 | 922,337,204 | 10,675| 29.2 |
+ /// | 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
+
+ /// \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
+
+ /// \brief Default logic family
+ ///
+ static constexpr const char *DEFAULT_LOGIC_FAMILY() { return "74XX"; }
+
+ /// \brief Maximum queue size
+ ///
+ 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
+
+ /// \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>;
-// Use nano-second resolution - Sufficient for now
+ /// \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>;
-static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
-//static constexpr const auto NETLIST_INTERNAL_RES = 1000000000000;
-static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
+ using use_float128_matrix = std::integral_constant<bool,
+ NL_USE_FLOAT128>;
-//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000))
-//#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
-//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000000))
-//#define NETLIST_CLOCK (UINT64_C(1000000000))
+ /// \brief Floating point types used
+ ///
+ /// nl_fptype is the floating point type used throughout the
+ /// netlist core.
+ ///
+ /// Don't change this! Simple analog circuits like pong
+ /// work with float. Kidniki just doesn't work at all.
+ ///
+ /// 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>;
-//#define nl_double float
-using nl_double = double;
+ /// \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;
+
+ /// \brief Specific constants depending on floating type
+ ///
+ /// \tparam FT floating point type: double/float
+ ///
+ 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"; }
+ };
+
+ /// \brief Specific constants for double floating point type
+ ///
+ 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 ""; }
+ };
+
+ /// \brief Specific constants for float floating point type
+ ///
+ 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"; }
+ };
+
+#if (NL_USE_FLOAT128)
+ /// \brief Specific constants for FLOAT128 floating point type
+ ///
+ template <>
+ struct fp_constants<FLOAT128>
+ {
+ #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; }
+
+ static constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept { return 1e100Q; }
+ static constexpr FLOAT128 TIMESTEP_MINDIV() noexcept { return 1e-60Q; }
+
+ 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
+ };
+#endif
+} // namespace netlist
-#endif /* NLCONFIG_H_ */
+#endif // NLCONFIG_H_