diff options
author | 2020-08-12 22:12:06 +0200 | |
---|---|---|
committer | 2020-08-12 22:12:20 +0200 | |
commit | 9d00d87dac0d4f606268f3eb43335eb81a58cad1 (patch) | |
tree | 33ff4f662eba9fdb9fdc969aa88acbfa3a6d174d | |
parent | 7d5a0c74f6078382b91be916f3416d1c6159abd5 (diff) |
netlist: commit missing files in last commit.
-rw-r--r-- | src/lib/netlist/core/device_macros.h | 172 | ||||
-rw-r--r-- | src/lib/netlist/core/devices.h | 181 |
2 files changed, 353 insertions, 0 deletions
diff --git a/src/lib/netlist/core/device_macros.h b/src/lib/netlist/core/device_macros.h new file mode 100644 index 00000000000..127447e194a --- /dev/null +++ b/src/lib/netlist/core/device_macros.h @@ -0,0 +1,172 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +#ifndef NL_CORE_DEVICE_MACROS_H_ +#define NL_CORE_DEVICE_MACROS_H_ + +/// +/// \file device_macros.h +/// + +//============================================================ +// MACROS / New Syntax +//============================================================ + +/// \brief Construct a netlist device name +/// +#define NETLIB_NAME(chip) nld_ ## chip + +/// \brief Start a netlist device class. +/// +/// Used to start defining a netlist device class. +/// The simplest device without inputs or outputs would look like this: +/// +/// NETLIB_OBJECT(some_object) +/// { +/// public: +/// NETLIB_CONSTRUCTOR(some_object) { } +/// }; +/// +/// Also refer to #NETLIB_CONSTRUCTOR. +#define NETLIB_OBJECT(name) \ +class NETLIB_NAME(name) : public delegator_t<device_t> + +/// \brief Start a derived netlist device class. +/// +/// Used to define a derived device class based on plcass. +/// The simplest device without inputs or outputs would look like this: +/// +/// NETLIB_OBJECT_DERIVED(some_object, parent_object) +/// { +/// public: +/// NETLIB_CONSTRUCTOR(some_object) { } +/// }; +/// +/// Also refer to #NETLIB_CONSTRUCTOR. +#define NETLIB_OBJECT_DERIVED(name, pclass) \ +class NETLIB_NAME(name) : public delegator_t<NETLIB_NAME(pclass)> + + + +// Only used for analog objects like diodes and resistors + +#define NETLIB_BASE_OBJECT(name) \ +class NETLIB_NAME(name) : public delegator_t<base_device_t> + +#define NETLIB_CONSTRUCTOR_PASS(cname, ...) \ + using this_type = NETLIB_NAME(cname); \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name) \ + : base_type(owner, name, __VA_ARGS__) + +/// \brief Used to define the constructor of a netlist device. +/// +/// Use this to define the constructor of a netlist device. Please refer to +/// #NETLIB_OBJECT for an example. +#define NETLIB_CONSTRUCTOR(cname) \ + using this_type = NETLIB_NAME(cname); \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name)\ + : base_type(owner, name) + +/// \brief Used to define the constructor of a netlist device and define a default model. +/// +/// +/// NETLIB_CONSTRUCTOR_MODEL(some_object, "TTL") +/// { +/// public: +/// NETLIB_CONSTRUCTOR(some_object) { } +/// }; +/// +#define NETLIB_CONSTRUCTOR_MODEL(cname, cmodel) \ + using this_type = NETLIB_NAME(cname); \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name) \ + : base_type(owner, name, cmodel) + +/// \brief Define an extended constructor and add further parameters to it. +/// The macro allows to add further parameters to a device constructor. This is +/// normally used for sub-devices and system devices only. +#define NETLIB_CONSTRUCTOR_EX(cname, ...) \ + using this_type = NETLIB_NAME(cname); \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name, __VA_ARGS__) \ + : base_type(owner, name) + +/// \brief Used to define the destructor of a netlist device. +/// The use of a destructor for netlist device should normally not be necessary. +#define NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)() noexcept override + +/// \brief Add this to a device definition to mark the device as dynamic. +/// +/// If NETLIB_IS_DYNAMIC(true) is added to the device definition the device +/// is treated as an analog dynamic device, i.e. \ref NETLIB_UPDATE_TERMINALSI +/// is called on a each step of the Newton-Raphson step +/// of solving the linear equations. +/// +/// You may also use e.g. NETLIB_IS_DYNAMIC(m_func() != "") to only make the +/// device a dynamic device if parameter m_func is set. +/// +/// \param expr boolean expression +/// +#define NETLIB_IS_DYNAMIC(expr) \ + public: virtual bool is_dynamic() const noexcept override { return expr; } + +/// \brief Add this to a device definition to mark the device as a time-stepping device. +/// +/// You have to implement NETLIB_TIMESTEP in this case as well. Currently, only +/// the capacitor and inductor devices uses this. +/// +/// You may also use e.g. NETLIB_IS_TIMESTEP(m_func() != "") to only make the +/// device a dynamic device if parameter m_func is set. This is used by the +/// Voltage Source element. +/// +/// Example: +/// +/// \code +/// NETLIB_TIMESTEP_IS_TIMESTEP() +/// NETLIB_TIMESTEPI() +/// { +/// // Gpar should support convergence +/// const nl_fptype G = m_C.Value() / step + m_GParallel; +/// const nl_fptype I = -G/// deltaV(); +/// set(G, 0.0, I); +/// } +/// \endcode + +#define NETLIB_IS_TIMESTEP(expr) \ + public: virtual bool is_timestep() const noexcept override { return expr; } + +/// \brief Used to implement the time stepping code. +/// +/// Please see \ref NETLIB_IS_TIMESTEP for an example. + +#define NETLIB_TIMESTEPI() \ + public: virtual void timestep(timestep_type ts_type, nl_fptype step) noexcept override + +/// \brief Used to implement the body of the time stepping code. +/// +/// Used when the implementation is outside the class definition +/// +/// Please see \ref NETLIB_IS_TIMESTEP for an example. +/// +/// \param cname Name of object as given to \ref NETLIB_OBJECT +/// +#define NETLIB_TIMESTEP(cname) \ + void NETLIB_NAME(cname) :: timestep(timestep_type ts_type, nl_fptype step) noexcept + +#define NETLIB_DELEGATE(name) nldelegate(&this_type :: name, this) + +#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() noexcept override +#define NETLIB_HANDLERI(name) void name() noexcept +#define NETLIB_UPDATE_PARAMI() virtual void update_param() noexcept override +#define NETLIB_RESETI() virtual void reset() override + +#define NETLIB_SUB(chip) nld_ ## chip +#define NETLIB_SUB_UPTR(ns, chip) device_arena::unique_ptr< ns :: nld_ ## chip > + +#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() noexcept + +#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void) + +#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param() noexcept + +#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals() noexcept + +#endif // NL_CORE_DEVICE_MACROS_H_ diff --git a/src/lib/netlist/core/devices.h b/src/lib/netlist/core/devices.h new file mode 100644 index 00000000000..de4b11b994a --- /dev/null +++ b/src/lib/netlist/core/devices.h @@ -0,0 +1,181 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +#ifndef NL_CORE_DEVICES_H_ +#define NL_CORE_DEVICES_H_ + +/// +/// \file devices.h +/// +/// The core is accessing members or type definitions of devices defined +/// here directly (e.g. nld_nc_pin). +/// + +#if 0 +#include "core/base_objects.h" +#include "core/logic.h" +#include "core/logic_family.h" +#include "core/netlist_state.h" +#include "core/nets.h" +#include "core/object_array.h" +#include "core/param.h" +#include "core/state_var.h" +#include "core/exec.h" +#endif +#include "analog.h" +#include "device.h" +#include "device_macros.h" + +//============================================================ +// Namespace starts +//============================================================ + +namespace netlist +{ + namespace devices + { + // ----------------------------------------------------------------------------- + // mainclock + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(mainclock) + { + NETLIB_CONSTRUCTOR(mainclock) + , m_Q(*this, "Q") + , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5)) + { + m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two())); + } + + NETLIB_RESETI() + { + m_Q.net().set_next_scheduled_time(exec().time()); + } + + NETLIB_UPDATE_PARAMI() + { + m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two())); + } + + public: + logic_output_t m_Q; // NOLINT: needed in core + netlist_time m_inc; // NOLINT: needed in core + private: + param_fp_t m_freq; + }; + + // ----------------------------------------------------------------------------- + // power pins - not a device, but a helper + // ----------------------------------------------------------------------------- + + /// \brief Power pins class. + /// + /// Power Pins are passive inputs. Delegate noop will silently ignore any + /// updates. + + class nld_power_pins + { + public: + using this_type = nld_power_pins; + + explicit nld_power_pins(device_t &owner) + : m_VCC(owner, owner.logic_family()->vcc_pin(), NETLIB_DELEGATE(noop)) + , m_GND(owner, owner.logic_family()->gnd_pin(), NETLIB_DELEGATE(noop)) + { + } + + // Some devices like the 74LS629 have two pairs of supply pins. + explicit nld_power_pins(device_t &owner, + const pstring &vcc, const pstring &gnd) + : m_VCC(owner, vcc, NETLIB_DELEGATE(noop)) + , m_GND(owner, gnd, NETLIB_DELEGATE(noop)) + { + } + + const analog_input_t &VCC() const noexcept + { + return m_VCC; + } + const analog_input_t &GND() const noexcept + { + return m_GND; + } + + private: + void noop() { } + analog_input_t m_VCC; + analog_input_t m_GND; + }; + + // ----------------------------------------------------------------------------- + // netlistparams + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(netlistparams) + { + NETLIB_CONSTRUCTOR(netlistparams) + , m_use_deactivate(*this, "USE_DEACTIVATE", false) + , m_startup_strategy(*this, "STARTUP_STRATEGY", 0) + , m_mos_capmodel(*this, "DEFAULT_MOS_CAPMODEL", 2) + , m_max_link_loops(*this, "MAX_LINK_RESOLVE_LOOPS", 100) + { + } + //NETLIB_RESETI() {} + //NETLIB_UPDATE_PARAMI() { } + public: + param_logic_t m_use_deactivate; + param_num_t<unsigned> m_startup_strategy; + param_num_t<unsigned> m_mos_capmodel; + //! How many times do we try to resolve links (connections) + param_num_t<unsigned> m_max_link_loops; + }; + + // ----------------------------------------------------------------------------- + // nld_nc_pin + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(nc_pin) + { + public: + NETLIB_CONSTRUCTOR(nc_pin) + , m_I(*this, "I", NETLIB_DELEGATE(noop)) + { + } + + protected: + //NETLIB_RESETI() {} + + private: + NETLIB_HANDLERI(noop) + { + } + + analog_input_t m_I; + + }; + + // ----------------------------------------------------------------------------- + // nld_gnd + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(gnd) + { + NETLIB_CONSTRUCTOR(gnd) + , m_Q(*this, "Q") + { + } + + NETLIB_UPDATE_PARAMI() + { + m_Q.push(nlconst::zero()); + } + + //NETLIB_RESETI() {} + protected: + analog_output_t m_Q; + }; + + } // namespace devices +} // namespace netlist + +#endif // NL_CORE_DEVICES_H_ |