mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
Merge netlist_dev branch, all code_refactoring: (nw)
Object model optimisation. Merge remote-tracking branch 'origin/master' into netlist_dev Fix a merge issue. #if ==> #elif. Ouch. Default PHAS_PMF_INTERNAL=0 for 32bit windows mingw. Change UINT8 to uint_[fast|least|8_t. Move state_var so it can be used by base devices as well. Remove last traces of ATTR_ALIGN. Refactored netlist_time into a template. Removed implicit double assignment to netlist. Doomed to produce bugs. Instead, use netlist_time::from_double. Switch to using proper (i.e. bool type) param_logic_t. Formally differentiate between logic inputs (e.g. switches) and int inputs (e.g. resistor ladders or selection switches). Added parameter USE_DEACTIVATE to truthtable devices. Added more constexpr to netlist_time. Fixed some ifdef code paths. - More c++. - Simplify main processing loop. As a nice side-effect that squeezed out some cycles. - More cycle squeezing. - Removed pvector_t. - Use std::sort. - Refactored netlist state manager. - Introduction of state_var object template to be used on device state members. - Changed remaining save occurrences to state_var. - Rewrote nltool's listdevices command. This allowed removal of one member from devices which served solely for listdevices. - Remove hashmap_t. Fix kidniki regression.
This commit is contained in:
parent
809de6dd7f
commit
404e589cff
@ -27,6 +27,7 @@ const device_type NETLIST_SOUND = &device_creator<netlist_mame_sound_device_t>;
|
||||
/* subdevices */
|
||||
|
||||
const device_type NETLIST_ANALOG_INPUT = &device_creator<netlist_mame_analog_input_t>;
|
||||
const device_type NETLIST_INT_INPUT = &device_creator<netlist_mame_int_input_t>;
|
||||
const device_type NETLIST_LOGIC_INPUT = &device_creator<netlist_mame_logic_input_t>;
|
||||
const device_type NETLIST_STREAM_INPUT = &device_creator<netlist_mame_stream_input_t>;
|
||||
|
||||
@ -113,11 +114,11 @@ void netlist_mame_analog_output_t::device_start()
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_logic_input_t
|
||||
// netlist_mame_int_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
netlist_mame_logic_input_t::netlist_mame_logic_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, NETLIST_ANALOG_INPUT, "Netlist Logic Input", tag, owner, clock, "netlist_logic_input", __FILE__),
|
||||
netlist_mame_int_input_t::netlist_mame_int_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, NETLIST_INT_INPUT, "Netlist Logic Input", tag, owner, clock, "netlist_logic_input", __FILE__),
|
||||
netlist_mame_sub_interface(*owner),
|
||||
m_param(nullptr),
|
||||
m_mask(0xffffffff),
|
||||
@ -126,16 +127,16 @@ netlist_mame_logic_input_t::netlist_mame_logic_input_t(const machine_config &mco
|
||||
{
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::static_set_params(device_t &device, const char *param_name, const UINT32 mask, const UINT32 shift)
|
||||
void netlist_mame_int_input_t::static_set_params(device_t &device, const char *param_name, const UINT32 mask, const UINT32 shift)
|
||||
{
|
||||
netlist_mame_logic_input_t &netlist = downcast<netlist_mame_logic_input_t &>(device);
|
||||
netlist_mame_int_input_t &netlist = downcast<netlist_mame_int_input_t &>(device);
|
||||
LOG_DEV_CALLS(("static_set_params %s\n", device.tag()));
|
||||
netlist.m_param_name = param_name;
|
||||
netlist.m_shift = shift;
|
||||
netlist.m_mask = mask;
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::device_start()
|
||||
void netlist_mame_int_input_t::device_start()
|
||||
{
|
||||
LOG_DEV_CALLS(("start %s\n", tag()));
|
||||
netlist::param_t *p = downcast<netlist_mame_device_t *>(this->owner())->setup().find_param(m_param_name);
|
||||
@ -146,6 +147,38 @@ void netlist_mame_logic_input_t::device_start()
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_logic_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
netlist_mame_logic_input_t::netlist_mame_logic_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, NETLIST_LOGIC_INPUT, "Netlist Logic Input", tag, owner, clock, "netlist_logic_input", __FILE__),
|
||||
netlist_mame_sub_interface(*owner),
|
||||
m_param(nullptr),
|
||||
m_shift(0),
|
||||
m_param_name("")
|
||||
{
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::static_set_params(device_t &device, const char *param_name, const UINT32 shift)
|
||||
{
|
||||
netlist_mame_logic_input_t &netlist = downcast<netlist_mame_logic_input_t &>(device);
|
||||
LOG_DEV_CALLS(("static_set_params %s\n", device.tag()));
|
||||
netlist.m_param_name = param_name;
|
||||
netlist.m_shift = shift;
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::device_start()
|
||||
{
|
||||
LOG_DEV_CALLS(("start %s\n", tag()));
|
||||
netlist::param_t *p = downcast<netlist_mame_device_t *>(this->owner())->setup().find_param(m_param_name);
|
||||
m_param = dynamic_cast<netlist::param_logic_t *>(p);
|
||||
if (m_param == nullptr)
|
||||
{
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.cstr());
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_stream_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -322,9 +355,9 @@ void netlist_mame_device_t::device_start()
|
||||
m_setup->start_devices();
|
||||
m_setup->resolve_inputs();
|
||||
|
||||
netlist().save_item(this, m_rem, "m_rem");
|
||||
netlist().save_item(this, m_div, "m_div");
|
||||
netlist().save_item(this, m_old, "m_old");
|
||||
netlist().save(*this, m_rem, "m_rem");
|
||||
netlist().save(*this, m_div, "m_div");
|
||||
netlist().save(*this, m_old, "m_old");
|
||||
|
||||
save_state();
|
||||
|
||||
@ -366,7 +399,7 @@ ATTR_COLD void netlist_mame_device_t::device_post_load()
|
||||
{
|
||||
LOG_DEV_CALLS(("device_post_load\n"));
|
||||
|
||||
netlist().post_load();
|
||||
netlist().state().post_load();
|
||||
netlist().rebuild_lists();
|
||||
}
|
||||
|
||||
@ -374,14 +407,14 @@ ATTR_COLD void netlist_mame_device_t::device_pre_save()
|
||||
{
|
||||
LOG_DEV_CALLS(("device_pre_save\n"));
|
||||
|
||||
netlist().pre_save();
|
||||
netlist().state().pre_save();
|
||||
}
|
||||
|
||||
void netlist_mame_device_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::update_time_x()
|
||||
void netlist_mame_device_t::update_time_x()
|
||||
{
|
||||
const netlist::netlist_time newt(netlist().time());
|
||||
const netlist::netlist_time delta(newt - m_old + m_rem);
|
||||
@ -391,7 +424,7 @@ ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::update_time_x()
|
||||
m_icount -= d;
|
||||
}
|
||||
|
||||
ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::check_mame_abort_slice()
|
||||
void netlist_mame_device_t::check_mame_abort_slice()
|
||||
{
|
||||
if (m_icount <= 0)
|
||||
netlist().abort_current_queue_slice();
|
||||
@ -399,53 +432,48 @@ ATTR_HOT ATTR_ALIGN void netlist_mame_device_t::check_mame_abort_slice()
|
||||
|
||||
ATTR_COLD void netlist_mame_device_t::save_state()
|
||||
{
|
||||
for (auto const & s : netlist().save_list())
|
||||
for (auto const & s : netlist().state().save_list())
|
||||
{
|
||||
netlist().log().debug("saving state for {1}\n", s->m_name.cstr());
|
||||
switch (s->m_dt)
|
||||
if (s->m_dt.is_float)
|
||||
{
|
||||
case pstate_data_type_e::DT_DOUBLE:
|
||||
{
|
||||
double *td = s->resolved<double>();
|
||||
if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
|
||||
}
|
||||
break;
|
||||
case pstate_data_type_e::DT_FLOAT:
|
||||
{
|
||||
float *td = s->resolved<float>();
|
||||
if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
|
||||
}
|
||||
break;
|
||||
#if (PHAS_INT128)
|
||||
case pstate_data_type_e::DT_INT128:
|
||||
// FIXME: we are cheating here
|
||||
save_pointer((char *) s->m_ptr, s->m_name.cstr(), s->m_count * sizeof(INT128));
|
||||
break;
|
||||
#endif
|
||||
case pstate_data_type_e::DT_INT64:
|
||||
save_pointer((INT64 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
break;
|
||||
case pstate_data_type_e::DT_INT16:
|
||||
save_pointer((INT16 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
break;
|
||||
case pstate_data_type_e::DT_INT8:
|
||||
save_pointer((INT8 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
break;
|
||||
case pstate_data_type_e::DT_INT:
|
||||
save_pointer((int *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
break;
|
||||
case pstate_data_type_e::DT_BOOLEAN:
|
||||
save_pointer((bool *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
break;
|
||||
case pstate_data_type_e::DT_CUSTOM:
|
||||
break;
|
||||
case pstate_data_type_e::NOT_SUPPORTED:
|
||||
default:
|
||||
netlist().log().fatal("found unsupported save element %s\n", s->m_name);
|
||||
break;
|
||||
if (s->m_dt.size == sizeof(double))
|
||||
{
|
||||
double *td = s->resolved<double>();
|
||||
if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
|
||||
}
|
||||
else if (s->m_dt.size == sizeof(float))
|
||||
{
|
||||
float *td = s->resolved<float>();
|
||||
if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
|
||||
}
|
||||
else
|
||||
netlist().log().fatal("Unknown floating type for {1}\n", s->m_name.cstr());
|
||||
}
|
||||
else if (s->m_dt.is_integral)
|
||||
{
|
||||
if (s->m_dt.size == sizeof(INT64))
|
||||
save_pointer((INT64 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
else if (s->m_dt.size == sizeof(INT32))
|
||||
save_pointer((INT32 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
else if (s->m_dt.size == sizeof(INT16))
|
||||
save_pointer((INT16 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
else if (s->m_dt.size == sizeof(INT8))
|
||||
save_pointer((INT8 *) s->m_ptr, s->m_name.cstr(), s->m_count);
|
||||
#if (PHAS_INT128)
|
||||
else if (s->m_dt.size == sizeof(INT128))
|
||||
save_pointer((INT64 *) s->m_ptr, s->m_name.cstr(), s->m_count * 2);
|
||||
#endif
|
||||
else
|
||||
netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->m_dt.size, s->m_name.cstr());
|
||||
}
|
||||
else if (s->m_dt.is_custom)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else
|
||||
netlist().log().fatal("found unsupported save element {1}\n", s->m_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -566,7 +594,7 @@ void netlist_mame_sound_device_t::device_start()
|
||||
|
||||
// Configure outputs
|
||||
|
||||
plib::pvector_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
|
||||
std::vector<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
|
||||
if (outdevs.size() == 0)
|
||||
fatalerror("No output devices");
|
||||
|
||||
@ -592,7 +620,7 @@ void netlist_mame_sound_device_t::device_start()
|
||||
m_num_inputs = 0;
|
||||
m_in = nullptr;
|
||||
|
||||
plib::pvector_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
|
||||
std::vector<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
|
||||
if (indevs.size() > 1)
|
||||
fatalerror("A maximum of one input device is allowed!");
|
||||
if (indevs.size() == 1)
|
||||
|
@ -36,9 +36,13 @@
|
||||
netlist_analog_output_delegate(& _class :: _member, \
|
||||
# _class "::" # _member, _class_tag, (_class *)nullptr) );
|
||||
|
||||
#define MCFG_NETLIST_LOGIC_INPUT(_basetag, _tag, _name, _shift, _mask) \
|
||||
#define MCFG_NETLIST_LOGIC_INPUT(_basetag, _tag, _name, _shift) \
|
||||
MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_LOGIC_INPUT, 0) \
|
||||
netlist_mame_logic_input_t::static_set_params(*device, _name, _mask, _shift);
|
||||
netlist_mame_logic_input_t::static_set_params(*device, _name, _shift);
|
||||
|
||||
#define MCFG_NETLIST_INT_INPUT(_basetag, _tag, _name, _shift, _mask) \
|
||||
MCFG_DEVICE_ADD(_basetag ":" _tag, NETLIST_INT_INPUT, 0) \
|
||||
netlist_mame_int_input_t::static_set_params(*device, _name, _mask, _shift);
|
||||
|
||||
#define MCFG_NETLIST_STREAM_INPUT(_basetag, _chan, _name) \
|
||||
MCFG_DEVICE_ADD(_basetag ":cin" # _chan, NETLIST_STREAM_INPUT, 0) \
|
||||
@ -52,6 +56,9 @@
|
||||
#define NETLIST_LOGIC_PORT_CHANGED(_base, _tag) \
|
||||
PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_logic_input_t, input_changed, 0)
|
||||
|
||||
#define NETLIST_INT_PORT_CHANGED(_base, _tag) \
|
||||
PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_logic_input_t, input_changed, 0)
|
||||
|
||||
#define NETLIST_ANALOG_PORT_CHANGED(_base, _tag) \
|
||||
PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_analog_input_t, input_changed, 0)
|
||||
|
||||
@ -404,17 +411,17 @@ private:
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_logic_input_t
|
||||
// netlist_mame_int_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_mame_logic_input_t : public device_t,
|
||||
class netlist_mame_int_input_t : public device_t,
|
||||
public netlist_mame_sub_interface
|
||||
{
|
||||
public:
|
||||
|
||||
// construction/destruction
|
||||
netlist_mame_logic_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~netlist_mame_logic_input_t() { }
|
||||
netlist_mame_int_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~netlist_mame_int_input_t() { }
|
||||
|
||||
static void static_set_params(device_t &device, const char *param_name, const UINT32 mask, const UINT32 shift);
|
||||
|
||||
@ -449,6 +456,51 @@ private:
|
||||
pstring m_param_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_logic_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_mame_logic_input_t : public device_t,
|
||||
public netlist_mame_sub_interface
|
||||
{
|
||||
public:
|
||||
|
||||
// construction/destruction
|
||||
netlist_mame_logic_input_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~netlist_mame_logic_input_t() { }
|
||||
|
||||
static void static_set_params(device_t &device, const char *param_name, const UINT32 shift);
|
||||
|
||||
inline void write(const UINT32 val)
|
||||
{
|
||||
const UINT32 v = (val >> m_shift) & 1;
|
||||
if (v != m_param->Value())
|
||||
synchronize(0, v);
|
||||
}
|
||||
|
||||
inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
|
||||
DECLARE_WRITE_LINE_MEMBER(write_line) { write(state); }
|
||||
DECLARE_WRITE8_MEMBER(write8) { write(data); }
|
||||
DECLARE_WRITE16_MEMBER(write16) { write(data); }
|
||||
DECLARE_WRITE32_MEMBER(write32) { write(data); }
|
||||
DECLARE_WRITE64_MEMBER(write64) { write(data); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override
|
||||
{
|
||||
if (is_sound_device())
|
||||
update_to_current_time();
|
||||
m_param->setTo(param);
|
||||
}
|
||||
|
||||
private:
|
||||
netlist::param_logic_t *m_param;
|
||||
UINT32 m_shift;
|
||||
pstring m_param_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_stream_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -507,10 +559,9 @@ public:
|
||||
: device_t(anetlist, name)
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(0)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
|
||||
save(NLNAME(m_last));
|
||||
}
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
@ -542,7 +593,7 @@ private:
|
||||
netlist::analog_input_t m_in;
|
||||
netlist_analog_output_delegate m_callback;
|
||||
netlist_mame_cpu_device_t *m_cpu_device;
|
||||
nl_double m_last;
|
||||
netlist::state_var<nl_double> m_last;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -557,10 +608,10 @@ public:
|
||||
, m_channel(*this, "CHAN", 0)
|
||||
, m_mult(*this, "MULT", 1000.0)
|
||||
, m_offset(*this, "OFFSET", 0.0)
|
||||
, m_sample(netlist::netlist_time::from_hz(1)) //sufficiently big enough
|
||||
, m_in(*this, "IN")
|
||||
, m_last_buffer(*this, "m_last_buffer", netlist::netlist_time::zero())
|
||||
{
|
||||
m_sample = netlist::netlist_time::from_hz(1); //sufficiently big enough
|
||||
save(NAME(m_last_buffer));
|
||||
}
|
||||
|
||||
static const int BUFSIZE = 2048;
|
||||
@ -615,7 +666,7 @@ private:
|
||||
netlist::analog_input_t m_in;
|
||||
double m_cur;
|
||||
int m_last_pos;
|
||||
netlist::netlist_time m_last_buffer;
|
||||
netlist::state_var<netlist::netlist_time> m_last_buffer;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -710,6 +761,7 @@ extern const device_type NETLIST_CPU;
|
||||
extern const device_type NETLIST_SOUND;
|
||||
extern const device_type NETLIST_ANALOG_INPUT;
|
||||
extern const device_type NETLIST_LOGIC_INPUT;
|
||||
extern const device_type NETLIST_INT_INPUT;
|
||||
|
||||
extern const device_type NETLIST_ANALOG_OUTPUT;
|
||||
extern const device_type NETLIST_STREAM_INPUT;
|
||||
|
@ -105,7 +105,7 @@ NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
|
||||
, m_gB(NETLIST_GMIN_DEFAULT)
|
||||
, m_gC(NETLIST_GMIN_DEFAULT)
|
||||
, m_V(0.0)
|
||||
, m_state_on(0)
|
||||
, m_state_on(*this, "m_state_on", 0)
|
||||
{
|
||||
register_subalias("B", m_RB.m_P);
|
||||
register_subalias("E", m_RB.m_N);
|
||||
@ -119,8 +119,6 @@ NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
|
||||
|
||||
connect_late(m_RB.m_P, m_BC_dummy.m_P);
|
||||
connect_late(m_RC.m_P, m_BC_dummy.m_N);
|
||||
|
||||
save(NLNAME(m_state_on));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -141,7 +139,7 @@ protected:
|
||||
nl_double m_gB; // base conductance / switch on
|
||||
nl_double m_gC; // collector conductance / switch on
|
||||
nl_double m_V; // internal voltage source
|
||||
UINT8 m_state_on;
|
||||
state_var<unsigned> m_state_on;
|
||||
|
||||
private:
|
||||
};
|
||||
@ -155,11 +153,13 @@ NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
|
||||
, m_D_CB(*this, "m_D_CB", true)
|
||||
, m_D_EB(*this, "m_D_EB", true)
|
||||
, m_D_EC(*this, "m_D_EC", true)
|
||||
, m_alpha_f(0)
|
||||
, m_alpha_r(0)
|
||||
, m_gD_BC(*this, "m_D_BC")
|
||||
, m_gD_BE(*this, "m_D_BE")
|
||||
, m_D_CB(*this, "m_D_CB", true)
|
||||
, m_D_EB(*this, "m_D_EB", true)
|
||||
, m_D_EC(*this, "m_D_EC", true)
|
||||
, m_alpha_f(0)
|
||||
, m_alpha_r(0)
|
||||
{
|
||||
register_subalias("E", m_D_EB.m_P); // Cathode
|
||||
register_subalias("B", m_D_EB.m_N); // Anode
|
||||
@ -173,9 +173,6 @@ public:
|
||||
connect_late(m_D_EB.m_P, m_D_EC.m_P);
|
||||
connect_late(m_D_EB.m_N, m_D_CB.m_N);
|
||||
connect_late(m_D_CB.m_P, m_D_EC.m_N);
|
||||
|
||||
m_gD_BE.save("m_D_BE", *this);
|
||||
m_gD_BC.save("m_D_BC", *this);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -44,7 +44,7 @@ NETLIB_OBJECT(OPAMP)
|
||||
, m_G1(*this, "G1")
|
||||
, m_VCC(*this, "VCC")
|
||||
, m_GND(*this, "GND")
|
||||
, m_model(*this, "MODEL", "")
|
||||
, m_model(*this, "MODEL", "LM324")
|
||||
, m_VH(*this, "VH")
|
||||
, m_VL(*this, "VL")
|
||||
, m_VREF(*this, "VREF")
|
||||
|
@ -27,7 +27,7 @@ NETLIB_RESET(switch1)
|
||||
|
||||
NETLIB_UPDATE(switch1)
|
||||
{
|
||||
if (m_POS.Value() == 0)
|
||||
if (!m_POS.Value())
|
||||
{
|
||||
m_R.set_R(R_OFF);
|
||||
}
|
||||
@ -57,7 +57,7 @@ NETLIB_RESET(switch2)
|
||||
|
||||
NETLIB_UPDATE(switch2)
|
||||
{
|
||||
if (m_POS.Value() == 0)
|
||||
if (!m_POS.Value())
|
||||
{
|
||||
m_R1.set_R(R_ON);
|
||||
m_R2.set_R(R_OFF);
|
||||
|
@ -47,7 +47,7 @@ NETLIB_OBJECT(switch1)
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
NETLIB_SUB(R_base) m_R;
|
||||
param_int_t m_POS;
|
||||
param_logic_t m_POS;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(switch2)
|
||||
@ -71,7 +71,7 @@ NETLIB_OBJECT(switch2)
|
||||
|
||||
NETLIB_SUB(R_base) m_R1;
|
||||
NETLIB_SUB(R_base) m_R2;
|
||||
param_int_t m_POS;
|
||||
param_logic_t m_POS;
|
||||
};
|
||||
|
||||
} //namespace devices
|
||||
|
@ -19,12 +19,18 @@ namespace netlist
|
||||
// generic_diode
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
generic_diode::generic_diode()
|
||||
generic_diode::generic_diode(device_t &dev, pstring name)
|
||||
: m_Vd(dev, name + ".m_Vd", 0.7)
|
||||
, m_Id(dev, name + ".m_Id", 0.0)
|
||||
, m_G(dev, name + ".m_G", 1e-15)
|
||||
, m_Vt(0.0)
|
||||
, m_Is(0.0)
|
||||
, m_n(0.0)
|
||||
, m_gmin(1e-15)
|
||||
, m_VtInv(0.0)
|
||||
, m_Vcrit(0.0)
|
||||
{
|
||||
m_Vd = 0.7;
|
||||
set_param(1e-15, 1, 1e-15);
|
||||
m_G = m_gmin;
|
||||
m_Id = 0.0;
|
||||
}
|
||||
|
||||
void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin)
|
||||
@ -40,13 +46,6 @@ void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double g
|
||||
m_VtInv = 1.0 / m_Vt;
|
||||
}
|
||||
|
||||
void generic_diode::save(pstring name, object_t &parent)
|
||||
{
|
||||
parent.save(m_Vd, name + ".m_Vd");
|
||||
parent.save(m_Id, name + ".m_Id");
|
||||
parent.save(m_G, name + ".m_G");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_twoterm
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -311,7 +311,7 @@ private:
|
||||
class generic_diode
|
||||
{
|
||||
public:
|
||||
generic_diode();
|
||||
generic_diode(device_t &dev, pstring name);
|
||||
|
||||
inline void update_diode(const nl_double nVd)
|
||||
{
|
||||
@ -360,12 +360,10 @@ public:
|
||||
|
||||
/* owning object must save those ... */
|
||||
|
||||
void save(pstring name, object_t &parent);
|
||||
|
||||
private:
|
||||
nl_double m_Vd;
|
||||
nl_double m_Id;
|
||||
nl_double m_G;
|
||||
state_var<nl_double> m_Vd;
|
||||
state_var<nl_double> m_Id;
|
||||
state_var<nl_double> m_G;
|
||||
|
||||
nl_double m_Vt;
|
||||
nl_double m_Is;
|
||||
@ -385,11 +383,10 @@ NETLIB_OBJECT_DERIVED(D, twoterm)
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(D, twoterm)
|
||||
, m_model(*this, "MODEL", "")
|
||||
, m_D(*this, "m_D")
|
||||
{
|
||||
register_subalias("A", m_P);
|
||||
register_subalias("K", m_N);
|
||||
|
||||
m_D.save("m_D", *this);
|
||||
}
|
||||
|
||||
NETLIB_DYNAMIC()
|
||||
|
@ -22,9 +22,8 @@ namespace netlist
|
||||
, m_IP(*this, "IP")
|
||||
, m_Q(*this, {{"Q1", "_Q2", "_Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9",
|
||||
"Q10", "Q11", "Q12", "Q13", "Q14"}})
|
||||
, m_cnt(0)
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
{
|
||||
save(NLNAME(m_cnt));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
@ -36,12 +35,12 @@ namespace netlist
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
void update_outputs(const UINT16 cnt);
|
||||
void update_outputs(const unsigned cnt);
|
||||
|
||||
logic_input_t m_IP;
|
||||
object_array_t<logic_output_t, 14> m_Q;
|
||||
|
||||
UINT16 m_cnt;
|
||||
state_var<unsigned> m_cnt;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(CD4020)
|
||||
@ -80,10 +79,9 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(CD4020_sub)
|
||||
{
|
||||
UINT8 cnt = m_cnt;
|
||||
cnt = ( cnt + 1) & 0x3fff;
|
||||
update_outputs(cnt);
|
||||
m_cnt = cnt;
|
||||
++m_cnt;
|
||||
m_cnt &= 0x3fff;
|
||||
update_outputs(m_cnt);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(CD4020)
|
||||
@ -101,7 +99,7 @@ namespace netlist
|
||||
m_sub.m_IP.activate_hl();
|
||||
}
|
||||
|
||||
inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const UINT16 cnt))
|
||||
inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const unsigned cnt))
|
||||
{
|
||||
/* static */ const netlist_time out_delayQn[14] = {
|
||||
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
|
||||
|
@ -18,14 +18,10 @@ namespace netlist
|
||||
, m_clk(*this, "CLK")
|
||||
, m_Q(*this, "Q")
|
||||
, m_QQ(*this, "QQ")
|
||||
, m_Q1(0)
|
||||
, m_Q2(0)
|
||||
, m_F(0)
|
||||
|
||||
, m_Q1(*this, "m_Q1", 0)
|
||||
, m_Q2(*this, "m_Q2", 0)
|
||||
, m_F(*this, "m_F", 0)
|
||||
{
|
||||
save(NLNAME(m_Q1));
|
||||
save(NLNAME(m_Q2));
|
||||
save(NLNAME(m_F));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -37,9 +33,9 @@ namespace netlist
|
||||
logic_output_t m_Q;
|
||||
logic_output_t m_QQ;
|
||||
|
||||
netlist_sig_t m_Q1;
|
||||
netlist_sig_t m_Q2;
|
||||
netlist_sig_t m_F;
|
||||
state_var<netlist_sig_t> m_Q1;
|
||||
state_var<netlist_sig_t> m_Q2;
|
||||
state_var<netlist_sig_t> m_F;
|
||||
|
||||
void newstate(const netlist_sig_t state);
|
||||
|
||||
@ -141,7 +137,7 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(74107A)
|
||||
{
|
||||
const UINT8 JK = (INPLOGIC(m_J) << 1) | INPLOGIC(m_K);
|
||||
const auto JK = (INPLOGIC(m_J) << 1) | INPLOGIC(m_K);
|
||||
|
||||
switch (JK)
|
||||
{
|
||||
|
@ -32,6 +32,9 @@ namespace netlist
|
||||
, m_Q(*this, "Q")
|
||||
, m_QQ(*this, "QQ")
|
||||
, m_CV(*this, "_CV") // internal
|
||||
, m_last_trig(*this, "m_last_trig", 0)
|
||||
, m_state(*this, "m_state", 0)
|
||||
, m_KP(*this, "m_KP", 0)
|
||||
, m_K(*this, "K", (m_dev_type == 4538) ? 0.4 : 0.4)
|
||||
, m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
|
||||
{
|
||||
@ -49,10 +52,6 @@ namespace netlist
|
||||
|
||||
connect_late(m_RN.m_R.m_P, m_RP.m_R.m_N);
|
||||
connect_late(m_CV, m_RN.m_R.m_P);
|
||||
|
||||
save(NLNAME(m_last_trig));
|
||||
save(NLNAME(m_state));
|
||||
save(NLNAME(m_KP));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -75,9 +74,9 @@ namespace netlist
|
||||
|
||||
analog_input_t m_CV;
|
||||
|
||||
netlist_sig_t m_last_trig;
|
||||
UINT8 m_state;
|
||||
double m_KP;
|
||||
state_var<netlist_sig_t> m_last_trig;
|
||||
state_var<unsigned> m_state;
|
||||
state_var<double> m_KP;
|
||||
|
||||
param_double_t m_K;
|
||||
param_double_t m_RI;
|
||||
|
@ -23,9 +23,8 @@ namespace netlist
|
||||
, m_C(*this, {{"C0", "C1", "C2", "C3"}})
|
||||
, m_G(*this, "G")
|
||||
, m_Y(*this, "AY") //FIXME: Change netlists
|
||||
, m_chan(0)
|
||||
, m_chan(*this, "m_chan", 0)
|
||||
{
|
||||
save(NLNAME(m_chan));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -37,7 +36,7 @@ namespace netlist
|
||||
|
||||
logic_output_t m_Y;
|
||||
|
||||
int m_chan;
|
||||
state_var<unsigned> m_chan;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(74153)
|
||||
@ -110,7 +109,7 @@ namespace netlist
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
|
||||
if (!INPLOGIC(m_G))
|
||||
{
|
||||
UINT8 t = INPLOGIC(m_C[m_chan]);
|
||||
uint_fast8_t t = INPLOGIC(m_C[m_chan]);
|
||||
OUTLOGIC(m_Y, t, delay[t] );
|
||||
}
|
||||
else
|
||||
|
@ -18,10 +18,9 @@ namespace netlist
|
||||
, m_CLK(*this, "CLK")
|
||||
, m_Q(*this, {{"Q1", "Q2", "Q3", "Q4"}})
|
||||
, m_QQ(*this, {{"Q1Q", "Q2Q", "Q3Q", "Q4Q"}})
|
||||
, m_data(0)
|
||||
, m_clrq(*this, "m_clr", 0)
|
||||
, m_data(*this, "m_data", 0)
|
||||
{
|
||||
save(NLNAME(m_clrq));
|
||||
save(NLNAME(m_data));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -32,8 +31,8 @@ namespace netlist
|
||||
object_array_t<logic_output_t, 4> m_Q;
|
||||
object_array_t<logic_output_t, 4> m_QQ;
|
||||
|
||||
netlist_sig_t m_clrq;
|
||||
UINT8 m_data;
|
||||
state_var<netlist_sig_t> m_clrq;
|
||||
state_var<unsigned> m_data;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(74175)
|
||||
@ -109,7 +108,7 @@ namespace netlist
|
||||
{
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
UINT8 d = (m_data >> i) & 1;
|
||||
netlist_sig_t d = (m_data >> i) & 1;
|
||||
OUTLOGIC(m_Q[i], d, delay[d]);
|
||||
OUTLOGIC(m_QQ[i], d ^ 1, delay[d ^ 1]);
|
||||
}
|
||||
@ -119,7 +118,7 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(74175)
|
||||
{
|
||||
UINT8 d = 0;
|
||||
uint_fast8_t d = 0;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
d |= (INPLOGIC(m_D[i]) << i);
|
||||
|
@ -33,7 +33,7 @@ namespace netlist
|
||||
logic_input_t m_C;
|
||||
logic_input_t m_D;
|
||||
|
||||
inline UINT8 read_ABCD() const
|
||||
uint_fast8_t read_ABCD() const
|
||||
{
|
||||
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
||||
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
|
||||
@ -48,6 +48,9 @@ namespace netlist
|
||||
, m_LOADQ(*this, "LOADQ")
|
||||
, m_CU(*this, "CU")
|
||||
, m_CD(*this, "CD")
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_last_CU(*this, "m_last_CU", 0)
|
||||
, m_last_CD(*this, "m_last_CD", 0)
|
||||
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
|
||||
, m_BORROWQ(*this, "BORROWQ")
|
||||
, m_CARRYQ(*this, "CARRYQ")
|
||||
@ -56,10 +59,6 @@ namespace netlist
|
||||
register_subalias("B", m_ABCD.m_B);
|
||||
register_subalias("C", m_ABCD.m_C);
|
||||
register_subalias("D", m_ABCD.m_D);
|
||||
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_last_CU));
|
||||
save(NLNAME(m_last_CD));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -72,9 +71,9 @@ namespace netlist
|
||||
logic_input_t m_CU;
|
||||
logic_input_t m_CD;
|
||||
|
||||
INT8 m_cnt;
|
||||
UINT8 m_last_CU;
|
||||
UINT8 m_last_CD;
|
||||
state_var<int> m_cnt;
|
||||
state_var<unsigned> m_last_CU;
|
||||
state_var<unsigned> m_last_CD;
|
||||
|
||||
object_array_t<logic_output_t, 4> m_Q;
|
||||
logic_output_t m_BORROWQ;
|
||||
|
@ -25,17 +25,13 @@ namespace netlist
|
||||
, m_LOADQ(*this, "LOADQ")
|
||||
, m_CU(*this, "CU")
|
||||
, m_CD(*this, "CD")
|
||||
, m_cnt(0)
|
||||
, m_last_CU(0)
|
||||
, m_last_CD(0)
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_last_CU(*this, "m_last_CU", 0)
|
||||
, m_last_CD(*this, "m_last_CD", 0)
|
||||
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
|
||||
, m_BORROWQ(*this, "BORROWQ")
|
||||
, m_CARRYQ(*this, "CARRYQ")
|
||||
{
|
||||
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_last_CU));
|
||||
save(NLNAME(m_last_CD));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -51,9 +47,9 @@ namespace netlist
|
||||
logic_input_t m_CU;
|
||||
logic_input_t m_CD;
|
||||
|
||||
INT8 m_cnt;
|
||||
UINT8 m_last_CU;
|
||||
UINT8 m_last_CD;
|
||||
state_var<int> m_cnt;
|
||||
state_var<unsigned> m_last_CU;
|
||||
state_var<unsigned> m_last_CD;
|
||||
|
||||
object_array_t<logic_output_t, 4> m_Q;
|
||||
logic_output_t m_BORROWQ;
|
||||
|
@ -13,14 +13,6 @@ namespace netlist
|
||||
namespace devices
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: Using truthtable is a lot slower than the explicit device
|
||||
* in breakout. Performance drops by 20%.
|
||||
*/
|
||||
|
||||
#define USE_TRUTHTABLE_7448 (0)
|
||||
|
||||
#if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE)
|
||||
|
||||
NETLIB_TRUTHTABLE(7448, 7, 7, 0);
|
||||
@ -37,18 +29,17 @@ namespace netlist
|
||||
, m_LTQ(*this, "LTQ")
|
||||
, m_BIQ(*this, "BIQ")
|
||||
, m_RBIQ(*this, "RBIQ")
|
||||
, m_state(0)
|
||||
, m_state(*this, "m_state", 0)
|
||||
, m_Q(*this, {{"a", "b", "c", "d", "e", "f", "g"}})
|
||||
{
|
||||
save(NLNAME(m_state));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
void update_outputs(UINT8 v);
|
||||
static const UINT8 tab7448[16][7];
|
||||
void update_outputs(uint_fast8_t v);
|
||||
static const uint_fast8_t tab7448[16][7];
|
||||
|
||||
logic_input_t m_A;
|
||||
logic_input_t m_B;
|
||||
@ -58,7 +49,7 @@ namespace netlist
|
||||
logic_input_t m_BIQ;
|
||||
logic_input_t m_RBIQ;
|
||||
|
||||
UINT8 m_state;
|
||||
state_var<unsigned> m_state;
|
||||
|
||||
object_array_t<logic_output_t, 7> m_Q; /* a .. g */
|
||||
|
||||
@ -167,7 +158,7 @@ namespace netlist
|
||||
m_C.activate();
|
||||
m_B.activate();
|
||||
m_A.activate();
|
||||
UINT8 v;
|
||||
uint_fast8_t v;
|
||||
|
||||
v = (INPLOGIC(m_A) << 0) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_D) << 3);
|
||||
if ((!INPLOGIC(m_RBIQ) && (v==0)))
|
||||
@ -186,7 +177,7 @@ namespace netlist
|
||||
m_RBIQ.inactivate();
|
||||
}
|
||||
|
||||
NETLIB_FUNC_VOID(7448, update_outputs, (UINT8 v))
|
||||
NETLIB_FUNC_VOID(7448, update_outputs, (uint_fast8_t v))
|
||||
{
|
||||
nl_assert(v<16);
|
||||
if (v != m_state)
|
||||
@ -199,7 +190,7 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
const UINT8 NETLIB_NAME(7448)::tab7448[16][7] =
|
||||
const uint_fast8_t NETLIB_NAME(7448)::tab7448[16][7] =
|
||||
{
|
||||
{ 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */
|
||||
{ 0, 1, 1, 0, 0, 0, 0 }, /* 01 */
|
||||
|
@ -26,6 +26,14 @@
|
||||
|
||||
#include "nl_base.h"
|
||||
|
||||
/*
|
||||
* FIXME: Using truthtable is a lot slower than the explicit device
|
||||
* in breakout. Performance drops by 20%. This can be fixed by
|
||||
* setting param USE_DEACTIVATE for the device.
|
||||
*/
|
||||
|
||||
#define USE_TRUTHTABLE_7448 (0)
|
||||
|
||||
#define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \
|
||||
NET_REGISTER_DEV(TTL_7448, name) \
|
||||
NET_CONNECT(name, A, cA0) \
|
||||
|
@ -69,12 +69,12 @@ namespace netlist
|
||||
m_B.activate();
|
||||
m_C.activate();
|
||||
m_D.activate();
|
||||
UINT8 t1 = INPLOGIC(m_A) & INPLOGIC(m_B);
|
||||
UINT8 t2 = INPLOGIC(m_C) & INPLOGIC(m_D);
|
||||
uint_fast8_t t1 = INPLOGIC(m_A) & INPLOGIC(m_B);
|
||||
uint_fast8_t t2 = INPLOGIC(m_C) & INPLOGIC(m_D);
|
||||
|
||||
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
|
||||
|
||||
UINT8 res = 0;
|
||||
uint_fast8_t res = 0;
|
||||
if (t1 ^ 1)
|
||||
{
|
||||
if (t2 ^ 1)
|
||||
|
@ -18,10 +18,8 @@ namespace netlist
|
||||
, m_CLK(*this, "CLK")
|
||||
, m_Q(*this, "Q")
|
||||
, m_QQ(*this, "QQ")
|
||||
, m_nextD(0)
|
||||
, m_nextD(*this, "m_nextD", 0)
|
||||
{
|
||||
|
||||
save(NLNAME(m_nextD));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -31,9 +29,9 @@ namespace netlist
|
||||
logic_input_t m_CLK;
|
||||
logic_output_t m_Q;
|
||||
logic_output_t m_QQ;
|
||||
INT8 m_nextD;
|
||||
state_var<unsigned> m_nextD;
|
||||
|
||||
inline void newstate(const UINT8 stateQ, const UINT8 stateQQ);
|
||||
inline void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ);
|
||||
|
||||
private:
|
||||
|
||||
@ -95,7 +93,7 @@ namespace netlist
|
||||
NETLIB_SUB(7474) m_2;
|
||||
};
|
||||
|
||||
inline void NETLIB_NAME(7474sub)::newstate(const UINT8 stateQ, const UINT8 stateQQ)
|
||||
inline void NETLIB_NAME(7474sub)::newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
|
||||
{
|
||||
// 0: High-to-low 40 ns, 1: Low-to-high 25 ns
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
|
||||
|
@ -24,14 +24,13 @@ namespace netlist
|
||||
, m_B2(*this, "B2")
|
||||
, m_B3(*this, "B3")
|
||||
, m_B4(*this, "B4")
|
||||
, m_lastr(0)
|
||||
, m_lastr(*this, "m_lastr", 0)
|
||||
, m_S1(*this, "S1")
|
||||
, m_S2(*this, "S2")
|
||||
, m_S3(*this, "S3")
|
||||
, m_S4(*this, "S4")
|
||||
, m_C4(*this, "C4")
|
||||
{
|
||||
save(NLNAME(m_lastr));
|
||||
}
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
@ -47,7 +46,7 @@ namespace netlist
|
||||
logic_input_t m_B3;
|
||||
logic_input_t m_B4;
|
||||
|
||||
UINT8 m_lastr;
|
||||
state_var<unsigned> m_lastr;
|
||||
|
||||
logic_output_t m_S1;
|
||||
logic_output_t m_S2;
|
||||
@ -90,10 +89,10 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(7483)
|
||||
{
|
||||
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
|
||||
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
|
||||
uint_fast8_t a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
|
||||
uint_fast8_t b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
|
||||
|
||||
UINT8 r = a + b + INPLOGIC(m_C0);
|
||||
uint_fast8_t r = a + b + INPLOGIC(m_C0);
|
||||
|
||||
if (r != m_lastr)
|
||||
{
|
||||
|
@ -21,14 +21,11 @@ namespace netlist
|
||||
, m_R2(*this, "R2")
|
||||
, m_R91(*this, "R91")
|
||||
, m_R92(*this, "R92")
|
||||
, m_cnt(0)
|
||||
, m_last_A(0)
|
||||
, m_last_B(0)
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_last_A(*this, "m_last_A", 0)
|
||||
, m_last_B(*this, "m_last_B", 0)
|
||||
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
|
||||
{
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_last_A));
|
||||
save(NLNAME(m_last_B));
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI();
|
||||
@ -44,9 +41,9 @@ namespace netlist
|
||||
logic_input_t m_R91;
|
||||
logic_input_t m_R92;
|
||||
|
||||
UINT8 m_cnt;
|
||||
UINT8 m_last_A;
|
||||
UINT8 m_last_B;
|
||||
state_var_u8 m_cnt;
|
||||
state_var_u8 m_last_A;
|
||||
state_var_u8 m_last_B;
|
||||
|
||||
object_array_t<logic_output_t, 4> m_Q;
|
||||
};
|
||||
|
@ -19,10 +19,9 @@ namespace netlist
|
||||
NETLIB_CONSTRUCTOR(7493ff)
|
||||
, m_I(*this, "CLK")
|
||||
, m_Q(*this, "Q")
|
||||
, m_reset(*this, "m_reset", 0)
|
||||
, m_state(*this, "m_state", 0)
|
||||
{
|
||||
|
||||
save(NLNAME(m_reset));
|
||||
save(NLNAME(m_state));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -32,8 +31,8 @@ namespace netlist
|
||||
logic_input_t m_I;
|
||||
logic_output_t m_Q;
|
||||
|
||||
UINT8 m_reset;
|
||||
UINT8 m_state;
|
||||
state_var_u8 m_reset;
|
||||
state_var_u8 m_state;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(7493)
|
||||
|
@ -52,15 +52,11 @@ namespace netlist
|
||||
NETLIB_CONSTRUCTOR(SN74LS629clk)
|
||||
, m_FB(*this, "FB")
|
||||
, m_Y(*this, "Y")
|
||||
, m_enableq(1)
|
||||
, m_out(0)
|
||||
, m_inc(netlist_time::zero())
|
||||
, m_enableq(*this, "m_enableq", 1)
|
||||
, m_out(*this, "m_out", 0)
|
||||
, m_inc(*this, "m_inc", netlist_time::zero())
|
||||
{
|
||||
connect_late(m_FB, m_Y);
|
||||
|
||||
save(NLNAME(m_enableq));
|
||||
save(NLNAME(m_inc));
|
||||
save(NLNAME(m_out));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
@ -76,9 +72,9 @@ namespace netlist
|
||||
logic_input_t m_FB;
|
||||
logic_output_t m_Y;
|
||||
|
||||
netlist_sig_t m_enableq;
|
||||
netlist_sig_t m_out;
|
||||
netlist_time m_inc;
|
||||
state_var<netlist_sig_t> m_enableq;
|
||||
state_var<netlist_sig_t> m_out;
|
||||
state_var<netlist_time> m_inc;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(SN74LS629)
|
||||
@ -216,7 +212,7 @@ namespace netlist
|
||||
|
||||
// FIXME: we need a possibility to remove entries from queue ...
|
||||
// or an exact model ...
|
||||
m_clock.m_inc = netlist_time(0.5 / (double) freq);
|
||||
m_clock.m_inc = netlist_time::from_double(0.5 / (double) freq);
|
||||
//m_clock.update();
|
||||
|
||||
//NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq));
|
||||
|
@ -22,8 +22,8 @@ namespace netlist
|
||||
, m_WEQ(*this, "WEQ")
|
||||
, m_DIN(*this, "DIN")
|
||||
, m_DOUTQ(*this, "DOUTQ")
|
||||
, m_ram(*this, "m_ram", 0)
|
||||
{
|
||||
save(NLNAME(m_ram));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -38,8 +38,7 @@ namespace netlist
|
||||
logic_input_t m_DIN;
|
||||
logic_output_t m_DOUTQ;
|
||||
|
||||
//netlist_state_t<UINT8[256]> m_ram;
|
||||
UINT64 m_ram[4]; // 256 bits
|
||||
state_var<uint_fast64_t[4]> m_ram; // 256 bits
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(82S16_dip, 82S16)
|
||||
@ -88,7 +87,7 @@ namespace netlist
|
||||
|
||||
if (!INPLOGIC(m_WEQ))
|
||||
{
|
||||
m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((UINT64) 1 << (adr & 0x3f))) | ((UINT64) INPLOGIC(m_DIN) << (adr & 0x3f));
|
||||
m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((uint_fast64_t) 1 << (adr & 0x3f))) | ((uint_fast64_t) INPLOGIC(m_DIN) << (adr & 0x3f));
|
||||
}
|
||||
OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace netlist
|
||||
logic_input_t m_C;
|
||||
logic_input_t m_D;
|
||||
|
||||
inline UINT8 read_ABCD() const
|
||||
uint_fast8_t read_ABCD() const
|
||||
{
|
||||
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
||||
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
|
||||
@ -50,19 +50,16 @@ namespace netlist
|
||||
, m_QC(*this, "QC")
|
||||
, m_QD(*this, "QD")
|
||||
, m_RC(*this, "RC")
|
||||
, m_cnt(0)
|
||||
, m_loadq(0)
|
||||
, m_ent(0)
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_loadq(*this, "m_loadq", 0)
|
||||
, m_ent(*this, "m_ent", 0)
|
||||
{
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_loadq));
|
||||
save(NLNAME(m_ent));
|
||||
}
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
public:
|
||||
inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
|
||||
inline void update_outputs(const UINT8 cnt);
|
||||
inline void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay);
|
||||
inline void update_outputs(const uint_fast8_t cnt);
|
||||
|
||||
logic_input_t m_CLK;
|
||||
|
||||
@ -73,9 +70,10 @@ namespace netlist
|
||||
logic_output_t m_QC;
|
||||
logic_output_t m_QD;
|
||||
logic_output_t m_RC;
|
||||
UINT8 m_cnt;
|
||||
netlist_sig_t m_loadq;
|
||||
netlist_sig_t m_ent;
|
||||
|
||||
state_var_u8 m_cnt;
|
||||
state_var_u8 m_loadq;
|
||||
state_var_u8 m_ent;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(9310)
|
||||
@ -211,7 +209,7 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
|
||||
inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const uint_fast8_t cnt, const netlist_time out_delay))
|
||||
{
|
||||
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
|
||||
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
|
||||
@ -219,7 +217,7 @@ namespace netlist
|
||||
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
|
||||
}
|
||||
|
||||
inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const UINT8 cnt))
|
||||
inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const uint_fast8_t cnt))
|
||||
{
|
||||
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||
#if 0
|
||||
|
@ -35,20 +35,35 @@ namespace netlist
|
||||
NETLIB_TRUTHTABLE(9312, 12, 2, 0);
|
||||
#else
|
||||
|
||||
NETLIB_DEVICE(9312,
|
||||
NETLIB_OBJECT(9312)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(9312)
|
||||
, m_A(*this, "A")
|
||||
, m_B(*this, "B")
|
||||
, m_C(*this, "C")
|
||||
, m_G(*this, "G")
|
||||
, m_D(*this, {{"D0","D1","D2","D3","D4","D5","D6","D7"}})
|
||||
, m_Y(*this, "Y")
|
||||
, m_YQ(*this, "YQ")
|
||||
, m_last_chan(*this, "m_last_chan", 0)
|
||||
, m_last_G(*this, "m_last_G", 0)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
public:
|
||||
// C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ
|
||||
logic_input_t m_A;
|
||||
logic_input_t m_B;
|
||||
logic_input_t m_C;
|
||||
logic_input_t m_G;
|
||||
logic_input_t m_D[8];
|
||||
object_array_t<logic_input_t, 8> m_D;
|
||||
logic_output_t m_Y;
|
||||
logic_output_t m_YQ;
|
||||
|
||||
UINT8 m_last_chan;
|
||||
UINT8 m_last_G;
|
||||
);
|
||||
state_var_u8 m_last_chan;
|
||||
state_var_u8 m_last_G;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -140,7 +155,7 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(9312)
|
||||
{
|
||||
const UINT8 G = INPLOGIC(m_G);
|
||||
const NLUINT8 G = INPLOGIC(m_G);
|
||||
if (G)
|
||||
{
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
|
||||
@ -161,46 +176,20 @@ namespace netlist
|
||||
m_B.activate();
|
||||
m_C.activate();
|
||||
}
|
||||
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
|
||||
const UINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
|
||||
constexpr netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
|
||||
const NLUINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
|
||||
if (m_last_chan != chan)
|
||||
{
|
||||
m_D[m_last_chan].inactivate();
|
||||
m_D[chan].activate();
|
||||
}
|
||||
const UINT8 val = INPLOGIC(m_D[chan]);
|
||||
const auto val = INPLOGIC(m_D[chan]);
|
||||
OUTLOGIC(m_Y, val, delay[val]);
|
||||
OUTLOGIC(m_YQ, !val, delay[!val]);
|
||||
m_last_chan = chan;
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_START(9312)
|
||||
{
|
||||
register_input("G", m_G);
|
||||
register_input("A", m_A);
|
||||
register_input("B", m_B);
|
||||
register_input("C", m_C);
|
||||
|
||||
register_input("D0", m_D[0]);
|
||||
register_input("D1", m_D[1]);
|
||||
register_input("D2", m_D[2]);
|
||||
register_input("D3", m_D[3]);
|
||||
register_input("D4", m_D[4]);
|
||||
register_input("D5", m_D[5]);
|
||||
register_input("D6", m_D[6]);
|
||||
register_input("D7", m_D[7]);
|
||||
|
||||
register_output("Y", m_Y);
|
||||
register_output("YQ", m_YQ);
|
||||
|
||||
m_last_chan = 0;
|
||||
m_last_G = 0;
|
||||
|
||||
save(NLNAME(m_last_chan));
|
||||
save(NLNAME(m_last_G));
|
||||
}
|
||||
|
||||
NETLIB_RESET(9312)
|
||||
{
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace netlist
|
||||
logic_input_t m_C;
|
||||
logic_input_t m_D;
|
||||
|
||||
inline UINT8 read_ABCD() const
|
||||
uint_fast8_t read_ABCD() const
|
||||
{
|
||||
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
|
||||
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
|
||||
@ -49,23 +49,19 @@ namespace netlist
|
||||
, m_QC(*this, "QC")
|
||||
, m_QD(*this, "QD")
|
||||
, m_RC(*this, "RC")
|
||||
, m_cnt(0)
|
||||
, m_ABCD(nullptr)
|
||||
, m_loadq(0)
|
||||
, m_ent(0)
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_loadq(*this, "m_loadq", 0)
|
||||
, m_ent(*this, "m_ent", 0)
|
||||
{
|
||||
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_loadq));
|
||||
save(NLNAME(m_ent));
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
|
||||
inline void update_outputs(const UINT8 cnt);
|
||||
inline void update_outputs_all(const uint_fast8_t cnt, const netlist_time out_delay);
|
||||
inline void update_outputs(const uint_fast8_t cnt);
|
||||
|
||||
logic_input_t m_CLK;
|
||||
|
||||
@ -75,10 +71,12 @@ namespace netlist
|
||||
logic_output_t m_QD;
|
||||
logic_output_t m_RC;
|
||||
|
||||
UINT8 m_cnt;
|
||||
NETLIB_NAME(9316_subABCD) *m_ABCD;
|
||||
netlist_sig_t m_loadq;
|
||||
netlist_sig_t m_ent;
|
||||
|
||||
state_var_u8 m_cnt;
|
||||
state_var_u8 m_loadq;
|
||||
state_var_u8 m_ent;
|
||||
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(9316)
|
||||
@ -211,7 +209,7 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
inline NETLIB_FUNC_VOID(9316_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
|
||||
inline NETLIB_FUNC_VOID(9316_sub, update_outputs_all, (const uint_fast8_t cnt, const netlist_time out_delay))
|
||||
{
|
||||
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
|
||||
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
|
||||
@ -219,7 +217,7 @@ namespace netlist
|
||||
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
|
||||
}
|
||||
|
||||
inline NETLIB_FUNC_VOID(9316_sub, update_outputs, (const UINT8 cnt))
|
||||
inline NETLIB_FUNC_VOID(9316_sub, update_outputs, (const uint_fast8_t cnt))
|
||||
{
|
||||
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
|
||||
#if 0
|
||||
|
@ -42,9 +42,8 @@ namespace netlist
|
||||
, m_Q(*this, "2")
|
||||
, m_L_to_H(*this, "L_TO_H", 10)
|
||||
, m_H_to_L(*this, "H_TO_L", 10)
|
||||
, m_last(0)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
save(NLNAME(m_last));
|
||||
}
|
||||
|
||||
//NETLIB_UPDATE_PARAMI();
|
||||
@ -58,7 +57,7 @@ namespace netlist
|
||||
param_int_t m_L_to_H;
|
||||
param_int_t m_H_to_L;
|
||||
|
||||
UINT8 m_last;
|
||||
state_var_u8 m_last;
|
||||
};
|
||||
|
||||
NETLIB_RESET(nicRSFF)
|
||||
|
@ -28,10 +28,10 @@ namespace netlist
|
||||
/* clock */
|
||||
, m_feedback(*this, "FB")
|
||||
, m_Q(*this, "Q")
|
||||
, m_inc(0, 1)
|
||||
, m_inc(netlist_time::from_hz(56000))
|
||||
, m_shift(*this, "m_shift", 0)
|
||||
, m_is_timestep(false)
|
||||
{
|
||||
m_inc = netlist_time::from_hz(56000);
|
||||
connect_late(m_feedback, m_Q);
|
||||
|
||||
/* output */
|
||||
@ -41,9 +41,6 @@ namespace netlist
|
||||
|
||||
/* device */
|
||||
register_subalias("3", m_RV.m_P);
|
||||
|
||||
save(NLNAME(m_shift));
|
||||
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
@ -61,10 +58,10 @@ namespace netlist
|
||||
/* clock stage */
|
||||
logic_input_t m_feedback;
|
||||
logic_output_t m_Q;
|
||||
netlist_time m_inc;
|
||||
const netlist_time m_inc;
|
||||
|
||||
/* state */
|
||||
UINT32 m_shift;
|
||||
state_var_u32 m_shift;
|
||||
|
||||
/* cache */
|
||||
bool m_is_timestep;
|
||||
@ -90,10 +87,10 @@ namespace netlist
|
||||
*
|
||||
*/
|
||||
|
||||
const UINT32 last_state = m_shift & 0x01;
|
||||
const auto last_state = m_shift & 0x01;
|
||||
/* shift */
|
||||
m_shift = (m_shift >> 1) | (((m_shift & 0x01) ^ ((m_shift >> 3) & 0x01)) << 16);
|
||||
const UINT32 state = m_shift & 0x01;
|
||||
const auto state = m_shift & 0x01;
|
||||
|
||||
if (state != last_state)
|
||||
{
|
||||
|
@ -28,8 +28,8 @@ namespace netlist
|
||||
, m_THRES(*this, "THRESH") // Pin 6
|
||||
, m_TRIG(*this, "TRIG") // Pin 2
|
||||
, m_OUT(*this, "OUT") // Pin 3
|
||||
, m_last_out(false)
|
||||
, m_ff(false)
|
||||
, m_last_out(*this, "m_last_out", false)
|
||||
, m_ff(*this, "m_ff", false)
|
||||
{
|
||||
|
||||
register_subalias("GND", m_R3.m_N); // Pin 1
|
||||
@ -40,9 +40,6 @@ namespace netlist
|
||||
connect_late(m_R1.m_N, m_R2.m_P);
|
||||
connect_late(m_R2.m_N, m_R3.m_P);
|
||||
connect_late(m_RDIS.m_N, m_R3.m_N);
|
||||
|
||||
save(NLNAME(m_last_out));
|
||||
save(NLNAME(m_ff));
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI();
|
||||
@ -60,8 +57,8 @@ namespace netlist
|
||||
analog_output_t m_OUT;
|
||||
|
||||
private:
|
||||
bool m_last_out;
|
||||
bool m_ff;
|
||||
state_var<bool> m_last_out;
|
||||
state_var<bool> m_ff;
|
||||
|
||||
inline nl_double clamp(const nl_double v, const nl_double a, const nl_double b);
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(clock)
|
||||
{
|
||||
OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
|
||||
OUTLOGIC(m_Q, !INPLOGIC(m_feedback), m_inc );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -40,7 +40,7 @@ namespace netlist
|
||||
NETLIB_RESET(extclock)
|
||||
{
|
||||
m_cnt = 0;
|
||||
m_off = netlist_time(m_offset.Value());
|
||||
m_off = netlist_time::from_double(m_offset.Value());
|
||||
//m_Q.initial(0);
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ namespace netlist
|
||||
stack[ptr-1] = stack[ptr-1] / stack[ptr];
|
||||
break;
|
||||
case PUSH_INPUT:
|
||||
stack[ptr++] = INPANALOG(m_I[(int) rc.m_param]);
|
||||
stack[ptr++] = INPANALOG((*m_I[(int) rc.m_param]));
|
||||
break;
|
||||
case PUSH_CONST:
|
||||
stack[ptr++] = rc.m_param;
|
||||
|
@ -32,11 +32,11 @@ namespace netlist
|
||||
typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl;
|
||||
};
|
||||
|
||||
static const uint64_t all_set = ~((uint64_t) 0);
|
||||
static const uint_least64_t all_set = ~((uint_least64_t) 0);
|
||||
|
||||
unsigned truthtable_desc_t::count_bits(uint64_t v)
|
||||
unsigned truthtable_desc_t::count_bits(uint_least64_t v)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
uint_least64_t ret = 0;
|
||||
for (; v != 0; v = v >> 1)
|
||||
{
|
||||
ret += (v & 1);
|
||||
@ -44,9 +44,9 @@ unsigned truthtable_desc_t::count_bits(uint64_t v)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t truthtable_desc_t::set_bits(uint64_t v, uint64_t b)
|
||||
uint_least64_t truthtable_desc_t::set_bits(uint_least64_t v, uint_least64_t b)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
uint_least64_t ret = 0;
|
||||
for (size_t i = 0; v != 0; v = v >> 1, ++i)
|
||||
{
|
||||
if (v & 1)
|
||||
@ -58,9 +58,9 @@ uint64_t truthtable_desc_t::set_bits(uint64_t v, uint64_t b)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t truthtable_desc_t::get_ignored_simple(uint64_t i)
|
||||
uint_least64_t truthtable_desc_t::get_ignored_simple(uint_least64_t i)
|
||||
{
|
||||
uint64_t m_enable = 0;
|
||||
uint_least64_t m_enable = 0;
|
||||
for (size_t j=0; j<m_size; j++)
|
||||
{
|
||||
if (m_outs[j] != m_outs[i])
|
||||
@ -71,10 +71,10 @@ uint64_t truthtable_desc_t::get_ignored_simple(uint64_t i)
|
||||
return m_enable ^ (m_size - 1);
|
||||
}
|
||||
|
||||
uint64_t truthtable_desc_t::get_ignored_extended(uint64_t state)
|
||||
uint_least64_t truthtable_desc_t::get_ignored_extended(uint_least64_t state)
|
||||
{
|
||||
// Determine all inputs which may be ignored ...
|
||||
uint64_t ignore = 0;
|
||||
uint_least64_t ignore = 0;
|
||||
for (unsigned j=0; j<m_NI; j++)
|
||||
{
|
||||
if (m_outs[state] == m_outs[state ^ (1 << j)])
|
||||
@ -84,17 +84,17 @@ uint64_t truthtable_desc_t::get_ignored_extended(uint64_t state)
|
||||
* We have to remove those where the ignored inputs
|
||||
* may change the output
|
||||
*/
|
||||
uint64_t bits = (1<<count_bits(ignore));
|
||||
uint_least64_t bits = (1<<count_bits(ignore));
|
||||
std::vector<bool> t(bits);
|
||||
|
||||
for (size_t j=1; j<bits; j++)
|
||||
{
|
||||
uint64_t tign = set_bits(ignore, j);
|
||||
uint_least64_t tign = set_bits(ignore, j);
|
||||
t[j] = 0;
|
||||
uint64_t bitsk=(1<<count_bits(tign));
|
||||
uint_least64_t bitsk=(1<<count_bits(tign));
|
||||
for (size_t k=0; k<bitsk; k++)
|
||||
{
|
||||
uint64_t b=set_bits(tign, k);
|
||||
uint_least64_t b=set_bits(tign, k);
|
||||
if (m_outs[state] != m_outs[(state & ~tign) | b])
|
||||
{
|
||||
t[j] = 1;
|
||||
@ -104,7 +104,7 @@ uint64_t truthtable_desc_t::get_ignored_extended(uint64_t state)
|
||||
}
|
||||
size_t jb=0;
|
||||
size_t jm=0;
|
||||
for (UINT32 j=1; j<bits; j++)
|
||||
for (size_t j=1; j<bits; j++)
|
||||
{
|
||||
size_t nb = count_bits(j);
|
||||
if ((t[j] == 0) && (nb>jb))
|
||||
@ -121,7 +121,7 @@ uint64_t truthtable_desc_t::get_ignored_extended(uint64_t state)
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list,
|
||||
uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index)
|
||||
uint_least64_t state, uint_least64_t val, std::vector<uint_least8_t> &timing_index)
|
||||
{
|
||||
pstring elem = list[cur].trim();
|
||||
int start = 0;
|
||||
@ -146,7 +146,7 @@ void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list,
|
||||
nl_assert_always(false, "unknown input value (not 0, 1, or X)");
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
const UINT64 nstate = state | (i << cur);
|
||||
const uint_least64_t nstate = state | (i << cur);
|
||||
|
||||
if (cur < m_num_bits - 1)
|
||||
{
|
||||
@ -165,7 +165,7 @@ void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list,
|
||||
}
|
||||
}
|
||||
|
||||
void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 disabled_ignore)
|
||||
void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, uint_least64_t disabled_ignore)
|
||||
{
|
||||
unsigned line = 0;
|
||||
|
||||
@ -195,8 +195,8 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
plib::pstring_vector_t times(io[2], ",");
|
||||
nl_assert_always(times.size() == m_NO, "timing count not matching");
|
||||
|
||||
UINT16 val = 0;
|
||||
std::vector<UINT8> tindex;
|
||||
uint_least64_t val = 0;
|
||||
std::vector<uint_least8_t> tindex;
|
||||
|
||||
for (unsigned j=0; j<m_NO; j++)
|
||||
{
|
||||
@ -222,7 +222,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
}
|
||||
|
||||
// determine ignore
|
||||
std::vector<uint64_t> ign(m_size, all_set);
|
||||
std::vector<uint_least64_t> ign(m_size, all_set);
|
||||
|
||||
for (size_t i=0; i<m_size; i++)
|
||||
{
|
||||
@ -240,10 +240,10 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
|
||||
ign[i] = tign;
|
||||
/* don't need to recalculate similar ones */
|
||||
uint64_t bitsk=(1<<count_bits(tign));
|
||||
for (uint64_t k=0; k<bitsk; k++)
|
||||
uint_least64_t bitsk=(1<<count_bits(tign));
|
||||
for (uint_least64_t k=0; k<bitsk; k++)
|
||||
{
|
||||
uint64_t b=set_bits(tign, k);
|
||||
uint_least64_t b=set_bits(tign, k);
|
||||
ign[(i & ~tign) | b] = tign;
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +64,10 @@ namespace netlist
|
||||
};
|
||||
|
||||
template<unsigned bits> struct uint_for_size;
|
||||
template<> struct uint_for_size<1> { typedef uint8_t type; };
|
||||
template<> struct uint_for_size<2> { typedef uint16_t type; };
|
||||
template<> struct uint_for_size<4> { typedef uint32_t type; };
|
||||
template<> struct uint_for_size<8> { typedef uint64_t type; };
|
||||
template<> struct uint_for_size<1> { typedef uint_least8_t type; };
|
||||
template<> struct uint_for_size<2> { typedef uint_least16_t type; };
|
||||
template<> struct uint_for_size<4> { typedef uint_least32_t type; };
|
||||
template<> struct uint_for_size<8> { typedef uint_least64_t type; };
|
||||
|
||||
struct packed_int
|
||||
{
|
||||
@ -77,39 +77,39 @@ namespace netlist
|
||||
, m_size(sizeof(C))
|
||||
{}
|
||||
|
||||
void set(const size_t pos, const uint64_t val)
|
||||
void set(const size_t pos, const uint_least64_t val)
|
||||
{
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: ((uint8_t *) m_data)[pos] = val; break;
|
||||
case 2: ((uint16_t *) m_data)[pos] = val; break;
|
||||
case 4: ((uint32_t *) m_data)[pos] = val; break;
|
||||
case 8: ((uint64_t *) m_data)[pos] = val; break;
|
||||
case 1: ((uint_least8_t *) m_data)[pos] = val; break;
|
||||
case 2: ((uint_least16_t *) m_data)[pos] = val; break;
|
||||
case 4: ((uint_least32_t *) m_data)[pos] = val; break;
|
||||
case 8: ((uint_least64_t *) m_data)[pos] = val; break;
|
||||
default: { }
|
||||
}
|
||||
}
|
||||
|
||||
UINT64 operator[] (size_t pos) const
|
||||
uint_least64_t operator[] (size_t pos) const
|
||||
{
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: return ((uint8_t *) m_data)[pos]; break;
|
||||
case 2: return ((uint16_t *) m_data)[pos]; break;
|
||||
case 4: return ((uint32_t *) m_data)[pos]; break;
|
||||
case 8: return ((uint64_t *) m_data)[pos]; break;
|
||||
case 1: return ((uint_least8_t *) m_data)[pos]; break;
|
||||
case 2: return ((uint_least16_t *) m_data)[pos]; break;
|
||||
case 4: return ((uint_least32_t *) m_data)[pos]; break;
|
||||
case 8: return ((uint_least64_t *) m_data)[pos]; break;
|
||||
default:
|
||||
return 0; //should never happen
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t adjust(uint64_t val) const
|
||||
uint_least64_t adjust(uint_least64_t val) const
|
||||
{
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: return ((uint8_t) val); break;
|
||||
case 2: return ((uint16_t) val); break;
|
||||
case 4: return ((uint32_t) val); break;
|
||||
case 8: return ((uint64_t) val); break;
|
||||
case 1: return ((uint_least8_t) val); break;
|
||||
case 2: return ((uint_least16_t) val); break;
|
||||
case 4: return ((uint_least32_t) val); break;
|
||||
case 8: return ((uint_least64_t) val); break;
|
||||
default:
|
||||
return 0; //should never happen
|
||||
}
|
||||
@ -122,7 +122,7 @@ namespace netlist
|
||||
struct truthtable_desc_t
|
||||
{
|
||||
truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
|
||||
packed_int outs, UINT8 *timing, netlist_time *timing_nt)
|
||||
packed_int outs, uint_least8_t *timing, netlist_time *timing_nt)
|
||||
: m_NO(NO), m_NI(NI), /*m_has_state(has_state),*/ m_initialized(initialized),
|
||||
m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
|
||||
m_num_bits(m_NI + has_state * (m_NI + m_NO)),
|
||||
@ -130,21 +130,21 @@ namespace netlist
|
||||
{
|
||||
}
|
||||
|
||||
void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore);
|
||||
void setup(const plib::pstring_vector_t &desc, uint_least64_t disabled_ignore);
|
||||
|
||||
private:
|
||||
void help(unsigned cur, plib::pstring_vector_t list,
|
||||
uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index);
|
||||
static unsigned count_bits(uint64_t v);
|
||||
static uint64_t set_bits(uint64_t v, uint64_t b);
|
||||
uint64_t get_ignored_simple(uint64_t i);
|
||||
uint64_t get_ignored_extended(uint64_t i);
|
||||
uint_least64_t state, uint_least64_t val, std::vector<uint_least8_t> &timing_index);
|
||||
static unsigned count_bits(uint_least64_t v);
|
||||
static uint_least64_t set_bits(uint_least64_t v, uint_least64_t b);
|
||||
uint_least64_t get_ignored_simple(uint_least64_t i);
|
||||
uint_least64_t get_ignored_extended(uint_least64_t i);
|
||||
|
||||
unsigned m_NO;
|
||||
unsigned m_NI;
|
||||
bool *m_initialized;
|
||||
packed_int m_outs;
|
||||
uint8_t *m_timing;
|
||||
uint_least8_t *m_timing;
|
||||
netlist_time *m_timing_nt;
|
||||
|
||||
/* additional values */
|
||||
@ -171,7 +171,7 @@ namespace netlist
|
||||
{}
|
||||
bool m_initialized;
|
||||
typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type m_outs[m_size];
|
||||
UINT8 m_timing[m_size * m_NO];
|
||||
uint_least8_t m_timing[m_size * m_NO];
|
||||
netlist_time m_timing_nt[16];
|
||||
};
|
||||
|
||||
@ -180,9 +180,10 @@ namespace netlist
|
||||
truthtable_t *ttp, const char *desc[])
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_last_state(*this, "m_last_state", 0)
|
||||
, m_ign(*this, "m_ign", 0)
|
||||
, m_active(*this, "m_active", 1)
|
||||
, m_use_deactivate(*this, "USE_DEACTIVATE", true)
|
||||
, m_ttp(ttp)
|
||||
{
|
||||
while (*desc != nullptr && **desc != 0 )
|
||||
@ -198,9 +199,10 @@ namespace netlist
|
||||
truthtable_t *ttp, const plib::pstring_vector_t &desc)
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_last_state(*this, "m_last_state", 0)
|
||||
, m_ign(*this, "m_ign", 0)
|
||||
, m_active(*this, "m_active", 1)
|
||||
, m_use_deactivate(*this, "USE_DEACTIVATE", true)
|
||||
, m_ttp(ttp)
|
||||
{
|
||||
m_desc = desc;
|
||||
@ -231,11 +233,11 @@ namespace netlist
|
||||
}
|
||||
// Connect output "Q" to input "_Q" if this exists
|
||||
// This enables timed state without having explicit state ....
|
||||
UINT32 disabled_ignore = 0;
|
||||
uint_least64_t disabled_ignore = 0;
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
pstring tmp = "_" + out[i];
|
||||
const int idx = inout.indexof(tmp);
|
||||
const int idx = plib::container::indexof(inout, tmp);
|
||||
if (idx>=0)
|
||||
{
|
||||
connect_late(m_Q[i], m_I[idx]);
|
||||
@ -251,18 +253,14 @@ namespace netlist
|
||||
&m_ttp->m_initialized, packed_int(m_ttp->m_outs), m_ttp->m_timing, m_ttp->m_timing_nt);
|
||||
|
||||
desc.setup(m_desc, disabled_ignore * 0);
|
||||
|
||||
#if 0
|
||||
printf("%s\n", name().cstr());
|
||||
for (int j=0; j < m_size; j++)
|
||||
printf("%05x %04x %04x %04x\n", j, m_ttp.m_outs[j] & ((1 << m_NO)-1),
|
||||
m_ttp.m_outs[j] >> m_NO, m_ttp.m_timing[j * m_NO + 0]);
|
||||
for (int k=0; m_ttp.m_timing_nt[k] != netlist_time::zero(); k++)
|
||||
printf("%d %f\n", k, m_ttp.m_timing_nt[k].as_double() * 1000000.0);
|
||||
printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1),
|
||||
m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]);
|
||||
for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero(); k++)
|
||||
printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0);
|
||||
#endif
|
||||
save(NLNAME(m_last_state));
|
||||
save(NLNAME(m_ign));
|
||||
save(NLNAME(m_active));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
@ -285,8 +283,7 @@ namespace netlist
|
||||
public:
|
||||
void inc_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (m_NI > 1 && m_has_state == 0 && m_use_deactivate)
|
||||
if (++m_active == 1)
|
||||
{
|
||||
process<false>();
|
||||
@ -295,14 +292,13 @@ namespace netlist
|
||||
|
||||
void dec_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
/* FIXME:
|
||||
* Based on current measurements there is no point to disable
|
||||
* 1 input devices. This should actually be a parameter so that we
|
||||
* can decide for each individual gate whether it is benefitial to
|
||||
* ignore deactivation.
|
||||
*/
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (m_NI > 1 && m_has_state == 0 && m_use_deactivate)
|
||||
if (--m_active == 0)
|
||||
{
|
||||
for (std::size_t i = 0; i< m_NI; i++)
|
||||
@ -325,7 +321,7 @@ namespace netlist
|
||||
{
|
||||
netlist_time mt = netlist_time::zero();
|
||||
|
||||
uint64_t state = 0;
|
||||
uint_least64_t state = 0;
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
auto ign = m_ign;
|
||||
@ -389,10 +385,11 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 m_last_state;
|
||||
UINT32 m_ign;
|
||||
INT32 m_active;
|
||||
|
||||
/* FIXME: check width */
|
||||
state_var_u32 m_last_state;
|
||||
state_var_u32 m_ign;
|
||||
state_var_s32 m_active;
|
||||
param_logic_t m_use_deactivate;
|
||||
truthtable_t *m_ttp;
|
||||
plib::pstring_vector_t m_desc;
|
||||
};
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef NLID_SYSTEM_H_
|
||||
#define NLID_SYSTEM_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
@ -119,6 +121,8 @@ namespace netlist
|
||||
, m_offset(*this, "OFFSET", 0.0)
|
||||
, m_feedback(*this, "FB")
|
||||
, m_Q(*this, "Q")
|
||||
, m_cnt(*this, "m_cnt", 0)
|
||||
, m_off(*this, "m_off", netlist_time::zero())
|
||||
{
|
||||
m_inc[0] = netlist_time::from_hz(m_freq.Value()*2);
|
||||
|
||||
@ -126,7 +130,7 @@ namespace netlist
|
||||
{
|
||||
netlist_time base = netlist_time::from_hz(m_freq.Value()*2);
|
||||
plib::pstring_vector_t pat(m_pattern.Value(),",");
|
||||
m_off = netlist_time(m_offset.Value());
|
||||
m_off = netlist_time::from_double(m_offset.Value());
|
||||
|
||||
int pati[256];
|
||||
m_size = pat.size();
|
||||
@ -144,8 +148,6 @@ namespace netlist
|
||||
}
|
||||
m_inc[m_size - 1] = base * total - ttotal;
|
||||
}
|
||||
save(NLNAME(m_cnt));
|
||||
save(NLNAME(m_off));
|
||||
}
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
@ -158,10 +160,10 @@ namespace netlist
|
||||
|
||||
logic_input_t m_feedback;
|
||||
logic_output_t m_Q;
|
||||
unsigned m_cnt;
|
||||
unsigned m_size;
|
||||
netlist_time m_inc[32];
|
||||
netlist_time m_off;
|
||||
state_var<unsigned> m_cnt;
|
||||
state_var<netlist_time> m_off;
|
||||
unsigned m_size;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -258,7 +260,7 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(frontier, base_dummy)
|
||||
, m_RIN(*this, "m_RIN")
|
||||
, m_RIN(*this, "m_RIN", true)
|
||||
, m_ROUT(*this, "m_ROUT", true)
|
||||
, m_I(*this, "_I")
|
||||
, m_Q(*this, "_Q")
|
||||
@ -311,8 +313,8 @@ namespace netlist
|
||||
, m_Q(*this, "Q")
|
||||
{
|
||||
|
||||
for (std::size_t i=0; i < m_N; i++)
|
||||
m_I.emplace(i, *this, plib::pfmt("A{1}")(i));
|
||||
for (int i=0; i < m_N; i++)
|
||||
m_I.push_back(plib::make_unique<analog_input_t>(*this, plib::pfmt("A{1}")(i)));
|
||||
|
||||
plib::pstring_vector_t cmds(m_func.Value(), " ");
|
||||
m_precompiled.clear();
|
||||
@ -375,9 +377,9 @@ namespace netlist
|
||||
param_int_t m_N;
|
||||
param_str_t m_func;
|
||||
analog_output_t m_Q;
|
||||
plib::uninitialised_array_t<analog_input_t, 10> m_I;
|
||||
std::vector<std::unique_ptr<analog_input_t>> m_I;
|
||||
|
||||
plib::pvector_t<rpn_inst> m_precompiled;
|
||||
std::vector<rpn_inst> m_precompiled;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -392,12 +394,10 @@ namespace netlist
|
||||
, m_I(*this, "I")
|
||||
, m_RON(*this, "RON", 1.0)
|
||||
, m_ROFF(*this, "ROFF", 1.0E20)
|
||||
, m_last_state(0)
|
||||
, m_last_state(*this, "m_last_state", 0)
|
||||
{
|
||||
register_subalias("1", m_R.m_P);
|
||||
register_subalias("2", m_R.m_N);
|
||||
|
||||
save(NLNAME(m_last_state));
|
||||
}
|
||||
|
||||
NETLIB_SUB(R) m_R;
|
||||
@ -414,8 +414,7 @@ namespace netlist
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
private:
|
||||
|
||||
UINT8 m_last_state;
|
||||
state_var_u8 m_last_state;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -518,7 +517,7 @@ namespace netlist
|
||||
: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
|
||||
, m_GNDHack(*this, "_Q")
|
||||
, m_RV(*this, "RV")
|
||||
, m_last_state(-1)
|
||||
, m_last_state(*this, "m_last_var", -1)
|
||||
, m_is_timestep(false)
|
||||
{
|
||||
//register_sub(m_RV);
|
||||
@ -528,8 +527,6 @@ namespace netlist
|
||||
register_subalias("Q", m_RV.m_P);
|
||||
|
||||
connect_late(m_RV.m_N, m_GNDHack);
|
||||
|
||||
save(NLNAME(m_last_state));
|
||||
}
|
||||
|
||||
virtual ~nld_d_to_a_proxy() {}
|
||||
@ -542,7 +539,7 @@ namespace netlist
|
||||
private:
|
||||
analog_output_t m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
NETLIB_SUB(twoterm) m_RV;
|
||||
int m_last_state;
|
||||
state_var<int> m_last_state;
|
||||
bool m_is_timestep;
|
||||
};
|
||||
|
||||
|
@ -104,15 +104,16 @@ const logic_family_desc_t *family_CD4XXX()
|
||||
|
||||
queue_t::queue_t(netlist_t &nl)
|
||||
: timed_queue<net_t *, netlist_time>(512)
|
||||
, object_t(nl, "QUEUE", QUEUE)
|
||||
, plib::pstate_callback_t()
|
||||
, object_t("QUEUE")
|
||||
, netlist_ref(nl)
|
||||
, plib::state_manager_t::callback_t()
|
||||
, m_qsize(0)
|
||||
, m_times(512)
|
||||
, m_names(512)
|
||||
{
|
||||
}
|
||||
|
||||
void queue_t::register_state(plib::pstate_manager_t &manager, const pstring &module)
|
||||
void queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
|
||||
{
|
||||
netlist().log().debug("register_state\n");
|
||||
manager.save_item(this, m_qsize, module + "." + "qsize");
|
||||
@ -154,10 +155,8 @@ void queue_t::on_post_load()
|
||||
// object_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
object_t::object_t(netlist_t &nl, const pstring &aname, const type_t atype)
|
||||
: m_netlist(nl)
|
||||
, m_name(aname)
|
||||
, m_objtype(atype)
|
||||
object_t::object_t(const pstring &aname)
|
||||
: m_name(aname)
|
||||
{
|
||||
}
|
||||
|
||||
@ -175,8 +174,9 @@ const pstring &object_t::name() const
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const type_t atype)
|
||||
: object_t(dev.netlist(), aname, atype)
|
||||
: object_t(aname)
|
||||
, m_device(dev)
|
||||
, m_type(atype)
|
||||
{
|
||||
}
|
||||
|
||||
@ -186,22 +186,21 @@ device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
netlist_t::netlist_t(const pstring &aname)
|
||||
: pstate_manager_t(),
|
||||
m_stop(netlist_time::zero()),
|
||||
m_time(netlist_time::zero()),
|
||||
m_use_deactivate(0),
|
||||
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)
|
||||
: m_state()
|
||||
, m_time(netlist_time::zero())
|
||||
, m_queue(*this)
|
||||
, m_use_deactivate(0)
|
||||
, m_mainclock(nullptr)
|
||||
, m_solver(nullptr)
|
||||
, m_gnd(nullptr)
|
||||
, m_params(nullptr)
|
||||
, m_name(aname)
|
||||
, m_setup(nullptr)
|
||||
, m_log(this)
|
||||
, m_lib(nullptr)
|
||||
{
|
||||
save_item(this, static_cast<plib::pstate_callback_t &>(m_queue), "m_queue");
|
||||
save_item(this, m_time, "m_time");
|
||||
state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
|
||||
state().save_item(this, m_time, "m_time");
|
||||
}
|
||||
|
||||
netlist_t::~netlist_t()
|
||||
@ -331,51 +330,43 @@ void netlist_t::reset()
|
||||
|
||||
void netlist_t::process_queue(const netlist_time &delta)
|
||||
{
|
||||
m_stop = m_time + delta;
|
||||
netlist_time stop(m_time + delta);
|
||||
|
||||
m_queue.push(stop, nullptr);
|
||||
|
||||
if (m_mainclock == nullptr)
|
||||
{
|
||||
while ( (m_time < m_stop) & (!m_queue.empty()))
|
||||
queue_t::entry_t e(m_queue.pop());
|
||||
m_time = e.m_exec_time;
|
||||
while (e.m_object != nullptr)
|
||||
{
|
||||
const queue_t::entry_t e(m_queue.pop());
|
||||
m_time = e.m_exec_time;
|
||||
e.m_object->update_devs();
|
||||
|
||||
add_to_stat(m_perf_out_processed, 1);
|
||||
e = m_queue.pop();
|
||||
m_time = e.m_exec_time;
|
||||
}
|
||||
if (m_queue.empty())
|
||||
m_time = m_stop;
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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());
|
||||
|
||||
while (m_time < m_stop)
|
||||
while (1)
|
||||
{
|
||||
if (!m_queue.empty())
|
||||
while (m_queue.top().m_exec_time > mc_time)
|
||||
{
|
||||
while (m_queue.top().m_exec_time > mc_time)
|
||||
{
|
||||
m_time = mc_time;
|
||||
mc_time += inc;
|
||||
mc_net.toggle_new_Q();
|
||||
mc_net.update_devs();
|
||||
//devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
|
||||
}
|
||||
|
||||
const queue_t::entry_t &e = m_queue.pop();
|
||||
m_time = e.m_exec_time;
|
||||
e.m_object->update_devs();
|
||||
|
||||
} else {
|
||||
m_time = mc_time;
|
||||
mc_time += inc;
|
||||
mc_net.toggle_new_Q();
|
||||
mc_net.update_devs();
|
||||
//devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
|
||||
}
|
||||
|
||||
const queue_t::entry_t e(m_queue.pop());
|
||||
m_time = e.m_exec_time;
|
||||
if (e.m_object == nullptr)
|
||||
break;
|
||||
e.m_object->update_devs();
|
||||
add_to_stat(m_perf_out_processed, 1);
|
||||
}
|
||||
mc_net.set_time(mc_time);
|
||||
@ -410,13 +401,13 @@ param_template_t<C, T>::param_template_t(device_t &device, const pstring name, c
|
||||
{
|
||||
/* pstrings not yet supported, these need special logic */
|
||||
if (T != param_t::STRING && T != param_t::MODEL)
|
||||
save(NLNAME(m_param));
|
||||
netlist().save(*this, m_param, "m_param");
|
||||
device.setup().register_and_set_param(device.name() + "." + name, *this);
|
||||
}
|
||||
|
||||
template class param_template_t<double, param_t::DOUBLE>;
|
||||
template class param_template_t<int, param_t::INTEGER>;
|
||||
template class param_template_t<int, param_t::LOGIC>;
|
||||
template class param_template_t<bool, param_t::LOGIC>;
|
||||
template class param_template_t<pstring, param_t::STRING>;
|
||||
template class param_template_t<pstring, param_t::MODEL>;
|
||||
|
||||
@ -425,7 +416,9 @@ template class param_template_t<pstring, param_t::MODEL>;
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
core_device_t::core_device_t(netlist_t &owner, const pstring &name)
|
||||
: object_t(owner, name, DEVICE), logic_family_t()
|
||||
: object_t(name)
|
||||
, logic_family_t()
|
||||
, netlist_ref(owner)
|
||||
#if (NL_KEEP_STATISTICS)
|
||||
, stat_total_time(0)
|
||||
, stat_update_count(0)
|
||||
@ -437,8 +430,9 @@ core_device_t::core_device_t(netlist_t &owner, const pstring &name)
|
||||
}
|
||||
|
||||
core_device_t::core_device_t(core_device_t &owner, const pstring &name)
|
||||
: object_t(owner.netlist(), owner.name() + "." + name, DEVICE)
|
||||
: object_t(owner.name() + "." + name)
|
||||
, logic_family_t()
|
||||
, netlist_ref(owner.netlist())
|
||||
#if (NL_KEEP_STATISTICS)
|
||||
, stat_total_time(0)
|
||||
, stat_update_count(0)
|
||||
@ -509,9 +503,6 @@ void device_t::register_subalias(const pstring &name, core_terminal_t &term)
|
||||
|
||||
// everything already fully qualified
|
||||
setup().register_alias_nofqn(alias, term.name());
|
||||
|
||||
if (term.is_type(terminal_t::INPUT) || term.is_type(terminal_t::TERMINAL))
|
||||
m_terminals.push_back(alias);
|
||||
}
|
||||
|
||||
void device_t::register_subalias(const pstring &name, const pstring &aliased)
|
||||
@ -521,10 +512,6 @@ void device_t::register_subalias(const pstring &name, const pstring &aliased)
|
||||
|
||||
// everything already fully qualified
|
||||
setup().register_alias_nofqn(alias, aliased_fqn);
|
||||
|
||||
// FIXME: make this working again
|
||||
//if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL))
|
||||
// m_terminals.add(name);
|
||||
}
|
||||
|
||||
void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2)
|
||||
@ -573,32 +560,26 @@ struct do_nothing_deleter{
|
||||
|
||||
|
||||
net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr)
|
||||
: object_t(nl, aname, NET)
|
||||
, m_new_Q(0)
|
||||
, m_cur_Q (0)
|
||||
, m_time(netlist_time::zero())
|
||||
, m_active(0)
|
||||
, m_in_queue(2)
|
||||
: object_t(aname)
|
||||
, netlist_ref(nl)
|
||||
, m_new_Q(*this, "m_new_Q", 0)
|
||||
, m_cur_Q (*this, "m_cur_Q", 0)
|
||||
, m_time(*this, "m_time", netlist_time::zero())
|
||||
, m_active(*this, "m_active", 0)
|
||||
, m_in_queue(*this, "m_in_queue", 2)
|
||||
, m_railterminal(nullptr)
|
||||
, m_cur_Analog(0.0)
|
||||
, m_cur_Analog(*this, "m_cur_Analog", 0.0)
|
||||
{
|
||||
m_railterminal = mr;
|
||||
if (mr != nullptr)
|
||||
nl.m_nets.push_back(std::shared_ptr<net_t>(this, do_nothing_deleter()));
|
||||
else
|
||||
nl.m_nets.push_back(std::shared_ptr<net_t>(this));
|
||||
|
||||
save(NLNAME(m_time));
|
||||
save(NLNAME(m_active));
|
||||
save(NLNAME(m_in_queue));
|
||||
save(NLNAME(m_cur_Analog));
|
||||
save(NLNAME(m_cur_Q));
|
||||
save(NLNAME(m_new_Q));
|
||||
}
|
||||
|
||||
net_t::~net_t()
|
||||
{
|
||||
netlist().remove_save_items(this);
|
||||
netlist().state().remove_save_items(this);
|
||||
}
|
||||
|
||||
void net_t::inc_active(core_terminal_t &term)
|
||||
@ -770,19 +751,19 @@ analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t
|
||||
{
|
||||
}
|
||||
|
||||
bool analog_net_t::already_processed(plib::pvector_t<list_t> &groups)
|
||||
bool analog_net_t::already_processed(std::vector<list_t> &groups)
|
||||
{
|
||||
if (isRailNet())
|
||||
return true;
|
||||
for (auto & grp : groups)
|
||||
{
|
||||
if (grp.contains(this))
|
||||
if (plib::container::contains(grp, this))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void analog_net_t::process_net(plib::pvector_t<list_t> &groups)
|
||||
void analog_net_t::process_net(std::vector<list_t> &groups)
|
||||
{
|
||||
if (num_cons() == 0)
|
||||
return;
|
||||
@ -809,9 +790,8 @@ core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const
|
||||
: device_object_t(dev, dev.name() + "." + aname, atype)
|
||||
, plib::linkedlist_t<core_terminal_t>::element_t()
|
||||
, m_net(nullptr)
|
||||
, m_state(STATE_NONEX)
|
||||
, m_state(*this, "m_state", STATE_NONEX)
|
||||
{
|
||||
save(NLNAME(m_state));
|
||||
}
|
||||
|
||||
void core_terminal_t::reset()
|
||||
@ -822,7 +802,7 @@ void core_terminal_t::reset()
|
||||
set_state(STATE_INP_ACTIVE);
|
||||
}
|
||||
|
||||
void core_terminal_t::set_net(net_t::ptr_t anet)
|
||||
void core_terminal_t::set_net(net_t *anet)
|
||||
{
|
||||
m_net = anet;
|
||||
}
|
||||
@ -840,14 +820,11 @@ void core_terminal_t::set_net(net_t::ptr_t anet)
|
||||
terminal_t::terminal_t(core_device_t &dev, const pstring &aname)
|
||||
: analog_t(dev, aname, TERMINAL)
|
||||
, m_otherterm(nullptr)
|
||||
, m_Idr1(nullptr)
|
||||
, m_go1(nullptr)
|
||||
, m_gt1(nullptr)
|
||||
, m_Idr1(*this, "m_Idr1", nullptr)
|
||||
, m_go1(*this, "m_go1", nullptr)
|
||||
, m_gt1(*this, "m_gt1", nullptr)
|
||||
{
|
||||
netlist().setup().register_term(*this);
|
||||
save(NLNAME(m_Idr1));
|
||||
save(NLNAME(m_go1));
|
||||
save(NLNAME(m_gt1));
|
||||
}
|
||||
|
||||
|
||||
@ -967,6 +944,7 @@ nl_double param_model_t::model_value(const pstring &entity)
|
||||
return netlist().setup().model_value(m_map, entity);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace netlist
|
||||
|
@ -156,8 +156,10 @@
|
||||
#define NLBASE_H_
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <cmath>
|
||||
//#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#include "nl_lists.h"
|
||||
#include "nl_time.h"
|
||||
@ -169,12 +171,7 @@
|
||||
// Type definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* unsigned int would be a 20% speed increase over UINT8 for pong.
|
||||
* For breakout it causes a slight decrease.
|
||||
*
|
||||
*/
|
||||
using netlist_sig_t = std::uint32_t;
|
||||
using netlist_sig_t = std::uint_least32_t;
|
||||
|
||||
//============================================================
|
||||
// MACROS / New Syntax
|
||||
@ -266,7 +263,7 @@ namespace netlist
|
||||
class NETLIB_NAME(mainclock);
|
||||
class NETLIB_NAME(netlistparams);
|
||||
class NETLIB_NAME(base_proxy);
|
||||
class nld_base_d_to_a_proxy;
|
||||
class NETLIB_NAME(base_d_to_a_proxy);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
@ -287,13 +284,13 @@ namespace netlist
|
||||
class setup_t;
|
||||
class netlist_t;
|
||||
class core_device_t;
|
||||
class param_model_t;
|
||||
class device_t;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// model_map_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using model_map_t = plib::hashmap_t<pstring, pstring>;
|
||||
using model_map_t = std::unordered_map<pstring, pstring>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// logic_family_t
|
||||
@ -341,41 +338,77 @@ namespace netlist
|
||||
const logic_family_desc_t *family_CD4XXX();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// State variables - use to preserve state
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct state_var
|
||||
{
|
||||
public:
|
||||
template <typename O>
|
||||
state_var(O &owner, const pstring name, const T &value);
|
||||
state_var(const state_var &rhs) NOEXCEPT = default;
|
||||
state_var(state_var &&rhs) NOEXCEPT = default;
|
||||
state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; }
|
||||
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
|
||||
operator T & () { return m_value; }
|
||||
T & operator()() { return m_value; }
|
||||
operator const T & () const { return m_value; }
|
||||
const T & operator()() const { return m_value; }
|
||||
|
||||
T * ptr() { return &m_value; }
|
||||
const T * ptr() const { return &m_value; }
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct state_var<T[N]>
|
||||
{
|
||||
public:
|
||||
state_var(device_t &dev, const pstring name, const T & value);
|
||||
state_var(const state_var &rhs) NOEXCEPT = default;
|
||||
state_var(state_var &&rhs) NOEXCEPT = default;
|
||||
state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; }
|
||||
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
|
||||
T & operator[](const std::size_t i) { return m_value[i]; }
|
||||
const T & operator[](const std::size_t i) const { return m_value[i]; }
|
||||
private:
|
||||
T m_value[N];
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// State variables - predefined and c++11 non-optioanl
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using state_var_u8 = state_var<std::uint_fast8_t>;
|
||||
using state_var_s8 = state_var<std::int_fast8_t>;
|
||||
|
||||
using state_var_u32 = state_var<std::uint_fast32_t>;
|
||||
using state_var_s32 = state_var<std::int_fast32_t>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// object_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class object_t : public plib::pstate_interface_t<object_t>
|
||||
|
||||
class object_t
|
||||
{
|
||||
P_PREVENT_COPYING(object_t)
|
||||
public:
|
||||
enum type_t {
|
||||
TERMINAL = 0,
|
||||
INPUT = 1,
|
||||
OUTPUT = 2,
|
||||
PARAM = 3,
|
||||
NET = 4,
|
||||
DEVICE = 5,
|
||||
QUEUE = 6
|
||||
};
|
||||
|
||||
object_t(netlist_t &nl, const pstring &aname, const type_t atype);
|
||||
object_t(const pstring &aname);
|
||||
~object_t();
|
||||
|
||||
const pstring &name() const;
|
||||
|
||||
plib::pstate_manager_t &state_manager();
|
||||
|
||||
type_t type() const { return m_objtype; }
|
||||
bool is_type(const type_t atype) const { return (m_objtype == atype); }
|
||||
|
||||
netlist_t & netlist() { return m_netlist; }
|
||||
const netlist_t & netlist() const { return m_netlist; }
|
||||
//netlist_t & m_netlist;
|
||||
//netlist_t & netlist() { return m_netlist; }
|
||||
//const netlist_t & netlist() const { return m_netlist; }
|
||||
|
||||
private:
|
||||
netlist_t & m_netlist;
|
||||
pstring m_name;
|
||||
const type_t m_objtype;
|
||||
|
||||
public:
|
||||
void * operator new (size_t size, void *ptr) { return ptr; }
|
||||
@ -384,6 +417,18 @@ namespace netlist
|
||||
void operator delete (void * mem);
|
||||
};
|
||||
|
||||
struct netlist_ref
|
||||
{
|
||||
netlist_ref(netlist_t &nl) : m_netlist(nl) { }
|
||||
|
||||
netlist_t & netlist() { return m_netlist; }
|
||||
const netlist_t & netlist() const { return m_netlist; }
|
||||
|
||||
private:
|
||||
netlist_t & m_netlist;
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// device_object_t
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -392,10 +437,24 @@ namespace netlist
|
||||
{
|
||||
P_PREVENT_COPYING(device_object_t)
|
||||
public:
|
||||
enum type_t {
|
||||
TERMINAL = 0,
|
||||
INPUT = 1,
|
||||
OUTPUT = 2,
|
||||
PARAM = 3,
|
||||
};
|
||||
|
||||
device_object_t(core_device_t &dev, const pstring &aname, const type_t atype);
|
||||
core_device_t &device() const { return m_device; }
|
||||
|
||||
type_t type() const { return m_type; }
|
||||
bool is_type(const type_t atype) const { return (m_type == atype); }
|
||||
|
||||
netlist_t &netlist();
|
||||
|
||||
private:
|
||||
core_device_t & m_device;
|
||||
const type_t m_type;
|
||||
};
|
||||
|
||||
|
||||
@ -408,7 +467,7 @@ namespace netlist
|
||||
P_PREVENT_COPYING(core_terminal_t)
|
||||
public:
|
||||
|
||||
using list_t = plib::pvector_t<core_terminal_t *>;
|
||||
using list_t = std::vector<core_terminal_t *>;
|
||||
|
||||
/* needed here ... */
|
||||
|
||||
@ -446,7 +505,7 @@ namespace netlist
|
||||
|
||||
private:
|
||||
net_t * m_net;
|
||||
state_e m_state;
|
||||
state_var<state_e> m_state;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -475,8 +534,6 @@ namespace netlist
|
||||
P_PREVENT_COPYING(terminal_t)
|
||||
public:
|
||||
|
||||
using list_t = plib::pvector_t<terminal_t *>;
|
||||
|
||||
terminal_t(core_device_t &dev, const pstring &aname);
|
||||
|
||||
terminal_t *m_otherterm;
|
||||
@ -521,9 +578,9 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
nl_double *m_Idr1; // drive current
|
||||
nl_double *m_go1; // conductance for Voltage from other term
|
||||
nl_double *m_gt1; // conductance for total conductance
|
||||
state_var<nl_double *> m_Idr1; // drive current
|
||||
state_var<nl_double *> m_go1; // conductance for Voltage from other term
|
||||
state_var<nl_double *> m_gt1; // conductance for total conductance
|
||||
|
||||
};
|
||||
|
||||
@ -589,14 +646,11 @@ namespace netlist
|
||||
// net_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class net_t : public object_t
|
||||
class net_t : public object_t, public netlist_ref
|
||||
{
|
||||
P_PREVENT_COPYING(net_t)
|
||||
public:
|
||||
|
||||
using ptr_t = net_t *;
|
||||
using list_t = plib::pvector_t<std::shared_ptr<net_t>>;
|
||||
|
||||
net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||
virtual ~net_t();
|
||||
|
||||
@ -622,7 +676,7 @@ namespace netlist
|
||||
bool isRailNet() const { return !(m_railterminal == nullptr); }
|
||||
core_terminal_t & railterminal() const { return *m_railterminal; }
|
||||
|
||||
int num_cons() const { return m_core_terms.size(); }
|
||||
std::size_t num_cons() const { return m_core_terms.size(); }
|
||||
|
||||
void inc_active(core_terminal_t &term);
|
||||
void dec_active(core_terminal_t &term);
|
||||
@ -631,15 +685,15 @@ namespace netlist
|
||||
|
||||
void move_connections(net_t *new_net);
|
||||
|
||||
plib::pvector_t<core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
|
||||
protected:
|
||||
netlist_sig_t m_new_Q;
|
||||
netlist_sig_t m_cur_Q;
|
||||
state_var<netlist_sig_t> m_new_Q;
|
||||
state_var<netlist_sig_t> m_cur_Q;
|
||||
|
||||
netlist_time m_time;
|
||||
INT32 m_active;
|
||||
UINT8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
|
||||
state_var<netlist_time> m_time;
|
||||
state_var_s32 m_active;
|
||||
state_var_u8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
|
||||
|
||||
private:
|
||||
plib::linkedlist_t<core_terminal_t> m_list_active;
|
||||
@ -647,7 +701,7 @@ namespace netlist
|
||||
|
||||
public:
|
||||
// FIXME: Have to fix the public at some time
|
||||
nl_double m_cur_Analog;
|
||||
state_var<nl_double> m_cur_Analog;
|
||||
|
||||
};
|
||||
|
||||
@ -656,8 +710,6 @@ namespace netlist
|
||||
P_PREVENT_COPYING(logic_net_t)
|
||||
public:
|
||||
|
||||
using list_t = plib::pvector_t<logic_net_t *>;
|
||||
|
||||
logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||
virtual ~logic_net_t() { };
|
||||
|
||||
@ -699,7 +751,7 @@ namespace netlist
|
||||
P_PREVENT_COPYING(analog_net_t)
|
||||
public:
|
||||
|
||||
using list_t = plib::pvector_t<analog_net_t *>;
|
||||
using list_t = std::vector<analog_net_t *>;
|
||||
|
||||
analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||
|
||||
@ -712,8 +764,8 @@ namespace netlist
|
||||
devices::matrix_solver_t *solver() { return m_solver; }
|
||||
void set_solver(devices::matrix_solver_t *solver) { m_solver = solver; }
|
||||
|
||||
bool already_processed(plib::pvector_t<list_t> &groups);
|
||||
void process_net(plib::pvector_t<list_t> &groups);
|
||||
bool already_processed(std::vector<list_t> &groups);
|
||||
void process_net(std::vector<list_t> &groups);
|
||||
|
||||
private:
|
||||
devices::matrix_solver_t *m_solver;
|
||||
@ -759,8 +811,6 @@ namespace netlist
|
||||
// param_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class device_t;
|
||||
|
||||
class param_t : public device_object_t
|
||||
{
|
||||
P_PREVENT_COPYING(param_t)
|
||||
@ -806,7 +856,7 @@ namespace netlist
|
||||
using param_int_t = param_template_t<int, param_t::INTEGER>;
|
||||
using param_str_t = param_template_t<pstring, param_t::STRING>;
|
||||
|
||||
using param_logic_t = param_template_t<int, param_t::INTEGER>;
|
||||
using param_logic_t = param_template_t<bool, param_t::LOGIC>;
|
||||
|
||||
class param_model_t : public param_str_t
|
||||
{
|
||||
@ -831,13 +881,10 @@ namespace netlist
|
||||
// core_device_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class core_device_t : public object_t, public logic_family_t
|
||||
class core_device_t : public object_t, public logic_family_t, public netlist_ref
|
||||
{
|
||||
P_PREVENT_COPYING(core_device_t)
|
||||
public:
|
||||
|
||||
using list_t = plib::pvector_t<core_device_t *>;
|
||||
|
||||
core_device_t(netlist_t &owner, const pstring &name);
|
||||
core_device_t(core_device_t &owner, const pstring &name);
|
||||
|
||||
@ -884,8 +931,8 @@ namespace netlist
|
||||
#if (NL_KEEP_STATISTICS)
|
||||
/* stats */
|
||||
plib::ticks_t stat_total_time;
|
||||
INT32 stat_update_count;
|
||||
INT32 stat_call_count;
|
||||
int_fast32_t stat_update_count;
|
||||
int_fast32_t stat_call_count;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@ -965,17 +1012,12 @@ namespace netlist
|
||||
void connect_late(const pstring &t1, const pstring &t2);
|
||||
void connect_late(core_terminal_t &t1, core_terminal_t &t2);
|
||||
void connect_post_start(core_terminal_t &t1, core_terminal_t &t2);
|
||||
|
||||
plib::pvector_t<pstring> m_terminals;
|
||||
|
||||
protected:
|
||||
|
||||
NETLIB_UPDATEI() { }
|
||||
NETLIB_UPDATE_TERMINALSI() { }
|
||||
|
||||
private:
|
||||
void register_p(const pstring &name, object_t &obj);
|
||||
void register_sub_p(device_t &dev);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1003,23 +1045,24 @@ namespace netlist
|
||||
// queue_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class queue_t : public timed_queue<net_t *, netlist_time>,
|
||||
public object_t,
|
||||
public plib::pstate_callback_t
|
||||
class queue_t : public timed_queue<net_t *, netlist_time>,
|
||||
public object_t,
|
||||
public netlist_ref,
|
||||
public plib::state_manager_t::callback_t
|
||||
{
|
||||
public:
|
||||
queue_t(netlist_t &nl);
|
||||
|
||||
protected:
|
||||
|
||||
void register_state(plib::pstate_manager_t &manager, const pstring &module) override;
|
||||
void register_state(plib::state_manager_t &manager, const pstring &module) override;
|
||||
void on_pre_save() override;
|
||||
void on_post_load() override;
|
||||
|
||||
private:
|
||||
struct names_t { char m_buf[64]; };
|
||||
int m_qsize;
|
||||
std::vector<netlist_time::INTERNALTYPE> m_times;
|
||||
std::vector<netlist_time::internal_type> m_times;
|
||||
std::vector<names_t> m_names;
|
||||
};
|
||||
|
||||
@ -1028,7 +1071,7 @@ namespace netlist
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class netlist_t : public plib::pstate_manager_t, public plib::plog_dispatch_intf //, public device_owner_t
|
||||
class netlist_t : public plib::plog_dispatch_intf //, public device_owner_t
|
||||
{
|
||||
P_PREVENT_COPYING(netlist_t)
|
||||
public:
|
||||
@ -1041,18 +1084,18 @@ namespace netlist
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
const queue_t &queue() const { return m_queue; }
|
||||
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; }
|
||||
const queue_t &queue() const { return m_queue; }
|
||||
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; }
|
||||
nl_double gmin() const;
|
||||
|
||||
void push_to_queue(net_t &out, const netlist_time attime) NOEXCEPT;
|
||||
void remove_from_queue(net_t &out);
|
||||
|
||||
void process_queue(const netlist_time &delta);
|
||||
void abort_current_queue_slice() { m_stop = netlist_time::zero(); }
|
||||
void abort_current_queue_slice() { m_queue.retime(m_time, nullptr); }
|
||||
|
||||
bool use_deactivate() const { return m_use_deactivate; }
|
||||
|
||||
@ -1064,9 +1107,9 @@ namespace netlist
|
||||
net_t *find_net(const pstring &name);
|
||||
|
||||
template<class device_class>
|
||||
plib::pvector_t<device_class *> get_device_list()
|
||||
std::vector<device_class *> get_device_list()
|
||||
{
|
||||
plib::pvector_t<device_class *> tmp;
|
||||
std::vector<device_class *> tmp;
|
||||
for (auto &d : m_devices)
|
||||
{
|
||||
device_class *dev = dynamic_cast<device_class *>(d.get());
|
||||
@ -1097,16 +1140,27 @@ namespace netlist
|
||||
plib::plog_base<NL_DEBUG> &log() { return m_log; }
|
||||
const plib::plog_base<NL_DEBUG> &log() const { return m_log; }
|
||||
|
||||
plib::state_manager_t &state() { return m_state; }
|
||||
|
||||
template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
|
||||
{
|
||||
this->state().save_item((void *)&owner, state, pstring(owner.name()) + "." + stname);
|
||||
}
|
||||
template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const int count)
|
||||
{
|
||||
this->state().save_state_ptr((void *)&owner, pstring(owner.name()) + "." + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
|
||||
}
|
||||
|
||||
virtual void reset();
|
||||
|
||||
plib::dynlib &lib() { return *m_lib; }
|
||||
|
||||
void print_stats() const;
|
||||
|
||||
plib::pvector_t<plib::owned_ptr<core_device_t>> m_devices;
|
||||
std::vector<plib::owned_ptr<core_device_t>> m_devices;
|
||||
|
||||
/* sole use is to manage lifetime of net objects */
|
||||
net_t::list_t m_nets;
|
||||
std::vector<std::shared_ptr<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;
|
||||
@ -1121,16 +1175,16 @@ protected:
|
||||
#endif
|
||||
|
||||
private:
|
||||
netlist_time m_stop; // target time for current queue processing
|
||||
|
||||
plib::state_manager_t m_state;
|
||||
/* mostly rw */
|
||||
netlist_time m_time;
|
||||
bool m_use_deactivate;
|
||||
queue_t m_queue;
|
||||
/* mostly rw */
|
||||
bool m_use_deactivate;
|
||||
|
||||
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;
|
||||
@ -1162,11 +1216,6 @@ protected:
|
||||
// inline implementations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
inline plib::pstate_manager_t &object_t::state_manager()
|
||||
{
|
||||
return m_netlist;
|
||||
}
|
||||
|
||||
template <class C, param_t::param_type_t T>
|
||||
inline void param_template_t<C, T>::setTo(const C ¶m)
|
||||
{
|
||||
@ -1238,7 +1287,7 @@ protected:
|
||||
|
||||
inline void net_t::push_to_queue(const netlist_time delay) NOEXCEPT
|
||||
{
|
||||
if (!is_queued() && (num_cons() > 0))
|
||||
if (!is_queued() && (num_cons() != 0))
|
||||
{
|
||||
m_time = netlist().time() + delay;
|
||||
m_in_queue = (m_active > 0); /* queued ? */
|
||||
@ -1317,10 +1366,28 @@ protected:
|
||||
out.set_Q(val, delay);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename O>
|
||||
state_var<T>::state_var(O &owner, const pstring name, const T &value)
|
||||
: m_value(value)
|
||||
{
|
||||
owner.netlist().save(owner, m_value, name);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
state_var<T[N]>::state_var(device_t &dev, const pstring name, const T & value)
|
||||
{
|
||||
dev.netlist().save(dev, m_value, name);
|
||||
for (std::size_t i=0; i<N; i++)
|
||||
m_value[i] = value;
|
||||
}
|
||||
|
||||
inline netlist_t &device_object_t::netlist()
|
||||
{
|
||||
return m_device.netlist();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NETLIST_SAVE_TYPE(netlist::core_terminal_t::state_e, pstate_data_type_e::DT_INT);
|
||||
|
||||
|
||||
#endif /* NLBASE_H_ */
|
||||
|
@ -8,6 +8,8 @@
|
||||
#ifndef NLCONFIG_H_
|
||||
#define NLCONFIG_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "plib/pconfig.h"
|
||||
|
||||
//============================================================
|
||||
@ -126,7 +128,7 @@
|
||||
//============================================================
|
||||
|
||||
// this macro passes an item followed by a string version of itself as two consecutive parameters
|
||||
#define NLNAME(x) x, #x
|
||||
//#define NLNAME(x) x, #x
|
||||
|
||||
#define NOEXCEPT noexcept
|
||||
|
||||
@ -137,16 +139,17 @@
|
||||
#endif // !defined(USE_OPENMP)
|
||||
|
||||
// Use nano-second resolution - Sufficient for now
|
||||
#define NETLIST_INTERNAL_RES (U64(1000000000))
|
||||
//#define NETLIST_INTERNAL_RES (U64(1000000000000))
|
||||
#define NETLIST_INTERNAL_RES (UINT64_C(1000000000))
|
||||
//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000000))
|
||||
|
||||
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
|
||||
|
||||
//#define nl_double float
|
||||
//#define NL_FCONST(x) (x ## f)
|
||||
|
||||
#define nl_double double
|
||||
//#define nl_double double
|
||||
#define NL_FCONST(x) x
|
||||
using nl_double = double;
|
||||
|
||||
|
||||
//============================================================
|
||||
|
@ -65,7 +65,7 @@ namespace netlist
|
||||
}
|
||||
};
|
||||
|
||||
class factory_list_t : public plib::pvector_t<plib::owned_ptr<base_factory_t>>
|
||||
class factory_list_t : public std::vector<plib::owned_ptr<base_factory_t>>
|
||||
{
|
||||
public:
|
||||
factory_list_t(setup_t &m_setup);
|
||||
|
@ -68,13 +68,12 @@ namespace netlist
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
m_lock = 0;
|
||||
#endif
|
||||
//nl_assert(m_end - m_list < Size);
|
||||
}
|
||||
|
||||
entry_t pop() NOEXCEPT { return *(--m_end); }
|
||||
entry_t top() const NOEXCEPT { return *(m_end-1); }
|
||||
entry_t pop() NOEXCEPT { return *(--m_end); }
|
||||
const entry_t &top() const NOEXCEPT { return *(m_end-1); }
|
||||
|
||||
void remove(const Element &elem) NOEXCEPT
|
||||
void remove(const Element &elem) NOEXCEPT
|
||||
{
|
||||
/* Lock */
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
@ -101,6 +100,12 @@ namespace netlist
|
||||
#endif
|
||||
}
|
||||
|
||||
void retime(const Time t, const Element &elem) NOEXCEPT
|
||||
{
|
||||
remove(elem);
|
||||
push(t, elem);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_end = &m_list[0];
|
||||
|
@ -110,7 +110,7 @@ void setup_t::register_dev(plib::owned_ptr<device_t> dev)
|
||||
|
||||
void setup_t::register_lib_entry(const pstring &name)
|
||||
{
|
||||
if (m_lib.contains(name))
|
||||
if (plib::container::contains(m_lib, name))
|
||||
log().warning("Lib entry collection already contains {1}. IGNORED", name);
|
||||
else
|
||||
m_lib.push_back(name);
|
||||
@ -118,7 +118,7 @@ void setup_t::register_lib_entry(const pstring &name)
|
||||
|
||||
void setup_t::register_dev(const pstring &classname, const pstring &name)
|
||||
{
|
||||
if (m_lib.contains(classname))
|
||||
if (plib::container::contains(m_lib, classname))
|
||||
{
|
||||
namespace_push(name);
|
||||
include(classname);
|
||||
@ -151,13 +151,13 @@ void setup_t::register_model(const pstring &model_in)
|
||||
log().fatal("Unable to parse model: {1}", model_in);
|
||||
pstring model = model_in.left(pos).trim().ucase();
|
||||
pstring def = model_in.substr(pos + 1).trim();
|
||||
if (!m_models.add(model, def))
|
||||
if (!m_models.insert({model, def}).second)
|
||||
log().fatal("Model already exists: {1}", model_in);
|
||||
}
|
||||
|
||||
void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out)
|
||||
{
|
||||
if (!m_alias.add(alias, out))
|
||||
if (!m_alias.insert({alias, out}).second)
|
||||
log().fatal("Error adding alias {1} to alias list\n", alias);
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ void setup_t::register_dippins_arr(const pstring &terms)
|
||||
}
|
||||
}
|
||||
|
||||
pstring setup_t::objtype_as_str(object_t &in) const
|
||||
pstring setup_t::objtype_as_str(device_object_t &in) const
|
||||
{
|
||||
switch (in.type())
|
||||
{
|
||||
@ -191,14 +191,8 @@ pstring setup_t::objtype_as_str(object_t &in) const
|
||||
return "INPUT";
|
||||
case terminal_t::OUTPUT:
|
||||
return "OUTPUT";
|
||||
case terminal_t::NET:
|
||||
return "NET";
|
||||
case terminal_t::PARAM:
|
||||
return "PARAM";
|
||||
case terminal_t::DEVICE:
|
||||
return "DEVICE";
|
||||
case terminal_t::QUEUE:
|
||||
return "QUEUE";
|
||||
}
|
||||
// FIXME: noreturn
|
||||
log().fatal("Unknown object type {1}\n", (unsigned) in.type());
|
||||
@ -207,9 +201,10 @@ pstring setup_t::objtype_as_str(object_t &in) const
|
||||
|
||||
void setup_t::register_and_set_param(pstring name, param_t ¶m)
|
||||
{
|
||||
if (m_param_values.contains(name))
|
||||
auto i = m_param_values.find(name);
|
||||
if (i != m_param_values.end())
|
||||
{
|
||||
const pstring val = m_param_values[name];
|
||||
const pstring val = i->second;
|
||||
log().debug("Found parameter ... {1} : {1}\n", name, val);
|
||||
switch (param.param_type())
|
||||
{
|
||||
@ -240,24 +235,13 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m)
|
||||
log().fatal("Parameter is not supported {1} : {2}\n", name, val);
|
||||
}
|
||||
}
|
||||
if (!m_params.add(param.name(), param_ref_t(param.name(), param.device(), param)))
|
||||
if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second)
|
||||
log().fatal("Error adding parameter {1} to parameter list\n", name);
|
||||
}
|
||||
|
||||
void setup_t::register_term(core_terminal_t &term)
|
||||
{
|
||||
if (term.is_type(terminal_t::OUTPUT))
|
||||
{
|
||||
}
|
||||
else if (term.is_type(terminal_t::INPUT))
|
||||
{
|
||||
static_cast<device_t &>(term.device()).m_terminals.push_back(term.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<device_t &>(term.device()).m_terminals.push_back(term.name());
|
||||
}
|
||||
if (!m_terminals.add(term.name(), &term))
|
||||
if (!m_terminals.insert({term.name(), &term}).second)
|
||||
log().fatal("Error adding {1} {2} to terminal list\n", objtype_as_str(term), term.name());
|
||||
log().debug("{1} {2}\n", objtype_as_str(term), term.name());
|
||||
}
|
||||
@ -291,15 +275,16 @@ void setup_t::remove_connections(const pstring pin)
|
||||
pstring pinfn = build_fqn(pin);
|
||||
bool found = false;
|
||||
|
||||
for (int i = m_links.size() - 1; i >= 0; i--)
|
||||
for (auto link = m_links.begin(); link != m_links.end(); )
|
||||
{
|
||||
auto &link = m_links[i];
|
||||
if ((link.first == pinfn) || (link.second == pinfn))
|
||||
if ((link->first == pinfn) || (link->second == pinfn))
|
||||
{
|
||||
log().verbose("removing connection: {1} <==> {2}\n", link.first, link.second);
|
||||
m_links.remove_at(i);
|
||||
log().verbose("removing connection: {1} <==> {2}\n", link->first, link->second);
|
||||
link = m_links.erase(link);
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
link++;
|
||||
}
|
||||
if (!found)
|
||||
log().fatal("remove_connections: found no occurrence of {1}\n", pin);
|
||||
@ -345,15 +330,15 @@ void setup_t::register_param(const pstring ¶m, const pstring &value)
|
||||
{
|
||||
pstring fqn = build_fqn(param);
|
||||
|
||||
int idx = m_param_values.index_of(fqn);
|
||||
if (idx < 0)
|
||||
auto idx = m_param_values.find(fqn);
|
||||
if (idx == m_param_values.end())
|
||||
{
|
||||
if (!m_param_values.add(fqn, value))
|
||||
if (!m_param_values.insert({fqn, value}).second)
|
||||
log().fatal("Unexpected error adding parameter {1} to parameter list\n", param);
|
||||
}
|
||||
else
|
||||
{
|
||||
log().warning("Overwriting {1} old <{2}> new <{3}>\n", fqn, m_param_values.value_at(idx), value);
|
||||
log().warning("Overwriting {1} old <{2}> new <{3}>\n", fqn, idx->second, value);
|
||||
m_param_values[fqn] = value;
|
||||
}
|
||||
}
|
||||
@ -366,8 +351,8 @@ const pstring setup_t::resolve_alias(const pstring &name) const
|
||||
/* FIXME: Detect endless loop */
|
||||
do {
|
||||
ret = temp;
|
||||
int p = m_alias.index_of(ret);
|
||||
temp = (p>=0 ? m_alias.value_at(p) : "");
|
||||
auto p = m_alias.find(ret);
|
||||
temp = (p != m_alias.end() ? p->second : "");
|
||||
} while (temp != "");
|
||||
|
||||
log().debug("{1}==>{2}\n", name, ret);
|
||||
@ -377,17 +362,15 @@ const pstring setup_t::resolve_alias(const pstring &name) const
|
||||
core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
int ret;
|
||||
|
||||
ret = m_terminals.index_of(tname);
|
||||
auto ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret < 0)
|
||||
if (ret == m_terminals.end())
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
ret = m_terminals.index_of(tname + ".Q");
|
||||
ret = m_terminals.find(tname + ".Q");
|
||||
}
|
||||
|
||||
core_terminal_t *term = (ret < 0 ? nullptr : m_terminals.value_at(ret));
|
||||
core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
|
||||
|
||||
if (term == nullptr && required)
|
||||
log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname);
|
||||
@ -396,22 +379,20 @@ core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool require
|
||||
return term;
|
||||
}
|
||||
|
||||
core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, object_t::type_t atype, bool required)
|
||||
core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, device_object_t::type_t atype, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
int ret;
|
||||
|
||||
ret = m_terminals.index_of(tname);
|
||||
auto ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret < 0 && atype == object_t::OUTPUT)
|
||||
if (ret == m_terminals.end() && atype == device_object_t::OUTPUT)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
ret = m_terminals.index_of(tname + ".Q");
|
||||
ret = m_terminals.find(tname + ".Q");
|
||||
}
|
||||
if (ret < 0 && required)
|
||||
if (ret == m_terminals.end() && required)
|
||||
log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname);
|
||||
|
||||
core_terminal_t *term = (ret < 0 ? nullptr : m_terminals.value_at(ret));
|
||||
core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
|
||||
|
||||
if (term != nullptr && term->type() != atype)
|
||||
{
|
||||
@ -431,14 +412,12 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required)
|
||||
const pstring param_in_fqn = build_fqn(param_in);
|
||||
|
||||
const pstring &outname = resolve_alias(param_in_fqn);
|
||||
int ret;
|
||||
|
||||
ret = m_params.index_of(outname);
|
||||
if (ret < 0 && required)
|
||||
auto ret = m_params.find(outname);
|
||||
if (ret == m_params.end() && required)
|
||||
log().fatal("parameter {1}({2}) not found!\n", param_in_fqn, outname);
|
||||
if (ret != -1)
|
||||
if (ret != m_params.end())
|
||||
log().debug("Found parameter {1}\n", outname);
|
||||
return (ret == -1 ? nullptr : &m_params.value_at(ret).m_param);
|
||||
return (ret == m_params.end() ? nullptr : &ret->second.m_param);
|
||||
}
|
||||
|
||||
// FIXME avoid dynamic cast here
|
||||
@ -588,7 +567,7 @@ void setup_t::connect_terminals(core_terminal_t &t1, core_terminal_t &t2)
|
||||
{
|
||||
log().debug("adding analog net ...\n");
|
||||
// FIXME: Nets should have a unique name
|
||||
analog_net_t::ptr_t anet = plib::palloc<analog_net_t>(netlist(),"net." + t1.name());
|
||||
auto anet = plib::palloc<analog_net_t>(netlist(),"net." + t1.name());
|
||||
t1.set_net(anet);
|
||||
anet->register_con(t2);
|
||||
anet->register_con(t1);
|
||||
@ -706,16 +685,16 @@ void setup_t::resolve_inputs()
|
||||
int tries = 100;
|
||||
while (m_links.size() > 0 && tries > 0) // FIXME: convert into constant
|
||||
{
|
||||
unsigned li = 0;
|
||||
while (li < m_links.size())
|
||||
auto li = m_links.begin();
|
||||
while (li != m_links.end())
|
||||
{
|
||||
const pstring t1s = m_links[li].first;
|
||||
const pstring t2s = m_links[li].second;
|
||||
const pstring t1s = li->first;
|
||||
const pstring t2s = li->second;
|
||||
core_terminal_t *t1 = find_terminal(t1s);
|
||||
core_terminal_t *t2 = find_terminal(t2s);
|
||||
|
||||
if (connect(*t1, *t2))
|
||||
m_links.remove_at(li);
|
||||
li = m_links.erase(li);
|
||||
else
|
||||
li++;
|
||||
}
|
||||
@ -733,28 +712,23 @@ void setup_t::resolve_inputs()
|
||||
|
||||
// delete empty nets ... and save m_list ...
|
||||
|
||||
net_t::list_t todelete;
|
||||
|
||||
for (auto & net : netlist().m_nets)
|
||||
for (auto net = netlist().m_nets.begin(); net != netlist().m_nets.end();)
|
||||
{
|
||||
if (net->num_cons() == 0)
|
||||
todelete.push_back(net);
|
||||
if (net->get()->num_cons() == 0)
|
||||
{
|
||||
log().verbose("Deleting net {1} ...", net->get()->name());
|
||||
net = netlist().m_nets.erase(net);
|
||||
}
|
||||
else
|
||||
net->rebuild_list();
|
||||
}
|
||||
|
||||
for (auto & net : todelete)
|
||||
{
|
||||
log().verbose("Deleting net {1} ...", net->name());
|
||||
netlist().m_nets.remove(net);
|
||||
++net;
|
||||
}
|
||||
|
||||
pstring errstr("");
|
||||
|
||||
log().verbose("looking for terminals not connected ...");
|
||||
for (std::size_t i = 0; i < m_terminals.size(); i++)
|
||||
for (auto & i : m_terminals)
|
||||
{
|
||||
core_terminal_t *term = m_terminals.value_at(i);
|
||||
core_terminal_t *term = i.second;
|
||||
if (!term->has_net() && dynamic_cast< devices::NETLIB_NAME(dummy_input) *>(&term->device()) != nullptr)
|
||||
log().warning("Found dummy terminal {1} without connections", term->name());
|
||||
else if (!term->has_net())
|
||||
@ -862,13 +836,12 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
static pstring model_string(model_map_t &map)
|
||||
{
|
||||
pstring ret = map["COREMODEL"] + "(";
|
||||
for (unsigned i=0; i<map.size(); i++)
|
||||
ret = ret + map.key_at(i) + "=" + map.value_at(i) + " ";
|
||||
for (auto & i : map)
|
||||
ret = ret + i.first + "=" + i.second + " ";
|
||||
|
||||
return ret + ")";
|
||||
}
|
||||
|
||||
|
||||
void setup_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
{
|
||||
pstring model = model_in;
|
||||
@ -881,9 +854,10 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
if (pos >= 0) break;
|
||||
|
||||
key = model.ucase();
|
||||
if (!m_models.contains(key))
|
||||
auto i = m_models.find(key);
|
||||
if (i == m_models.end())
|
||||
log().fatal("Model {1} not found\n", model);
|
||||
model = m_models[key];
|
||||
model = i->second;
|
||||
}
|
||||
pstring xmodel = model.left(pos);
|
||||
|
||||
@ -891,7 +865,8 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
map["COREMODEL"] = key;
|
||||
else
|
||||
{
|
||||
if (m_models.contains(xmodel))
|
||||
auto i = m_models.find(xmodel);
|
||||
if (i != m_models.end())
|
||||
model_parse(xmodel, map);
|
||||
else
|
||||
log().fatal("Model doesn't exist: <{1}>\n", model_in);
|
||||
@ -918,7 +893,7 @@ const pstring setup_t::model_value_str(model_map_t &map, const pstring &entity)
|
||||
|
||||
if (entity != entity.ucase())
|
||||
log().fatal("model parameters should be uppercase:{1} {2}\n", entity, model_string(map));
|
||||
if (!map.contains(entity))
|
||||
if (map.find(entity) == map.end())
|
||||
log().fatal("Entity {1} not found in model {2}\n", entity, model_string(map));
|
||||
else
|
||||
ret = map[entity];
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
|
||||
@ -91,7 +93,7 @@ namespace netlist
|
||||
class source_t
|
||||
{
|
||||
public:
|
||||
using list_t = plib::pvector_t<std::shared_ptr<source_t>>;
|
||||
using list_t = std::vector<std::shared_ptr<source_t>>;
|
||||
|
||||
source_t()
|
||||
{}
|
||||
@ -167,7 +169,7 @@ namespace netlist
|
||||
factory_list_t &factory() { return m_factory; }
|
||||
const factory_list_t &factory() const { return m_factory; }
|
||||
|
||||
bool is_library_item(const pstring &name) const { return m_lib.contains(name); }
|
||||
bool is_library_item(const pstring &name) const { return plib::container::contains(m_lib, name); }
|
||||
|
||||
/* model / family related */
|
||||
|
||||
@ -180,14 +182,14 @@ namespace netlist
|
||||
plib::plog_base<NL_DEBUG> &log() { return netlist().log(); }
|
||||
const plib::plog_base<NL_DEBUG> &log() const { return netlist().log(); }
|
||||
|
||||
plib::pvector_t<std::pair<pstring, base_factory_t *>> m_device_factory;
|
||||
std::vector<std::pair<pstring, base_factory_t *>> m_device_factory;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
core_terminal_t *find_terminal(const pstring &outname_in, bool required = true);
|
||||
core_terminal_t *find_terminal(const pstring &outname_in, object_t::type_t atype, bool required = true);
|
||||
core_terminal_t *find_terminal(const pstring &outname_in, device_object_t::type_t atype, bool required = true);
|
||||
|
||||
void connect_terminals(core_terminal_t &in, core_terminal_t &out);
|
||||
void connect_input_output(core_terminal_t &in, core_terminal_t &out);
|
||||
@ -196,30 +198,32 @@ namespace netlist
|
||||
bool connect_input_input(core_terminal_t &t1, core_terminal_t &t2);
|
||||
|
||||
// helpers
|
||||
pstring objtype_as_str(object_t &in) const;
|
||||
pstring objtype_as_str(device_object_t &in) const;
|
||||
|
||||
const pstring resolve_alias(const pstring &name) const;
|
||||
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
|
||||
|
||||
netlist_t &m_netlist;
|
||||
|
||||
plib::hashmap_t<pstring, pstring> m_alias;
|
||||
plib::hashmap_t<pstring, param_ref_t> m_params;
|
||||
plib::hashmap_t<pstring, pstring> m_param_values;
|
||||
plib::hashmap_t<pstring, core_terminal_t *> m_terminals;
|
||||
public:
|
||||
std::unordered_map<pstring, pstring> m_alias;
|
||||
std::unordered_map<pstring, param_ref_t> m_params;
|
||||
std::unordered_map<pstring, pstring> m_param_values;
|
||||
std::unordered_map<pstring, core_terminal_t *> m_terminals;
|
||||
private:
|
||||
|
||||
plib::pvector_t<link_t> m_links;
|
||||
std::vector<link_t> m_links;
|
||||
|
||||
factory_list_t m_factory;
|
||||
|
||||
plib::hashmap_t<pstring, pstring> m_models;
|
||||
std::unordered_map<pstring, pstring> m_models;
|
||||
|
||||
int m_proxy_cnt;
|
||||
int m_frontier_cnt;
|
||||
|
||||
std::stack<pstring> m_namespace_stack;
|
||||
source_t::list_t m_sources;
|
||||
plib::pvector_t<pstring> m_lib;
|
||||
std::vector<pstring> m_lib;
|
||||
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef NLTIME_H_
|
||||
#define NLTIME_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "plib/pstate.h"
|
||||
|
||||
@ -25,114 +27,113 @@
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
struct netlist_time final
|
||||
template <typename TYPE, TYPE RES>
|
||||
struct ptime final
|
||||
{
|
||||
public:
|
||||
|
||||
#if (PHAS_INT128)
|
||||
using INTERNALTYPE = UINT128;
|
||||
static const pstate_data_type_e STATETYPE = DT_INT128;
|
||||
#else
|
||||
using INTERNALTYPE = UINT64;
|
||||
static constexpr pstate_data_type_e STATETYPE = pstate_data_type_e::DT_INT64;
|
||||
#endif
|
||||
static constexpr INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
|
||||
using internal_type = TYPE;
|
||||
using mult_type = std::uint_fast64_t;
|
||||
static constexpr internal_type resolution = RES;
|
||||
|
||||
constexpr netlist_time() NOEXCEPT : m_time(0) {}
|
||||
netlist_time(const netlist_time &rhs) NOEXCEPT = default;
|
||||
netlist_time(netlist_time &&rhs) NOEXCEPT = default;
|
||||
constexpr ptime() NOEXCEPT : m_time(0) {}
|
||||
constexpr ptime(const ptime &rhs) NOEXCEPT = default;
|
||||
constexpr ptime(ptime &&rhs) NOEXCEPT = default;
|
||||
|
||||
constexpr explicit netlist_time(const double t)
|
||||
: m_time((INTERNALTYPE) ( t * (double) RESOLUTION)) { }
|
||||
constexpr explicit netlist_time(const INTERNALTYPE nom, const INTERNALTYPE den)
|
||||
: m_time(nom * (RESOLUTION / den)) { }
|
||||
constexpr explicit ptime(const double t) = delete;
|
||||
//: m_time((internal_type) ( t * (double) resolution)) { }
|
||||
constexpr explicit ptime(const internal_type nom, const internal_type den)
|
||||
: m_time(nom * (resolution / den)) { }
|
||||
|
||||
ptime &operator=(const ptime rhs) { m_time = rhs.m_time; return *this; }
|
||||
|
||||
netlist_time &operator=(const netlist_time rhs) { m_time = rhs.m_time; return *this; }
|
||||
ptime &operator+=(const ptime &rhs) { m_time += rhs.m_time; return *this; }
|
||||
ptime &operator-=(const ptime &rhs) { m_time -= rhs.m_time; return *this; }
|
||||
|
||||
netlist_time &operator+=(const netlist_time &rhs) { m_time += rhs.m_time; return *this; }
|
||||
netlist_time &operator-=(const netlist_time &rhs) { m_time -= rhs.m_time; return *this; }
|
||||
|
||||
friend netlist_time operator-(netlist_time lhs, const netlist_time &rhs)
|
||||
friend ptime operator-(ptime lhs, const ptime &rhs)
|
||||
{
|
||||
lhs -= rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend netlist_time operator+(netlist_time lhs, const netlist_time &rhs)
|
||||
friend ptime operator+(ptime lhs, const ptime &rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend netlist_time operator*(netlist_time lhs, const UINT64 factor)
|
||||
friend ptime operator*(ptime lhs, const mult_type factor)
|
||||
{
|
||||
lhs.m_time *= static_cast<INTERNALTYPE>(factor);
|
||||
lhs.m_time *= static_cast<internal_type>(factor);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend UINT64 operator/(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend mult_type operator/(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return static_cast<UINT64>(lhs.m_time / rhs.m_time);
|
||||
return static_cast<mult_type>(lhs.m_time / rhs.m_time);
|
||||
}
|
||||
|
||||
friend bool operator<(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator<(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return (lhs.m_time < rhs.m_time);
|
||||
}
|
||||
|
||||
friend bool operator>(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator>(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
return (rhs < lhs);
|
||||
}
|
||||
|
||||
friend bool operator<=(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator<=(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
friend bool operator>=(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator>=(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
friend bool operator==(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator==(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return lhs.m_time == rhs.m_time;
|
||||
}
|
||||
|
||||
friend bool operator!=(const netlist_time &lhs, const netlist_time &rhs)
|
||||
friend bool operator!=(const ptime &lhs, const ptime &rhs)
|
||||
{
|
||||
return lhs.m_time != rhs.m_time;
|
||||
}
|
||||
|
||||
INTERNALTYPE as_raw() const { return m_time; }
|
||||
double as_double() const { return (double) m_time / (double) RESOLUTION; }
|
||||
constexpr internal_type as_raw() const { return m_time; }
|
||||
constexpr double as_double() const { return (double) m_time / (double) resolution; }
|
||||
|
||||
// for save states ....
|
||||
INTERNALTYPE *get_internaltype_ptr() { return &m_time; }
|
||||
internal_type *get_internaltype_ptr() { return &m_time; }
|
||||
|
||||
static inline netlist_time from_nsec(const INTERNALTYPE ns) { return netlist_time(ns, U64(1000000000)); }
|
||||
static inline netlist_time from_usec(const INTERNALTYPE us) { return netlist_time(us, U64(1000000)); }
|
||||
static inline netlist_time from_msec(const INTERNALTYPE ms) { return netlist_time(ms, U64(1000)); }
|
||||
static inline netlist_time from_hz(const INTERNALTYPE hz) { return netlist_time(1 , hz); }
|
||||
static inline netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw, RESOLUTION); }
|
||||
static inline constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); }
|
||||
static inline constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); }
|
||||
static inline constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); }
|
||||
static inline constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); }
|
||||
static inline constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); }
|
||||
static inline constexpr ptime from_double(const double t) { return ptime((internal_type) ( t * (double) resolution), resolution); }
|
||||
|
||||
static inline netlist_time zero() { return netlist_time(0, RESOLUTION); }
|
||||
static inline netlist_time quantum() { return netlist_time(1, RESOLUTION); }
|
||||
static inline netlist_time never() { return netlist_time(std::numeric_limits<netlist_time::INTERNALTYPE>::max(), RESOLUTION); }
|
||||
static inline constexpr ptime zero() { return ptime(0, resolution); }
|
||||
static inline constexpr ptime quantum() { return ptime(1, resolution); }
|
||||
static inline constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
|
||||
private:
|
||||
INTERNALTYPE m_time;
|
||||
internal_type m_time;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if (PHAS_INT128)
|
||||
using netlist_time = ptime<UINT128, NETLIST_INTERNAL_RES>;
|
||||
#else
|
||||
using netlist_time = ptime<std::uint_fast64_t, NETLIST_INTERNAL_RES>;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace plib {
|
||||
template<> inline void pstate_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname)
|
||||
template<> inline void state_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname)
|
||||
{
|
||||
save_state_ptr(owner, stname, netlist::netlist_time::STATETYPE, sizeof(netlist::netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
|
||||
save_state_ptr(owner, stname, datatype_t(sizeof(netlist::netlist_time::internal_type), false, true, false), 1, nlt.get_internaltype_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,26 +16,6 @@
|
||||
#include "pconfig.h"
|
||||
#include "pstring.h"
|
||||
|
||||
#if (PSTANDALONE)
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
|
||||
#if !defined(__ppc__) && !defined (__PPC__) && !defined(__ppc64__) && !defined(__PPC64__)
|
||||
#define ATTR_ALIGN __attribute__ ((aligned(64)))
|
||||
#else
|
||||
#define ATTR_ALIGN
|
||||
#endif
|
||||
#else
|
||||
#define ATTR_ALIGN
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define ATTR_ALIGN
|
||||
|
||||
#endif
|
||||
|
||||
namespace plib {
|
||||
|
||||
//============================================================
|
||||
@ -171,8 +151,8 @@ private:
|
||||
struct block
|
||||
{
|
||||
block() : m_num_alloc(0), m_free(0), cur_ptr(nullptr), data(nullptr) { }
|
||||
int m_num_alloc;
|
||||
int m_free;
|
||||
std::size_t m_num_alloc;
|
||||
std::size_t m_free;
|
||||
char *cur_ptr;
|
||||
char *data;
|
||||
};
|
||||
|
@ -23,25 +23,17 @@
|
||||
#endif
|
||||
|
||||
#if (PHAS_INT128)
|
||||
typedef _uint128_t UINT128;
|
||||
typedef _int128_t INT128;
|
||||
typedef __uint128_t UINT128;
|
||||
typedef __int128_t INT128;
|
||||
#endif
|
||||
|
||||
#if !(PSTANDALONE)
|
||||
#include "osdcomm.h"
|
||||
//#include "eminline.h"
|
||||
|
||||
#ifndef assert
|
||||
#define assert(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define RESTRICT __restrict__
|
||||
#define ATTR_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#define RESTRICT
|
||||
#define ATTR_UNUSED
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
//============================================================
|
||||
// Standard defines
|
||||
@ -54,27 +46,18 @@ typedef _int128_t INT128;
|
||||
name &operator=(const name &);
|
||||
|
||||
//============================================================
|
||||
// Compiling standalone
|
||||
// cut down delegate implementation
|
||||
//============================================================
|
||||
|
||||
#if !(PSTANDALONE)
|
||||
|
||||
/* use MAME */
|
||||
#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
|
||||
#define PHAS_PMF_INTERNAL 1
|
||||
#else
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* determine PMF approach */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* does not work in versions over 4.7.x of 32bit MINGW */
|
||||
#if defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#elif defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__)
|
||||
#define PHAS_PMF_INTERNAL 1
|
||||
#define MEMBER_ABI _thiscall
|
||||
#elif defined(__clang__) && defined(__i386__) && defined(_WIN32)
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#elif defined(__arm__) || defined(__ARMEL__)
|
||||
@ -83,56 +66,16 @@ typedef _int128_t INT128;
|
||||
#define PHAS_PMF_INTERNAL 1
|
||||
#endif
|
||||
#else
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#define PHAS_PMF_INTERNAL 0
|
||||
#endif
|
||||
|
||||
#ifndef MEMBER_ABI
|
||||
#define MEMBER_ABI
|
||||
#endif
|
||||
|
||||
#define RESTRICT __restrict__
|
||||
#define ATTR_PRINTF(x,y) __attribute__((format(printf, x, y)))
|
||||
#define ATTR_UNUSED __attribute__((__unused__))
|
||||
|
||||
/* 8-bit values */
|
||||
typedef unsigned char UINT8;
|
||||
typedef signed char INT8;
|
||||
|
||||
/* 16-bit values */
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed short INT16;
|
||||
|
||||
/* 32-bit values */
|
||||
#ifndef WINDOWS_H
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed int INT32;
|
||||
#endif
|
||||
|
||||
/* 64-bit values */
|
||||
#ifndef WINDOWS_H
|
||||
#ifdef _MSC_VER
|
||||
typedef signed _int64 INT64;
|
||||
typedef unsigned _int64 UINT64;
|
||||
#else
|
||||
typedef uint64_t UINT64;
|
||||
typedef int64_t INT64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* U64 and S64 are used to wrap long integer constants. */
|
||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||
#define U64(val) val##ULL
|
||||
#define S64(val) val##LL
|
||||
#else
|
||||
#define U64(val) val
|
||||
#define S64(val) val
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace plib {
|
||||
|
||||
using ticks_t = INT64;
|
||||
using ticks_t = int64_t;
|
||||
|
||||
static inline ticks_t ticks()
|
||||
{
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
//#include <cstring>
|
||||
//#include <array>
|
||||
|
||||
#include "palloc.h"
|
||||
#include "pstring.h"
|
||||
@ -71,48 +69,6 @@ private:
|
||||
typename std::aligned_storage<sizeof(C), alignof(C)>::type m_buf[N];
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// plist_t: a simple list
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename LC>
|
||||
class pvector_t : public std::vector<LC>
|
||||
{
|
||||
public:
|
||||
pvector_t() : std::vector<LC>() {}
|
||||
|
||||
bool contains(const LC &elem) const
|
||||
{
|
||||
return (std::find(this->begin(), this->end(), elem) != this->end());
|
||||
}
|
||||
|
||||
void remove(const LC &elem)
|
||||
{
|
||||
this->erase(std::remove(this->begin(), this->end(), elem), this->end());
|
||||
}
|
||||
|
||||
void insert_at(const std::size_t index, const LC &elem)
|
||||
{
|
||||
this->insert(this->begin() + index, elem);
|
||||
}
|
||||
|
||||
void remove_at(const std::size_t pos)
|
||||
{
|
||||
this->erase(this->begin() + pos);
|
||||
}
|
||||
|
||||
int indexof(const LC &elem) const
|
||||
{
|
||||
for (std::size_t i = 0; i < this->size(); i++)
|
||||
{
|
||||
if (this->at(i) == elem)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// plinkedlist_t: a simple linked list
|
||||
// the list allows insertions / deletions if used properly
|
||||
@ -187,249 +143,10 @@ public:
|
||||
void clear() { m_head = nullptr; }
|
||||
bool empty() const { return (m_head == nullptr); }
|
||||
|
||||
//private:
|
||||
private:
|
||||
LC *m_head;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// hashmap list
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class C>
|
||||
struct hash_functor
|
||||
{
|
||||
hash_functor()
|
||||
: m_hash(0)
|
||||
{}
|
||||
hash_functor(const C &v)
|
||||
: m_hash(v)
|
||||
{
|
||||
}
|
||||
friend unsigned operator%(const hash_functor &lhs, const unsigned &rhs) { return lhs.m_hash % rhs; }
|
||||
bool operator==(const hash_functor &lhs) const { return (m_hash == lhs.m_hash); }
|
||||
private:
|
||||
unsigned m_hash;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash_functor<pstring>
|
||||
{
|
||||
hash_functor()
|
||||
: m_hash(0)
|
||||
{}
|
||||
hash_functor(const pstring &v)
|
||||
{
|
||||
/* modified djb2 */
|
||||
const pstring::mem_t *string = v.cstr();
|
||||
unsigned result = 5381;
|
||||
for (pstring::mem_t c = *string; c != 0; c = *string++)
|
||||
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ c;
|
||||
//result = (result*33) ^ c;
|
||||
m_hash = result;
|
||||
}
|
||||
friend unsigned operator%(const hash_functor<pstring> &lhs, const unsigned &rhs) { return lhs.m_hash % rhs; }
|
||||
unsigned operator()() { return m_hash; }
|
||||
bool operator==(const hash_functor<pstring> &lhs) const { return (m_hash == lhs.m_hash); }
|
||||
private:
|
||||
unsigned m_hash;
|
||||
};
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
unsigned hash(const pstring &v) const
|
||||
{
|
||||
/* Fowler???Noll???Vo hash - FNV-1 */
|
||||
const char *string = v.cstr();
|
||||
unsigned result = 2166136261;
|
||||
for (UINT8 c = *string++; c != 0; c = *string++)
|
||||
result = (result * 16777619) ^ c;
|
||||
// result = (result ^ c) * 16777619; FNV 1a
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
unsigned hash(const pstring &v) const
|
||||
{
|
||||
/* jenkins one at a time algo */
|
||||
unsigned result = 0;
|
||||
const char *string = v.cstr();
|
||||
while (*string)
|
||||
{
|
||||
result += *string;
|
||||
string++;
|
||||
result += (result << 10);
|
||||
result ^= (result >> 6);
|
||||
}
|
||||
result += (result << 3);
|
||||
result ^= (result >> 11);
|
||||
result += (result << 15);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <class K, class V, class H = hash_functor<K> >
|
||||
class hashmap_t
|
||||
{
|
||||
public:
|
||||
hashmap_t() : m_hash(37)
|
||||
{
|
||||
for (unsigned i=0; i<m_hash.size(); i++)
|
||||
m_hash[i] = -1;
|
||||
}
|
||||
|
||||
~hashmap_t()
|
||||
{
|
||||
}
|
||||
|
||||
struct element_t
|
||||
{
|
||||
element_t(const K &key, const H &hash, const V &value)
|
||||
: m_key(key), m_hash(hash), m_value(value), m_next(-1)
|
||||
{}
|
||||
K m_key;
|
||||
H m_hash;
|
||||
V m_value;
|
||||
int m_next;
|
||||
};
|
||||
|
||||
void clear()
|
||||
{
|
||||
#if 0
|
||||
if (0)
|
||||
{
|
||||
unsigned cnt = 0;
|
||||
for (unsigned i=0; i<m_hash.size(); i++)
|
||||
if (m_hash[i] >= 0)
|
||||
cnt++;
|
||||
const unsigned s = m_values.size();
|
||||
if (s>0)
|
||||
printf("phashmap: %d elements %d hashsize, percent in overflow: %d\n", s, (unsigned) m_hash.size(), (s - cnt) * 100 / s);
|
||||
else
|
||||
printf("phashmap: No elements .. \n");
|
||||
}
|
||||
#endif
|
||||
m_values.clear();
|
||||
for (unsigned i=0; i<m_hash.size(); i++)
|
||||
m_hash[i] = -1;
|
||||
}
|
||||
|
||||
bool contains(const K &key) const
|
||||
{
|
||||
return (get_idx(key) >= 0);
|
||||
}
|
||||
|
||||
int index_of(const K &key) const
|
||||
{
|
||||
return get_idx(key);
|
||||
}
|
||||
|
||||
unsigned size() const { return m_values.size(); }
|
||||
|
||||
bool add(const K &key, const V &value)
|
||||
{
|
||||
/*
|
||||
* we are using the Euler prime function here
|
||||
*
|
||||
* n * n + n + 41 | 40 >= n >=0
|
||||
*
|
||||
* and accept that outside we will not have a prime
|
||||
*
|
||||
*/
|
||||
if (m_values.size() * 3 / 2 > m_hash.size())
|
||||
{
|
||||
unsigned n = std::sqrt( 2 * m_hash.size());
|
||||
n = n * n + n + 41;
|
||||
m_hash.resize(n);
|
||||
rebuild();
|
||||
}
|
||||
const H hash(key);
|
||||
const unsigned pos = hash % m_hash.size();
|
||||
if (m_hash[pos] == -1)
|
||||
{
|
||||
unsigned vpos = m_values.size();
|
||||
m_values.push_back(element_t(key, hash, value));
|
||||
m_hash[pos] = vpos;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ep = m_hash[pos];
|
||||
|
||||
for (; ep != -1; ep = m_values[ep].m_next)
|
||||
{
|
||||
if (m_values[ep].m_hash == hash && m_values[ep].m_key == key )
|
||||
return false; /* duplicate */
|
||||
}
|
||||
unsigned vpos = m_values.size();
|
||||
m_values.push_back(element_t(key, hash, value));
|
||||
m_values[vpos].m_next = m_hash[pos];
|
||||
m_hash[pos] = vpos;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
V& operator[](const K &key)
|
||||
{
|
||||
int p = get_idx(key);
|
||||
if (p == -1)
|
||||
{
|
||||
p = m_values.size();
|
||||
add(key, V());
|
||||
}
|
||||
return m_values[p].m_value;
|
||||
}
|
||||
|
||||
V& value_at(const unsigned pos) { return m_values[pos].m_value; }
|
||||
const V& value_at(const unsigned pos) const { return m_values[pos].m_value; }
|
||||
|
||||
V& key_at(const unsigned pos) { return m_values[pos].m_key; }
|
||||
private:
|
||||
|
||||
int get_idx(const K &key) const
|
||||
{
|
||||
H hash(key);
|
||||
const unsigned pos = hash % m_hash.size();
|
||||
|
||||
for (int ep = m_hash[pos]; ep != -1; ep = m_values[ep].m_next)
|
||||
if (m_values[ep].m_hash == hash && m_values[ep].m_key == key )
|
||||
return ep;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rebuild()
|
||||
{
|
||||
for (unsigned i=0; i<m_hash.size(); i++)
|
||||
m_hash[i] = -1;
|
||||
for (unsigned i=0; i<m_values.size(); i++)
|
||||
{
|
||||
unsigned pos = m_values[i].m_hash % m_hash.size();
|
||||
m_values[i].m_next = m_hash[pos];
|
||||
m_hash[pos] = i;
|
||||
}
|
||||
|
||||
}
|
||||
pvector_t<element_t> m_values;
|
||||
std::vector<int> m_hash;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// sort a list ... slow, I am lazy
|
||||
// elements must support ">" operator.
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
static inline void sort_list(T &sl)
|
||||
{
|
||||
for(unsigned i = 0; i < sl.size(); i++)
|
||||
{
|
||||
for(unsigned j = i + 1; j < sl.size(); j++)
|
||||
if(sl[i] > sl[j])
|
||||
std::swap(sl[i], sl[j]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* PLISTS_H_ */
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
|
||||
virtual int parse(pstring argument) override
|
||||
{
|
||||
if (m_limit.contains(argument))
|
||||
if (plib::container::contains(m_limit, argument))
|
||||
{
|
||||
m_val = argument;
|
||||
return 0;
|
||||
@ -224,7 +224,7 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pvector_t<option *> m_opts;
|
||||
std::vector<option *> m_opts;
|
||||
pstring m_app;
|
||||
};
|
||||
|
||||
|
@ -197,7 +197,7 @@ ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
token_id_t id(plib::container::indexof(m_tokens, tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
@ -225,14 +225,14 @@ ptokenizer::token_t ptokenizer::get_token_internal()
|
||||
/* expensive, check for single char tokens */
|
||||
if (tokstr.len() == 1)
|
||||
{
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
token_id_t id(plib::container::indexof(m_tokens, tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
}
|
||||
c = getc();
|
||||
}
|
||||
ungetc();
|
||||
token_id_t id = token_id_t(m_tokens.indexof(tokstr));
|
||||
token_id_t id(plib::container::indexof(m_tokens, tokstr));
|
||||
if (id.id() >= 0)
|
||||
return token_t(id, tokstr);
|
||||
else
|
||||
@ -267,7 +267,7 @@ ppreprocessor::ppreprocessor()
|
||||
m_expr_sep.push_back(" ");
|
||||
m_expr_sep.push_back("\t");
|
||||
|
||||
m_defines.add("__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1"));
|
||||
m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")});
|
||||
}
|
||||
|
||||
void ppreprocessor::error(const pstring &err)
|
||||
@ -349,9 +349,9 @@ double ppreprocessor::expr(const pstring_vector_t &sexpr, std::size_t &start, in
|
||||
|
||||
ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
|
||||
{
|
||||
int idx = m_defines.index_of(name);
|
||||
if (idx >= 0)
|
||||
return &m_defines.value_at(idx);
|
||||
auto idx = m_defines.find(name);
|
||||
if (idx != m_defines.end())
|
||||
return &idx->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@ -440,7 +440,7 @@ pstring ppreprocessor::process_line(const pstring &line)
|
||||
{
|
||||
if (lti.size() != 3)
|
||||
error("PREPRO: only simple defines allowed: " + line);
|
||||
m_defines.add(lti[1], define_t(lti[1], lti[2]));
|
||||
m_defines.insert({lti[1], define_t(lti[1], lti[2])});
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -8,6 +8,9 @@
|
||||
#ifndef PPARSER_H_
|
||||
#define PPARSER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pstring.h"
|
||||
#include "plists.h"
|
||||
@ -139,7 +142,7 @@ private:
|
||||
pstring m_identifier_chars;
|
||||
pstring m_number_chars;
|
||||
pstring m_number_chars_start;
|
||||
pvector_t<pstring> m_tokens;
|
||||
std::vector<pstring> m_tokens;
|
||||
pstring m_whitespace;
|
||||
pstring::code_t m_string;
|
||||
|
||||
@ -189,11 +192,10 @@ private:
|
||||
|
||||
pstring process_line(const pstring &line);
|
||||
|
||||
hashmap_t<pstring, define_t> m_defines;
|
||||
std::unordered_map<pstring, define_t> m_defines;
|
||||
plib::pstring_vector_t m_expr_sep;
|
||||
|
||||
//pstringbuffer m_ret;
|
||||
UINT32 m_ifflag; // 31 if levels
|
||||
std::uint_least32_t m_ifflag; // 31 if levels
|
||||
int m_level;
|
||||
int m_lineno;
|
||||
};
|
||||
|
@ -9,70 +9,53 @@
|
||||
|
||||
namespace plib {
|
||||
|
||||
pstate_manager_t::pstate_manager_t()
|
||||
state_manager_t::state_manager_t()
|
||||
{
|
||||
}
|
||||
|
||||
pstate_manager_t::~pstate_manager_t()
|
||||
state_manager_t::~state_manager_t()
|
||||
{
|
||||
m_save.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pstate_manager_t::save_state_ptr(const void *owner, const pstring &stname, const pstate_data_type_e dt, const int size, const int count, void *ptr, bool is_ptr)
|
||||
void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const int count, void *ptr)
|
||||
{
|
||||
pstring fullname = stname;
|
||||
ATTR_UNUSED pstring ts[] = {
|
||||
"NOT_SUPPORTED",
|
||||
"DT_CUSTOM",
|
||||
"DT_DOUBLE",
|
||||
#if (PHAS_INT128)
|
||||
"DT_INT128",
|
||||
#endif
|
||||
"DT_INT64",
|
||||
"DT_INT16",
|
||||
"DT_INT8",
|
||||
"DT_INT",
|
||||
"DT_BOOLEAN",
|
||||
"DT_FLOAT"
|
||||
};
|
||||
|
||||
auto p = plib::make_unique<pstate_entry_t>(stname, dt, owner, size, count, ptr, is_ptr);
|
||||
auto p = plib::make_unique<entry_t>(stname, dt, owner, count, ptr);
|
||||
m_save.push_back(std::move(p));
|
||||
}
|
||||
|
||||
void pstate_manager_t::remove_save_items(const void *owner)
|
||||
void state_manager_t::remove_save_items(const void *owner)
|
||||
{
|
||||
unsigned i = 0;
|
||||
while (i < m_save.size())
|
||||
for (auto i = m_save.begin(); i != m_save.end(); )
|
||||
{
|
||||
if (m_save[i]->m_owner == owner)
|
||||
m_save.remove_at(i);
|
||||
if (i->get()->m_owner == owner)
|
||||
i = m_save.erase(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void pstate_manager_t::pre_save()
|
||||
void state_manager_t::pre_save()
|
||||
{
|
||||
for (auto & s : m_save)
|
||||
if (s->m_dt == DT_CUSTOM)
|
||||
if (s->m_dt.is_custom)
|
||||
s->m_callback->on_pre_save();
|
||||
}
|
||||
|
||||
void pstate_manager_t::post_load()
|
||||
void state_manager_t::post_load()
|
||||
{
|
||||
for (auto & s : m_save)
|
||||
if (s->m_dt == DT_CUSTOM)
|
||||
if (s->m_dt.is_custom)
|
||||
s->m_callback->on_post_load();
|
||||
}
|
||||
|
||||
template<> void pstate_manager_t::save_item(const void *owner, pstate_callback_t &state, const pstring &stname)
|
||||
template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname)
|
||||
{
|
||||
//save_state_ptr(stname, DT_CUSTOM, 0, 1, &state);
|
||||
pstate_callback_t *state_p = &state;
|
||||
auto p = plib::make_unique<pstate_entry_t>(stname, owner, state_p);
|
||||
callback_t *state_p = &state;
|
||||
auto p = plib::make_unique<entry_t>(stname, owner, state_p);
|
||||
m_save.push_back(std::move(p));
|
||||
state.register_state(*this, stname);
|
||||
}
|
||||
|
@ -9,134 +9,114 @@
|
||||
#define PSTATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include "plists.h"
|
||||
#include "pstring.h"
|
||||
#include "ptypes.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// state saving ...
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
enum pstate_data_type_e {
|
||||
NOT_SUPPORTED,
|
||||
DT_CUSTOM,
|
||||
DT_DOUBLE,
|
||||
#if (PHAS_INT128)
|
||||
DT_INT128,
|
||||
#endif
|
||||
DT_INT64,
|
||||
DT_INT16,
|
||||
DT_INT8,
|
||||
DT_INT,
|
||||
DT_BOOLEAN,
|
||||
DT_FLOAT
|
||||
};
|
||||
|
||||
template<typename ItemType> struct pstate_datatype
|
||||
{
|
||||
static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED);
|
||||
static const bool is_ptr = false;
|
||||
};
|
||||
|
||||
template<typename ItemType> struct pstate_datatype<ItemType *>
|
||||
{
|
||||
static const pstate_data_type_e type = pstate_data_type_e(NOT_SUPPORTED);
|
||||
static const bool is_ptr = true;
|
||||
};
|
||||
|
||||
//template<typename ItemType> struct type_checker<ItemType*> { static const bool is_atom = false; static const bool is_pointer = true; };
|
||||
|
||||
#define NETLIST_SAVE_TYPE(TYPE, TYPEDESC) \
|
||||
template<> struct pstate_datatype<TYPE>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); static const bool is_ptr = false;}; \
|
||||
template<> struct pstate_datatype<TYPE *>{ static const pstate_data_type_e type = pstate_data_type_e(TYPEDESC); static const bool is_ptr = true;}
|
||||
|
||||
NETLIST_SAVE_TYPE(char, DT_INT8);
|
||||
NETLIST_SAVE_TYPE(double, DT_DOUBLE);
|
||||
NETLIST_SAVE_TYPE(float, DT_FLOAT);
|
||||
NETLIST_SAVE_TYPE(INT8, DT_INT8);
|
||||
NETLIST_SAVE_TYPE(UINT8, DT_INT8);
|
||||
#if (PHAS_INT128)
|
||||
NETLIST_SAVE_TYPE(INT128, DT_INT128);
|
||||
NETLIST_SAVE_TYPE(UINT128, DT_INT128);
|
||||
#endif
|
||||
NETLIST_SAVE_TYPE(INT64, DT_INT64);
|
||||
NETLIST_SAVE_TYPE(UINT64, DT_INT64);
|
||||
NETLIST_SAVE_TYPE(bool, DT_BOOLEAN);
|
||||
NETLIST_SAVE_TYPE(UINT32, DT_INT);
|
||||
NETLIST_SAVE_TYPE(INT32, DT_INT);
|
||||
NETLIST_SAVE_TYPE(UINT16, DT_INT16);
|
||||
NETLIST_SAVE_TYPE(INT16, DT_INT16);
|
||||
//NETLIST_SAVE_TYPE(std::size_t, DT_INT64);
|
||||
|
||||
namespace plib {
|
||||
|
||||
class pstate_manager_t;
|
||||
|
||||
class pstate_callback_t
|
||||
class state_manager_t
|
||||
{
|
||||
public:
|
||||
using list_t = pvector_t<pstate_callback_t *>;
|
||||
|
||||
virtual ~pstate_callback_t() { };
|
||||
|
||||
virtual void register_state(pstate_manager_t &manager, const pstring &module) = 0;
|
||||
virtual void on_pre_save() = 0;
|
||||
virtual void on_post_load() = 0;
|
||||
protected:
|
||||
};
|
||||
|
||||
struct pstate_entry_t
|
||||
{
|
||||
using list_t = pvector_t<std::unique_ptr<pstate_entry_t>>;
|
||||
|
||||
pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner,
|
||||
const int size, const int count, void *ptr, bool is_ptr)
|
||||
: m_name(stname), m_dt(dt), m_owner(owner), m_callback(nullptr), m_size(size), m_count(count), m_ptr(ptr), m_is_ptr(is_ptr) { }
|
||||
|
||||
pstate_entry_t(const pstring &stname, const void *owner, pstate_callback_t *callback)
|
||||
: m_name(stname), m_dt(DT_CUSTOM), m_owner(owner), m_callback(callback), m_size(0), m_count(0), m_ptr(nullptr), m_is_ptr(false) { }
|
||||
|
||||
~pstate_entry_t() { }
|
||||
|
||||
pstring m_name;
|
||||
const pstate_data_type_e m_dt;
|
||||
const void *m_owner;
|
||||
pstate_callback_t *m_callback;
|
||||
const int m_size;
|
||||
const int m_count;
|
||||
void *m_ptr;
|
||||
bool m_is_ptr;
|
||||
|
||||
template<typename T>
|
||||
T *resolved()
|
||||
struct datatype_t
|
||||
{
|
||||
if (m_is_ptr)
|
||||
return *static_cast<T **>(m_ptr);
|
||||
else
|
||||
return static_cast<T *>(m_ptr);
|
||||
}
|
||||
};
|
||||
datatype_t(std::size_t bsize, bool bptr, bool bintegral, bool bfloat)
|
||||
: size(bsize), is_ptr(bptr), is_integral(bintegral), is_float(bfloat), is_custom(false)
|
||||
{}
|
||||
datatype_t(bool bcustom)
|
||||
: size(0), is_ptr(false), is_integral(false), is_float(false), is_custom(bcustom)
|
||||
{}
|
||||
|
||||
class pstate_manager_t
|
||||
{
|
||||
public:
|
||||
const std::size_t size;
|
||||
const bool is_ptr;
|
||||
const bool is_integral;
|
||||
const bool is_float;
|
||||
const bool is_custom;
|
||||
};
|
||||
|
||||
pstate_manager_t();
|
||||
~pstate_manager_t();
|
||||
template<typename T> struct datatype_f
|
||||
{
|
||||
static inline const datatype_t f()
|
||||
{
|
||||
return datatype_t(sizeof(T), false, plib::is_integral<T>::value || std::is_enum<T>::value,
|
||||
std::is_floating_point<T>::value); }
|
||||
};
|
||||
|
||||
template<typename T> struct datatype_f<T *>
|
||||
{
|
||||
static inline const datatype_t f()
|
||||
{
|
||||
return datatype_t(sizeof(T), true, plib::is_integral<T>::value || std::is_enum<T>::value,
|
||||
std::is_floating_point<T>::value);
|
||||
}
|
||||
};
|
||||
|
||||
class callback_t
|
||||
{
|
||||
public:
|
||||
using list_t = std::vector<callback_t *>;
|
||||
|
||||
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;
|
||||
protected:
|
||||
};
|
||||
|
||||
struct entry_t
|
||||
{
|
||||
using list_t = std::vector<std::unique_ptr<entry_t>>;
|
||||
|
||||
entry_t(const pstring &stname, const datatype_t dt, const void *owner,
|
||||
const std::size_t count, void *ptr)
|
||||
: m_name(stname), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { }
|
||||
|
||||
entry_t(const pstring &stname, const void *owner, callback_t *callback)
|
||||
: m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }
|
||||
|
||||
~entry_t() { }
|
||||
|
||||
pstring m_name;
|
||||
const datatype_t m_dt;
|
||||
const void * m_owner;
|
||||
callback_t * m_callback;
|
||||
const std::size_t m_count;
|
||||
void * m_ptr;
|
||||
|
||||
template<typename T>
|
||||
T *resolved()
|
||||
{
|
||||
if (m_dt.is_ptr)
|
||||
return *static_cast<T **>(m_ptr);
|
||||
else
|
||||
return static_cast<T *>(m_ptr);
|
||||
}
|
||||
};
|
||||
|
||||
state_manager_t();
|
||||
~state_manager_t();
|
||||
|
||||
template<typename C> void save_item(const void *owner, C &state, const pstring &stname)
|
||||
{
|
||||
save_state_ptr( owner, stname, pstate_datatype<C>::type, sizeof(C), 1, &state, pstate_datatype<C>::is_ptr);
|
||||
save_state_ptr( owner, stname, datatype_f<C>::f(), 1, &state);
|
||||
}
|
||||
|
||||
template<typename C, std::size_t N> void save_item(const void *owner, C (&state)[N], const pstring &stname)
|
||||
{
|
||||
save_state_ptr(owner, stname, pstate_datatype<C>::type, sizeof(state[0]), N, &(state[0]), false);
|
||||
save_state_ptr(owner, stname, datatype_f<C>::f(), N, &(state[0]));
|
||||
}
|
||||
|
||||
template<typename C> void save_item(const void *owner, C *state, const pstring &stname, const int count)
|
||||
{
|
||||
save_state_ptr(owner, stname, pstate_datatype<C>::type, sizeof(C), count, state, false);
|
||||
save_state_ptr(owner, stname, datatype_f<C>::f(), count, state);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
@ -149,18 +129,19 @@ public:
|
||||
void post_load();
|
||||
void remove_save_items(const void *owner);
|
||||
|
||||
const pstate_entry_t::list_t &save_list() const { return m_save; }
|
||||
const entry_t::list_t &save_list() const { return m_save; }
|
||||
|
||||
void save_state_ptr(const void *owner, const pstring &stname, const pstate_data_type_e, const int size, const int count, void *ptr, bool is_ptr);
|
||||
void save_state_ptr(const void *owner, const pstring &stname, const datatype_t dt, const int count, void *ptr);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
pstate_entry_t::list_t m_save;
|
||||
entry_t::list_t m_save;
|
||||
};
|
||||
|
||||
template<> void pstate_manager_t::save_item(const void *owner, pstate_callback_t &state, const pstring &stname);
|
||||
template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname);
|
||||
|
||||
#if 0
|
||||
template <typename T>
|
||||
class pstate_interface_t
|
||||
{
|
||||
@ -169,24 +150,24 @@ public:
|
||||
|
||||
template<typename C> void save(C &state, const pstring &stname)
|
||||
{
|
||||
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
state_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
pstring module = static_cast<T*>(this)->name();
|
||||
manager.save_item(this, state, module + "." + stname);
|
||||
}
|
||||
template<typename C, std::size_t N> void save(C (&state)[N], const pstring &stname)
|
||||
{
|
||||
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
state_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
pstring module = static_cast<T*>(this)->name();
|
||||
manager.save_state_ptr(this, module + "." + stname, pstate_datatype<C>::type, sizeof(state[0]), N, &(state[0]), false);
|
||||
manager.save_state_ptr(this, module + "." + stname, state_manager_t::datatype_f<C>::f(), N, &(state[0]));
|
||||
}
|
||||
template<typename C> void save(C *state, const pstring &stname, const int count)
|
||||
{
|
||||
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
state_manager_t &manager = static_cast<T*>(this)->state_manager();
|
||||
pstring module = static_cast<T*>(this)->name();
|
||||
manager.save_state_ptr(this, module + "." + stname, pstate_datatype<C>::type, sizeof(C), count, state, false);
|
||||
manager.save_state_ptr(this, module + "." + stname, state_manager_t::datatype_f<C>::f(), count, state);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* PSTATE_H_ */
|
||||
|
@ -21,7 +21,7 @@ namespace plib {
|
||||
|
||||
bool pistream::readline(pstring &line)
|
||||
{
|
||||
UINT8 c = 0;
|
||||
char c = 0;
|
||||
pstringbuffer buf;
|
||||
if (!this->read(c))
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ public:
|
||||
|
||||
bool readline(pstring &line);
|
||||
|
||||
bool read(UINT8 &c)
|
||||
bool read(char &c)
|
||||
{
|
||||
return (read(&c, 1) == 1);
|
||||
}
|
||||
|
@ -374,8 +374,8 @@ pstr_t *pstring_t<F>::salloc(int n)
|
||||
if (stk == nullptr)
|
||||
stk = plib::palloc_array<std::stack<pstr_t *>>(17);
|
||||
pstr_t *p;
|
||||
unsigned sn= ((32 - countleadbits(n)) + 1) / 2;
|
||||
unsigned size = sizeof(pstr_t) + ((UINT64) 1<<(sn * 2)) + 1;
|
||||
std::size_t sn= ((32 - countleadbits(n)) + 1) / 2;
|
||||
std::size_t size = sizeof(pstr_t) + ((std::size_t) 1<<(sn * 2)) + 1;
|
||||
if (stk[sn].empty())
|
||||
p = (pstr_t *) plib::palloc_array<char>(size);
|
||||
else
|
||||
|
@ -306,7 +306,6 @@ public:
|
||||
// construction with copy
|
||||
pstring(const mem_t *string) : type_t(string) { }
|
||||
pstring(const type_t &string) : type_t(string) { }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -345,7 +344,7 @@ public:
|
||||
operator pstring() const { return pstring(m_ptr); }
|
||||
|
||||
// concatenation operators
|
||||
pstringbuffer& operator+=(const UINT8 c) { UINT8 buf[2] = { c, 0 }; pcat((char *) buf); return *this; }
|
||||
pstringbuffer& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; }
|
||||
pstringbuffer& operator+=(const pstring &string) { pcat(string); return *this; }
|
||||
pstringbuffer& operator+=(const char *string) { pcat(string); return *this; }
|
||||
|
||||
@ -378,4 +377,22 @@ private:
|
||||
|
||||
};
|
||||
|
||||
// custom specialization of std::hash can be injected in namespace std
|
||||
namespace std
|
||||
{
|
||||
template<> struct hash<pstring>
|
||||
{
|
||||
typedef pstring argument_type;
|
||||
typedef std::size_t result_type;
|
||||
result_type operator()(argument_type const& s) const
|
||||
{
|
||||
const pstring::mem_t *string = s.cstr();
|
||||
result_type result = 5381;
|
||||
for (pstring::mem_t c = *string; c != 0; c = *string++)
|
||||
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ c;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* PSTRING_H_ */
|
||||
|
@ -8,10 +8,36 @@
|
||||
#ifndef PTYPES_H_
|
||||
#define PTYPES_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "pstring.h"
|
||||
|
||||
namespace plib {
|
||||
namespace plib
|
||||
{
|
||||
|
||||
template<typename T> struct is_integral : public std::is_integral<T> { };
|
||||
template<typename T> struct numeric_limits : public std::numeric_limits<T> { };
|
||||
|
||||
/* 128 bit support at least on GCC is not fully supported */
|
||||
#if PHAS_INT128
|
||||
template<> struct is_integral<UINT128> { static constexpr bool value = true; };
|
||||
template<> struct is_integral<INT128> { static constexpr bool value = true; };
|
||||
template<> struct numeric_limits<UINT128>
|
||||
{
|
||||
static inline constexpr UINT128 max()
|
||||
{
|
||||
return ~((UINT128)0);
|
||||
}
|
||||
};
|
||||
template<> struct numeric_limits<INT128>
|
||||
{
|
||||
static inline constexpr INT128 max()
|
||||
{
|
||||
return (~((UINT128)0)) >> 1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// penum - strongly typed enumeration
|
||||
|
@ -41,7 +41,7 @@ namespace plib
|
||||
}
|
||||
|
||||
pstring_vector_t::pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty)
|
||||
: pvector_t<pstring>()
|
||||
: std::vector<pstring>()
|
||||
{
|
||||
int p = 0;
|
||||
int pn;
|
||||
@ -64,7 +64,7 @@ namespace plib
|
||||
}
|
||||
|
||||
pstring_vector_t::pstring_vector_t(const pstring &str, const pstring_vector_t &onstrl)
|
||||
: pvector_t<pstring>()
|
||||
: std::vector<pstring>()
|
||||
{
|
||||
pstring col = "";
|
||||
|
||||
|
@ -21,14 +21,49 @@ namespace plib
|
||||
const pstring environment(const pstring &var, const pstring &default_val = "");
|
||||
}
|
||||
|
||||
namespace container
|
||||
{
|
||||
template <class C>
|
||||
bool contains(C &con, const typename C::value_type &elem)
|
||||
{
|
||||
return std::find(con.begin(), con.end(), elem) != con.end();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
int indexof(C &con, const typename C::value_type &elem)
|
||||
{
|
||||
auto it = std::find(con.begin(), con.end(), elem);
|
||||
if (it != con.end())
|
||||
return it - con.begin();
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void insert_at(C &con, const std::size_t index, const typename C::value_type &elem)
|
||||
{
|
||||
con.insert(con.begin() + index, elem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class C>
|
||||
struct indexed_compare
|
||||
{
|
||||
indexed_compare(const C& target): m_target(target) {}
|
||||
|
||||
bool operator()(int a, int b) const { return m_target[a] < m_target[b]; }
|
||||
|
||||
const C& m_target;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// string list
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class pstring_vector_t : public pvector_t<pstring>
|
||||
class pstring_vector_t : public std::vector<pstring>
|
||||
{
|
||||
public:
|
||||
pstring_vector_t() : pvector_t<pstring>() { }
|
||||
pstring_vector_t() : std::vector<pstring>() { }
|
||||
pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty = false);
|
||||
pstring_vector_t(const pstring &str, const pstring_vector_t &onstrl);
|
||||
};
|
||||
|
@ -11,12 +11,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef PSTANDALONE
|
||||
#if (PSTANDALONE)
|
||||
#define PSTANDALONE_PROVIDED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "plib/poptions.h"
|
||||
#include "plib/pstring.h"
|
||||
#include "plib/plists.h"
|
||||
@ -129,7 +123,7 @@ protected:
|
||||
{
|
||||
pout("{}: {}\n", l.name().cstr(), ls.cstr());
|
||||
if (l == plib::plog_level::FATAL)
|
||||
throw;
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -162,7 +156,7 @@ struct input_t
|
||||
int e = sscanf(line.cstr(), "%lf,%[^,],%lf", &t, buf, &m_value);
|
||||
if ( e!= 3)
|
||||
throw netlist::fatalerror_e(plib::pfmt("error {1} scanning line {2}\n")(e)(line));
|
||||
m_time = netlist::netlist_time(t);
|
||||
m_time = netlist::netlist_time::from_double(t);
|
||||
m_param = netlist->setup().find_param(buf, true);
|
||||
}
|
||||
|
||||
@ -191,9 +185,9 @@ struct input_t
|
||||
|
||||
};
|
||||
|
||||
plib::pvector_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
|
||||
std::vector<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
|
||||
{
|
||||
plib::pvector_t<input_t> *ret = plib::palloc<plib::pvector_t<input_t>>();
|
||||
std::vector<input_t> *ret = plib::palloc<std::vector<input_t>>();
|
||||
if (fname != "")
|
||||
{
|
||||
plib::pifilestream f(fname);
|
||||
@ -225,7 +219,7 @@ static void run(tool_options_t &opts)
|
||||
|
||||
nt.read_netlist(opts.opt_file(), opts.opt_name());
|
||||
|
||||
plib::pvector_t<input_t> *inps = read_input(&nt, opts.opt_inp());
|
||||
std::vector<input_t> *inps = read_input(&nt, opts.opt_inp());
|
||||
|
||||
double ttr = opts.opt_ttr();
|
||||
|
||||
@ -236,16 +230,16 @@ static void run(tool_options_t &opts)
|
||||
unsigned pos = 0;
|
||||
netlist::netlist_time nlt = netlist::netlist_time::zero();
|
||||
|
||||
while (pos < inps->size() && (*inps)[pos].m_time < netlist::netlist_time(ttr))
|
||||
while (pos < inps->size() && (*inps)[pos].m_time < netlist::netlist_time::from_double(ttr))
|
||||
{
|
||||
nt.process_queue((*inps)[pos].m_time - nlt);
|
||||
(*inps)[pos].setparam();
|
||||
nlt = (*inps)[pos].m_time;
|
||||
pos++;
|
||||
}
|
||||
nt.process_queue(netlist::netlist_time(ttr) - nlt);
|
||||
nt.process_queue(netlist::netlist_time::from_double(ttr) - nlt);
|
||||
nt.stop();
|
||||
pfree(inps);
|
||||
plib::pfree(inps);
|
||||
|
||||
double emutime = (double) (plib::ticks() - t) / (double) plib::ticks_per_second();
|
||||
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", ttr, emutime, ttr/emutime*100.0);
|
||||
@ -285,19 +279,34 @@ static void listdevices()
|
||||
nt.setup().start_devices();
|
||||
nt.setup().resolve_inputs();
|
||||
|
||||
std::vector<plib::owned_ptr<netlist::core_device_t>> devs;
|
||||
|
||||
for (auto & f : list)
|
||||
{
|
||||
pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name());
|
||||
pstring terms("");
|
||||
|
||||
auto d = f->Create(nt.setup().netlist(), "dummy");
|
||||
|
||||
auto d = f->Create(nt.setup().netlist(), f->name() + "_lc");
|
||||
// get the list of terminals ...
|
||||
for (auto & inp : d->m_terminals)
|
||||
|
||||
for (auto & t : nt.setup().m_terminals)
|
||||
{
|
||||
if (inp.startsWith(d->name() + "."))
|
||||
inp = inp.substr(d->name().len() + 1);
|
||||
terms += "," + inp;
|
||||
if (t.second->name().startsWith(d->name()))
|
||||
{
|
||||
pstring tn(t.second->name().substr(d->name().len()+1));
|
||||
if (tn.find(".")<0)
|
||||
terms += ", " + tn;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & t : nt.setup().m_alias)
|
||||
{
|
||||
if (t.first.startsWith(d->name()))
|
||||
{
|
||||
pstring tn(t.first.substr(d->name().len()+1));
|
||||
if (tn.find(".")<0)
|
||||
terms += ", " + tn;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->param_desc().startsWith("+"))
|
||||
@ -317,6 +326,7 @@ static void listdevices()
|
||||
printf("%s\n", out.cstr());
|
||||
if (terms != "")
|
||||
printf("Terminals: %s\n", terms.substr(1).cstr());
|
||||
devs.push_back(std::move(d));
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,10 +336,6 @@ static void listdevices()
|
||||
main - primary entry point
|
||||
-------------------------------------------------*/
|
||||
|
||||
#if (!PSTANDALONE)
|
||||
#include "corealloc.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static const char *pmf_verbose[] =
|
||||
{
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
|
||||
unsigned m_railstart;
|
||||
|
||||
plib::pvector_t<unsigned> m_nz; /* all non zero for multiplication */
|
||||
plib::pvector_t<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */
|
||||
plib::pvector_t<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
|
||||
std::vector<unsigned> m_nz; /* all non zero for multiplication */
|
||||
std::vector<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */
|
||||
std::vector<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
|
||||
|
||||
/* state */
|
||||
nl_double m_last_V;
|
||||
@ -84,12 +84,12 @@ public:
|
||||
nl_double m_h_n_m_1;
|
||||
|
||||
private:
|
||||
plib::pvector_t<int> m_net_other;
|
||||
plib::pvector_t<nl_double> m_go;
|
||||
plib::pvector_t<nl_double> m_gt;
|
||||
plib::pvector_t<nl_double> m_Idr;
|
||||
plib::pvector_t<nl_double *> m_other_curanalog;
|
||||
plib::pvector_t<terminal_t *> m_term;
|
||||
std::vector<int> m_net_other;
|
||||
std::vector<nl_double> m_go;
|
||||
std::vector<nl_double> m_gt;
|
||||
std::vector<nl_double> m_Idr;
|
||||
std::vector<nl_double *> m_other_curanalog;
|
||||
std::vector<terminal_t *> m_term;
|
||||
|
||||
};
|
||||
|
||||
@ -109,8 +109,7 @@ public:
|
||||
class matrix_solver_t : public device_t
|
||||
{
|
||||
public:
|
||||
using list_t = plib::pvector_t<matrix_solver_t *>;
|
||||
using dev_list_t = core_device_t::list_t;
|
||||
using list_t = std::vector<matrix_solver_t *>;
|
||||
|
||||
enum eSortType
|
||||
{
|
||||
@ -121,28 +120,20 @@ public:
|
||||
|
||||
matrix_solver_t(netlist_t &anetlist, const pstring &name,
|
||||
const eSortType sort, const solver_parameters_t *params)
|
||||
: device_t(anetlist, name),
|
||||
m_stat_calculations(0),
|
||||
m_stat_newton_raphson(0),
|
||||
m_stat_vsolver_calls(0),
|
||||
m_iterative_fail(0),
|
||||
m_iterative_total(0),
|
||||
m_params(*params),
|
||||
m_last_step(0, 1),
|
||||
m_cur_ts(0),
|
||||
m_fb_sync(*this, "FB_sync"),
|
||||
m_Q_sync(*this, "Q_sync"),
|
||||
m_sort(sort)
|
||||
: device_t(anetlist, name)
|
||||
, m_params(*params)
|
||||
, m_stat_calculations(*this, "m_stat_calculations", 0)
|
||||
, m_stat_newton_raphson(*this, "m_stat_newton_raphson", 0)
|
||||
, m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
|
||||
, m_iterative_fail(*this, "m_iterative_fail", 0)
|
||||
, m_iterative_total(*this, "m_iterative_total", 0)
|
||||
, m_last_step(*this, "m_last_step", netlist_time::quantum())
|
||||
, m_cur_ts(*this, "m_cur_ts", 0)
|
||||
, m_fb_sync(*this, "FB_sync")
|
||||
, m_Q_sync(*this, "Q_sync")
|
||||
, m_sort(sort)
|
||||
{
|
||||
connect_post_start(m_fb_sync, m_Q_sync);
|
||||
|
||||
save(NLNAME(m_last_step));
|
||||
save(NLNAME(m_cur_ts));
|
||||
save(NLNAME(m_stat_calculations));
|
||||
save(NLNAME(m_stat_newton_raphson));
|
||||
save(NLNAME(m_stat_vsolver_calls));
|
||||
save(NLNAME(m_iterative_fail));
|
||||
save(NLNAME(m_iterative_total));
|
||||
}
|
||||
|
||||
virtual ~matrix_solver_t();
|
||||
@ -200,27 +191,27 @@ protected:
|
||||
template <typename T>
|
||||
void build_LE_RHS();
|
||||
|
||||
plib::pvector_t<terms_t *> m_terms;
|
||||
plib::pvector_t<analog_net_t *> m_nets;
|
||||
std::vector<terms_t *> m_terms;
|
||||
std::vector<analog_net_t *> m_nets;
|
||||
std::vector<std::unique_ptr<proxied_analog_output_t>> m_inps;
|
||||
|
||||
plib::pvector_t<terms_t *> m_rails_temp;
|
||||
|
||||
int m_stat_calculations;
|
||||
int m_stat_newton_raphson;
|
||||
int m_stat_vsolver_calls;
|
||||
int m_iterative_fail;
|
||||
int m_iterative_total;
|
||||
std::vector<terms_t *> m_rails_temp;
|
||||
|
||||
const solver_parameters_t &m_params;
|
||||
|
||||
state_var<int> m_stat_calculations;
|
||||
state_var<int> m_stat_newton_raphson;
|
||||
state_var<int> m_stat_vsolver_calls;
|
||||
state_var<int> m_iterative_fail;
|
||||
state_var<int> m_iterative_total;
|
||||
|
||||
inline nl_double current_timestep() { return m_cur_ts; }
|
||||
private:
|
||||
|
||||
netlist_time m_last_step;
|
||||
nl_double m_cur_ts;
|
||||
dev_list_t m_step_devices;
|
||||
dev_list_t m_dynamic_devices;
|
||||
state_var<netlist_time> m_last_step;
|
||||
state_var<nl_double> m_cur_ts;
|
||||
std::vector<core_device_t *> m_step_devices;
|
||||
std::vector<core_device_t *> m_dynamic_devices;
|
||||
|
||||
logic_input_t m_fb_sync;
|
||||
logic_output_t m_Q_sync;
|
||||
|
@ -161,18 +161,18 @@ protected:
|
||||
template <typename T1>
|
||||
inline nl_ext_double &RHS(const T1 &r) { return m_A[r][N()]; }
|
||||
#endif
|
||||
ATTR_ALIGN nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
|
||||
private:
|
||||
static const std::size_t m_pitch = (((storage_N + 1) + 7) / 8) * 8;
|
||||
//static const std::size_t m_pitch = (((storage_N + 1) + 15) / 16) * 16;
|
||||
//static const std::size_t m_pitch = (((storage_N + 1) + 31) / 32) * 32;
|
||||
#if (NL_USE_DYNAMIC_ALLOCATION)
|
||||
ATTR_ALIGN nl_ext_double * RESTRICT m_A;
|
||||
nl_ext_double * RESTRICT m_A;
|
||||
#else
|
||||
ATTR_ALIGN nl_ext_double m_A[storage_N][m_pitch];
|
||||
nl_ext_double m_A[storage_N][m_pitch];
|
||||
#endif
|
||||
//ATTR_ALIGN nl_ext_double m_RHSx[storage_N];
|
||||
//nl_ext_double m_RHSx[storage_N];
|
||||
|
||||
const unsigned m_dim;
|
||||
|
||||
@ -206,18 +206,14 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
{
|
||||
terms_t * t = m_terms[k];
|
||||
|
||||
if (!t->m_nzrd.contains(N()))
|
||||
if (!plib::container::contains(t->m_nzrd, N()))
|
||||
t->m_nzrd.push_back(N());
|
||||
}
|
||||
|
||||
save(NLNAME(m_last_RHS));
|
||||
netlist().save(*this, m_last_RHS, "m_last_RHS");
|
||||
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
pstring num = plib::pfmt("{1}")(k);
|
||||
|
||||
save(RHS(k), "RHS." + num);
|
||||
}
|
||||
netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,15 +142,15 @@ protected:
|
||||
template <typename T1, typename T2>
|
||||
inline nl_ext_double &A(const T1 r, const T2 c) { return m_A[r][c]; }
|
||||
|
||||
//ATTR_ALIGN nl_double m_A[storage_N][((storage_N + 7) / 8) * 8];
|
||||
ATTR_ALIGN nl_double m_RHS[storage_N];
|
||||
ATTR_ALIGN nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
ATTR_ALIGN nl_double m_last_V[storage_N];
|
||||
//nl_double m_A[storage_N][((storage_N + 7) / 8) * 8];
|
||||
nl_double m_RHS[storage_N];
|
||||
nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_double m_last_V[storage_N];
|
||||
|
||||
terms_t *m_rails_temp;
|
||||
|
||||
private:
|
||||
ATTR_ALIGN nl_ext_double m_A[storage_N][((storage_N + 7) / 8) * 8];
|
||||
nl_ext_double m_A[storage_N][((storage_N + 7) / 8) * 8];
|
||||
|
||||
const unsigned m_dim;
|
||||
nl_double m_lp_fact;
|
||||
@ -334,10 +334,11 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
t->m_nz.add(other[i]);
|
||||
}
|
||||
}
|
||||
psort_list(t->m_nzrd);
|
||||
std::sort(t->m_nzrd.begin(), t->m_nzrd.end());
|
||||
|
||||
t->m_nz.add(k); // add diagonal
|
||||
psort_list(t->m_nz);
|
||||
|
||||
std::sort(t->m_nz.begin(), t->m_nz.end());
|
||||
}
|
||||
|
||||
if(0)
|
||||
|
@ -62,13 +62,13 @@ private:
|
||||
{
|
||||
plib::postringstream t;
|
||||
csc_private(t);
|
||||
plib::hash_functor<pstring> h(t.str());
|
||||
std::hash<pstring> h;
|
||||
|
||||
return plib::pfmt("nl_gcr_{1:x}_{2}")(h())(mat.nz_num);
|
||||
return plib::pfmt("nl_gcr_{1:x}_{2}")(h( t.str() ))(mat.nz_num);
|
||||
}
|
||||
|
||||
unsigned m_dim;
|
||||
plib::pvector_t<int> m_term_cr[storage_N];
|
||||
std::vector<int> m_term_cr[storage_N];
|
||||
mat_cr_t<storage_N> mat;
|
||||
nl_double m_A[storage_N * storage_N];
|
||||
|
||||
@ -243,8 +243,8 @@ int matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra
|
||||
{
|
||||
const unsigned iN = this->N();
|
||||
|
||||
ATTR_ALIGN nl_double RHS[storage_N];
|
||||
ATTR_ALIGN nl_double new_V[storage_N];
|
||||
nl_double RHS[storage_N];
|
||||
nl_double new_V[storage_N];
|
||||
|
||||
for (unsigned i=0, e=mat.nz_num; i<e; i++)
|
||||
m_A[i] = 0.0;
|
||||
|
@ -48,7 +48,7 @@ private:
|
||||
|
||||
int solve_ilu_gmres(nl_double * RESTRICT x, const nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy);
|
||||
|
||||
plib::pvector_t<int> m_term_cr[storage_N];
|
||||
std::vector<int> m_term_cr[storage_N];
|
||||
|
||||
bool m_use_iLU_preconditioning;
|
||||
bool m_use_more_precise_stop_condition;
|
||||
@ -125,8 +125,8 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_
|
||||
*/
|
||||
|
||||
//nz_num = 0;
|
||||
ATTR_ALIGN nl_double RHS[storage_N];
|
||||
ATTR_ALIGN nl_double new_V[storage_N];
|
||||
nl_double RHS[storage_N];
|
||||
nl_double new_V[storage_N];
|
||||
|
||||
for (unsigned i=0, e=mat.nz_num; i<e; i++)
|
||||
m_A[i] = 0.0;
|
||||
|
@ -90,19 +90,19 @@ protected:
|
||||
template <typename T1, typename T2>
|
||||
inline nl_ext_double &lAinv(const T1 &r, const T2 &c) { return m_lAinv[r][c]; }
|
||||
|
||||
ATTR_ALIGN nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
|
||||
private:
|
||||
static const std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8;
|
||||
ATTR_ALIGN nl_ext_double m_A[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_Ainv[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_W[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_ext_double m_A[storage_N][m_pitch];
|
||||
nl_ext_double m_Ainv[storage_N][m_pitch];
|
||||
nl_ext_double m_W[storage_N][m_pitch];
|
||||
nl_ext_double m_RHS[storage_N]; // right hand side - contains currents
|
||||
|
||||
ATTR_ALIGN nl_ext_double m_lA[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_lAinv[storage_N][m_pitch];
|
||||
nl_ext_double m_lA[storage_N][m_pitch];
|
||||
nl_ext_double m_lAinv[storage_N][m_pitch];
|
||||
|
||||
//ATTR_ALIGN nl_ext_double m_RHSx[storage_N];
|
||||
//nl_ext_double m_RHSx[storage_N];
|
||||
|
||||
const unsigned m_dim;
|
||||
|
||||
@ -128,15 +128,10 @@ void matrix_solver_sm_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
|
||||
matrix_solver_t::setup_base(nets);
|
||||
|
||||
|
||||
save(NLNAME(m_last_RHS));
|
||||
netlist().save(*this, m_last_RHS, "m_last_RHS");
|
||||
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
pstring num = plib::pfmt("{1}")(k);
|
||||
|
||||
save(RHS(k), "RHS." + num);
|
||||
}
|
||||
netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
matrix_solver_SOR_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, int size)
|
||||
: matrix_solver_direct_t<m_N, storage_N>(anetlist, name, matrix_solver_t::ASCENDING, params, size)
|
||||
, m_lp_fact(0)
|
||||
, m_lp_fact(*this, "m_lp_fact", 0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public:
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
private:
|
||||
nl_double m_lp_fact;
|
||||
state_var<nl_double> m_lp_fact;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -51,7 +51,6 @@ template <unsigned m_N, unsigned storage_N>
|
||||
void matrix_solver_SOR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
{
|
||||
matrix_solver_direct_t<m_N, storage_N>::vsetup(nets);
|
||||
this->save(NLNAME(m_lp_fact));
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned storage_N>
|
||||
@ -71,10 +70,10 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra
|
||||
|
||||
const nl_double ws = this->m_params.m_sor;
|
||||
|
||||
ATTR_ALIGN nl_double w[storage_N];
|
||||
ATTR_ALIGN nl_double one_m_w[storage_N];
|
||||
ATTR_ALIGN nl_double RHS[storage_N];
|
||||
ATTR_ALIGN nl_double new_V[storage_N];
|
||||
nl_double w[storage_N];
|
||||
nl_double one_m_w[storage_N];
|
||||
nl_double RHS[storage_N];
|
||||
nl_double new_V[storage_N];
|
||||
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
|
@ -32,10 +32,11 @@ public:
|
||||
|
||||
matrix_solver_SOR_mat_t(netlist_t &anetlist, const pstring &name, const solver_parameters_t *params, int size)
|
||||
: matrix_solver_direct_t<m_N, storage_N>(anetlist, name, matrix_solver_t::DESCENDING, params, size)
|
||||
, m_omega(params->m_sor)
|
||||
, m_lp_fact(0)
|
||||
, m_gs_fail(0)
|
||||
, m_gs_total(0)
|
||||
, m_Vdelta(*this, "m_Vdelta", 0.0)
|
||||
, m_omega(*this, "m_omega", params->m_sor)
|
||||
, m_lp_fact(*this, "m_lp_fact", 0)
|
||||
, m_gs_fail(*this, "m_gs_fail", 0)
|
||||
, m_gs_total(*this, "m_gs_total", 0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,12 +47,12 @@ public:
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
private:
|
||||
nl_double m_Vdelta[storage_N];
|
||||
state_var<nl_double[storage_N]> m_Vdelta;
|
||||
|
||||
nl_double m_omega;
|
||||
nl_double m_lp_fact;
|
||||
int m_gs_fail;
|
||||
int m_gs_total;
|
||||
state_var<nl_double> m_omega;
|
||||
state_var<nl_double> m_lp_fact;
|
||||
state_var<int> m_gs_fail;
|
||||
state_var<int> m_gs_total;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -62,11 +63,6 @@ template <unsigned m_N, unsigned storage_N>
|
||||
void matrix_solver_SOR_mat_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
{
|
||||
matrix_solver_direct_t<m_N, storage_N>::vsetup(nets);
|
||||
this->save(NLNAME(m_omega));
|
||||
this->save(NLNAME(m_lp_fact));
|
||||
this->save(NLNAME(m_gs_fail));
|
||||
this->save(NLNAME(m_gs_total));
|
||||
this->save(NLNAME(m_Vdelta));
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -127,7 +123,7 @@ int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newto
|
||||
*/
|
||||
|
||||
|
||||
ATTR_ALIGN nl_double new_v[storage_N] = { 0.0 };
|
||||
nl_double new_v[storage_N] = { 0.0 };
|
||||
const unsigned iN = this->N();
|
||||
|
||||
matrix_solver_t::build_LE_A<matrix_solver_SOR_mat_t>();
|
||||
|
@ -95,26 +95,26 @@ protected:
|
||||
template <typename T1, typename T2>
|
||||
inline nl_ext_double &lA(const T1 &r, const T2 &c) { return m_lA[r][c]; }
|
||||
|
||||
ATTR_ALIGN nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_double m_last_RHS[storage_N]; // right hand side - contains currents
|
||||
|
||||
private:
|
||||
static const std::size_t m_pitch = ((( storage_N) + 7) / 8) * 8;
|
||||
ATTR_ALIGN nl_ext_double m_A[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_Ainv[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_W[storage_N][m_pitch];
|
||||
ATTR_ALIGN nl_ext_double m_RHS[storage_N]; // right hand side - contains currents
|
||||
nl_ext_double m_A[storage_N][m_pitch];
|
||||
nl_ext_double m_Ainv[storage_N][m_pitch];
|
||||
nl_ext_double m_W[storage_N][m_pitch];
|
||||
nl_ext_double m_RHS[storage_N]; // right hand side - contains currents
|
||||
|
||||
ATTR_ALIGN nl_ext_double m_lA[storage_N][m_pitch];
|
||||
nl_ext_double m_lA[storage_N][m_pitch];
|
||||
|
||||
/* temporary */
|
||||
ATTR_ALIGN nl_double H[storage_N][m_pitch] ;
|
||||
nl_double H[storage_N][m_pitch] ;
|
||||
unsigned rows[storage_N];
|
||||
unsigned cols[storage_N][m_pitch];
|
||||
unsigned colcount[storage_N];
|
||||
|
||||
unsigned m_cnt;
|
||||
|
||||
//ATTR_ALIGN nl_ext_double m_RHSx[storage_N];
|
||||
//nl_ext_double m_RHSx[storage_N];
|
||||
|
||||
const unsigned m_dim;
|
||||
|
||||
@ -137,15 +137,10 @@ void matrix_solver_w_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
|
||||
matrix_solver_t::setup_base(nets);
|
||||
|
||||
|
||||
save(NLNAME(m_last_RHS));
|
||||
netlist().save(*this, m_last_RHS, "m_last_RHS");
|
||||
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
pstring num = plib::pfmt("{1}")(k);
|
||||
|
||||
save(RHS(k), "RHS." + num);
|
||||
}
|
||||
netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,12 +67,12 @@ void terms_t::add(terminal_t *term, int net_other, bool sorted)
|
||||
{
|
||||
if (m_net_other[i] > net_other)
|
||||
{
|
||||
m_term.insert_at(i, term);
|
||||
m_net_other.insert_at(i, net_other);
|
||||
m_gt.insert_at(i, 0.0);
|
||||
m_go.insert_at(i, 0.0);
|
||||
m_Idr.insert_at(i, 0.0);
|
||||
m_other_curanalog.insert_at(i, nullptr);
|
||||
plib::container::insert_at(m_term, i, term);
|
||||
plib::container::insert_at(m_net_other, i, net_other);
|
||||
plib::container::insert_at(m_gt, i, 0.0);
|
||||
plib::container::insert_at(m_go, i, 0.0);
|
||||
plib::container::insert_at(m_Idr, i, 0.0);
|
||||
plib::container::insert_at(m_other_curanalog, i, nullptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,7 @@ void terms_t::set_pointers()
|
||||
for (unsigned i = 0; i < count(); i++)
|
||||
{
|
||||
m_term[i]->set_ptrs(&m_gt[i], &m_go[i], &m_Idr[i]);
|
||||
m_other_curanalog[i] = &m_term[i]->m_otherterm->net().m_cur_Analog;
|
||||
m_other_curanalog[i] = m_term[i]->m_otherterm->net().m_cur_Analog.ptr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,10 +135,10 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
{
|
||||
case terminal_t::TERMINAL:
|
||||
if (p->device().is_timestep())
|
||||
if (!m_step_devices.contains(&p->device()))
|
||||
if (!plib::container::contains(m_step_devices, &p->device()))
|
||||
m_step_devices.push_back(&p->device());
|
||||
if (p->device().is_dynamic())
|
||||
if (!m_dynamic_devices.contains(&p->device()))
|
||||
if (!plib::container::contains(m_dynamic_devices, &p->device()))
|
||||
m_dynamic_devices.push_back(&p->device());
|
||||
{
|
||||
terminal_t *pterm = dynamic_cast<terminal_t *>(p);
|
||||
@ -257,13 +257,13 @@ void matrix_solver_t::setup_matrix()
|
||||
t->m_nz.clear();
|
||||
|
||||
for (unsigned i = 0; i < t->m_railstart; i++)
|
||||
if (!t->m_nz.contains(other[i]))
|
||||
if (!plib::container::contains(t->m_nz, other[i]))
|
||||
t->m_nz.push_back(other[i]);
|
||||
|
||||
t->m_nz.push_back(k); // add diagonal
|
||||
|
||||
/* and sort */
|
||||
plib::sort_list(t->m_nz);
|
||||
std::sort(t->m_nz.begin(), t->m_nz.end());
|
||||
}
|
||||
|
||||
/* create a list of non zero elements right of the diagonal
|
||||
@ -281,22 +281,21 @@ void matrix_solver_t::setup_matrix()
|
||||
else
|
||||
{
|
||||
t->m_nzrd = m_terms[k-1]->m_nzrd;
|
||||
unsigned j=0;
|
||||
while(j < t->m_nzrd.size())
|
||||
for (auto j = t->m_nzrd.begin(); j != t->m_nzrd.end(); )
|
||||
{
|
||||
if (t->m_nzrd[j] < k + 1)
|
||||
t->m_nzrd.remove_at(j);
|
||||
if (*j < k + 1)
|
||||
j = t->m_nzrd.erase(j);
|
||||
else
|
||||
j++;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < t->m_railstart; i++)
|
||||
if (!t->m_nzrd.contains(other[i]) && other[i] >= (int) (k + 1))
|
||||
if (!plib::container::contains(t->m_nzrd, other[i]) && other[i] >= (int) (k + 1))
|
||||
t->m_nzrd.push_back(other[i]);
|
||||
|
||||
/* and sort */
|
||||
plib::sort_list(t->m_nzrd);
|
||||
std::sort(t->m_nzrd.begin(), t->m_nzrd.end());
|
||||
}
|
||||
|
||||
/* create a list of non zero elements below diagonal k
|
||||
@ -324,7 +323,7 @@ void matrix_solver_t::setup_matrix()
|
||||
if (touched[row][k])
|
||||
{
|
||||
ops++;
|
||||
if (!m_terms[k]->m_nzbd.contains(row))
|
||||
if (!plib::container::contains(m_terms[k]->m_nzbd, row))
|
||||
m_terms[k]->m_nzbd.push_back(row);
|
||||
for (unsigned col = k + 1; col < iN; col++)
|
||||
if (touched[k][col])
|
||||
@ -353,13 +352,13 @@ void matrix_solver_t::setup_matrix()
|
||||
{
|
||||
pstring num = plib::pfmt("{1}")(k);
|
||||
|
||||
save(m_terms[k]->m_last_V, "lastV." + num);
|
||||
save(m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
|
||||
save(m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
|
||||
netlist().save(*this, m_terms[k]->m_last_V, "lastV." + num);
|
||||
netlist().save(*this, m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
|
||||
netlist().save(*this, m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
|
||||
|
||||
save(m_terms[k]->go(),"GO" + num, m_terms[k]->count());
|
||||
save(m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
|
||||
save(m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
|
||||
netlist().save(*this, m_terms[k]->go(),"GO" + num, m_terms[k]->count());
|
||||
netlist().save(*this, m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
|
||||
netlist().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
|
||||
}
|
||||
|
||||
for (unsigned k=0; k<iN; k++)
|
||||
@ -404,7 +403,7 @@ void matrix_solver_t::update_forced()
|
||||
if (m_params.m_dynamic && has_timestep_devices())
|
||||
{
|
||||
m_Q_sync.net().toggle_new_Q();
|
||||
m_Q_sync.net().reschedule_in_queue(netlist_time(m_params.m_min_timestep));
|
||||
m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,7 +535,7 @@ netlist_time matrix_solver_t::compute_next_timestep()
|
||||
}
|
||||
//if (new_solver_timestep > 10.0 * hn)
|
||||
// new_solver_timestep = 10.0 * hn;
|
||||
return netlist_time(new_solver_timestep);
|
||||
return netlist_time::from_double(new_solver_timestep);
|
||||
}
|
||||
|
||||
|
||||
@ -552,11 +551,11 @@ void matrix_solver_t::log_stats()
|
||||
log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep");
|
||||
log().verbose(" {1:6.3} average newton raphson loops", (double) this->m_stat_newton_raphson / (double) this->m_stat_vsolver_calls);
|
||||
log().verbose(" {1:10} invocations ({2:6} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
|
||||
this->m_stat_calculations,
|
||||
this->m_stat_calculations * 10 / (int) (this->netlist().time().as_double() * 10.0),
|
||||
this->m_iterative_fail,
|
||||
100.0 * (double) this->m_iterative_fail / (double) this->m_stat_calculations,
|
||||
(double) this->m_iterative_total / (double) this->m_stat_calculations);
|
||||
this->m_stat_calculations(),
|
||||
this->m_stat_calculations() * 10 / (int) (this->netlist().time().as_double() * 10.0),
|
||||
this->m_iterative_fail(),
|
||||
100.0 * (double) this->m_iterative_fail() / (double) this->m_stat_calculations(),
|
||||
(double) this->m_iterative_total() / (double) this->m_stat_calculations());
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,7 +628,7 @@ NETLIB_UPDATE(solver)
|
||||
if (!m_Q_step.net().is_queued())
|
||||
{
|
||||
m_Q_step.net().toggle_new_Q();
|
||||
m_Q_step.net().push_to_queue(netlist_time(m_params.m_max_timestep));
|
||||
m_Q_step.net().push_to_queue(netlist_time::from_double(m_params.m_max_timestep));
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,14 +697,14 @@ std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(int size, co
|
||||
|
||||
void NETLIB_NAME(solver)::post_start()
|
||||
{
|
||||
plib::pvector_t<analog_net_t::list_t> groups;
|
||||
std::vector<analog_net_t::list_t> groups;
|
||||
const bool use_specific = true;
|
||||
|
||||
m_params.m_pivot = m_pivot.Value();
|
||||
m_params.m_accuracy = m_accuracy.Value();
|
||||
m_params.m_gs_loops = m_gs_loops.Value();
|
||||
m_params.m_nr_loops = m_nr_loops.Value();
|
||||
m_params.m_nt_sync_delay = netlist_time(m_sync_delay.Value());
|
||||
m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay.Value());
|
||||
m_params.m_lte = m_lte.Value();
|
||||
m_params.m_sor = m_sor.Value();
|
||||
|
||||
|
@ -11,26 +11,6 @@
|
||||
#include "nl_convert.h"
|
||||
|
||||
|
||||
template<typename Class>
|
||||
static plib::pvector_t<int> bubble(const plib::pvector_t<Class> &sl)
|
||||
{
|
||||
plib::pvector_t<int> ret;
|
||||
for (unsigned i=0; i<sl.size(); i++)
|
||||
ret.push_back(i);
|
||||
|
||||
for(unsigned i=0; i < sl.size(); i++)
|
||||
{
|
||||
for(unsigned j=i+1; j < sl.size(); j++)
|
||||
{
|
||||
if(sl[ret[i]]->name() > sl[ret[j]]->name())
|
||||
{
|
||||
std::swap(ret[i], ret[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
convert - convert a spice netlist
|
||||
-------------------------------------------------*/
|
||||
@ -38,7 +18,7 @@ static plib::pvector_t<int> bubble(const plib::pvector_t<Class> &sl)
|
||||
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
|
||||
{
|
||||
pstring pname = devname + "." + name;
|
||||
m_pins.add(pname, plib::make_unique<pin_alias_t>(pname, devname + "." + alias));
|
||||
m_pins.insert({pname, plib::make_unique<pin_alias_t>(pname, devname + "." + alias)});
|
||||
}
|
||||
|
||||
void nl_convert_base_t::add_ext_alias(const pstring &alias)
|
||||
@ -73,13 +53,14 @@ void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
|
||||
void nl_convert_base_t::add_term(pstring netname, pstring termname)
|
||||
{
|
||||
net_t * net = nullptr;
|
||||
if (m_nets.contains(netname))
|
||||
auto idx = m_nets.find(netname);
|
||||
if (idx != m_nets.end())
|
||||
net = m_nets[netname].get();
|
||||
else
|
||||
{
|
||||
auto nets = std::make_shared<net_t>(netname);
|
||||
net = nets.get();
|
||||
m_nets.add(netname, nets);
|
||||
m_nets.insert({netname, nets});
|
||||
}
|
||||
|
||||
/* if there is a pin alias, translate ... */
|
||||
@ -102,7 +83,12 @@ void nl_convert_base_t::dump_nl()
|
||||
if (net->terminals().size() == 1)
|
||||
net->set_no_export();
|
||||
}
|
||||
plib::pvector_t<int> sorted = bubble(m_devs);
|
||||
|
||||
std::vector<int> sorted;
|
||||
for (unsigned i=0; i < m_devs.size(); i++)
|
||||
sorted.push_back(i);
|
||||
std::sort(sorted.begin(), sorted.end(), plib::indexed_compare<std::vector<std::shared_ptr<dev_t>>>(m_devs));
|
||||
|
||||
for (std::size_t i=0; i<m_devs.size(); i++)
|
||||
{
|
||||
std::size_t j = sorted[i];
|
||||
@ -118,9 +104,9 @@ void nl_convert_base_t::dump_nl()
|
||||
m_devs[j]->name().cstr());
|
||||
}
|
||||
// print nets
|
||||
for (std::size_t i=0; i<m_nets.size(); i++)
|
||||
for (auto & i : m_nets)
|
||||
{
|
||||
net_t * net = m_nets.value_at(i).get();
|
||||
net_t * net = i.second.get();
|
||||
if (!net->is_no_export())
|
||||
{
|
||||
//printf("Net {}\n", net->name().cstr());
|
||||
|
@ -130,10 +130,10 @@ private:
|
||||
|
||||
plib::postringstream m_buf;
|
||||
|
||||
plib::pvector_t<std::shared_ptr<dev_t>> m_devs;
|
||||
plib::hashmap_t<pstring, std::shared_ptr<net_t> > m_nets;
|
||||
plib::pvector_t<pstring> m_ext_alias;
|
||||
plib::hashmap_t<pstring, std::shared_ptr<pin_alias_t>> m_pins;
|
||||
std::vector<std::shared_ptr<dev_t>> m_devs;
|
||||
std::unordered_map<pstring, std::shared_ptr<net_t> > m_nets;
|
||||
std::vector<pstring> m_ext_alias;
|
||||
std::unordered_map<pstring, std::shared_ptr<pin_alias_t>> m_pins;
|
||||
|
||||
static unit_t m_units[];
|
||||
|
||||
|
@ -455,11 +455,11 @@ static MACHINE_CONFIG_FRAGMENT( irem_audio_base )
|
||||
MCFG_NETLIST_SETUP(kidniki)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ibd", "I_BD0.IN", 0, 1)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "isd", "I_SD0.IN", 0, 1)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ich", "I_CH0.IN", 0, 1)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ioh", "I_OH0.IN", 0, 1)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "sinh", "SINH.IN", 0, 1)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ibd", "I_BD0.IN", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "isd", "I_SD0.IN", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ich", "I_CH0.IN", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "ioh", "I_OH0.IN", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "sinh", "SINH.IN", 0)
|
||||
|
||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 0, "R_AY45M_A.R")
|
||||
MCFG_NETLIST_STREAM_INPUT("snd_nl", 1, "R_AY45M_B.R")
|
||||
|
@ -372,10 +372,10 @@ static MACHINE_CONFIG_START( pong, pong_state )
|
||||
MCFG_NETLIST_ANALOG_MULT_OFFSET(1.0 / 100.0 * RES_K(50), RES_K(56) )
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot0", "ic_b9_POT.DIAL")
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot1", "ic_a9_POT.DIAL")
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1a", "sw1a.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1b", "sw1b.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw", "coinsw.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1a", "sw1a.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1b", "sw1b.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw", "coinsw.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0)
|
||||
|
||||
MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "snd0", "sound", pong_state, sound_cb, "")
|
||||
MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_vid, "fixfreq")
|
||||
@ -403,21 +403,21 @@ static MACHINE_CONFIG_START( breakout, breakout_state )
|
||||
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot1", "POTP1.DIAL")
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot2", "POTP2.DIAL")
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw1", "COIN1.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw2", "COIN2.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw1", "START1.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw2", "START2.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "servesw", "SERVE.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw4", "S4.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw3", "S3.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw2", "S2.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw1", "COIN1.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw2", "COIN2.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw1", "START1.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw2", "START2.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "servesw", "SERVE.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw4", "S4.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw3", "S3.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw2", "S2.POS", 0)
|
||||
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_1", "S1_1.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_2", "S1_2.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_3", "S1_3.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_4", "S1_4.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_1", "S1_1.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_2", "S1_2.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_3", "S1_3.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1_4", "S1_4.POS", 0)
|
||||
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0)
|
||||
|
||||
MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "snd0", "sound", breakout_state, sound_cb, "")
|
||||
MCFG_NETLIST_ANALOG_OUTPUT("maincpu", "vid0", "videomix", fixedfreq_device, update_vid, "fixfreq")
|
||||
@ -462,20 +462,14 @@ static MACHINE_CONFIG_START( pongd, pong_state )
|
||||
MCFG_DEVICE_ADD("maincpu", NETLIST_CPU, NETLIST_CLOCK)
|
||||
MCFG_NETLIST_SETUP(pongdoubles)
|
||||
|
||||
#if 0
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "vr0", "ic_b9_R.R")
|
||||
MCFG_NETLIST_ANALOG_INPUT_MULT_OFFSET(1.0 / 100.0 * RES_K(50), RES_K(56) )
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "vr1", "ic_a9_R.R")
|
||||
MCFG_NETLIST_ANALOG_INPUT_MULT_OFFSET(1.0 / 100.0 * RES_K(50), RES_K(56) )
|
||||
#endif
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot0", "A10_POT.DIAL")
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot1", "B10_POT.DIAL")
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot2", "B9B_POT.DIAL")
|
||||
MCFG_NETLIST_ANALOG_INPUT("maincpu", "pot3", "B9A_POT.DIAL")
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1a", "DIPSW1.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1b", "DIPSW2.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw", "COIN_SW.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw", "START_SW.POS", 0, 0x01)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1a", "DIPSW1.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "sw1b", "DIPSW2.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "coinsw", "COIN_SW.POS", 0)
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "startsw", "START_SW.POS", 0)
|
||||
#if 0
|
||||
MCFG_NETLIST_LOGIC_INPUT("maincpu", "antenna", "antenna.IN", 0, 0x01)
|
||||
#endif
|
||||
|
@ -283,6 +283,9 @@ CIRCUIT_LAYOUT( breakout )
|
||||
CHIP("J3", 7402)
|
||||
CHIP("J4", 9312)
|
||||
CHIP("J5", 7448)
|
||||
#if USE_TRUTHTABLE_7448
|
||||
PARAM(J5.USE_DEACTIVATE, 0) // only use this if compiled with 7448 as a truthtable
|
||||
#endif
|
||||
CHIP("J6", 9310)
|
||||
CHIP("J7", 7420)
|
||||
CHIP("J8", 74279)
|
||||
|
Loading…
Reference in New Issue
Block a user