summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-08-10 21:13:27 +0200
committer couriersud <couriersud@gmx.org>2020-08-12 20:17:10 +0200
commit167da15753419aceb58cc3dea4abc042f9be0185 (patch)
tree498b9edd7eb081fd944870ea32ed15c50459f4a0
parent4985e1e9b97637cc66dbc98cdce327349f18551b (diff)
netlist: improve parsing performance
* preparational work for easier device addition.
-rw-r--r--src/lib/netlist/core/setup.h19
-rw-r--r--src/lib/netlist/devices/net_lib.h5
-rw-r--r--src/lib/netlist/macro/nlm_base_lib.cpp20
-rw-r--r--src/lib/netlist/nl_base.cpp17
-rw-r--r--src/lib/netlist/nl_errstr.h1
-rw-r--r--src/lib/netlist/nl_parser.cpp40
-rw-r--r--src/lib/netlist/nl_parser.h8
-rw-r--r--src/lib/netlist/nl_setup.cpp39
-rw-r--r--src/lib/netlist/nl_setup.h4
9 files changed, 132 insertions, 21 deletions
diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h
index 5048c2ae765..20fc9cb3678 100644
--- a/src/lib/netlist/core/setup.h
+++ b/src/lib/netlist/core/setup.h
@@ -333,6 +333,25 @@ namespace netlist
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:
+ stream_ptr stream(const pstring &name) override;
+
+ private:
+ parser_t::token_store m_store;
+ pstring m_name;
+ };
+
} // namespace netlist
diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h
index a5779cf162e..a891b8f1b0b 100644
--- a/src/lib/netlist/devices/net_lib.h
+++ b/src/lib/netlist/devices/net_lib.h
@@ -29,11 +29,6 @@
#endif
NETLIST_EXTERNAL(base_lib)
-NETLIST_EXTERNAL(cd4xxx_lib)
-NETLIST_EXTERNAL(opamp_lib)
-NETLIST_EXTERNAL(otheric_lib)
-NETLIST_EXTERNAL(ttl74xx_lib)
-NETLIST_EXTERNAL(roms_lib)
#if NL_AUTO_DEVICES
#include "nld_devinc.h"
diff --git a/src/lib/netlist/macro/nlm_base_lib.cpp b/src/lib/netlist/macro/nlm_base_lib.cpp
index 04676fc5338..51969930564 100644
--- a/src/lib/netlist/macro/nlm_base_lib.cpp
+++ b/src/lib/netlist/macro/nlm_base_lib.cpp
@@ -3,6 +3,16 @@
#include "netlist/devices/net_lib.h"
/* ----------------------------------------------------------------------------
+ * External declarations
+ * ---------------------------------------------------------------------------*/
+
+NETLIST_EXTERNAL(cd4xxx_lib)
+NETLIST_EXTERNAL(opamp_lib)
+NETLIST_EXTERNAL(otheric_lib)
+NETLIST_EXTERNAL(ttl74xx_lib)
+NETLIST_EXTERNAL(roms_lib)
+
+/* ----------------------------------------------------------------------------
* Diode Models
* ---------------------------------------------------------------------------*/
@@ -107,11 +117,11 @@ NETLIST_START(base_lib)
LOCAL_SOURCE(mosfet_models)
LOCAL_SOURCE(family_models)
- LOCAL_SOURCE(ttl74xx_lib)
- LOCAL_SOURCE(cd4xxx_lib)
- LOCAL_SOURCE(opamp_lib)
- LOCAL_SOURCE(otheric_lib)
- LOCAL_SOURCE(roms_lib)
+ EXTERNAL_SOURCE(ttl74xx_lib)
+ EXTERNAL_SOURCE(cd4xxx_lib)
+ EXTERNAL_SOURCE(opamp_lib)
+ EXTERNAL_SOURCE(otheric_lib)
+ EXTERNAL_SOURCE(roms_lib)
INCLUDE(diode_models)
INCLUDE(bjt_models)
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 532a3f98f47..c8684baccbf 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -144,17 +144,18 @@ namespace netlist
NETLIST_NAME(base_lib)(m_setup->parser());
#else
// FIXME: This is very slow - need optimized parsing scanning
-#if 0
- m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp");
+#if 1
+ m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{1}.cpp");
+ m_setup->parser().include("base_lib");
#else
pstring dir = "src/lib/netlist/macro/";
//m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_base.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_opamp.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_roms.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_cd4xxx.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_other.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_ttl74xx.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_base_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_opamp_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_roms_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_cd4xxx_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_otheric_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(dir + "nlm_ttl74xx_lib.cpp");
m_setup->parser().include("base_lib");
#endif
#endif
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index 67510fbf453..c0097cadb15 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -43,6 +43,7 @@ namespace netlist
PERRMSGV(MF_UNEXPECTED_NETLIST_END, 0, "Unexpected NETLIST_END")
PERRMSGV(MF_UNEXPECTED_END_OF_FILE, 0, "Unexpected end of file, missing NETLIST_END")
PERRMSGV(MF_UNEXPECTED_NETLIST_START, 0, "Unexpected NETLIST_START")
+ PERRMSGV(MF_UNEXPECTED_NETLIST_EXTERNAL, 0, "Unexpected NETLIST_EXTERNAL within a netlist")
PERRMSGV(MF_EXPECTED_NETLIST_START_1, 1, "Expected NETLIST_START but got {1}")
PERRMSGV(MF_EXPECTED_IDENTIFIER_GOT_1, 1, "Expected an identifier, but got {1}")
PERRMSGV(MF_EXPECTED_COMMA_OR_RP_1, 1, "Expected comma or right parenthesis but found <{1}>")
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 8edecb84a3a..f86b3d129eb 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -47,6 +47,8 @@ parser_t::parser_t(nlparse_t &setup)
m_tok_SUBMODEL = m_tokenizer.register_token("SUBMODEL");
m_tok_NETLIST_START = m_tokenizer.register_token("NETLIST_START");
m_tok_NETLIST_END = m_tokenizer.register_token("NETLIST_END");
+ m_tok_NETLIST_EXTERNAL = m_tokenizer.register_token("NETLIST_EXTERNAL");
+ m_tok_EXTERNAL_SOURCE = m_tokenizer.register_token("EXTERNAL_SOURCE");
m_tok_TRUTHTABLE_START = m_tokenizer.register_token("TRUTHTABLE_START");
m_tok_TRUTHTABLE_END = m_tokenizer.register_token("TRUTHTABLE_END");
m_tok_TT_HEAD = m_tokenizer.register_token("TT_HEAD");
@@ -75,7 +77,7 @@ void parser_t::parse_tokens(plib::psource_t::stream_ptr &&strm, token_store &tok
m_tokenizer.append_to_store(&u8reader, tokstor);
}
-bool parser_t::parse(token_store &tokstor, const pstring &nlname)
+bool parser_t::parse(const token_store &tokstor, const pstring &nlname)
{
set_token_source(&tokstor);
@@ -134,6 +136,14 @@ bool parser_t::parse(token_store &tokstor, const pstring &nlname)
m_cur_local->push_back(token_t(m_tok_paren_right));
in_nl = true;
}
+ else if (token.is(m_tok_NETLIST_EXTERNAL))
+ {
+ if (in_nl)
+ error (MF_UNEXPECTED_NETLIST_EXTERNAL());
+ require_token(m_tok_paren_left);
+ token_t name = get_token();
+ require_token(m_tok_paren_right);
+ }
else if (!in_nl)
{
if (!token.is(m_tok_static))
@@ -179,13 +189,17 @@ void parser_t::parse_netlist(const pstring &nlname)
net_include();
else if (token.is(m_tok_LOCAL_SOURCE))
net_local_source();
+ else if (token.is(m_tok_EXTERNAL_SOURCE))
+ net_external_source();
else if (token.is(m_tok_TRUTHTABLE_START))
net_truthtable_start(nlname);
else if (token.is(m_tok_LOCAL_LIB_ENTRY))
{
require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ register_local_as_source(name);
// FIXME: Need to pass in parameter definition FIXME: get line number right
- m_setup.register_lib_entry(get_identifier(), "", plib::source_location("parser: " + nlname, 1));
+ m_setup.register_lib_entry(name, "", plib::source_location("parser: " + nlname, 1));
require_token(m_tok_paren_right);
}
else if (token.is(m_tok_NET_REGISTER_DEV))
@@ -321,6 +335,28 @@ void parser_t::net_local_source()
pstring name(get_identifier());
require_token(m_tok_paren_right);
+ register_local_as_source(name);
+}
+
+void parser_t::register_local_as_source(const pstring &name)
+{
+ auto p = m_local.find(name);
+ if (p != m_local.end())
+ {
+ printf("found %s\n", name.c_str());
+ m_setup.register_source<source_token_t>(name, p->second);
+ }
+ else
+ printf("argh %s\n", name.c_str());
+}
+
+void parser_t::net_external_source()
+{
+ // This directive is only for hardcoded netlists. Ignore it here.
+ require_token(m_tok_paren_left);
+ pstring name(get_identifier());
+ require_token(m_tok_paren_right);
+
}
void parser_t::net_alias()
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index c552663af6a..5e00c7c8470 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -26,7 +26,7 @@ namespace netlist
parser_t(nlparse_t &setup);
bool parse(plib::psource_t::stream_ptr &&strm, const pstring &nlname);
- bool parse(token_store &tokstor, const pstring &nlname);
+ bool parse(const token_store &tokstor, const pstring &nlname);
void parse_tokens(plib::psource_t::stream_ptr &&strm, token_store &tokstor);
protected:
@@ -44,12 +44,16 @@ namespace netlist
void net_submodel();
void net_include();
void net_local_source();
+ void net_external_source();
void net_register_dev();
void net_truthtable_start(const pstring &nlname);
void verror(const pstring &msg) override;
private:
+ void register_local_as_source(const pstring &name);
+
pstring stringify_expression(token_t &tok);
+
token_id_t m_tok_paren_left;
token_id_t m_tok_paren_right;
token_id_t m_tok_comma;
@@ -65,8 +69,10 @@ namespace netlist
token_id_t m_tok_NET_REGISTER_DEV;
token_id_t m_tok_NETLIST_START;
token_id_t m_tok_NETLIST_END;
+ token_id_t m_tok_NETLIST_EXTERNAL;
token_id_t m_tok_SUBMODEL;
token_id_t m_tok_INCLUDE;
+ token_id_t m_tok_EXTERNAL_SOURCE;
token_id_t m_tok_LOCAL_SOURCE;
token_id_t m_tok_LOCAL_LIB_ENTRY;
token_id_t m_tok_TRUTHTABLE_START;
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index aed7a509d5e..32ccfb5725f 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -352,8 +352,15 @@ namespace netlist
return false;
}
+ bool nlparse_t::parse_tokens(const parser_t::token_store &tokens, const pstring &name)
+ {
+ parser_t parser(*this);
+ return parser.parse(tokens, name);
+ }
+
bool nlparse_t::parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name)
{
+#if 0
auto key = istrm.filename();
if (m_source_cache.find(key) != m_source_cache.end())
@@ -374,6 +381,18 @@ namespace netlist
parser.parse_tokens(plib::psource_t::stream_ptr(std::move(abc), key), st);
return parser.parse(st, name);
}
+#else
+ plib::ppreprocessor y(m_includes, &m_defines);
+ y.process(std::move(istrm), istrm.filename());
+
+ auto abc = std::make_unique<std::stringstream>();
+ plib::copystream(*abc, y);
+
+ parser_t::token_store st;
+ parser_t parser(*this);
+ parser.parse_tokens(plib::psource_t::stream_ptr(std::move(abc), istrm.filename()), st);
+ return parser.parse(st, name);
+#endif
}
void nlparse_t::add_define(const pstring &defstr)
@@ -1712,8 +1731,10 @@ source_file_t::stream_ptr source_pattern_t::stream(const pstring &name)
{
pstring filename = plib::pfmt(m_pattern)(name);
auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(filename));
+ printf("checking <%s> %s\n", name.c_str(), filename.c_str());
if (f->is_open())
{
+ printf("found\n");
return stream_ptr(std::move(f), filename);
}
else
@@ -1738,5 +1759,23 @@ source_proc_t::stream_ptr source_proc_t::stream(const pstring &name)
return stream_ptr();
}
+bool source_token_t::parse(nlparse_t &setup, const pstring &name)
+{
+ if (name == m_name)
+ {
+ auto ret = setup.parse_tokens(m_store, name);
+ printf("parsed tokens: %s %d\n", name.c_str(), (int) ret);
+ return ret;
+ }
+
+ return false;
+}
+
+source_proc_t::stream_ptr source_token_t::stream(const pstring &name)
+{
+ plib::unused_var(name);
+ return stream_ptr();
+}
+
} // namespace netlist
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 31fad70a746..964cb0d19d2 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -83,6 +83,9 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
#define LOCAL_SOURCE(name) \
setup.register_source_proc(# name, &NETLIST_NAME(name));
+#define EXTERNAL_SOURCE(name) \
+ setup.register_source_proc(# name, &NETLIST_NAME(name));
+
// FIXME: Need to pass in parameter definition
#define LOCAL_LIB_ENTRY_1(name) \
LOCAL_SOURCE(name) \
@@ -230,6 +233,7 @@ namespace netlist
// FIXME: used by source_t - need a different approach at some time
bool parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name);
+ bool parse_tokens(const parser_t::token_store &tokens, const pstring &name);
template <typename S, typename... Args>
void add_include(Args&&... args)