// 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 "../nl_factory.h" #include "../nl_setup.h" #include "../nltypes.h" //#include "../plib/ppreprocessor.h" #include "../plib/pstream.h" #include "../plib/pstring.h" #include #include #include #include #include namespace netlist { // ---------------------------------------------------------------------------------------- // Collection of models // ---------------------------------------------------------------------------------------- class models_t { public: using raw_map_t = std::unordered_map; using map_t = std::unordered_map; 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); std::vector known_models() const { std::vector ret; for (const auto &e : m_models) ret.push_back(e.first); return ret; } private: void model_parse(const pstring &model, map_t &map); const raw_map_t &m_models; std::unordered_map m_cache; }; namespace detail { // ----------------------------------------------------------------------------- // abstract_t // ----------------------------------------------------------------------------- struct abstract_t { using link_t = std::pair; abstract_t(log_type &log) : m_factory(log) { } std::unordered_map m_alias; std::vector m_links; std::unordered_map m_param_values; models_t::raw_map_t m_models; // need to preserve order of device creation ... std::vector> m_device_factory; // lifetime control only - can be cleared before run std::vector> m_defparams; std::unordered_map 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); param_ref_t find_param(const pstring ¶m_in) const; // needed by nltool std::vector 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; // 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); bool connect(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 m_terminals; std::unordered_map m_connected_terminals; std::unordered_map m_params; std::unordered_map m_proxies; std::vector> 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: plib::istream_uptr 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: plib::istream_uptr stream(const pstring &name) override; private: pstring m_filename; }; class source_pattern_t : public source_netlist_t { public: explicit source_pattern_t(const pstring &pat) : m_pattern(pat) { } protected: plib::istream_uptr stream(const pstring &name) override; private: pstring m_pattern; }; class source_mem_t : public source_netlist_t { public: explicit source_mem_t(const char *mem) : m_str(mem) { } protected: plib::istream_uptr stream(const pstring &name) override; private: std::string 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: plib::istream_uptr stream(const pstring &name) override; private: nlsetup_func m_setup_func; pstring m_setup_func_name; }; class source_token_t : public source_netlist_t { public: source_token_t(const pstring &name, const parser_t::token_store &store) : m_store(store) , m_name(name) { } bool parse(nlparse_t &setup, const pstring &name) override; protected: plib::istream_uptr stream(const pstring &name) override; private: parser_t::token_store m_store; pstring m_name; }; } // namespace netlist #endif // NL_CORE_SETUP_H_