diff options
Diffstat (limited to 'src/lib/netlist/nl_setup.h')
-rw-r--r-- | src/lib/netlist/nl_setup.h | 566 |
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 ¶m) - : 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 ¶m, const pstring &value); - void register_param(const pstring ¶m, 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> ¶ms_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 ¶m, 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 ¶m, 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 ¶m); - - 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 ¶m_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 ¶m, 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_ |