diff options
Diffstat (limited to 'src/lib/netlist/core/setup.h')
-rw-r--r-- | src/lib/netlist/core/setup.h | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h new file mode 100644 index 00000000000..d21b948f4ee --- /dev/null +++ b/src/lib/netlist/core/setup.h @@ -0,0 +1,323 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +/// +/// \file setup.h +/// + +#ifndef NL_CORE_SETUP_H_ +#define NL_CORE_SETUP_H_ + +#include "../nl_config.h" +#include "../nltypes.h" +#include "../nl_factory.h" +#include "../nl_setup.h" + +#include "../plib/ppreprocessor.h" +#include "../plib/pstream.h" +#include "../plib/pstring.h" + +#include <initializer_list> +#include <memory> +#include <stack> +#include <unordered_map> +#include <vector> + + +namespace netlist +{ + + // ---------------------------------------------------------------------------------------- + // Collection of models + // ---------------------------------------------------------------------------------------- + + class models_t + { + public: + using raw_map_t = std::unordered_map<pstring, pstring>; + using map_t = std::unordered_map<pstring, pstring>; + class model_t + { + public: + model_t(const pstring &model, const map_t &map) + : m_model(model), m_map(map) { } + + pstring value_str(const pstring &entity) const; + + nl_fptype value(const pstring &entity) const; + + pstring type() const { return value_str("COREMODEL"); } + + private: + static pstring model_string(const map_t &map); + + const pstring m_model; // only for error messages + const map_t &m_map; + }; + + models_t(const raw_map_t &models) + : m_models(models) + {} + + model_t get_model(const pstring &model); + + private: + + void model_parse(const pstring &model, map_t &map); + + const raw_map_t &m_models; + std::unordered_map<pstring, map_t> m_cache; + }; + + namespace detail + { + // ----------------------------------------------------------------------------- + // abstract_t + // ----------------------------------------------------------------------------- + + struct abstract_t + { + using link_t = std::pair<pstring, pstring>; + + abstract_t(log_type &log) : m_factory(log) { } + std::unordered_map<pstring, pstring> m_alias; + std::vector<link_t> m_links; + std::unordered_map<pstring, pstring> m_param_values; + models_t::raw_map_t m_models; + + // need to preserve order of device creation ... + std::vector<std::pair<pstring, factory::element_t *>> m_device_factory; + // lifetime control only - can be cleared before run + std::vector<std::pair<pstring, pstring>> m_defparams; + std::unordered_map<pstring, bool> m_hints; + factory::list_t m_factory; + }; + } // namespace detail + + // ----------------------------------------------------------------------------- + // param_ref_t + // ----------------------------------------------------------------------------- + + struct param_ref_t + { + param_ref_t() noexcept : m_device(nullptr), m_param(nullptr) {} + param_ref_t(core_device_t &device, param_t ¶m) noexcept + : m_device(&device) + , m_param(¶m) + { } + + ~param_ref_t() = default; + PCOPYASSIGNMOVE(param_ref_t, default) + + const core_device_t &device() const noexcept { return *m_device; } + param_t ¶m() const noexcept { return *m_param; } + + bool is_valid() const noexcept { return (m_device != nullptr) && (m_param != nullptr); } + private: + core_device_t *m_device; + param_t *m_param; + }; + + // ---------------------------------------------------------------------------------------- + // setup_t + // ---------------------------------------------------------------------------------------- + + class setup_t + { + public: + + explicit setup_t(netlist_state_t &nlstate); + ~setup_t() noexcept = default; + + PCOPYASSIGNMOVE(setup_t, delete) + + // called from param_t creation + void register_param_t(param_t ¶m); + pstring get_initial_param_val(const pstring &name, const pstring &def) const; + + void register_term(detail::core_terminal_t &term); + void register_term(terminal_t &term, terminal_t &other_term); + + // called from net_splitter + terminal_t *get_connected_terminal(const terminal_t &term) const noexcept + { + auto ret(m_connected_terminals.find(&term)); + return (ret != m_connected_terminals.end()) ? ret->second : nullptr; + } + + // get family -> truthtable + const logic_family_desc_t *family_from_model(const pstring &model); + + // FIXME: return param_ref_t + param_ref_t find_param(const pstring ¶m_in) const; + // needed by nltool + std::vector<pstring> get_terminals_for_device_name(const pstring &devname) const; + + // needed by proxy device to check power terminals + detail::core_terminal_t *find_terminal(const pstring &terminal_in, detail::terminal_type atype, bool required = true) const; + detail::core_terminal_t *find_terminal(const pstring &terminal_in, bool required = true) const; + pstring de_alias(const pstring &alias) const; + // FIXME: only needed by solver code outside of setup_t + bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2); + + // run preparation + + void prepare_to_run(); + + models_t &models() noexcept { return m_models; } + const models_t &models() const noexcept { return m_models; } + + netlist_state_t &nlstate() { return m_nlstate; } + const netlist_state_t &nlstate() const { return m_nlstate; } + + nlparse_t &parser() { return m_parser; } + const nlparse_t &parser() const { return m_parser; } + + log_type &log() noexcept; + const log_type &log() const noexcept; + + // FIXME: needed from matrix_solver_t + void add_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false); + + private: + + void resolve_inputs(); + pstring resolve_alias(const pstring &name) const; + + void merge_nets(detail::net_t &thisnet, detail::net_t &othernet); + + void connect_terminals(detail::core_terminal_t &t1, detail::core_terminal_t &t2); + 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 + static pstring termtype_as_str(detail::core_terminal_t &in); + + devices::nld_base_proxy *get_d_a_proxy(const detail::core_terminal_t &out); + devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp); + detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term); + + // net manipulations + + void remove_terminal(detail::net_t &net, detail::core_terminal_t &terminal) noexcept(false); + void move_connections(detail::net_t &net, detail::net_t &dest_net); + void delete_empty_nets(); + + detail::abstract_t m_abstract; + nlparse_t m_parser; + netlist_state_t &m_nlstate; + + models_t m_models; + + // FIXME: currently only used during setup + devices::nld_netlistparams * m_netlist_params; + + // FIXME: can be cleared before run + std::unordered_map<pstring, detail::core_terminal_t *> m_terminals; + std::unordered_map<const terminal_t *, terminal_t *> m_connected_terminals; + std::unordered_map<pstring, param_ref_t> m_params; + std::unordered_map<const detail::core_terminal_t *, + devices::nld_base_proxy *> m_proxies; + std::vector<host_arena::unique_ptr<param_t>> m_defparam_lifetime; + + unsigned m_proxy_cnt; + }; + + // ---------------------------------------------------------------------------------------- + // Specific netlist psource_t implementations + // ---------------------------------------------------------------------------------------- + + class source_netlist_t : public plib::psource_t + { + public: + + source_netlist_t() = default; + + PCOPYASSIGNMOVE(source_netlist_t, delete) + ~source_netlist_t() noexcept override = default; + + virtual bool parse(nlparse_t &setup, const pstring &name); + }; + + class source_data_t : public plib::psource_t + { + public: + + source_data_t() = default; + + PCOPYASSIGNMOVE(source_data_t, delete) + ~source_data_t() noexcept override = default; + }; + + class source_string_t : public source_netlist_t + { + public: + + explicit source_string_t(const pstring &source) + : m_str(source) + { + } + + protected: + stream_ptr stream(const pstring &name) override; + + private: + pstring m_str; + }; + + class source_file_t : public source_netlist_t + { + public: + + explicit source_file_t(const pstring &filename) + : m_filename(filename) + { + } + + protected: + stream_ptr stream(const pstring &name) override; + + private: + pstring m_filename; + }; + + class source_mem_t : public source_netlist_t + { + public: + explicit source_mem_t(const char *mem) + : m_str(mem) + { + } + + protected: + stream_ptr stream(const pstring &name) override; + + private: + pstring m_str; + }; + + class source_proc_t : public source_netlist_t + { + public: + source_proc_t(const pstring &name, nlsetup_func setup_func) + : m_setup_func(setup_func) + , m_setup_func_name(name) + { + } + + bool parse(nlparse_t &setup, const pstring &name) override; + + protected: + stream_ptr stream(const pstring &name) override; + + private: + nlsetup_func m_setup_func; + pstring m_setup_func_name; + }; + +} // namespace netlist + + +#endif // NL_CORE_SETUP_H_ |