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:
couriersud 2016-06-16 00:01:47 +02:00
parent 809de6dd7f
commit 404e589cff
73 changed files with 1225 additions and 1529 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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:

View File

@ -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")

View File

@ -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);

View File

@ -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

View File

@ -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
// ----------------------------------------------------------------------------------------

View File

@ -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()

View File

@ -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),

View File

@ -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)
{

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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) \

View File

@ -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)

View File

@ -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) };

View File

@ -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)
{

View File

@ -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;
};

View File

@ -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)

View File

@ -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));

View File

@ -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));
}

View File

@ -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

View File

@ -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)
{
}

View File

@ -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

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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

View File

@ -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 &param)
{
@ -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_ */

View File

@ -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;
//============================================================

View File

@ -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);

View File

@ -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];

View File

@ -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 &param)
{
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 &param)
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 &param, 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 &param_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];

View File

@ -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;
};

View File

@ -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());
}
}

View File

@ -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;
};

View File

@ -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()
{

View File

@ -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_ */

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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_ */

View File

@ -21,7 +21,7 @@ namespace plib {
bool pistream::readline(pstring &line)
{
UINT8 c = 0;
char c = 0;
pstringbuffer buf;
if (!this->read(c))
{

View File

@ -108,7 +108,7 @@ public:
bool readline(pstring &line);
bool read(UINT8 &c)
bool read(char &c)
{
return (read(&c, 1) == 1);
}

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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 = "";

View File

@ -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);
};

View File

@ -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[] =
{

View File

@ -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;

View File

@ -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));
}

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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));
}

View File

@ -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++)
{

View File

@ -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>();

View File

@ -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));
}

View File

@ -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();

View File

@ -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());

View File

@ -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[];

View File

@ -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")

View File

@ -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

View File

@ -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)