- setup_t is owned by netlist_t. Stop being complicated.

- Remove gnd() method. 
- Further simplification.
- Fix potential reset and initialization issues. (nw)
This commit is contained in:
couriersud 2017-01-09 21:52:36 +01:00 committed by couriersud
parent d04e7f7e62
commit 5b4026d13f
17 changed files with 104 additions and 112 deletions

View File

@ -43,7 +43,7 @@ NETLIST_START(dummy)
// .END
PARAM(Solver.ACCURACY, 1e-8)
PARAM(Solver.NR_LOOPS, 9000)
PARAM(Solver.NR_LOOPS, 90)
PARAM(Solver.SOR_FACTOR, 0.001)
PARAM(Solver.GS_LOOPS, 1)
PARAM(Solver.METHOD, "MAT_CR")

View File

@ -408,7 +408,6 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, cons
m_icount(0),
m_old(netlist::netlist_time::zero()),
m_netlist(nullptr),
m_setup(nullptr),
m_setup_func(nullptr)
{
}
@ -418,7 +417,6 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, devi
m_icount(0),
m_old(netlist::netlist_time::zero()),
m_netlist(nullptr),
m_setup(nullptr),
m_setup_func(nullptr)
{
}
@ -442,7 +440,6 @@ void netlist_mame_device_t::device_start()
//printf("clock is %d\n", clock());
m_netlist = global_alloc(netlist_mame_t(*this, "netlist"));
m_setup = global_alloc(netlist::setup_t(*m_netlist));
// register additional devices
@ -455,11 +452,11 @@ void netlist_mame_device_t::device_start()
if( sdev != nullptr )
{
LOG_DEV_CALLS(("Preparse subdevice %s/%s\n", d.name(), d.shortname()));
sdev->pre_parse_action(*m_setup);
sdev->pre_parse_action(setup());
}
}
m_setup_func(*m_setup);
m_setup_func(setup());
/* let sub-devices tweak the netlist */
for (device_t &d : subdevices())
@ -468,12 +465,11 @@ void netlist_mame_device_t::device_start()
if( sdev != nullptr )
{
LOG_DEV_CALLS(("Found subdevice %s/%s\n", d.name(), d.shortname()));
sdev->custom_netlist_additions(*m_setup);
sdev->custom_netlist_additions(setup());
}
}
m_setup->start_devices();
m_setup->resolve_inputs();
netlist().start();
netlist().save(*this, m_rem, "m_rem");
netlist().save(*this, m_div, "m_div");
@ -505,12 +501,8 @@ void netlist_mame_device_t::device_reset()
void netlist_mame_device_t::device_stop()
{
LOG_DEV_CALLS(("device_stop\n"));
netlist().print_stats();
netlist().stop();
global_free(m_setup);
m_setup = nullptr;
global_free(m_netlist);
m_netlist = nullptr;
}

View File

@ -160,7 +160,7 @@ public:
static void static_set_constructor(device_t &device, void (*setup_func)(netlist::setup_t &));
ATTR_HOT inline netlist::setup_t &setup() { return *m_setup; }
ATTR_HOT inline netlist::setup_t &setup() { return m_netlist->setup(); }
ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; }
ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; }
@ -195,7 +195,6 @@ private:
netlist::netlist_time m_old;
netlist_mame_t * m_netlist;
netlist::setup_t * m_setup;
void (*m_setup_func)(netlist::setup_t &);
};

View File

@ -58,7 +58,7 @@ NETLIB_OBJECT(VCCS)
public:
NETLIB_CONSTRUCTOR(VCCS)
, m_G(*this, "G", 1.0)
, m_RI(*this, "RI", NL_FCONST(1.0) / netlist().gmin())
, m_RI(*this, "RI", 1e9)
, m_OP(*this, "OP")
, m_ON(*this, "ON")
, m_IP(*this, "IP")

View File

@ -79,6 +79,8 @@ NETLIB_RESET(OPAMP)
double RP = 0.5 / 3.1459 / CP / m_model.model_value("FPF");
double G = m_model.model_value("UGF") / m_model.model_value("FPF") / RP;
printf("Min Freq %s: %f\n", name().c_str(), 1.0 / (CP*RP / (G*RP)));
m_CP->m_C.setTo(CP);
m_RP.set_R(RP);
m_G1.m_G.setTo(G);

View File

@ -99,7 +99,7 @@ NETLIB_OBJECT(OPAMP)
private:
NETLIB_SUB(R) m_RP;
NETLIB_SUB(R_base) m_RP;
NETLIB_SUB(VCCS) m_G1;
NETLIB_SUBXX(C) m_CP;
NETLIB_SUBXX(VCVS) m_EBUF;

View File

@ -182,7 +182,7 @@ protected:
NETLIB_OBJECT_DERIVED(R, R_base)
{
NETLIB_CONSTRUCTOR_DERIVED(R, R_base)
, m_R(*this, "R", 1.0 / netlist().gmin())
, m_R(*this, "R", 1e9)
{
}
@ -193,6 +193,10 @@ protected:
NETLIB_RESETI();
//NETLIB_UPDATEI() { }
NETLIB_UPDATE_PARAMI();
private:
/* protect set_R ... it's a recipe to desaster when used to bypass the parameter */
using NETLIB_NAME(R_base)::set_R;
};
// -----------------------------------------------------------------------------
@ -202,9 +206,9 @@ protected:
NETLIB_OBJECT(POT)
{
NETLIB_CONSTRUCTOR(POT)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R(*this, "R", 1.0 / netlist().gmin())
, m_R1(*this, "_R1")
, m_R2(*this, "_R2")
, m_R(*this, "R", 10000)
, m_Dial(*this, "DIAL", 0.5)
, m_DialIsLog(*this, "DIALLOG", 0)
{
@ -232,8 +236,8 @@ private:
NETLIB_OBJECT(POT2)
{
NETLIB_CONSTRUCTOR(POT2)
, m_R1(*this, "R1")
, m_R(*this, "R", 1.0 / netlist().gmin())
, m_R1(*this, "_R1")
, m_R(*this, "R", 10000)
, m_Dial(*this, "DIAL", 0.5)
, m_DialIsLog(*this, "DIALLOG", 0)
, m_Reverse(*this, "REVERSE", 0)

View File

@ -24,17 +24,25 @@ namespace netlist
{
}
NETLIB_RESETI() { }
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(vdd_vss) m_supply;
NETLIB_SUB(R) m_R;
NETLIB_SUB(R_base) m_R;
analog_input_t m_control;
param_double_t m_base_r;
};
NETLIB_RESET(CD4066_GATE)
{
// Start in off condition
// FIXME: is ROFF correct?
m_R.set_R(NL_FCONST(1.0) / netlist().gmin());
}
NETLIB_UPDATE(CD4066_GATE)
{
nl_double sup = (m_supply.vdd() - m_supply.vss());

View File

@ -16,24 +16,29 @@ namespace netlist { namespace devices {
NETLIB_CONSTRUCTOR(CD4316_GATE)
NETLIB_FAMILY("CD4XXX")
, m_supply(*this, "PS")
, m_R(*this, "R")
, m_R(*this, "_R")
, m_S(*this, "S")
, m_E(*this, "E")
, m_base_r(*this, "BASER", 45.0)
{
}
NETLIB_RESETI() { }
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(vdd_vss) m_supply;
NETLIB_SUB(R) m_R;
NETLIB_SUB(R_base) m_R;
logic_input_t m_S, m_E;
param_double_t m_base_r;
};
NETLIB_RESET(CD4316_GATE)
{
m_R.set_R(NL_FCONST(1.0) / netlist().gmin());
}
NETLIB_UPDATE(CD4316_GATE)
{
m_R.update_dev();

View File

@ -44,10 +44,10 @@ namespace netlist
NETLIB_RESETI();
protected:
NETLIB_SUB(R) m_R1;
NETLIB_SUB(R) m_R2;
NETLIB_SUB(R) m_R3;
NETLIB_SUB(R) m_RDIS;
NETLIB_SUB(R_base) m_R1;
NETLIB_SUB(R_base) m_R2;
NETLIB_SUB(R_base) m_R3;
NETLIB_SUB(R_base) m_RDIS;
logic_input_t m_RESET;
analog_input_t m_THRES;

View File

@ -91,6 +91,11 @@ namespace netlist
// nld_res_sw
// -----------------------------------------------------------------------------
NETLIB_RESET(res_sw)
{
m_last_state = 0;
m_R.set_R(m_ROFF());
}
NETLIB_UPDATE(res_sw)
{

View File

@ -386,7 +386,7 @@ namespace netlist
{
public:
NETLIB_CONSTRUCTOR(res_sw)
, m_R(*this, "R")
, m_R(*this, "_R")
, m_I(*this, "I")
, m_RON(*this, "RON", 1.0)
, m_ROFF(*this, "ROFF", 1.0E20)
@ -396,16 +396,12 @@ namespace netlist
register_subalias("2", m_R.m_N);
}
NETLIB_SUB(R) m_R;
NETLIB_SUB(R_base) m_R;
logic_input_t m_I;
param_double_t m_RON;
param_double_t m_ROFF;
NETLIB_RESETI()
{
m_last_state = 0;
m_R.set_R(m_ROFF());
}
NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
NETLIB_UPDATEI();

View File

@ -243,19 +243,20 @@ netlist_t::netlist_t(const pstring &aname)
, m_queue(*this)
, m_mainclock(nullptr)
, m_solver(nullptr)
, m_gnd(nullptr)
, m_params(nullptr)
, m_name(aname)
, m_setup(nullptr)
, m_log(this)
, m_lib(nullptr)
{
state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
state().save_item(this, m_time, "m_time");
m_setup = new setup_t(*this);
}
netlist_t::~netlist_t()
{
if (m_setup != nullptr)
delete m_setup;
m_nets.clear();
m_devices.clear();
@ -278,15 +279,15 @@ void netlist_t::register_dev(plib::owned_ptr<device_t> dev)
void netlist_t::start()
{
setup().start_devices1();
/* load the library ... */
/* make sure the solver and parameters are started first! */
for (auto & e : setup().m_device_factory)
{
if ( setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
|| setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
|| setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
if ( setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
|| setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
{
auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
@ -296,18 +297,14 @@ void netlist_t::start()
log().debug("Searching for mainclock and solver ...\n");
m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver");
m_gnd = get_single_device<devices::NETLIB_NAME(gnd)>("gnd");
m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
/* create devices */
for (auto & e : setup().m_device_factory)
{
if ( !setup().factory().is_class<devices::NETLIB_NAME(mainclock)>(e.second)
&& !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
&& !setup().factory().is_class<devices::NETLIB_NAME(gnd)>(e.second)
if ( !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
&& !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
{
auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
@ -315,6 +312,9 @@ void netlist_t::start()
}
}
log().debug("Searching for mainclock\n");
m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
bool use_deactivate = (m_params->m_use_deactivate() ? true : false);
for (auto &d : m_devices)
@ -333,16 +333,35 @@ void netlist_t::start()
d->set_hint_deactivate(false);
}
pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
m_lib = plib::palloc<plib::dynlib>(libpath);
/* resolve inputs */
setup().resolve_inputs1();
log().verbose("initialize solver ...\n");
if (m_solver == nullptr)
{
for (auto &p : m_nets)
if (p->is_analog())
log().fatal("No solver found for this net although analog elements are present\n");
}
else
m_solver->post_start();
/* finally, set the pointers */
log().debug("Setting delegate pointers ...\n");
for (auto &dev : m_devices)
dev->set_delegate_pointer();
}
void netlist_t::stop()
{
log().debug("Printing statistics ...\n");
print_stats();
log().debug("Stopping solver device ...\n");
m_solver->stop();
}

View File

@ -1166,11 +1166,10 @@ namespace netlist
void start();
void stop();
const detail::queue_t &queue() const { return m_queue; }
detail::queue_t &queue() { return m_queue; }
const netlist_time time() const { return m_time; }
devices::NETLIB_NAME(solver) *solver() const { return m_solver; }
devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; }
/* never use this in constructors! */
nl_double gmin() const;
void push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT;
@ -1181,7 +1180,6 @@ namespace netlist
void rebuild_lists(); /* must be called after post_load ! */
void set_setup(setup_t *asetup) { m_setup = asetup; }
setup_t &setup() { return *m_setup; }
void register_dev(plib::owned_ptr<device_t> dev);
@ -1237,14 +1235,18 @@ namespace netlist
plib::dynlib &lib() { return *m_lib; }
void print_stats() const;
std::vector<plib::owned_ptr<core_device_t>> m_devices;
/* sole use is to manage lifetime of net objects */
std::vector<plib::owned_ptr<detail::net_t>> m_nets;
/* sole use is to manage lifetime of family objects */
std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
const detail::queue_t &queue() const { return m_queue; }
detail::queue_t &queue() { return m_queue; }
protected:
void print_stats() const;
private:
plib::state_manager_t m_state;
/* mostly rw */
@ -1255,7 +1257,6 @@ namespace netlist
devices::NETLIB_NAME(mainclock) * m_mainclock;
devices::NETLIB_NAME(solver) * m_solver;
devices::NETLIB_NAME(gnd) * m_gnd;
devices::NETLIB_NAME(netlistparams) *m_params;
pstring m_name;

View File

@ -35,7 +35,6 @@ setup_t::setup_t(netlist_t &netlist)
, m_proxy_cnt(0)
, m_frontier_cnt(0)
{
netlist.set_setup(this);
initialize_factory(m_factory);
NETLIST_NAME(base)(*this);
}
@ -48,7 +47,6 @@ setup_t::~setup_t()
m_terminals.clear();
m_param_values.clear();
netlist().set_setup(nullptr);
m_sources.clear();
pstring::resetmem();
@ -703,10 +701,8 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t
return ret;
}
void setup_t::resolve_inputs()
void setup_t::resolve_inputs1()
{
bool has_twoterms = false;
log().verbose("Resolving inputs ...");
/* Netlist can directly connect input to input.
@ -776,31 +772,13 @@ void setup_t::resolve_inputs()
log().verbose("looking for two terms connected to rail nets ...\n");
for (auto & t : netlist().get_device_list<devices::NETLIB_NAME(twoterm)>())
{
has_twoterms = true;
if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
log().warning("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name());
}
log().verbose("initialize solver ...\n");
if (netlist().solver() == nullptr)
{
if (has_twoterms)
log().fatal("No solver found for this net although analog elements are present\n");
}
else
netlist().solver()->post_start();
/* finally, set the pointers */
log().debug("Initializing devices ...\n");
for (auto &dev : netlist().m_devices)
dev->set_delegate_pointer();
}
void setup_t::start_devices()
void setup_t::start_devices1()
{
pstring env = plib::util::environment("NL_LOGS");
@ -817,8 +795,6 @@ void setup_t::start_devices()
netlist().register_dev(std::move(nc));
}
}
netlist().start();
}
plib::plog_base<NL_DEBUG> &setup_t::log()

View File

@ -227,8 +227,8 @@ namespace netlist
param_t *find_param(const pstring &param_in, bool required = true) const;
void start_devices();
void resolve_inputs();
void start_devices1();
void resolve_inputs1();
/* handle namespace */

View File

@ -128,19 +128,16 @@ class netlist_tool_t : public netlist::netlist_t
public:
netlist_tool_t(const pstring &aname)
: netlist::netlist_t(aname), m_setup(nullptr)
: netlist::netlist_t(aname)
{
}
~netlist_tool_t()
{
if (m_setup != nullptr)
plib::pfree(m_setup);
}
void init()
{
m_setup = plib::palloc<netlist::setup_t>(*this);
}
void read_netlist(const pstring &filename, const pstring &name,
@ -151,19 +148,18 @@ public:
// read the netlist ...
for (auto & d : defines)
m_setup->register_define(d);
setup().register_define(d);
for (auto & r : roms)
m_setup->register_source(plib::make_unique_base<netlist::source_t, netlist_data_folder_t>(*m_setup, r));
setup().register_source(plib::make_unique_base<netlist::source_t, netlist_data_folder_t>(setup(), r));
m_setup->register_source(plib::make_unique_base<netlist::source_t,
netlist::source_file_t>(*m_setup, filename));
m_setup->include(name);
setup().register_source(plib::make_unique_base<netlist::source_t,
netlist::source_file_t>(setup(), filename));
setup().include(name);
log_setup(logs);
// start devices
m_setup->start_devices();
m_setup->resolve_inputs();
this->start();
// reset
this->reset();
}
@ -174,19 +170,16 @@ public:
for (auto & log : logs)
{
pstring name = "log_" + log;
/*netlist_device_t *nc = */ m_setup->register_dev("LOG", name);
m_setup->register_link(name + ".I", log);
/*netlist_device_t *nc = */ setup().register_dev("LOG", name);
setup().register_link(name + ".I", log);
}
}
netlist::setup_t &setup() { return *m_setup; }
protected:
void vlog(const plib::plog_level &l, const pstring &ls) const override;
private:
netlist::setup_t *m_setup;
};
void netlist_tool_t::vlog(const plib::plog_level &l, const pstring &ls) const
@ -210,18 +203,12 @@ void usage(tool_options_t &opts)
struct input_t
{
#if 0
input_t()
: m_param(nullptr), m_value(0.0)
{
}
#endif
input_t(const netlist::setup_t &setup, const pstring &line)
{
char buf[400];
double t;
int e = sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf, &m_value);
if ( e!= 3)
if (e != 3)
throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line));
m_time = netlist::netlist_time::from_double(t);
m_param = setup.find_param(buf, true);
@ -249,7 +236,6 @@ struct input_t
netlist::netlist_time m_time;
netlist::param_t *m_param;
double m_value;
};
static std::vector<input_t> read_input(const netlist::setup_t &setup, pstring fname)
@ -359,8 +345,7 @@ static void listdevices(tool_options_t &opts)
nt.setup().include("dummy");
nt.setup().start_devices();
nt.setup().resolve_inputs();
nt.start();
std::vector<plib::owned_ptr<netlist::core_device_t>> devs;