summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_setup.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_setup.h')
-rw-r--r--src/lib/netlist/nl_setup.h566
1 files changed, 178 insertions, 388 deletions
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 3650b3756a9..31e971026e9 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -1,233 +1,146 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * nlsetup.h
- *
- */
+
+///
+/// \file nl_setup.h
+///
#ifndef NLSETUP_H_
#define NLSETUP_H_
-#include "plib/pparser.h"
-#include "plib/pstream.h"
-#include "plib/pstring.h"
-#include "plib/putil.h"
-
#include "nl_config.h"
-#include "nl_factory.h"
#include "nltypes.h"
+#include "plib/ppreprocessor.h"
+#include "plib/psource.h"
+#include "plib/pstream.h"
+#include "plib/pstring.h"
+
+#include <initializer_list>
#include <memory>
#include <stack>
#include <unordered_map>
#include <vector>
-
//============================================================
-// MACROS / inline netlist definitions
+// MACROS - netlist definitions
//============================================================
-#define NET_STR(x) # x
+#define NET_STR(x) #x
-#define NET_MODEL(model) \
- setup.register_model(model);
+#define NET_MODEL(model) setup.register_model(model);
-#define ALIAS(alias, name) \
- setup.register_alias(# alias, # name);
+#define ALIAS(alias, name) setup.register_alias(#alias, #name);
#define DIPPINS(pin1, ...) \
- setup.register_dippins_arr( # pin1 ", " # __VA_ARGS__);
+ setup.register_dip_alias_arr(#pin1 ", " #__VA_ARGS__);
-/* to be used to reference new library truthtable devices */
-#define NET_REGISTER_DEV(type, name) \
- setup.register_dev(# type, # name);
+// to be used to reference new library truth table devices
+#define NET_REGISTER_DEV(type, name) setup.register_dev(#type, #name);
+
+// name is first element so that __VA_ARGS__ always has one element
+#define NET_REGISTER_DEVEXT(type, ...) \
+ setup.register_dev(#type, {PSTRINGIFY_VA(__VA_ARGS__)});
#define NET_CONNECT(name, input, output) \
- setup.register_link(# name "." # input, # output);
+ setup.register_link(#name "." #input, #output);
#define NET_C(term1, ...) \
- setup.register_link_arr( # term1 ", " # __VA_ARGS__);
+ setup.register_connection_arr(#term1 ", " #__VA_ARGS__);
+
+#define PARAM(name, val) setup.register_param(NET_STR(name), NET_STR(val));
-#define PARAM(name, val) \
- setup.register_param(# name, val);
+#define DEFPARAM(name, val) \
+ setup.register_default_param(NET_STR(name), NET_STR(val));
-#define HINT(name, val) \
- setup.register_param(# name ".HINT_" # val, 1);
+#define HINT(name, val) setup.register_hint(#name, ".HINT_" #val);
#define NETDEV_PARAMI(name, param, val) \
- setup.register_param(# name "." # param, val);
+ setup.register_param(#name "." #param, val);
-#define NETLIST_NAME(name) netlist ## _ ## name
+#define NETLIST_NAME(name) netlist##_##name
#define NETLIST_EXTERNAL(name) \
- void NETLIST_NAME(name)(netlist::nlparse_t &setup);
+ void NETLIST_NAME(name)(netlist::nlparse_t & setup);
#define NETLIST_START(name) \
-void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
-{
-#define NETLIST_END() }
+ void NETLIST_NAME(name)([[maybe_unused]] netlist::nlparse_t & setup)
#define LOCAL_SOURCE(name) \
- setup.register_source(plib::make_unique<netlist::source_proc_t>(# name, &NETLIST_NAME(name)));
+ setup.register_source_proc(#name, &NETLIST_NAME(name));
+
+#define EXTERNAL_SOURCE(name) \
+ setup.register_source_proc(#name, &NETLIST_NAME(name));
+
+#define LOCAL_LIB_ENTRY_2(type, name) \
+ type##_SOURCE(name) setup.register_lib_entry(#name, "", PSOURCELOC());
+
+#define LOCAL_LIB_ENTRY_3(type, name, param_spec) \
+ type##_SOURCE(name) \
+ setup.register_lib_entry(#name, param_spec, PSOURCELOC());
+
+#define LOCAL_LIB_ENTRY(...) PCALLVARARG(LOCAL_LIB_ENTRY_, LOCAL, __VA_ARGS__)
-#define LOCAL_LIB_ENTRY(name) \
- LOCAL_SOURCE(name) \
- setup.register_lib_entry(# name, __FILE__);
+#define EXTERNAL_LIB_ENTRY(...) \
+ PCALLVARARG(LOCAL_LIB_ENTRY_, EXTERNAL, __VA_ARGS__)
-#define INCLUDE(name) \
- setup.include(# name);
+#define INCLUDE(name) setup.include(#name);
#define SUBMODEL(model, name) \
- setup.namespace_push(# name); \
- NETLIST_NAME(model)(setup); \
- setup.namespace_pop();
+ setup.namespace_push(#name); \
+ setup.include(#model); \
+ setup.namespace_pop();
#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
- setup.register_frontier(# attach, r_in, r_out);
+ setup.register_frontier(#attach, PSTRINGIFY_VA(r_in), PSTRINGIFY_VA(r_out));
// -----------------------------------------------------------------------------
-// truthtable defines
+// truth table defines
// -----------------------------------------------------------------------------
-#define TRUTHTABLE_START(cname, in, out, def_params) \
- { \
- netlist::tt_desc desc; \
- desc.name = #cname ; \
- desc.classname = #cname ; \
- desc.ni = in; \
- desc.no = out; \
- desc.def_param = def_params; \
- desc.family = "";
+#define TRUTH_TABLE(cname, in, out, params) \
+ void NETLIST_NAME(cname##_impl)(netlist::nlparse_t & setup, \
+ netlist::tt_desc & desc); \
+ static void NETLIST_NAME(cname)(netlist::nlparse_t & setup) \
+ { \
+ netlist::tt_desc desc{#cname, in, out, "", {}}; \
+ NETLIST_NAME(cname##_impl)(setup, desc); \
+ setup.truth_table_create(desc, params, PSOURCELOC()); \
+ } \
+ static void NETLIST_NAME(cname##_impl)( \
+ [[maybe_unused]] netlist::nlparse_t & setup, netlist::tt_desc & desc)
-#define TT_HEAD(x) \
- desc.desc.emplace_back(x);
+#define TT_HEAD(x) desc.desc.emplace_back(x);
-#define TT_LINE(x) \
- desc.desc.emplace_back(x);
+#define TT_LINE(x) desc.desc.emplace_back(x);
-#define TT_FAMILY(x) \
- desc.family = x;
+#define TT_FAMILY(x) desc.family = x;
-#define TRUTHTABLE_END() \
- setup.tt_factory_create(desc, __FILE__); \
- }
+#define TRUTHTABLE_ENTRY(name) \
+ LOCAL_SOURCE(name) \
+ INCLUDE(name)
namespace netlist
{
- namespace detail {
- class core_terminal_t;
- class net_t;
- } // namespace detail
-
- namespace devices {
- class nld_base_proxy;
- class nld_netlistparams;
- } // namespace devices
-
- class core_device_t;
- class param_t;
- class setup_t;
- class netlist_state_t;
- class netlist_t;
- class logic_family_desc_t;
- class terminal_t;
-
// -----------------------------------------------------------------------------
- // truthtable desc
+ // truth table desc
// -----------------------------------------------------------------------------
struct tt_desc
{
- tt_desc() : ni(0), no(0) { }
- pstring name;
- pstring classname;
- unsigned long ni;
- unsigned long no;
- pstring def_param;
+ pstring name;
+ unsigned long ni;
+ unsigned long no;
+ pstring family;
std::vector<pstring> desc;
- pstring family;
- };
-
- // -----------------------------------------------------------------------------
- // param_ref_t
- // -----------------------------------------------------------------------------
-
- struct param_ref_t
- {
- param_ref_t(const pstring &name, core_device_t &device, param_t &param)
- : m_name(name)
- , m_device(device)
- , m_param(param)
- { }
- pstring m_name;
- core_device_t &m_device;
- param_t &m_param;
- };
-
- // ----------------------------------------------------------------------------------------
- // A Generic netlist sources implementation
- // ----------------------------------------------------------------------------------------
-
- class source_t
- {
- public:
-
- friend class setup_t;
-
- enum type_t
- {
- SOURCE,
- DATA
- };
-
- using list_t = std::vector<plib::unique_ptr<source_t>>;
-
- source_t(const type_t type = SOURCE)
- : m_type(type)
- {}
-
- COPYASSIGNMOVE(source_t, delete)
-
- virtual ~source_t() noexcept = default;
-
- virtual bool parse(nlparse_t &setup, const pstring &name);
-
- type_t type() const { return m_type; }
-
- protected:
- virtual plib::unique_ptr<std::istream> stream(const pstring &name) = 0;
-
- private:
- const type_t m_type;
};
-
// ----------------------------------------------------------------------------------------
- // Collection of models
+ // static compiled netlist.
// ----------------------------------------------------------------------------------------
- class models_t
- {
- public:
- void register_model(const pstring &model_in);
- /* model / family related */
-
- pstring value_str(const pstring &model, const pstring &entity);
-
- nl_double value(const pstring &model, const pstring &entity);
-
- pstring type(const pstring &model) { return value_str(model, "COREMODEL"); }
-
- private:
- using model_map_t = std::unordered_map<pstring, pstring>;
-
- void model_parse(const pstring &model, model_map_t &map);
- pstring model_string(model_map_t &map);
-
- std::unordered_map<pstring, pstring> m_models;
- std::unordered_map<pstring, model_map_t> m_cache;
- };
+ using nlsetup_func = void (*)(nlparse_t &);
// ----------------------------------------------------------------------------------------
// nlparse_t
@@ -236,266 +149,143 @@ namespace netlist
class nlparse_t
{
public:
- using link_t = std::pair<pstring, pstring>;
+ nlparse_t(log_type &log, detail::abstract_t &abstract);
- nlparse_t(setup_t &netlist, log_type &log);
-
- void register_model(const pstring &model_in) { m_models.register_model(model_in); }
- void register_alias(const pstring &alias, const pstring &out);
- void register_dippins_arr(const pstring &terms);
- void register_dev(const pstring &classname, const pstring &name);
- void register_link(const pstring &sin, const pstring &sout);
- void register_link_arr(const pstring &terms);
- void register_param(const pstring &param, const pstring &value);
- void register_param(const pstring &param, const double value);
- void register_lib_entry(const pstring &name, const pstring &sourcefile);
- void register_frontier(const pstring &attach, const double r_IN, const double r_OUT);
+ void register_model(const pstring &model_in);
- /* register a source */
- void register_source(plib::unique_ptr<source_t> &&src)
+ /// \brief Register an aliases
+ ///
+ /// Both alias and points_to are considered to be relative to the
+ /// current netlist naming level and changed to fully qualified names.
+ /// The alias type will be automatically determined. If it is a number,
+ /// it will be PACKAGE_PIN - in all other cases READABILITY.
+ /// This call is only used by the ALIAS macro.
+ /// \param alias the alias to be qualified
+ /// \param points_to the pin aliased
+ void register_alias(const pstring &alias, const pstring &points_to);
+ /// \brief Register an aliases
+ ///
+ /// Both alias and points_to are considered to be relative to the
+ /// current netlist naming level and changed to fully qualified names.
+ /// \param type the alias type see \ref alias_type
+ /// \param alias the alias to be qualified
+ /// \param points_to the pin aliased
+ void register_alias(detail::alias_type type, const pstring &alias,
+ const pstring &points_to);
+ /// \brief Register an aliases where alias and references are fully qualified names
+ /// \param type the alias type see \ref alias_type
+ /// \param alias the alias to be qualified
+ /// \param points_to the pin aliased
+ void register_fqn_alias(detail::alias_type type, const pstring &alias,
+ const pstring &points_to);
+ void register_dip_alias_arr(const pstring &terms);
+
+ // last argument only needed by nltool
+ void register_dev(const pstring &classname, const pstring &name,
+ const std::vector<pstring> &params_and_connections,
+ factory::element_t **factory_element = nullptr);
+ void register_dev(const pstring &classname,
+ std::initializer_list<const char *> more_parameters);
+ void register_dev(const pstring &classname, const pstring &name)
{
- m_sources.push_back(std::move(src));
+ register_dev(classname, name, std::vector<pstring>());
}
- void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
-
- /* handle namespace */
-
- void namespace_push(const pstring &aname);
- void namespace_pop();
-
- /* include other files */
-
- void include(const pstring &netlist_name);
-
- pstring build_fqn(const pstring &obj_name) const;
- void register_alias_nofqn(const pstring &alias, const pstring &out);
+ void
+ register_hint(const pstring &object_name, const pstring &hint_name);
- /* also called from devices for latebinding connected terminals */
- void register_link_fqn(const pstring &sin, const pstring &sout);
+ void register_connection(const pstring &sin, const pstring &sout);
+ void register_connection_arr(const pstring &terms);
+ // also called from devices for late binding connected terminals
+ void register_connection_fqn(const pstring &sin, const pstring &sout);
- /* used from netlist.cpp (mame) */
- bool device_exists(const pstring &name) const;
+ void register_param(const pstring &param, const pstring &value);
- /* FIXME: used by source_t - need a different approach at some time */
- bool parse_stream(plib::unique_ptr<std::istream> &&istrm, const pstring &name);
+ // DEFPARAM support
+ void register_default_param(const pstring &name, const pstring &def);
- void add_define(const pstring &def, const pstring &val)
+ template <typename T>
+ std::enable_if_t<plib::is_arithmetic<T>::value>
+ register_param(const pstring &param, T value)
{
- m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)});
+ register_param_fp(param, plib::narrow_cast<nl_fptype>(value));
}
- void add_define(const pstring &defstr);
-
- factory::list_t &factory() { return m_factory; }
- const factory::list_t &factory() const { return m_factory; }
-
- log_type &log() { return m_log; }
- const log_type &log() const { return m_log; }
-
- /* FIXME: sources may need access to the netlist parent type
- * since they may be created in a context in which they don't
- * have access to their environment.
- * Example is the MAME memregion source.
- * We thus need a better approach to creating netlists in a context
- * other than static procedures.
- */
- setup_t &setup() { return m_setup; }
- const setup_t &setup() const { return m_setup; }
-
- models_t &models() { return m_models; }
- const models_t &models() const { return m_models; }
-
- protected:
- models_t m_models;
- std::stack<pstring> m_namespace_stack;
- std::unordered_map<pstring, pstring> m_alias;
- std::vector<link_t> m_links;
- std::unordered_map<pstring, pstring> m_param_values;
-
- source_t::list_t m_sources;
-
- factory::list_t m_factory;
+ void register_lib_entry(const pstring &name, const pstring &def_params,
+ plib::source_location &&loc);
- /* need to preserve order of device creation ... */
- std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
+ void register_frontier(const pstring &attach, const pstring &r_IN,
+ const pstring &r_OUT);
+ // register a source
+ template <typename S, typename... Args>
+ void register_source(Args &&...args)
+ {
+ m_sources.add_source<S>(std::forward<Args>(args)...);
+ }
- private:
- plib::ppreprocessor::defines_map_type m_defines;
-
- setup_t &m_setup;
- log_type &m_log;
- unsigned m_frontier_cnt;
- };
-
- // ----------------------------------------------------------------------------------------
- // setup_t
- // ----------------------------------------------------------------------------------------
-
- class setup_t : public nlparse_t
- {
- public:
-
- explicit setup_t(netlist_state_t &nlstate);
- ~setup_t() noexcept;
-
- COPYASSIGNMOVE(setup_t, delete)
-
- netlist_state_t &nlstate() { return m_nlstate; }
- const netlist_state_t &nlstate() const { return m_nlstate; }
-
- void register_param_t(const pstring &name, param_t &param);
-
- pstring get_initial_param_val(const pstring &name, const pstring &def) const;
-
- void register_term(detail::core_terminal_t &obj);
-
- void remove_connections(const pstring &attach);
-
- bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
-
- param_t *find_param(const pstring &param_in, bool required = true) const;
-
- /* get family */
- const logic_family_desc_t *family_from_model(const pstring &model);
-
- void register_dynamic_log_devices();
- void resolve_inputs();
-
- plib::unique_ptr<std::istream> get_data_stream(const pstring &name);
-
- factory::list_t &factory() { return m_factory; }
- const factory::list_t &factory() const { return m_factory; }
-
- /* helper - also used by nltool */
- pstring resolve_alias(const pstring &name) const;
- pstring de_alias(const pstring &alias) const;
-
- /* needed by nltool */
- std::vector<pstring> get_terminals_for_device_name(const pstring &devname) const;
-
- log_type &log();
- const log_type &log() const;
-
- /* needed by proxy */
- detail::core_terminal_t *find_terminal(const pstring &outname_in, const detail::terminal_type atype, bool required = true) const;
- detail::core_terminal_t *find_terminal(const pstring &outname_in, bool required = true) const;
-
- /* core net handling */
-
- void delete_empty_nets();
-
- /* run preparation */
-
- void prepare_to_run();
-
- /* validation */
-
- void enable_validation() { m_validation = true; }
- bool is_validation() const { return m_validation; }
- private:
-
- void merge_nets(detail::net_t &thisnet, detail::net_t &othernet);
-
- void connect_terminals(detail::core_terminal_t &in, detail::core_terminal_t &out);
- void connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out);
- void connect_terminal_output(terminal_t &in, detail::core_terminal_t &out);
- void connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp);
- bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
-
- // helpers
- pstring termtype_as_str(detail::core_terminal_t &in) const;
+ void register_source_proc(const pstring &name, nlsetup_func func);
- devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
- devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
+ void truth_table_create(tt_desc &desc, const pstring &def_params,
+ plib::source_location &&loc);
- std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
+ // include other files
- netlist_state_t &m_nlstate;
- devices::nld_netlistparams *m_netlist_params;
- std::unordered_map<pstring, param_ref_t> m_params;
+ void include(const pstring &netlist_name);
- unsigned m_proxy_cnt;
- bool m_validation;
- };
+ // handle namespace
- // ----------------------------------------------------------------------------------------
- // base sources
- // ----------------------------------------------------------------------------------------
+ void namespace_push(const pstring &aname);
+ void namespace_pop();
- class source_string_t : public source_t
- {
- public:
+ // FIXME: used by source_t - need a different approach at some time
+ bool parse_stream(plib::istream_uptr &&in_stream, const pstring &name);
+ bool parse_tokens(const plib::detail::token_store_t &tokens,
+ const pstring &name);
- source_string_t(const pstring &source)
- : source_t(), m_str(source)
+ template <typename S, typename... Args>
+ void add_include(Args &&...args)
{
+ m_includes.add_source<S>(std::forward<Args>(args)...);
}
- protected:
- plib::unique_ptr<std::istream> stream(const pstring &name) override;
-
- private:
- pstring m_str;
- };
-
- class source_file_t : public source_t
- {
- public:
-
- source_file_t(const pstring &filename)
- : source_t(), m_filename(filename)
+ void add_define(const pstring &def, const pstring &val)
{
+ m_defines.insert({def, plib::ppreprocessor::define_t(def, val)});
}
- protected:
- plib::unique_ptr<std::istream> stream(const pstring &name) override;
+ void add_define(const pstring &define);
- private:
- pstring m_filename;
- };
+ // register a list of logs
+ void register_dynamic_log_devices(const std::vector<pstring> &log_list);
- class source_mem_t : public source_t
- {
- public:
- source_mem_t(const char *mem)
- : source_t(), m_str(mem)
- {
- }
+ factory::list_t &factory() noexcept;
+ const factory::list_t &factory() const noexcept;
- protected:
- plib::unique_ptr<std::istream> stream(const pstring &name) override;
+ log_type &log() noexcept { return m_log; }
+ const log_type &log() const noexcept { return m_log; }
- private:
- pstring m_str;
- };
+ plib::istream_uptr get_data_stream(const pstring &name);
- class source_proc_t : public source_t
- {
- public:
- source_proc_t(const pstring &name, void (*setup_func)(nlparse_t &))
- : source_t(),
- m_setup_func(setup_func),
- m_setup_func_name(name)
- {
- }
+ private:
+ pstring namespace_prefix() const;
+ pstring build_fqn(const pstring &obj_name) const;
+ void register_param_fp(const pstring &param, nl_fptype value);
+ bool device_exists(const pstring &name) const;
- bool parse(nlparse_t &setup, const pstring &name) override;
+ // FIXME: stale? - remove later
+ void remove_connections(const pstring &pin);
- protected:
- plib::unique_ptr<std::istream> stream(const pstring &name) override;
+ plib::ppreprocessor::defines_map_type m_defines;
+ plib::psource_collection_t m_includes;
+ std::stack<pstring> m_namespace_stack;
+ plib::psource_collection_t m_sources;
+ detail::abstract_t &m_abstract;
- private:
- void (*m_setup_func)(nlparse_t &);
- pstring m_setup_func_name;
+ log_type &m_log;
+ unsigned m_frontier_cnt;
};
- // -----------------------------------------------------------------------------
- // inline implementations
- // -----------------------------------------------------------------------------
-
} // namespace netlist
-
-#endif /* NLSETUP_H_ */
+#endif // NLSETUP_H_