netlist: Refactoring and some functionality enhancements. (nw)

- Removed dead code.
- nltool now adds a define NLTOOL_VERSION. This can be tested in
  netlists. It is used in kidniki to ensure I stop committing
  debug parameters.
- Optimized the proposal for no-deactivate hints.
- Documented in breakout that hints were manually optimized.
- Minor optimizations in the order of 2% enhancement.
This commit is contained in:
couriersud 2019-02-04 00:27:23 +01:00
parent 9b2c04fc9f
commit c87a487d6d
23 changed files with 250 additions and 169 deletions

View File

@ -301,7 +301,7 @@ public:
{
int pos = (upto - m_last_buffer_time) / m_sample_time;
if (pos > m_bufsize)
state().log().fatal("sound {1}: pos {2} exceeded bufsize {3}\n", name().c_str(), pos, m_bufsize);
throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize);
while (m_last_pos < pos )
{
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
@ -1050,10 +1050,8 @@ ATTR_COLD uint64_t netlist_mame_cpu_device::execute_cycles_to_clocks(uint64_t cy
ATTR_HOT void netlist_mame_cpu_device::execute_run()
{
bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
// debugging
//m_ppc = m_pc; // copy PC to previous PC
if (check_debugger)
if (debugger_enabled())
{
while (m_icount > 0)
{

View File

@ -109,7 +109,6 @@ public:
ATTR_HOT inline netlist::setup_t &setup();
ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; }
ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; }
ATTR_HOT void update_icount(netlist::netlist_time time);
ATTR_HOT void check_mame_abort_slice();

View File

@ -158,32 +158,35 @@ namespace netlist
NETLIB_UPDATE(9310_sub)
{
auto cnt(m_cnt);
if (m_loadq)
{
if (m_cnt < MAXCNT - 1)
if (cnt < MAXCNT - 1)
{
++m_cnt;
update_outputs(m_cnt);
++cnt;
update_outputs(cnt);
}
else if (m_cnt == MAXCNT - 1)
else if (cnt == MAXCNT - 1)
{
m_cnt = MAXCNT;
cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(20));
m_QA.push(1, NLTIME_FROM_NS(20));
}
else // MAXCNT
{
m_RC.push(0, NLTIME_FROM_NS(20));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
cnt = 0;
update_outputs_all(cnt, NLTIME_FROM_NS(20));
}
}
else
{
m_cnt = m_ABCD->read_ABCD();
m_RC.push(m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
cnt = m_ABCD->read_ABCD();
m_RC.push(m_ent & (cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(cnt, NLTIME_FROM_NS(22));
}
m_cnt = cnt;
}
NETLIB_UPDATE(9310)
@ -224,10 +227,10 @@ namespace netlist
#if 0
// for (int i=0; i<4; i++)
// m_Q[i], (cnt >> i) & 1, delay[i]);
m_QA, (cnt >> 0) & 1, out_delay);
m_QB, (cnt >> 1) & 1, out_delay);
m_QC, (cnt >> 2) & 1, out_delay);
m_QD, (cnt >> 3) & 1, out_delay);
m_QA.push((cnt >> 0) & 1, out_delay);
m_QB.push((cnt >> 1) & 1, out_delay);
m_QC.push((cnt >> 2) & 1, out_delay);
m_QD.push((cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
m_QA.push(1, out_delay);

View File

@ -105,27 +105,15 @@ namespace netlist
NETLIB_HANDLER(9316, clk)
{
auto cnt(m_cnt);
if (m_LOADQ())
{
++m_cnt &= MAXCNT;
//m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
#if 0
if (m_cnt == MAXCNT)
{
m_RC.push(m_ENT(), NLTIME_FROM_NS(27));
update_outputs_all(MAXCNT, NLTIME_FROM_NS(20));
}
else if (m_cnt == 0)
{
m_RC.push(0, NLTIME_FROM_NS(27));
update_outputs_all(0, NLTIME_FROM_NS(20));
}
else
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
#else
if (m_cnt > 0 && m_cnt < MAXCNT)
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
else if (m_cnt == 0)
++cnt &= MAXCNT;
//m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27));
if (cnt > 0 && cnt < MAXCNT)
update_outputs_all(cnt, NLTIME_FROM_NS(20));
else if (cnt == 0)
{
m_RC.push(0, NLTIME_FROM_NS(27));
update_outputs_all(0, NLTIME_FROM_NS(20));
@ -135,14 +123,14 @@ namespace netlist
m_RC.push(m_ENT(), NLTIME_FROM_NS(27));
update_outputs_all(MAXCNT, NLTIME_FROM_NS(20));
}
#endif
}
else
{
m_cnt = m_abcd;
m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
cnt = m_abcd;
m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(cnt, NLTIME_FROM_NS(22));
}
m_cnt = cnt;
}
NETLIB_UPDATE(9316)

View File

@ -40,15 +40,38 @@ namespace netlist
{
m_cnt = 0;
m_off = netlist_time::from_double(m_offset());
m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update);
//m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this);
//m_Q.initial(0);
}
NETLIB_HANDLER(extclock, clk2)
{
m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]);
if (++m_cnt >= m_size)
m_cnt = 0;
}
NETLIB_HANDLER(extclock, clk2_pow2)
{
m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]);
m_cnt = (++m_cnt) & (m_size-1);
}
NETLIB_UPDATE(extclock)
{
m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off);
m_off = netlist_time::zero();
if (++m_cnt >= m_size)
m_cnt = 0;
// continue with optimized clock handlers ....
if ((m_size & (m_size-1)) == 0) // power of 2?
m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this);
else
m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this);
}
// -----------------------------------------------------------------------------

View File

@ -52,7 +52,7 @@ namespace netlist
NETLIB_RESETI()
{
m_Q.net().set_time(netlist_time::zero());
m_Q.net().set_next_scheduled_time(netlist_time::zero());
}
NETLIB_UPDATE_PARAMI()
@ -65,7 +65,7 @@ namespace netlist
logic_net_t &net = m_Q.net();
// this is only called during setup ...
net.toggle_new_Q();
net.set_time(exec().time() + m_inc);
net.set_next_scheduled_time(exec().time() + m_inc);
}
public:
@ -73,13 +73,6 @@ namespace netlist
param_double_t m_freq;
netlist_time m_inc;
static void mc_update(logic_net_t &net)
{
net.toggle_new_Q();
net.update_devs();
}
};
// -----------------------------------------------------------------------------
@ -158,6 +151,10 @@ namespace netlist
NETLIB_UPDATEI();
NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
NETLIB_HANDLERI(clk2);
NETLIB_HANDLERI(clk2_pow2);
protected:
param_double_t m_freq;

View File

@ -179,7 +179,7 @@ namespace devices
m_I[i].activate();
//nstate |= (m_I[i]() ? (1 << i) : 0);
nstate |= (m_I[i]() << i);
mt = std::max(this->m_I[i].net().time(), mt);
mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
}
else
for (std::size_t i = 0; i < m_NI; i++)
@ -208,7 +208,7 @@ namespace devices
{
//nstate |= (m_I[i]() ? (1 << i) : 0);
nstate |= (m_I[i]() << i);
mt = std::max(this->m_I[i].net().time(), mt);
mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
}
else
for (std::size_t i = 0; i < m_NI; i++)

View File

@ -164,11 +164,9 @@ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstri
manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
}
void detail::queue_t::on_pre_save()
void detail::queue_t::on_pre_save(plib::state_manager_t &manager)
{
state().log().debug("on_pre_save\n");
m_qsize = this->size();
state().log().debug("qsize {1}\n", m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
m_times[i] = this->listptr()[i].m_exec_time.as_raw();
@ -177,10 +175,9 @@ void detail::queue_t::on_pre_save()
}
void detail::queue_t::on_post_load()
void detail::queue_t::on_post_load(plib::state_manager_t &manager)
{
this->clear();
state().log().debug("qsize {1}\n", m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
detail::net_t *n = state().nets()[m_net_ids[i]].get();
@ -247,11 +244,11 @@ detail::terminal_type detail::core_terminal_t::type() const
// ----------------------------------------------------------------------------------------
netlist_t::netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks)
: m_state(plib::make_unique<netlist_state_t>(aname,
: m_time(netlist_time::zero())
, m_mainclock(nullptr)
, m_state(plib::make_unique<netlist_state_t>(aname,
std::move(callbacks),
plib::make_unique<setup_t>(*this))) // FIXME, ugly but needed to have netlist_state_t constructed first
, m_time(netlist_time::zero())
, m_mainclock(nullptr)
, m_queue(*m_state)
, m_solver(nullptr)
{
@ -272,8 +269,7 @@ netlist_t::~netlist_t()
netlist_state_t::netlist_state_t(const pstring &aname,
std::unique_ptr<callbacks_t> &&callbacks,
std::unique_ptr<setup_t> &&setup)
: m_params(nullptr)
, m_name(aname)
: m_name(aname)
, m_state()
, m_callbacks(std::move(callbacks)) // Order is important here
, m_log(*m_callbacks)
@ -339,7 +335,7 @@ void netlist_t::reset()
m_time = netlist_time::zero();
m_queue.clear();
if (m_mainclock != nullptr)
m_mainclock->m_Q.net().set_time(netlist_time::zero());
m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero());
//if (m_solver != nullptr)
// m_solver->reset();
@ -452,7 +448,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
{
logic_net_t &mc_net(m_mainclock->m_Q.net());
const netlist_time inc(m_mainclock->m_inc);
netlist_time mc_time(mc_net.time());
netlist_time mc_time(mc_net.next_scheduled_time());
do
{
@ -474,7 +470,7 @@ void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT
else
break;
} while (true); //while (e.m_object != nullptr);
mc_net.set_time(mc_time);
mc_net.set_next_scheduled_time(mc_time);
}
m_stat_mainloop.stop();
}
@ -503,6 +499,9 @@ void netlist_t::print_stats() const
total_count += entry->m_stat_total_time.count();
}
log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
total_time, total_time / total_count);
nperftime_t<NL_KEEP_STATISTICS> overhead;
nperftime_t<NL_KEEP_STATISTICS> test;
overhead.start();
@ -531,10 +530,16 @@ void netlist_t::print_stats() const
/ static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(m_queue.m_prof_call());
log().verbose("Overhead per pop {1:11}", overhead_per_pop );
log().verbose("");
auto trigger = total_count * 200 / 1000000; // 200 ppm
for (auto &entry : m_state->m_devices)
{
if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count())
log().verbose("HINT({}, NO_DEACTIVATE)", entry->name());
// Factor of 3 offers best performace increase
if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count()
&& entry->m_stat_inc_active() > trigger)
log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", entry->name(),
static_cast<double>(entry->m_stat_inc_active()) / static_cast<double>(entry->m_stat_total_time.count()),
entry->m_stat_inc_active(), entry->m_stat_total_time.count());
}
}
}
@ -687,7 +692,7 @@ detail::net_t::net_t(netlist_base_t &nl, const pstring &aname, core_terminal_t *
, m_new_Q(*this, "m_new_Q", 0)
, m_cur_Q (*this, "m_cur_Q", 0)
, m_in_queue(*this, "m_in_queue", QS_DELIVERED)
, m_time(*this, "m_time", netlist_time::zero())
, m_next_scheduled_time(*this, "m_time", netlist_time::zero())
, m_railterminal(mr)
{
}
@ -697,35 +702,6 @@ detail::net_t::~net_t()
state().run_state_manager().remove_save_items(this);
}
void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT
{
const bool was_empty = m_list_active.empty();
m_list_active.push_front(&term);
if (was_empty)
{
railterminal().device().do_inc_active();
if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE)
{
if (m_time > exec().time())
{
m_in_queue = QS_QUEUED; /* pending */
exec().queue().push({m_time, this});
}
else
{
m_in_queue = QS_DELIVERED;
m_cur_Q = m_new_Q;
}
}
}
}
void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT
{
m_list_active.remove(&term);
if (m_list_active.empty())
railterminal().device().do_dec_active();
}
void detail::net_t::rebuild_list()
{
@ -779,7 +755,7 @@ void detail::net_t::update_devs() NL_NOEXCEPT
void detail::net_t::reset()
{
m_time = netlist_time::zero();
m_next_scheduled_time = netlist_time::zero();
m_in_queue = QS_DELIVERED;
m_new_Q = 0;

View File

@ -732,8 +732,8 @@ namespace netlist
void update_devs() NL_NOEXCEPT;
const netlist_time time() const noexcept { return m_time; }
void set_time(netlist_time ntime) noexcept { m_time = ntime; }
const netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; }
void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; }
bool isRailNet() const noexcept { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
@ -761,7 +761,7 @@ namespace netlist
state_var<netlist_sig_t> m_cur_Q;
state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
state_var<netlist_time> m_time;
state_var<netlist_time> m_next_scheduled_time;
private:
plib::linkedlist_t<core_terminal_t> m_list_active;
@ -803,7 +803,7 @@ namespace netlist
if (newQ != m_new_Q)
{
m_in_queue = QS_DELAYED_DUE_TO_INACTIVE;
m_time = at;
m_next_scheduled_time = at;
}
m_cur_Q = m_new_Q = newQ;
}
@ -1204,8 +1204,8 @@ namespace netlist
protected:
void register_state(plib::state_manager_t &manager, const pstring &module) override;
void on_pre_save() override;
void on_post_load() override;
void on_pre_save(plib::state_manager_t &manager) override;
void on_post_load(plib::state_manager_t &manager) override;
private:
std::size_t m_qsize;
@ -1272,8 +1272,6 @@ namespace netlist
template <typename T>
void register_net(plib::owned_ptr<T> &&net) { m_nets.push_back(std::move(net)); }
devices::NETLIB_NAME(netlistparams) *m_params;
template<class device_class>
inline std::vector<device_class *> get_device_list()
{
@ -1387,11 +1385,10 @@ namespace netlist
void print_stats() const;
private:
std::unique_ptr<netlist_state_t> m_state;
/* mostly rw */
netlist_time m_time;
devices::NETLIB_NAME(mainclock) * m_mainclock;
std::unique_ptr<netlist_state_t> m_state;
detail::queue_t m_queue;
devices::NETLIB_NAME(solver) * m_solver;
@ -1517,15 +1514,50 @@ namespace netlist
{
if ((num_cons() != 0))
{
auto &lexec(exec());
auto &q(lexec.queue());
auto nst(lexec.time() + delay);
if (is_queued())
exec().queue().remove(this);
m_time = exec().time() + delay;
q.remove(this);
m_in_queue = (!m_list_active.empty()) ? QS_QUEUED : QS_DELAYED_DUE_TO_INACTIVE; /* queued ? */
if (m_in_queue == QS_QUEUED)
exec().queue().push(queue_t::entry_t(m_time, this));
q.push(queue_t::entry_t(nst, this));
m_next_scheduled_time = nst;
}
}
inline void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT
{
if (m_list_active.empty())
{
m_list_active.push_front(&term);
railterminal().device().do_inc_active();
if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE)
{
if (m_next_scheduled_time > exec().time())
{
m_in_queue = QS_QUEUED; /* pending */
exec().queue().push({m_next_scheduled_time, this});
}
else
{
m_in_queue = QS_DELIVERED;
m_cur_Q = m_new_Q;
}
}
}
else
m_list_active.push_front(&term);
}
inline void detail::net_t::remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT
{
m_list_active.remove(&term);
if (m_list_active.empty())
railterminal().device().do_dec_active();
}
inline const analog_net_t & analog_t::net() const NL_NOEXCEPT
{
return static_cast<const analog_net_t &>(core_terminal_t::net());
@ -1583,6 +1615,7 @@ namespace netlist
return m_device.exec();
}
inline const netlist_t &detail::device_object_t::exec() const NL_NOEXCEPT
{
return m_device.exec();

View File

@ -27,6 +27,7 @@ namespace netlist
{
setup_t::setup_t(netlist_t &netlist)
: m_netlist(netlist)
, m_netlist_params(nullptr)
, m_factory(*this)
, m_proxy_cnt(0)
, m_frontier_cnt(0)
@ -970,13 +971,13 @@ std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name)
return std::unique_ptr<plib::pistream>(nullptr);
}
void setup_t::register_define(const pstring &defstr)
void setup_t::add_define(const pstring &defstr)
{
auto p = defstr.find("=");
if (p != pstring::npos)
register_define(plib::left(defstr, p), defstr.substr(p+1));
add_define(plib::left(defstr, p), defstr.substr(p+1));
else
register_define(defstr, "1");
add_define(defstr, "1");
}
// ----------------------------------------------------------------------------------------
@ -1024,7 +1025,7 @@ void setup_t::prepare_to_run()
log().debug("Searching for solver and parameters ...\n");
auto solver = netlist().get_single_device<devices::NETLIB_NAME(solver)>("solver");
netlist().m_params = netlist().get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
m_netlist_params = netlist().get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
/* create devices */
@ -1039,7 +1040,7 @@ void setup_t::prepare_to_run()
}
}
bool use_deactivate = (netlist().m_params->m_use_deactivate() ? true : false);
bool use_deactivate = m_netlist_params->m_use_deactivate() ? true : false;
for (auto &d : netlist().devices())
{

View File

@ -123,6 +123,7 @@ namespace netlist
namespace devices {
class nld_base_proxy;
class nld_netlistparams;
}
class core_device_t;
@ -274,8 +275,12 @@ namespace netlist
m_sources.push_back(std::move(src));
}
void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); }
void register_define(const pstring &defstr);
void add_define(pstring def, pstring val)
{
m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)});
}
void add_define(const pstring &defstr);
factory::list_t &factory() { return m_factory; }
const factory::list_t &factory() const { return m_factory; }
@ -337,14 +342,16 @@ namespace netlist
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
netlist_t &m_netlist;
devices::nld_netlistparams *m_netlist_params;
std::unordered_map<pstring, param_ref_t> m_params;
std::vector<link_t> m_links;
factory::list_t m_factory;
std::unordered_map<pstring, pstring> m_models;
std::stack<pstring> m_namespace_stack;
source_t::list_t m_sources;
std::vector<plib::ppreprocessor::define_t> m_defines;
plib::ppreprocessor::defines_map_type m_defines;
unsigned m_proxy_cnt;
unsigned m_frontier_cnt;

View File

@ -152,9 +152,10 @@ public:
void remove(const LC *elem) noexcept
{
auto p = &m_head;
for ( ; *p != elem; p = &((*p)->m_next))
while(*p != elem)
{
//nl_assert(*p != nullptr);
p = &((*p)->m_next);
}
(*p) = elem->m_next;
}

View File

@ -219,7 +219,7 @@ namespace plib {
}
pstring options::help(pstring description, pstring usage,
unsigned width, unsigned indent)
unsigned width, unsigned indent) const
{
pstring ret;
@ -293,7 +293,7 @@ namespace plib {
return ret;
}
option *options::getopt_short(pstring arg)
option *options::getopt_short(pstring arg) const
{
for (auto & optbase : m_opts)
{
@ -303,7 +303,7 @@ namespace plib {
}
return nullptr;
}
option *options::getopt_long(pstring arg)
option *options::getopt_long(pstring arg) const
{
for (auto & optbase : m_opts)
{

View File

@ -27,7 +27,7 @@ public:
option_base(options &parent, pstring help);
virtual ~option_base();
pstring help() { return m_help; }
pstring help() const { return m_help; }
private:
pstring m_help;
};
@ -39,7 +39,7 @@ public:
: option_base(parent, help), m_group(group) { }
~option_group();
pstring group() { return m_group; }
pstring group() const { return m_group; }
private:
pstring m_group;
};
@ -51,7 +51,7 @@ public:
: option_base(parent, help), m_example(group) { }
~option_example();
pstring example() { return m_example; }
pstring example() const { return m_example; }
private:
pstring m_example;
};
@ -93,7 +93,7 @@ public:
: option(parent, ashort, along, help, true), m_val(defval)
{}
pstring operator ()() { return m_val; }
pstring operator ()() const { return m_val; }
protected:
virtual int parse(const pstring &argument) override;
@ -128,7 +128,7 @@ public:
{
}
T operator ()() { return m_val; }
T operator ()() const { return m_val; }
pstring as_string() const { return limit()[m_val]; }
@ -157,7 +157,7 @@ public:
: option(parent, ashort, along, help, false), m_val(false)
{}
bool operator ()() { return m_val; }
bool operator ()() const { return m_val; }
protected:
virtual int parse(const pstring &argument) override;
@ -180,7 +180,7 @@ public:
, m_max(maxval)
{}
T operator ()() { return m_val; }
T operator ()() const { return m_val; }
protected:
virtual int parse(const pstring &argument) override
@ -203,7 +203,7 @@ public:
: option(parent, ashort, along, help, true)
{}
std::vector<pstring> operator ()() { return m_val; }
const std::vector<pstring> &operator ()() const { return m_val; }
protected:
virtual int parse(const pstring &argument) override;
@ -233,9 +233,9 @@ public:
int parse(int argc, char *argv[]);
pstring help(pstring description, pstring usage,
unsigned width = 72, unsigned indent = 20);
unsigned width = 72, unsigned indent = 20) const;
pstring app() { return m_app; }
pstring app() const { return m_app; }
private:
static pstring split_paragraphs(pstring text, unsigned width, unsigned indent,
@ -244,7 +244,7 @@ private:
void check_consistency();
template <typename T>
T *getopt_type()
T *getopt_type() const
{
for (auto & optbase : m_opts )
{
@ -254,8 +254,8 @@ private:
return nullptr;
}
option *getopt_short(pstring arg);
option *getopt_long(pstring arg);
option *getopt_short(pstring arg) const;
option *getopt_long(pstring arg) const;
std::vector<option_base *> m_opts;
pstring m_app;

View File

@ -268,7 +268,7 @@ void ptokenizer::error(const pstring &errs)
// A simple preprocessor
// ----------------------------------------------------------------------------------------
ppreprocessor::ppreprocessor(std::vector<define_t> *defines)
ppreprocessor::ppreprocessor(defines_map_type *defines)
: pistream()
, m_ifflag(0)
, m_level(0)
@ -292,12 +292,7 @@ ppreprocessor::ppreprocessor(std::vector<define_t> *defines)
m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")});
if (defines != nullptr)
{
for (auto & p : *defines)
{
m_defines.insert({p.m_name, p});
}
}
m_defines = *defines;
}
void ppreprocessor::error(const pstring &err)
@ -524,7 +519,10 @@ pstring ppreprocessor::process_line(pstring line)
}
}
else
error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line));
{
if (m_ifflag == 0)
error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line)));
}
}
else
{

View File

@ -163,7 +163,9 @@ public:
pstring m_replace;
};
explicit ppreprocessor(std::vector<define_t> *defines = nullptr);
using defines_map_type = std::unordered_map<pstring, define_t>;
explicit ppreprocessor(defines_map_type *defines = nullptr);
virtual ~ppreprocessor() override {}
template <typename T>
@ -214,7 +216,7 @@ private:
pstring process_line(pstring line);
pstring process_comments(pstring line);
std::unordered_map<pstring, define_t> m_defines;
defines_map_type m_defines;
std::vector<pstring> m_expr_sep;
std::uint_least64_t m_ifflag; // 31 if levels

View File

@ -48,13 +48,13 @@ void state_manager_t::remove_save_items(const void *owner)
void state_manager_t::pre_save()
{
for (auto & s : m_custom)
s->m_callback->on_pre_save();
s->m_callback->on_pre_save(*this);
}
void state_manager_t::post_load()
{
for (auto & s : m_custom)
s->m_callback->on_post_load();
s->m_callback->on_post_load(*this);
}
template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname)

View File

@ -56,8 +56,8 @@ public:
virtual ~callback_t();
virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
virtual void on_pre_save() = 0;
virtual void on_post_load() = 0;
virtual void on_pre_save(state_manager_t &manager) = 0;
virtual void on_post_load(state_manager_t &manager) = 0;
protected:
};

View File

@ -14,6 +14,10 @@
#include <algorithm>
#include <vector> // <<= needed by windows build
#define PSTRINGIFY_HELP(y) # y
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
namespace plib
{

View File

@ -17,6 +17,8 @@
#include <cstring>
#define NLTOOL_VERSION 20190202
class tool_app_t : public plib::app
{
public:
@ -36,7 +38,7 @@ public:
opt_name(*this, "n", "name", "", "the netlist in file specified by ""-f"" option to run; default is first one"),
opt_grp3(*this, "Options for run command", "These options are only used by the run command."),
opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)"),
opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)\n\n abc def\n\n xyz"),
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"),
@ -99,6 +101,8 @@ private:
void listdevices();
std::vector<pstring> m_options;
};
static NETLIST_START(dummy)
@ -186,7 +190,7 @@ public:
// read the netlist ...
for (auto & d : defines)
setup().register_define(d);
setup().add_define(d);
for (auto & r : roms)
setup().register_source(plib::make_unique_base<netlist::source_t, netlist_data_folder_t>(setup(), r));
@ -347,7 +351,7 @@ void tool_app_t::run()
nt.read_netlist(opt_file(), opt_name(),
opt_logs(),
opt_defines(), opt_rfolders());
m_options, opt_rfolders());
std::vector<input_t> inps = read_input(nt.setup(), opt_inp());
@ -423,7 +427,7 @@ void tool_app_t::static_compile()
nt.read_netlist(opt_file(), opt_name(),
opt_logs(),
opt_defines(), opt_rfolders());
m_options, opt_rfolders());
plib::putf8_writer w(&pout_strm);
std::map<pstring, pstring> mp;
@ -543,9 +547,9 @@ void tool_app_t::create_header()
if (last_source != e->sourcefile())
{
last_source = e->sourcefile();
pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72));
pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth()));
pout("{1}{2}\n", pstring("// Source: "), plib::replace_all(e->sourcefile(), "../", ""));
pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), 72));
pout("{1}\n", plib::rpad(pstring("// "), pstring("-"), opt_linewidth()));
}
cmac(e.get());
}
@ -697,7 +701,7 @@ int tool_app_t::execute()
if (opt_version())
{
pout(
"nltool (netlist) 0.1\n"
"nltool (netlist) " PSTRINGIFY(NLTOOL_VERSION) "\n"
"Copyright (C) 2019 Couriersud\n"
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.\n"
"This is free software: you are free to change and redistribute it.\n"
@ -706,6 +710,9 @@ int tool_app_t::execute()
return 0;
}
m_options = opt_defines();
m_options.push_back("NLTOOL_VERSION=" PSTRINGIFY(NLTOOL_VERSION));
try
{
pstring cmd = opt_cmd.as_string();

View File

@ -381,11 +381,11 @@ public:
nlwav_app() :
plib::app(),
opt_fmt(*this, "f", "format", 0, std::vector<pstring>({"wav","vcda","vcdd"}),
"output format. Available options are wav|vcda|vcdd.\n"
"wav : multichannel wav output\n"
"vcda : analog VCD output\n"
"vcdd : digital VCD output\n"
"Digital signals are created using the high and low options"
"output format. Available options are wav|vcda|vcdd."
" wav : multichannel wav output"
" vcda : analog VCD output"
" vcdd : digital VCD output"
" Digital signals are created using the --high and --low options"
),
opt_out(*this, "o", "output", "-", "output file"),
opt_rate(*this, "r", "rate", 48000, "sample rate of output file"),

View File

@ -2,8 +2,17 @@
// copyright-holders:Andrew Gardner, Couriersud
#include "netlist/devices/net_lib.h"
#ifdef NLBASE_H_
#error Somehow nl_base.h made it into the include chain.
#endif
#ifndef NLTOOL_VERSION
#define USE_FRONTIERS 1
#define USE_FIXED_STV 1
#else
#define USE_FRONTIERS 0
#define USE_FIXED_STV 1
#endif
/* ----------------------------------------------------------------------------
* Library section header START

View File

@ -1702,22 +1702,19 @@ CIRCUIT_LAYOUT( breakout )
NET_C(GND, D9.1, D9.2, D9.13, D9.3, D9.4, D9.5)
HINT(A3.1.sub, NO_DEACTIVATE)
#if 1
// 158% -- manually optimized
HINT(B6.s3, NO_DEACTIVATE)
HINT(C4.s3, NO_DEACTIVATE)
HINT(C4.s4, NO_DEACTIVATE)
HINT(C5.s3, NO_DEACTIVATE)
HINT(C5.s4, NO_DEACTIVATE)
HINT(D3.2.sub, NO_DEACTIVATE)
HINT(E2.s2, NO_DEACTIVATE)
HINT(E3.s2, NO_DEACTIVATE)
HINT(E5.s4, NO_DEACTIVATE)
HINT(E8.2.sub, NO_DEACTIVATE)
HINT(E9.s6, NO_DEACTIVATE)
HINT(F5.2.sub, NO_DEACTIVATE)
HINT(H2.s1, NO_DEACTIVATE)
HINT(H3.s1, NO_DEACTIVATE)
HINT(H6.sub, NO_DEACTIVATE)
HINT(J3.s4, NO_DEACTIVATE)
HINT(J5, NO_DEACTIVATE)
HINT(J6.sub, NO_DEACTIVATE)
@ -1729,9 +1726,47 @@ CIRCUIT_LAYOUT( breakout )
HINT(M4.s2, NO_DEACTIVATE)
HINT(M6.sub, NO_DEACTIVATE)
HINT(M8.s1, NO_DEACTIVATE)
HINT(N6.sub, NO_DEACTIVATE)
HINT(N7.s3, NO_DEACTIVATE)
#else
// 152% hints provided by log output
HINT(M4.s2, NO_DEACTIVATE) // 29.001761 197676 6816
HINT(M3.s3, NO_DEACTIVATE) // inf 129571 0
HINT(N7.s3, NO_DEACTIVATE) // inf 7850387 0
HINT(M3.s2, NO_DEACTIVATE) // 23.234535 395870 17038
HINT(M3.s1, NO_DEACTIVATE) // 14.500880 197676 13632
HINT(L7.s3, NO_DEACTIVATE) // 122672.000000 122672 1
HINT(L7.s2, NO_DEACTIVATE) // 122672.000000 122672 1
HINT(K7.s4, NO_DEACTIVATE) // 122673.000000 122673 1
HINT(K7.s3, NO_DEACTIVATE) // 122672.000000 122672 1
HINT(K7.s2, NO_DEACTIVATE) // 122673.000000 122673 1
HINT(K7.s1, NO_DEACTIVATE) // 122673.000000 122673 1
HINT(K4.s4, NO_DEACTIVATE) // 1438.774735 4202661 2921
HINT(K4.s2, NO_DEACTIVATE) // 3.939380 847790 215209
HINT(E2.s2, NO_DEACTIVATE) // 108.050000 315506 2920
HINT(L7.s4, NO_DEACTIVATE) // 122672.000000 122672 1
HINT(E9.s6, NO_DEACTIVATE) // inf 129571 0
HINT(J2.s6, NO_DEACTIVATE) // 493.408951 959187 1944
HINT(C5.s3, NO_DEACTIVATE) // inf 195514 0
HINT(M3.s4, NO_DEACTIVATE) // 27.744898 418726 15092
HINT(J8.s1, NO_DEACTIVATE) // 40890.000000 122670 3
HINT(E3.s2, NO_DEACTIVATE) // 203581.000000 203581 1
HINT(M9.s4, NO_DEACTIVATE) // inf 323268 0
HINT(L4.s2, NO_DEACTIVATE) // 7.290053 1192536 163584
HINT(J3.s4, NO_DEACTIVATE) // 393.639951 957726 2433
HINT(L7.s1, NO_DEACTIVATE) // inf 122672 0
HINT(F2.s1, NO_DEACTIVATE) // 286289.000000 286289 1
HINT(M8.s1, NO_DEACTIVATE) // 129571.000000 129571 1
HINT(J7.s2, NO_DEACTIVATE) // inf 122672 0
HINT(H2.s1, NO_DEACTIVATE) // 393.839704 958212 2433
HINT(H3.s1, NO_DEACTIVATE) // 3.932473 850122 216180
HINT(J2.s5, NO_DEACTIVATE) // 26.140344 203581 7788
HINT(J7.s1, NO_DEACTIVATE) // inf 122672 0
HINT(J8.s3, NO_DEACTIVATE) // 40890.000000 122670 3
#endif
CIRCUIT_LAYOUT_END
/*