summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2015-05-29 02:40:39 +0200
committer couriersud <couriersud@arcor.de>2015-05-29 16:42:29 +0200
commit84f26ad714a334c787d3867b48d7a4592a2d4a66 (patch)
treefe4e3afbd4465bda4f34e3bbc01be1646fdb115e
parente1d1a6b1f2d10d54f9827cc0c7e0c6464bffec63 (diff)
First version of a eagle to netlist converter. (nw)
-rw-r--r--src/emu/netlist/plib/poptions.h24
-rw-r--r--src/emu/netlist/plib/pparser.h5
-rw-r--r--src/tools/nltool.c346
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
{