summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_system.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_system.h')
-rw-r--r--src/lib/netlist/devices/nld_system.h513
1 files changed, 513 insertions, 0 deletions
diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h
new file mode 100644
index 00000000000..2ea6fbed4d4
--- /dev/null
+++ b/src/lib/netlist/devices/nld_system.h
@@ -0,0 +1,513 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * nld_system.h
+ *
+ * netlist devices defined in the core
+ */
+
+#ifndef NLD_SYSTEM_H_
+#define NLD_SYSTEM_H_
+
+#include "nl_setup.h"
+#include "nl_base.h"
+#include "nl_factory.h"
+#include "analog/nld_twoterm.h"
+
+// -----------------------------------------------------------------------------
+// Macros
+// -----------------------------------------------------------------------------
+
+#define TTL_INPUT(_name, _v) \
+ NET_REGISTER_DEV(TTL_INPUT, _name) \
+ PARAM(_name.IN, _v)
+
+#define LOGIC_INPUT(_name, _v, _family) \
+ NET_REGISTER_DEV(LOGIC_INPUT, _name) \
+ PARAM(_name.IN, _v) \
+ PARAM(_name.FAMILY, _family)
+
+#define ANALOG_INPUT(_name, _v) \
+ NET_REGISTER_DEV(ANALOG_INPUT, _name) \
+ PARAM(_name.IN, _v)
+
+#define MAINCLOCK(_name, _freq) \
+ NET_REGISTER_DEV(MAINCLOCK, _name) \
+ PARAM(_name.FREQ, _freq)
+
+#define CLOCK(_name, _freq) \
+ NET_REGISTER_DEV(CLOCK, _name) \
+ PARAM(_name.FREQ, _freq)
+
+#define EXTCLOCK(_name, _freq, _pattern) \
+ NET_REGISTER_DEV(EXTCLOCK, _name) \
+ PARAM(_name.FREQ, _freq) \
+ PARAM(_name.PATTERN, _pattern)
+
+#define GNDA() \
+ NET_REGISTER_DEV(GNDA, GND)
+
+#define DUMMY_INPUT(_name) \
+ NET_REGISTER_DEV(DUMMY_INPUT, _name)
+
+//FIXME: Usage discouraged, use OPTIMIZE_FRONTIER instead
+#define FRONTIER_DEV(_name, _IN, _G, _OUT) \
+ NET_REGISTER_DEV(FRONTIER_DEV, _name) \
+ NET_C(_IN, _name.I) \
+ NET_C(_G, _name.G) \
+ NET_C(_OUT, _name.Q)
+
+#define OPTIMIZE_FRONTIER(_attach, _r_in, _r_out) \
+ setup.register_frontier(# _attach, _r_in, _r_out);
+
+#define RES_SWITCH(_name, _IN, _P1, _P2) \
+ NET_REGISTER_DEV(RES_SWITCH, _name) \
+ NET_C(_IN, _name.I) \
+ NET_C(_P1, _name.1) \
+ NET_C(_P2, _name.2)
+
+/* Default device to hold netlist parameters */
+#define PARAMETERS(_name) \
+ NET_REGISTER_DEV(PARAMETERS, _name)
+
+#define AFUNC(_name, _N, _F) \
+ NET_REGISTER_DEV(AFUNC, _name) \
+ PARAM(_name.N, _N) \
+ PARAM(_name.FUNC, _F)
+
+NETLIB_NAMESPACE_DEVICES_START()
+
+// -----------------------------------------------------------------------------
+// netlistparams
+// -----------------------------------------------------------------------------
+
+NETLIB_DEVICE_WITH_PARAMS(netlistparams,
+public:
+ param_logic_t m_use_deactivate;
+);
+
+// -----------------------------------------------------------------------------
+// mainclock
+// -----------------------------------------------------------------------------
+
+NETLIB_DEVICE_WITH_PARAMS(mainclock,
+public:
+ logic_output_t m_Q;
+
+ param_double_t m_freq;
+ netlist_time m_inc;
+
+ ATTR_HOT inline static void mc_update(logic_net_t &net);
+);
+
+// -----------------------------------------------------------------------------
+// clock
+// -----------------------------------------------------------------------------
+
+NETLIB_DEVICE_WITH_PARAMS(clock,
+ logic_input_t m_feedback;
+ logic_output_t m_Q;
+
+ param_double_t m_freq;
+ netlist_time m_inc;
+);
+
+// -----------------------------------------------------------------------------
+// extclock
+// -----------------------------------------------------------------------------
+
+NETLIB_DEVICE_WITH_PARAMS(extclock,
+ logic_input_t m_feedback;
+ logic_output_t m_Q;
+
+ param_double_t m_freq;
+ param_str_t m_pattern;
+ param_double_t m_offset;
+
+ UINT8 m_cnt;
+ UINT8 m_size;
+ netlist_time m_off;
+ netlist_time m_inc[32];
+);
+
+// -----------------------------------------------------------------------------
+// Special support devices ...
+// -----------------------------------------------------------------------------
+
+NETLIB_DEVICE_WITH_PARAMS(logic_input,
+
+ virtual void stop();
+ logic_output_t m_Q;
+
+ param_logic_t m_IN;
+ param_model_t m_FAMILY;
+);
+
+NETLIB_DEVICE_WITH_PARAMS(analog_input,
+ analog_output_t m_Q;
+
+ param_double_t m_IN;
+);
+
+// -----------------------------------------------------------------------------
+// nld_gnd
+// -----------------------------------------------------------------------------
+
+class NETLIB_NAME(gnd) : public device_t
+{
+public:
+ NETLIB_NAME(gnd)()
+ : device_t(GND) { }
+
+ virtual ~NETLIB_NAME(gnd)() {}
+
+protected:
+
+ void start()
+ {
+ register_output("Q", m_Q);
+ }
+
+ void reset()
+ {
+ }
+
+ void update()
+ {
+ OUTANALOG(m_Q, 0.0);
+ }
+
+private:
+ analog_output_t m_Q;
+
+};
+
+// -----------------------------------------------------------------------------
+// nld_dummy_input
+// -----------------------------------------------------------------------------
+
+class NETLIB_NAME(dummy_input) : public device_t
+{
+public:
+ NETLIB_NAME(dummy_input)()
+ : device_t(DUMMY) { }
+
+ virtual ~NETLIB_NAME(dummy_input)() {}
+
+protected:
+
+ void start()
+ {
+ register_input("I", m_I);
+ }
+
+ void reset()
+ {
+ }
+
+ void update()
+ {
+ }
+
+private:
+ analog_input_t m_I;
+
+};
+
+// -----------------------------------------------------------------------------
+// nld_frontier
+// -----------------------------------------------------------------------------
+
+class NETLIB_NAME(frontier) : public device_t
+{
+public:
+ NETLIB_NAME(frontier)()
+ : device_t(DUMMY) { }
+
+ virtual ~NETLIB_NAME(frontier)() {}
+
+protected:
+
+ void start()
+ {
+ register_param("RIN", m_p_RIN, 1.0e6);
+ register_param("ROUT", m_p_ROUT, 50.0);
+
+ register_input("_I", m_I);
+ register_terminal("I",m_RIN.m_P);
+ register_terminal("G",m_RIN.m_N);
+ connect_late(m_I, m_RIN.m_P);
+
+ register_output("_Q", m_Q);
+ register_terminal("_OP",m_ROUT.m_P);
+ register_terminal("Q",m_ROUT.m_N);
+ connect_late(m_Q, m_ROUT.m_P);
+ }
+
+ void reset()
+ {
+ m_RIN.set(1.0 / m_p_RIN.Value(),0,0);
+ m_ROUT.set(1.0 / m_p_ROUT.Value(),0,0);
+ }
+
+ void update()
+ {
+ OUTANALOG(m_Q, INPANALOG(m_I));
+ }
+
+private:
+ NETLIB_NAME(twoterm) m_RIN;
+ NETLIB_NAME(twoterm) m_ROUT;
+ analog_input_t m_I;
+ analog_output_t m_Q;
+
+ param_double_t m_p_RIN;
+ param_double_t m_p_ROUT;
+};
+
+/* -----------------------------------------------------------------------------
+ * nld_function
+ *
+ * FIXME: Currently a proof of concept to get congo bongo working
+ * ----------------------------------------------------------------------------- */
+
+class NETLIB_NAME(function) : public device_t
+{
+public:
+ NETLIB_NAME(function)()
+ : device_t() { }
+
+ virtual ~NETLIB_NAME(function)() {}
+
+protected:
+
+ void start();
+ void reset();
+ void update();
+
+private:
+
+ enum rpn_cmd
+ {
+ ADD,
+ MULT,
+ SUB,
+ DIV,
+ PUSH_CONST,
+ PUSH_INPUT
+ };
+
+ struct rpn_inst
+ {
+ rpn_inst() : m_cmd(ADD), m_param(0.0) { }
+ rpn_cmd m_cmd;
+ nl_double m_param;
+ };
+
+ param_int_t m_N;
+ param_str_t m_func;
+ analog_output_t m_Q;
+ analog_input_t m_I[10];
+
+ plist_t<rpn_inst> m_precompiled;
+};
+
+// -----------------------------------------------------------------------------
+// nld_res_sw
+// -----------------------------------------------------------------------------
+
+class NETLIB_NAME(res_sw) : public device_t
+{
+public:
+ NETLIB_NAME(res_sw)()
+ : device_t() { }
+
+ virtual ~NETLIB_NAME(res_sw)() {}
+
+ param_double_t m_RON;
+ param_double_t m_ROFF;
+ logic_input_t m_I;
+ NETLIB_NAME(R) m_R;
+
+protected:
+
+ void start();
+ void reset();
+ ATTR_HOT void update();
+ ATTR_HOT void update_param();
+
+private:
+ UINT8 m_last_state;
+};
+
+// -----------------------------------------------------------------------------
+// nld_base_proxy
+// -----------------------------------------------------------------------------
+
+class nld_base_proxy : public device_t
+{
+public:
+ nld_base_proxy(logic_t *inout_proxied, core_terminal_t *proxy_inout)
+ : device_t()
+ {
+ m_logic_family = inout_proxied->logic_family();
+ m_term_proxied = inout_proxied;
+ m_proxy_term = proxy_inout;
+ }
+
+ virtual ~nld_base_proxy() {}
+
+ logic_t &term_proxied() const { return *m_term_proxied; }
+ core_terminal_t &proxy_term() const { return *m_proxy_term; }
+
+protected:
+
+ virtual const logic_family_desc_t &logic_family() const
+ {
+ return *m_logic_family;
+ }
+
+private:
+ const logic_family_desc_t *m_logic_family;
+ logic_t *m_term_proxied;
+ core_terminal_t *m_proxy_term;
+};
+
+// -----------------------------------------------------------------------------
+// nld_a_to_d_proxy
+// -----------------------------------------------------------------------------
+
+class nld_a_to_d_proxy : public nld_base_proxy
+{
+public:
+ nld_a_to_d_proxy(logic_input_t *in_proxied)
+ : nld_base_proxy(in_proxied, &m_I)
+ {
+ }
+
+ virtual ~nld_a_to_d_proxy() {}
+
+ analog_input_t m_I;
+ logic_output_t m_Q;
+
+protected:
+ void start()
+ {
+ register_input("I", m_I);
+ register_output("Q", m_Q);
+ }
+
+ void reset()
+ {
+ }
+
+ ATTR_HOT void update()
+ {
+ if (m_I.Q_Analog() > logic_family().m_high_thresh_V)
+ OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
+ else if (m_I.Q_Analog() < logic_family().m_low_thresh_V)
+ OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1));
+ else
+ {
+ // do nothing
+ }
+ }
+private:
+};
+
+// -----------------------------------------------------------------------------
+// nld_base_d_to_a_proxy
+// -----------------------------------------------------------------------------
+
+class nld_base_d_to_a_proxy : public nld_base_proxy
+{
+public:
+ virtual ~nld_base_d_to_a_proxy() {}
+
+ virtual logic_input_t &in() { return m_I; }
+
+protected:
+ nld_base_d_to_a_proxy(logic_output_t *out_proxied, core_terminal_t &proxy_out)
+ : nld_base_proxy(out_proxied, &proxy_out)
+ {
+ }
+
+ virtual void start()
+ {
+ register_input("I", m_I);
+ }
+
+ logic_input_t m_I;
+
+private:
+};
+
+class nld_d_to_a_proxy : public nld_base_d_to_a_proxy
+{
+public:
+ nld_d_to_a_proxy(logic_output_t *out_proxied)
+ : nld_base_d_to_a_proxy(out_proxied, m_RV.m_P)
+ , m_RV(TWOTERM)
+ , m_last_state(-1)
+ , m_is_timestep(false)
+ {
+ }
+
+ virtual ~nld_d_to_a_proxy() {}
+
+protected:
+ virtual void start();
+
+ virtual void reset();
+
+ ATTR_HOT void update();
+
+private:
+ analog_output_t m_Q;
+ nld_twoterm m_RV;
+ int m_last_state;
+ bool m_is_timestep;
+};
+
+
+class factory_lib_entry_t : public base_factory_t
+{
+ P_PREVENT_COPYING(factory_lib_entry_t)
+public:
+
+ ATTR_COLD factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : base_factory_t(name, classname, def_param), m_setup(setup) { }
+
+ class dummy : public device_t
+ {
+ public:
+ dummy(const pstring &dev_name) : device_t(), m_dev_name(dev_name) { }
+ protected:
+ virtual void init(netlist_t &anetlist, const pstring &aname)
+ {
+ anetlist.setup().namespace_push(aname);
+ anetlist.setup().include(m_dev_name);
+ anetlist.setup().namespace_pop();
+ }
+ void start() { }
+ void reset() { }
+ void update() { }
+
+ pstring m_dev_name;
+ };
+
+ ATTR_COLD device_t *Create()
+ {
+ device_t *r = palloc(dummy(this->name()));
+ return r;
+ }
+
+private:
+ setup_t &m_setup;
+};
+
+
+NETLIB_NAMESPACE_DEVICES_END()
+
+#endif /* NLD_SYSTEM_H_ */