diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/netlist/plib/poptions.cpp | 9 | ||||
-rw-r--r-- | src/lib/netlist/plib/poptions.h | 39 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.h | 72 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 89 |
4 files changed, 183 insertions, 26 deletions
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index fc2793c40f3..9defcf84975 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -31,7 +31,8 @@ namespace plib { } option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument) - : option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument) + : option_base(parent, help), m_short(ashort), m_long(along), + m_has_argument(has_argument), m_specified(false) { } @@ -149,13 +150,13 @@ namespace plib { { if (has_equal_arg) { - if (opt->parse(opt_arg) != 0) + if (opt->do_parse(opt_arg) != 0) return i; } else { i++; // FIXME: are there more arguments? - if (opt->parse(pstring(argv[i], pstring::UTF8)) != 0) + if (opt->do_parse(pstring(argv[i], pstring::UTF8)) != 0) return i - 1; } } @@ -163,7 +164,7 @@ namespace plib { { if (has_equal_arg) return i; - opt->parse(""); + opt->do_parse(""); } i++; } diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 221a7fa2c8a..6f80938167f 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -65,15 +65,25 @@ public: /* no_argument options will be called with "" argument */ - virtual int parse(const pstring &argument) = 0; - pstring short_opt() { return m_short; } pstring long_opt() { return m_long; } bool has_argument() { return m_has_argument ; } + bool was_specified() { return m_specified; } + + int do_parse(const pstring &argument) + { + m_specified = true; + return parse(argument); + } + +protected: + virtual int parse(const pstring &argument) = 0; + private: pstring m_short; pstring m_long; bool m_has_argument; + bool m_specified; }; class option_str : public option @@ -83,9 +93,11 @@ public: : option(parent, ashort, along, help, true), m_val(defval) {} + pstring operator ()() { return m_val; } + +protected: virtual int parse(const pstring &argument) override; - pstring operator ()() { return m_val; } private: pstring m_val; }; @@ -99,11 +111,12 @@ public: m_limit = plib::psplit(limit, ":"); } - virtual int parse(const pstring &argument) override; - pstring operator ()() { return m_val; } const std::vector<pstring> &limit() { return m_limit; } +protected: + virtual int parse(const pstring &argument) override; + private: pstring m_val; std::vector<pstring> m_limit; @@ -116,9 +129,11 @@ public: : option(parent, ashort, along, help, false), m_val(false) {} + bool operator ()() { return m_val; } + +protected: virtual int parse(const pstring &argument) override; - bool operator ()() { return m_val; } private: bool m_val; }; @@ -130,9 +145,11 @@ public: : option(parent, ashort, along, help, true), m_val(defval) {} + double operator ()() { return m_val; } + +protected: virtual int parse(const pstring &argument) override; - double operator ()() { return m_val; } private: double m_val; }; @@ -144,9 +161,11 @@ public: : option(parent, ashort, along, help, true), m_val(defval) {} + long operator ()() { return m_val; } + +protected: virtual int parse(const pstring &argument) override; - long operator ()() { return m_val; } private: long m_val; }; @@ -158,9 +177,11 @@ public: : option(parent, ashort, along, help, true) {} + std::vector<pstring> operator ()() { return m_val; } + +protected: virtual int parse(const pstring &argument) override; - std::vector<pstring> operator ()() { return m_val; } private: std::vector<pstring> m_val; }; diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index 83c514da2e1..10b2e9a82a5 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -12,6 +12,8 @@ #include "pfmtlog.h" #include "pexception.h" +#include <vector> + namespace plib { // ----------------------------------------------------------------------------- // pstream: things common to all streams @@ -371,6 +373,76 @@ protected: private: }; +// ----------------------------------------------------------------------------- +// pbinary_writer_t: writer on top of ostream +// ----------------------------------------------------------------------------- + +class pbinary_writer : plib::nocopyassignmove +{ +public: + explicit pbinary_writer(postream &strm) : m_strm(strm) {} + virtual ~pbinary_writer() {} + + template <typename T> + void write(const T val) + { + m_strm.write(&val, sizeof(T)); + } + + void write(const pstring s) + { + write(s.blen()); + m_strm.write(s.c_str(), s.blen()); + } + + template <typename T> + void write(const std::vector<T> val) + { + std::size_t sz = val.size(); + write(sz); + m_strm.write(val.data(), sizeof(T) * sz); + } + +private: + postream &m_strm; +}; + +class pbinary_reader : plib::nocopyassignmove +{ +public: + explicit pbinary_reader(pistream &strm) : m_strm(strm) {} + virtual ~pbinary_reader() {} + + template <typename T> + void read(T &val) + { + m_strm.read(&val, sizeof(T)); + } + + void read( pstring &s) + { + std::size_t sz = 0; + read(sz); + pstring::mem_t *buf = new pstring::mem_t[sz+1]; + m_strm.read(buf, sz); + buf[sz] = 0; + s = pstring(buf, pstring::UTF8); + delete [] buf; + } + + template <typename T> + void read(std::vector<T> &val) + { + std::size_t sz = 0; + read(sz); + val.resize(sz); + m_strm.read(val.data(), sizeof(T) * sz); + } + +private: + pistream &m_strm; +}; + } #endif /* PSTREAM_H_ */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index c3cd8edc842..b0e8112b9f5 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -26,7 +26,7 @@ public: opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static:header:docheader", "run|convert|listdevices|static|header"), opt_file(*this, "f", "file", "-", "file to process (default is stdin)"), opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."), - opt_rfolders(*this, "r", "rom", "where to look for files"), + opt_rfolders(*this, "r", "rom", "where to look for data files"), opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"), opt_quiet(*this, "q", "quiet", "be quiet - no warnings"), opt_version(*this, "", "version", "display version and exit"), @@ -37,6 +37,8 @@ public: opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"), opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."), opt_inp(*this, "i", "input", "", "input file to process (default is none)"), + opt_loadstate(*this,"", "loadstate", "", "load state from file and continue from there"), + opt_savestate(*this,"", "savestate", "", "save state to file at end of run"), opt_grp4(*this, "Options for convert command", "These options are only used by the convert command."), opt_type(*this, "y", "type", "spice", "spice:eagle:rinf", "type of file to be converted: spice,eagle,rinf"), @@ -61,6 +63,8 @@ public: plib::option_double opt_ttr; plib::option_vec opt_logs; plib::option_str opt_inp; + plib::option_str opt_loadstate; + plib::option_str opt_savestate; plib::option_group opt_grp4; plib::option_str_limit opt_type; plib::option_example opt_ex1; @@ -179,15 +183,16 @@ public: } } - void save_state() + template<typename T> + std::vector<T> save_state() { state().pre_save(); std::size_t size = 0; for (auto const & s : state().save_list()) - size += ((s->m_dt.size * s->m_count + sizeof(unsigned) - 1) / sizeof(unsigned)); + size += ((s->m_dt.size * s->m_count + sizeof(T) - 1) / sizeof(T)); - auto buf = plib::palloc_array<unsigned>(size); - auto p = buf; + auto buf = std::vector<T>(size); + auto p = buf.data(); for (auto const & s : state().save_list()) { @@ -196,8 +201,34 @@ public: std::memcpy(p, s->m_ptr, sz ); else log().fatal("found unsupported save element {1}\n", s->m_name); - p += ((sz + sizeof(unsigned) - 1) / sizeof(unsigned)); + p += ((sz + sizeof(T) - 1) / sizeof(T)); } + return buf; + } + + template<typename T> + void load_state(std::vector<T> &buf) + { + std::size_t size = 0; + for (auto const & s : state().save_list()) + size += ((s->m_dt.size * s->m_count + sizeof(T) - 1) / sizeof(T)); + + if (buf.size() != size) + throw netlist::nl_exception("Size different during load state."); + + auto p = buf.data(); + + for (auto const & s : state().save_list()) + { + std::size_t sz = s->m_dt.size * s->m_count; + if (s->m_dt.is_float || s->m_dt.is_integral) + std::memcpy(s->m_ptr, p, sz ); + else + log().fatal("found unsupported save element {1}\n", s->m_name); + p += ((sz + sizeof(T) - 1) / sizeof(T)); + } + state().post_load(); + rebuild_lists(); } protected: @@ -295,33 +326,65 @@ void tool_app_t::run() std::vector<input_t> inps = read_input(nt.setup(), opt_inp()); - double ttr = opt_ttr(); + netlist::netlist_time ttr = netlist::netlist_time::from_double(opt_ttr()); t.stop(); pout("startup time ==> {1:5.3f}\n", t.as_seconds() ); - pout("runnning ...\n"); t.reset(); t.start(); + // FIXME: error handling + if (opt_loadstate.was_specified()) + { + plib::pifilestream strm(opt_loadstate()); + plib::pbinary_reader reader(strm); + std::vector<char> loadstate; + reader.read(loadstate); + nt.load_state(loadstate); + pout("Loaded state, run will continue at {1:.6f}\n", nt.time().as_double()); + } + unsigned pos = 0; - netlist::netlist_time nlt = netlist::netlist_time::zero(); + netlist::netlist_time nlt = nt.time(); - while (pos < inps.size() && inps[pos].m_time < netlist::netlist_time::from_double(ttr)) + + while (pos < inps.size() + && inps[pos].m_time < ttr + && inps[pos].m_time >= nlt) { nt.process_queue(inps[pos].m_time - nlt); inps[pos].setparam(); nlt = inps[pos].m_time; pos++; } - nt.process_queue(netlist::netlist_time::from_double(ttr) - nlt); - nt.save_state(); + + pout("runnning ...\n"); + + if (ttr > nlt) + nt.process_queue(ttr - nlt); + else + { + pout("end time {1:.6f} less than saved time {2:.6f}\n", + ttr.as_double(), nlt.as_double()); + ttr = nlt; + } + + if (opt_savestate.was_specified()) + { + auto savestate = nt.save_state<char>(); + plib::pofilestream strm(opt_savestate()); + plib::pbinary_writer writer(strm); + writer.write(savestate); + } nt.stop(); t.stop(); double emutime = t.as_seconds(); - pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", ttr, emutime, ttr/emutime*100.0); + pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", + (ttr - nlt).as_double(), emutime, + (ttr - nlt).as_double() / emutime * 100.0); } void tool_app_t::static_compile() |