diff options
author | couriersud <couriersud@arcor.de> | 2015-05-29 02:40:39 +0200 |
---|---|---|
committer | couriersud <couriersud@arcor.de> | 2015-05-29 16:42:29 +0200 |
commit | 84f26ad714a334c787d3867b48d7a4592a2d4a66 (patch) | |
tree | fe4e3afbd4465bda4f34e3bbc01be1646fdb115e | |
parent | e1d1a6b1f2d10d54f9827cc0c7e0c6464bffec63 (diff) |
First version of a eagle to netlist converter. (nw)
-rw-r--r-- | src/emu/netlist/plib/poptions.h | 24 | ||||
-rw-r--r-- | src/emu/netlist/plib/pparser.h | 5 | ||||
-rw-r--r-- | src/tools/nltool.c | 346 |
3 files changed, 39 insertions, 336 deletions
diff --git a/src/emu/netlist/plib/poptions.h b/src/emu/netlist/plib/poptions.h index 7803a315d94..b082504930d 100644 --- a/src/emu/netlist/plib/poptions.h +++ b/src/emu/netlist/plib/poptions.h @@ -59,6 +59,30 @@ private: pstring m_val; }; +class poption_str_limit : public poption +{ +public: + poption_str_limit(pstring ashort, pstring along, pstring defval, pstring limit, pstring help, poptions *parent = NULL) + : poption(ashort, along, help, true, parent), m_val(defval), m_limit(limit, ":") + {} + + virtual int parse(pstring argument) + { + if (m_limit.contains(argument)) + { + m_val = argument; + return 0; + } + else + return 1; + } + + pstring operator ()() { return m_val; } +private: + pstring m_val; + pstring_list_t m_limit; +}; + class poption_bool : public poption { public: diff --git a/src/emu/netlist/plib/pparser.h b/src/emu/netlist/plib/pparser.h index a9f538eeaef..4a3305094aa 100644 --- a/src/emu/netlist/plib/pparser.h +++ b/src/emu/netlist/plib/pparser.h @@ -100,20 +100,21 @@ public: void set_identifier_chars(pstring s) { m_identifier_chars = s; } void set_number_chars(pstring st, pstring rem) { m_number_chars_start = st; m_number_chars = rem; } + void set_string_char(char c) { m_string = c; } void set_whitespace(pstring s) { m_whitespace = s; } void set_comment(pstring start, pstring end, pstring line) { m_tok_comment_start = register_token(start); m_tok_comment_end = register_token(end); m_tok_line_comment = register_token(line); - m_string = '"'; } token_t get_token_internal(); void error(const char *format, ...) ATTR_PRINTF(2,3); -protected: void reset(const char *p) { m_px = p; m_line = 1; m_line_ptr = p; } + +protected: virtual void verror(pstring msg, int line_num, pstring line) = 0; private: diff --git a/src/tools/nltool.c b/src/tools/nltool.c index 884c6b3c2fc..cd0cc5e62ad 100644 --- a/src/tools/nltool.c +++ b/src/tools/nltool.c @@ -23,6 +23,7 @@ #include "nl_factory.h" #include "nl_parser.h" #include "devices/net_lib.h" +#include "tools/nl_convert.h" #ifdef PSTANDALONE_PROVIDED @@ -101,6 +102,7 @@ public: opt_name("n", "name", "", "netlist in file to run; default is first one", this), opt_logs("l", "logs", "", "colon separated list of terminals to log", this), opt_file("f", "file", "-", "file to process (default is stdin)", this), + opt_type("y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle", this), opt_cmd ("c", "cmd", "run", "run|convert|listdevices", this), opt_verb("v", "verbose", "be verbose - this produces lots of output", this), opt_help("h", "help", "display help", this) @@ -110,6 +112,7 @@ public: poption_str opt_name; poption_str opt_logs; poption_str opt_file; + poption_str_limit opt_type; poption_str opt_cmd; poption_bool opt_verb; poption_bool opt_help; @@ -340,338 +343,6 @@ static void listdevices() } } -/*------------------------------------------------- - convert - convert a spice netlist --------------------------------------------------*/ - -class convert_t -{ -public: - - convert_t() {}; - ~convert_t() - { - nets.clear_and_free(); - devs.clear_and_free(); - } - - void convert(const pstring &contents) - { - pstring_list_t spnl(contents, "\n"); - - // Add gnd net - - // FIXME: Parameter - out("NETLIST_START(dummy)\n"); - nets.add(palloc(sp_net_t, "0"), false); - nets[0]->terminals().add("GND"); - - pstring line = ""; - - for (std::size_t i=0; i < spnl.size(); i++) - { - // Basic preprocessing - pstring inl = spnl[i].trim().ucase(); - if (inl.startsWith("+")) - line = line + inl.substr(1); - else - { - process_line(line); - line = inl; - } - } - process_line(line); - dump_nl(); - // FIXME: Parameter - out("NETLIST_END()\n"); - printf("%s", m_buf.cstr()); - } - -protected: - struct sp_net_t - { - public: - sp_net_t(const pstring &aname) - : m_name(aname), m_no_export(false) {} - - const pstring &name() { return m_name;} - pstring_list_t &terminals() { return m_terminals; } - void set_no_export() { m_no_export = true; } - bool is_no_export() { return m_no_export; } - - private: - pstring m_name; - bool m_no_export; - pstring_list_t m_terminals; - }; - - struct sp_dev_t - { - public: - sp_dev_t(const pstring &atype, const pstring &aname, const pstring &amodel) - : m_type(atype), m_name(aname), m_model(amodel), m_val(0), m_has_val(false) - {} - - sp_dev_t(const pstring &atype, const pstring &aname, double aval) - : m_type(atype), m_name(aname), m_model(""), m_val(aval), m_has_val(true) - {} - - sp_dev_t(const pstring &atype, const pstring &aname) - : m_type(atype), m_name(aname), m_model(""), m_val(0.0), m_has_val(false) - {} - - const pstring &name() { return m_name;} - const pstring &type() { return m_type;} - const pstring &model() { return m_model;} - const double &value() { return m_val;} - - bool has_model() { return m_model != ""; } - bool has_value() { return m_has_val; } - - private: - pstring m_type; - pstring m_name; - pstring m_model; - double m_val; - bool m_has_val; - }; - - struct sp_unit { - pstring sp_unit; - pstring nl_func; - double mult; - }; - - - void add_term(pstring netname, pstring termname) - { - sp_net_t * net = nets.find(netname); - if (net == NULL) - { - net = palloc(sp_net_t, netname); - nets.add(net, false); - } - net->terminals().add(termname); - } - - const pstring get_nl_val(const double val) - { - { - int i = 0; - while (m_sp_units[i].sp_unit != "-" ) - { - if (m_sp_units[i].mult <= nl_math::abs(val)) - break; - i++; - } - return pstring::sprintf(m_sp_units[i].nl_func.cstr(), val / m_sp_units[i].mult); - } - } - double get_sp_unit(const pstring &unit) - { - int i = 0; - while (m_sp_units[i].sp_unit != "-") - { - if (m_sp_units[i].sp_unit == unit) - return m_sp_units[i].mult; - i++; - } - fprintf(stderr, "Unit %s unknown\n", unit.cstr()); - return 0.0; - } - - double get_sp_val(const pstring &sin) - { - int p = sin.len() - 1; - while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9")) - p--; - pstring val = sin.substr(0,p + 1); - pstring unit = sin.substr(p + 1); - - double ret = get_sp_unit(unit) * val.as_double(); - //printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret); - return ret; - } - - void dump_nl() - { - for (int i=0; i<alias.size(); i++) - { - sp_net_t *net = nets.find(alias[i]); - // use the first terminal ... - out("ALIAS(%s, %s)\n", alias[i].cstr(), net->terminals()[0].cstr()); - // if the aliased net only has this one terminal connected ==> don't dump - if (net->terminals().size() == 1) - net->set_no_export(); - } - for (int i=0; i<devs.size(); i++) - { - if (devs[i]->has_value()) - out("%s(%s, %s)\n", devs[i]->type().cstr(), - devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr()); - else if (devs[i]->has_model()) - out("%s(%s, \"%s\")\n", devs[i]->type().cstr(), - devs[i]->name().cstr(), devs[i]->model().cstr()); - else - out("%s(%s)\n", devs[i]->type().cstr(), - devs[i]->name().cstr()); - } - // print nets - for (int i=0; i<nets.size(); i++) - { - sp_net_t * net = nets[i]; - if (!net->is_no_export()) - { - //printf("Net %s\n", net->name().cstr()); - out("NET_C(%s", net->terminals()[0].cstr() ); - for (int j=1; j<net->terminals().size(); j++) - { - out(", %s", net->terminals()[j].cstr() ); - } - out(")\n"); - } - } - devs.clear_and_free(); - nets.clear_and_free(); - alias.clear(); - } - - void process_line(const pstring &line) - { - if (line != "") - { - pstring_list_t tt(line, " ", true); - double val = 0.0; - switch (tt[0].cstr()[0]) - { - case ';': - out("// %s\n", line.substr(1).cstr()); - break; - case '*': - out("// %s\n", line.substr(1).cstr()); - break; - case '.': - if (tt[0].equals(".SUBCKT")) - { - out("NETLIST_START(%s)\n", tt[1].cstr()); - for (int i=2; i<tt.size(); i++) - alias.add(tt[i]); - } - else if (tt[0].equals(".ENDS")) - { - dump_nl(); - out("NETLIST_END()\n"); - } - else - out("// %s\n", line.cstr()); - break; - case 'Q': - { - bool cerr = false; - /* check for fourth terminal ... should be numeric net - * including "0" or start with "N" (ltspice) - */ - // FIXME: we need a is_long method .. - ATTR_UNUSED int nval =tt[4].as_long(&cerr); - if ((!cerr || tt[4].startsWith("N")) && tt.size() > 5) - devs.add(palloc(sp_dev_t, "QBJT", tt[0], tt[5]), false); - else - devs.add(palloc(sp_dev_t, "QBJT", tt[0], tt[4]), false); - add_term(tt[1], tt[0] + ".C"); - add_term(tt[2], tt[0] + ".B"); - add_term(tt[3], tt[0] + ".E"); - } - break; - case 'R': - val = get_sp_val(tt[3]); - devs.add(palloc(sp_dev_t, "RES", tt[0], val), false); - add_term(tt[1], tt[0] + ".1"); - add_term(tt[2], tt[0] + ".2"); - break; - case 'C': - val = get_sp_val(tt[3]); - devs.add(palloc(sp_dev_t, "CAP", tt[0], val), false); - add_term(tt[1], tt[0] + ".1"); - add_term(tt[2], tt[0] + ".2"); - break; - case 'V': - // just simple Voltage sources .... - if (tt[2].equals("0")) - { - val = get_sp_val(tt[3]); - devs.add(palloc(sp_dev_t, "ANALOG_INPUT", tt[0], val), false); - add_term(tt[1], tt[0] + ".Q"); - //add_term(tt[2], tt[0] + ".2"); - } - else - fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr()); - break; - case 'D': - // FIXME: Rewrite resistor value - devs.add(palloc(sp_dev_t, "DIODE", tt[0], tt[3]), false); - add_term(tt[1], tt[0] + ".A"); - add_term(tt[2], tt[0] + ".K"); - break; - case 'U': - case 'X': - { - // FIXME: specific code for KICAD exports - // last element is component type - // FIXME: Parameter - - pstring xname = tt[0].replace(".", "_"); - pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP"; - devs.add(palloc(sp_dev_t, tname, xname), false); - for (int i=1; i < tt.size() - 1; i++) - { - pstring term = pstring::sprintf("%s.%d", xname.cstr(), i); - add_term(tt[i], term); - } - break; - } - default: - pstring::sprintf("// IGNORED %s: %s\n", tt[0].cstr(), line.cstr()); - } - } - } - - void out(const char *format, ...) ATTR_PRINTF(2,3) - { - va_list ap; - va_start(ap, format); - m_buf += pstring(format).vprintf(ap); - va_end(ap); - } - - -private: - pnamedlist_t<sp_net_t *> nets; - pnamedlist_t<sp_dev_t *> devs; - plist_t<pstring> alias; - - pstringbuffer m_buf; - - static sp_unit m_sp_units[]; - -}; - -convert_t::sp_unit convert_t::m_sp_units[] = { - {"T", "", 1.0e12 }, - {"G", "", 1.0e9 }, - {"MEG", "RES_M(%g)", 1.0e6 }, - {"K", "RES_K(%g)", 1.0e3 }, - {"", "%g", 1.0e0 }, - {"M", "CAP_M(%g)", 1.0e-3 }, - {"U", "CAP_U(%g)", 1.0e-6 }, - {"ยต", "CAP_U(%g)", 1.0e-6 }, - {"N", "CAP_N(%g)", 1.0e-9 }, - {"P", "CAP_P(%g)", 1.0e-12}, - {"F", "%ge-15", 1.0e-15}, - - {"MIL", "%e", 25.4e-6}, - - {"-", "%g", 1.0 } -}; /*------------------------------------------------- @@ -709,8 +380,15 @@ int main(int argc, char *argv[]) else if (cmd == "convert") { pstring contents = filetobuf(opts.opt_file()); - convert_t converter; - converter.convert(contents); + nl_convert_base_t *converter = NULL; + if (opts.opt_type().equals("spice")) + converter = palloc(nl_convert_spice_t); + else + converter = palloc(nl_convert_eagle_t); + converter->convert(contents); + /* present result */ + printf("%s\n", converter->result().cstr()); + pfree(converter); } else { |