netlist: refactoring. (nw)

This commit is contained in:
couriersud 2019-03-01 19:52:06 +01:00
parent 59b4e839b4
commit 618f33f586
14 changed files with 442 additions and 545 deletions

View File

@ -27,11 +27,11 @@ namespace netlist
{
}
private:
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(clk);
public:
logic_input_t m_D;
logic_input_t m_CLRQ;
logic_input_t m_PREQ;
@ -39,7 +39,6 @@ namespace netlist
logic_output_t m_Q;
logic_output_t m_QQ;
private:
state_var<netlist_sig_t> m_nextD;
void newstate(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
@ -57,20 +56,20 @@ namespace netlist
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_CLRQ);
register_subalias("2", m_1.m_D);
register_subalias("3", m_1.m_CLK);
register_subalias("4", m_1.m_PREQ);
register_subalias("5", m_1.m_Q);
register_subalias("6", m_1.m_QQ);
register_subalias("1", "1.CLRQ");
register_subalias("2", "1.D");
register_subalias("3", "1.CLK");
register_subalias("4", "1.PREQ");
register_subalias("5", "1.Q");
register_subalias("6", "1.QQ");
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.m_QQ);
register_subalias("9", m_2.m_Q);
register_subalias("10", m_2.m_PREQ);
register_subalias("11", m_2.m_CLK);
register_subalias("12", m_2.m_D);
register_subalias("13", m_2.m_CLRQ);
register_subalias("8", "2.QQ");
register_subalias("9", "2.Q");
register_subalias("10", "2.PREQ");
register_subalias("11", "2.CLK");
register_subalias("12", "2.D");
register_subalias("13", "2.CLRQ");
// register_subalias("14", ); ==> VCC
}
NETLIB_UPDATEI();
@ -83,11 +82,8 @@ namespace netlist
NETLIB_HANDLER(7474, clk)
{
//if (INP_LH(m_CLK))
{
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
NETLIB_UPDATE(7474)

View File

@ -28,10 +28,10 @@ namespace netlist
{
}
private:
NETLIB_UPDATEI();
NETLIB_RESETI();
protected:
void update_outputs();
logic_input_t m_A;
@ -52,22 +52,22 @@ namespace netlist
{
NETLIB_CONSTRUCTOR_DERIVED(7490_dip, 7490)
{
register_subalias("1", m_B);
register_subalias("2", m_R1);
register_subalias("3", m_R2);
register_subalias("1", "B");
register_subalias("2", "R1");
register_subalias("3", "R2");
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
register_subalias("6", m_R91);
register_subalias("7", m_R92);
register_subalias("6", "R91");
register_subalias("7", "R92");
register_subalias("8", m_Q[2]);
register_subalias("9", m_Q[1]);
register_subalias("8", "QC");
register_subalias("9", "QB");
// register_subalias("10", ); --> GND
register_subalias("11", m_Q[3]);
register_subalias("12", m_Q[0]);
register_subalias("11", "QD");
register_subalias("12", "QA");
// register_subalias("13", ); --> NC
register_subalias("14", m_A);
register_subalias("14", "A");
}
};

View File

@ -22,7 +22,6 @@ namespace netlist
NETLIB_CONSTRUCTOR(7493)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_reset(*this, "_m_reset", 0)
, m_a(*this, "_m_a", 0)
, m_bcd(*this, "_m_b", 0)
, m_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA))
@ -35,34 +34,49 @@ namespace netlist
}
private:
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_RESETI()
{
m_a = m_bcd = 0;
m_CLKA.set_state(logic_t::STATE_INP_HL);
m_CLKB.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATEI()
{
if (!(m_R1() & m_R2()))
{
m_CLKA.activate_hl();
m_CLKB.activate_hl();
}
else
{
m_CLKA.inactivate();
m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40));
m_QB.push(0, NLTIME_FROM_NS(40));
m_QC.push(0, NLTIME_FROM_NS(40));
m_QD.push(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}
NETLIB_HANDLERI(updA)
{
//if (m_reset)
{
m_a ^= 1;
m_QA.push(m_a, out_delay);
}
m_a ^= 1;
m_QA.push(m_a, out_delay);
}
NETLIB_HANDLERI(updB)
{
//if (m_reset)
{
//++m_bcd &= 0x07;
auto cnt = (++m_bcd &= 0x07);
m_QD.push((cnt >> 2) & 1, out_delay3);
m_QC.push((cnt >> 1) & 1, out_delay2);
m_QB.push(cnt & 1, out_delay);
}
auto cnt = (++m_bcd &= 0x07);
m_QD.push((cnt >> 2) & 1, out_delay3);
m_QC.push((cnt >> 1) & 1, out_delay2);
m_QB.push(cnt & 1, out_delay);
}
logic_input_t m_R1;
logic_input_t m_R2;
state_var_sig m_reset;
state_var_sig m_a;
state_var_u8 m_bcd;
@ -98,34 +112,6 @@ namespace netlist
}
};
NETLIB_RESET(7493)
{
m_reset = 1;
m_a = m_bcd = 0;
m_CLKA.set_state(logic_t::STATE_INP_HL);
m_CLKB.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATE(7493)
{
m_reset = (m_R1() & m_R2()) ^ 1;
if (m_reset)
{
m_CLKA.activate_hl();
m_CLKB.activate_hl();
}
else
{
m_CLKA.inactivate();
m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40));
m_QB.push(0, NLTIME_FROM_NS(40));
m_QC.push(0, NLTIME_FROM_NS(40));
m_QD.push(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}
NETLIB_DEVICE_IMPL(7493, "TTL_7493", "+CLKA,+CLKB,+R1,+R2")
NETLIB_DEVICE_IMPL(7493_dip, "TTL_7493_DIP", "")

View File

@ -20,6 +20,7 @@ namespace netlist
NETLIB_CONSTRUCTOR(9316)
, m_CLK(*this, "CLK", NETLIB_DELEGATE(9316, clk))
, m_ENT(*this, "ENT")
, m_RC(*this, "RC")
, m_LOADQ(*this, "LOADQ")
, m_ENP(*this, "ENP")
, m_CLRQ(*this, "CLRQ")
@ -28,7 +29,6 @@ namespace netlist
, m_C(*this, "C", NETLIB_DELEGATE(9316, abcd))
, m_D(*this, "D", NETLIB_DELEGATE(9316, abcd))
, m_Q(*this, {{ "QA", "QB", "QC", "QD" }})
, m_RC(*this, "RC")
, m_cnt(*this, "m_cnt", 0)
, m_abcd(*this, "m_abcd", 0)
, m_loadq(*this, "m_loadq", 0)
@ -37,17 +37,54 @@ namespace netlist
}
private:
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(clk);
NETLIB_RESETI()
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_abcd = 0;
}
NETLIB_UPDATEI()
{
const auto CLRQ(m_CLRQ());
m_ent = m_ENT();
m_loadq = m_LOADQ();
if (((m_loadq ^ 1) || (m_ent && m_ENP())) && CLRQ)
{
m_CLK.activate_lh();
}
else
{
m_CLK.inactivate();
if (!CLRQ && (m_cnt>0))
{
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(36));
}
}
m_RC.push(m_ent && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
NETLIB_HANDLERI(clk)
{
auto cnt = (m_loadq ? m_cnt + 1 : m_abcd) & MAXCNT;
m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(cnt, NLTIME_FROM_NS(20));
m_cnt = cnt;
}
NETLIB_HANDLERI(abcd)
{
m_abcd = static_cast<uint8_t>((m_D() << 3) | (m_C() << 2) | (m_B() << 1) | (m_A() << 0));
}
logic_input_t m_CLK;
logic_input_t m_ENT;
logic_output_t m_RC;
logic_input_t m_LOADQ;
logic_input_t m_ENP;
@ -59,18 +96,15 @@ namespace netlist
logic_input_t m_D;
object_array_t<logic_output_t, 4> m_Q;
logic_output_t m_RC;
/* counter state */
state_var_u8 m_cnt;
state_var<unsigned> m_cnt;
/* cached pins */
state_var_u8 m_abcd;
state_var_sig m_loadq;
state_var_sig m_ent;
private:
void update_outputs_all(const unsigned &cnt, const netlist_time &out_delay) noexcept
void update_outputs_all(unsigned cnt, netlist_time out_delay) noexcept
{
m_Q[0].push((cnt >> 0) & 1, out_delay);
m_Q[1].push((cnt >> 1) & 1, out_delay);
@ -103,64 +137,6 @@ namespace netlist
}
};
NETLIB_RESET(9316)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_abcd = 0;
}
NETLIB_HANDLER(9316, clk)
{
auto cnt(m_cnt);
if (m_loadq)
{
++cnt &= MAXCNT;
//m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27));
if (cnt > 0 && cnt < MAXCNT)
update_outputs_all(cnt, NLTIME_FROM_NS(20));
else if (cnt == 0)
{
m_RC.push(0, NLTIME_FROM_NS(27));
update_outputs_all(0, NLTIME_FROM_NS(20));
}
else
{
m_RC.push(m_ent, NLTIME_FROM_NS(27));
update_outputs_all(MAXCNT, NLTIME_FROM_NS(20));
}
}
else
{
cnt = m_abcd;
m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(cnt, NLTIME_FROM_NS(22));
}
m_cnt = cnt;
}
NETLIB_UPDATE(9316)
{
const netlist_sig_t CLRQ(m_CLRQ());
m_ent = m_ENT();
m_loadq = m_LOADQ();
if (((m_loadq ^ 1) || (m_ent && m_ENP())) && CLRQ)
{
m_CLK.activate_lh();
}
else
{
m_CLK.inactivate();
if (!CLRQ && (m_cnt>0))
{
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(36));
}
}
m_RC.push(m_ent && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
NETLIB_DEVICE_IMPL(9316, "TTL_9316", "+CLK,+ENP,+ENT,+CLRQ,+LOADQ,+A,+B,+C,+D")
NETLIB_DEVICE_IMPL(9316_dip, "TTL_9316_DIP", "")

View File

@ -192,13 +192,8 @@ namespace netlist
} // namespace devices
namespace detail {
class object_t;
class device_object_t;
struct netlist_ref;
class core_terminal_t;
struct family_setter_t;
class queue_t;
class net_t;
} // namespace detail
class logic_output_t;
@ -359,17 +354,17 @@ namespace netlist
const T &value //!< Initial value after construction
);
//! Copy Constructor.
state_array(const state_array &rhs) NL_NOEXCEPT = default;
state_array(const state_array &rhs) noexcept = default;
//! Destructor.
~state_array() noexcept = default;
//! Move Constructor.
state_array(state_array &&rhs) NL_NOEXCEPT = default;
state_array &operator=(const state_array &rhs) NL_NOEXCEPT = default;
state_array &operator=(state_array &&rhs) NL_NOEXCEPT = default;
state_array(state_array &&rhs) noexcept = default;
state_array &operator=(const state_array &rhs) noexcept = default;
state_array &operator=(state_array &&rhs) noexcept = default;
state_array &operator=(const T &rhs) NL_NOEXCEPT { m_value = rhs; return *this; }
T & operator[](const std::size_t i) NL_NOEXCEPT { return m_value[i]; }
constexpr const T & operator[](const std::size_t i) const NL_NOEXCEPT { return m_value[i]; }
state_array &operator=(const T &rhs) noexcept { m_value = rhs; return *this; }
T & operator[](const std::size_t i) noexcept { return m_value[i]; }
constexpr const T & operator[](const std::size_t i) const noexcept { return m_value[i]; }
private:
std::array<T, N> m_value;
};
@ -390,190 +385,324 @@ namespace netlist
/*! predefined state variable type for sig_t */
using state_var_sig = state_var<netlist_sig_t>;
// -----------------------------------------------------------------------------
// object_t
// -----------------------------------------------------------------------------
namespace detail {
/*! The base class for netlist devices, terminals and parameters.
*
* This class serves as the base class for all device, terminal and
* objects. It provides new and delete operators to support e.g. pooled
* memory allocation to enhance locality. Please refer to \ref USE_MEMPOOL as
* well.
*/
class detail::object_t
{
public:
// -----------------------------------------------------------------------------
// object_t
// -----------------------------------------------------------------------------
/*! Constructor.
/*! The base class for netlist devices, terminals and parameters.
*
* Every class derived from the object_t class must have a name.
* This class serves as the base class for all device, terminal and
* objects. It provides new and delete operators to support e.g. pooled
* memory allocation to enhance locality. Please refer to \ref USE_MEMPOOL as
* well.
*/
explicit object_t(const pstring &aname /*!< string containing name of the object */);
COPYASSIGNMOVE(object_t, delete)
/*! return name of the object
*
* \returns name of the object.
*/
pstring name() const;
#if 0
void * operator new (size_t size, void *ptr) { plib::unused_var(size); return ptr; }
void operator delete (void *ptr, void *) { plib::unused_var(ptr); }
void * operator new (size_t size) = delete;
void operator delete (void * mem) = delete;
#endif
protected:
~object_t() noexcept = default; // only childs should be destructible
private:
//pstring m_name;
static std::unordered_map<const object_t *, pstring> &name_hash()
class object_t
{
static std::unordered_map<const object_t *, pstring> lhash;
return lhash;
}
};
public:
struct detail::netlist_ref
{
explicit netlist_ref(netlist_state_t &nl);
/*! Constructor.
*
* Every class derived from the object_t class must have a name.
*/
explicit object_t(const pstring &aname /*!< string containing name of the object */);
COPYASSIGNMOVE(netlist_ref, delete)
COPYASSIGNMOVE(object_t, delete)
/*! return name of the object
*
* \returns name of the object.
*/
pstring name() const;
netlist_state_t & state() noexcept;
const netlist_state_t & state() const noexcept;
#if 0
void * operator new (size_t size, void *ptr) { plib::unused_var(size); return ptr; }
void operator delete (void *ptr, void *) { plib::unused_var(ptr); }
void * operator new (size_t size) = delete;
void operator delete (void * mem) = delete;
#endif
protected:
~object_t() noexcept = default; // only childs should be destructible
setup_t & setup() noexcept;
const setup_t & setup() const noexcept;
netlist_t & exec() noexcept { return m_netlist; }
const netlist_t & exec() const noexcept { return m_netlist; }
protected:
~netlist_ref() noexcept = default; // prohibit polymorphic destruction
private:
netlist_t & m_netlist;
};
// -----------------------------------------------------------------------------
// device_object_t
// -----------------------------------------------------------------------------
/*! Base class for all objects being owned by a device.
*
* Serves as the base class of all objects being owned by a device.
*
*/
class detail::device_object_t : public detail::object_t
{
public:
/*! Constructor.
*
* \param dev device owning the object.
* \param name string holding the name of the device
*/
device_object_t(core_device_t &dev, const pstring &name);
/*! returns reference to owning device.
* \returns reference to owning device.
*/
core_device_t &device() noexcept { return m_device; }
const core_device_t &device() const noexcept { return m_device; }
/*! The netlist owning the owner of this object.
* \returns reference to netlist object.
*/
netlist_state_t &state() NL_NOEXCEPT;
const netlist_state_t &state() const NL_NOEXCEPT;
netlist_t &exec() NL_NOEXCEPT;
const netlist_t &exec() const NL_NOEXCEPT;
private:
core_device_t & m_device;
};
// -----------------------------------------------------------------------------
// core_terminal_t
// -----------------------------------------------------------------------------
/*! Base class for all terminals.
*
* All terminals are derived from this class.
*
*/
class detail::core_terminal_t : public device_object_t,
public plib::linkedlist_t<core_terminal_t>::element_t
{
public:
using list_t = std::vector<core_terminal_t *>;
static constexpr const auto INP_HL_SHIFT = 0;
static constexpr const auto INP_LH_SHIFT = 1;
static constexpr const auto INP_ACTIVE_SHIFT = 2;
enum state_e {
STATE_INP_PASSIVE = 0,
STATE_INP_HL = (1 << INP_HL_SHIFT),
STATE_INP_LH = (1 << INP_LH_SHIFT),
STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT),
STATE_OUT = 128,
STATE_BIDIR = 256
private:
//pstring m_name;
static std::unordered_map<const object_t *, pstring> &name_hash()
{
static std::unordered_map<const object_t *, pstring> lhash;
return lhash;
}
};
core_terminal_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
virtual ~core_terminal_t() noexcept = default;
COPYASSIGNMOVE(core_terminal_t, delete)
/*! The object type.
* \returns type of the object
*/
terminal_type type() const;
/*! Checks if object is of specified type.
* \param atype type to check object against.
* \returns true if object is of specified type else false.
*/
bool is_type(const terminal_type atype) const noexcept { return (type() == atype); }
void set_net(net_t *anet) noexcept { m_net = anet; }
void clear_net() noexcept { m_net = nullptr; }
bool has_net() const noexcept { return (m_net != nullptr); }
const net_t & net() const noexcept { return *m_net;}
net_t & net() noexcept { return *m_net;}
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
bool is_state(state_e astate) const noexcept { return (m_state == astate); }
state_e terminal_state() const noexcept { return m_state; }
void set_state(state_e astate) noexcept { m_state = astate; }
void reset() noexcept { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
nldelegate m_delegate;
#if USE_COPY_INSTEAD_OF_REFERENCE
void set_copied_input(netlist_sig_t val)
struct netlist_ref
{
m_Q = val;
}
explicit netlist_ref(netlist_state_t &nl);
state_var_sig m_Q;
#else
void set_copied_input(netlist_sig_t val) const { plib::unused_var(val); }
#endif
COPYASSIGNMOVE(netlist_ref, delete)
private:
net_t * m_net;
state_var<state_e> m_state;
};
netlist_state_t & state() noexcept;
const netlist_state_t & state() const noexcept;
setup_t & setup() noexcept;
const setup_t & setup() const noexcept;
netlist_t & exec() noexcept { return m_netlist; }
const netlist_t & exec() const noexcept { return m_netlist; }
protected:
~netlist_ref() noexcept = default; // prohibit polymorphic destruction
private:
netlist_t & m_netlist;
};
// -----------------------------------------------------------------------------
// device_object_t
// -----------------------------------------------------------------------------
/*! Base class for all objects being owned by a device.
*
* Serves as the base class of all objects being owned by a device.
*
*/
class device_object_t : public object_t
{
public:
/*! Constructor.
*
* \param dev device owning the object.
* \param name string holding the name of the device
*/
device_object_t(core_device_t &dev, const pstring &name);
/*! returns reference to owning device.
* \returns reference to owning device.
*/
core_device_t &device() noexcept { return m_device; }
const core_device_t &device() const noexcept { return m_device; }
/*! The netlist owning the owner of this object.
* \returns reference to netlist object.
*/
netlist_state_t &state() NL_NOEXCEPT;
const netlist_state_t &state() const NL_NOEXCEPT;
netlist_t &exec() NL_NOEXCEPT;
const netlist_t &exec() const NL_NOEXCEPT;
private:
core_device_t & m_device;
};
// -----------------------------------------------------------------------------
// core_terminal_t
// -----------------------------------------------------------------------------
/*! Base class for all terminals.
*
* All terminals are derived from this class.
*
*/
class net_t;
class core_terminal_t : public device_object_t,
public plib::linkedlist_t<core_terminal_t>::element_t
{
public:
using list_t = std::vector<core_terminal_t *>;
static constexpr const auto INP_HL_SHIFT = 0;
static constexpr const auto INP_LH_SHIFT = 1;
static constexpr const auto INP_ACTIVE_SHIFT = 2;
enum state_e {
STATE_INP_PASSIVE = 0,
STATE_INP_HL = (1 << INP_HL_SHIFT),
STATE_INP_LH = (1 << INP_LH_SHIFT),
STATE_INP_ACTIVE = (1 << INP_ACTIVE_SHIFT),
STATE_OUT = 128,
STATE_BIDIR = 256
};
core_terminal_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
virtual ~core_terminal_t() noexcept = default;
COPYASSIGNMOVE(core_terminal_t, delete)
/*! The object type.
* \returns type of the object
*/
terminal_type type() const;
/*! Checks if object is of specified type.
* \param atype type to check object against.
* \returns true if object is of specified type else false.
*/
bool is_type(const terminal_type atype) const noexcept { return (type() == atype); }
void set_net(net_t *anet) noexcept { m_net = anet; }
void clear_net() noexcept { m_net = nullptr; }
bool has_net() const noexcept { return (m_net != nullptr); }
const net_t & net() const noexcept { return *m_net;}
net_t & net() noexcept { return *m_net;}
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
bool is_state(state_e astate) const noexcept { return (m_state == astate); }
state_e terminal_state() const noexcept { return m_state; }
void set_state(state_e astate) noexcept { m_state = astate; }
void reset() noexcept { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
nldelegate m_delegate;
#if USE_COPY_INSTEAD_OF_REFERENCE
void set_copied_input(netlist_sig_t val)
{
m_Q = val;
}
state_var_sig m_Q;
#else
void set_copied_input(netlist_sig_t val) const { plib::unused_var(val); }
#endif
private:
net_t * m_net;
state_var<state_e> m_state;
};
// -----------------------------------------------------------------------------
// net_t
// -----------------------------------------------------------------------------
class net_t :
public object_t,
public netlist_ref
{
public:
enum class queue_status
{
DELAYED_DUE_TO_INACTIVE = 0,
QUEUED,
DELIVERED
};
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
COPYASSIGNMOVE(net_t, delete)
virtual ~net_t() noexcept = default;
void reset();
void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
void toggle_and_push_to_queue(netlist_time delay) NL_NOEXCEPT
{
toggle_new_Q();
push_to_queue(delay);
}
void push_to_queue(netlist_time delay) NL_NOEXCEPT;
bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
void update_devs() NL_NOEXCEPT;
netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; }
void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; }
bool isRailNet() const noexcept { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
std::size_t num_cons() const noexcept { return m_core_terms.size(); }
void add_to_active_list(core_terminal_t &term) NL_NOEXCEPT;
void remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT;
/* setup stuff */
void add_terminal(core_terminal_t &terminal);
void remove_terminal(core_terminal_t &terminal);
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
void rebuild_list(); /* rebuild m_list after a load */
void move_connections(net_t &dest_net);
std::vector<core_terminal_t *> &core_terms() { return m_core_terms; }
#if USE_COPY_INSTEAD_OF_REFERENCE
void update_inputs()
{
for (auto & term : m_core_terms)
term->m_Q = m_cur_Q;
}
#else
void update_inputs() const
{
/* nothing needs to be done */
}
#endif
protected:
/* only used for logic nets */
netlist_sig_t Q() const noexcept { return m_cur_Q; }
/* only used for logic nets */
void initial(const netlist_sig_t val) noexcept
{
m_cur_Q = m_new_Q = val;
update_inputs();
}
/* only used for logic nets */
void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
m_new_Q = newQ;
push_to_queue(delay);
}
}
/* only used for logic nets */
void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
m_next_scheduled_time = at;
}
m_cur_Q = m_new_Q = newQ;
update_inputs();
}
/* internal state support
* FIXME: get rid of this and implement export/import in MAME
*/
/* only used for logic nets */
netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); }
private:
state_var<netlist_sig_t> m_new_Q;
state_var<netlist_sig_t> m_cur_Q;
state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
state_var<netlist_time> m_next_scheduled_time;
core_terminal_t * m_railterminal;
plib::linkedlist_t<core_terminal_t> m_list_active;
std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
template <typename T>
void process(const T mask, netlist_sig_t sig);
};
} // detail
// -----------------------------------------------------------------------------
// analog_t
@ -713,133 +842,6 @@ namespace netlist
};
// -----------------------------------------------------------------------------
// net_t
// -----------------------------------------------------------------------------
class detail::net_t :
public detail::object_t,
public detail::netlist_ref
{
public:
enum class queue_status
{
DELAYED_DUE_TO_INACTIVE = 0,
QUEUED,
DELIVERED
};
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
COPYASSIGNMOVE(net_t, delete)
virtual ~net_t() noexcept = default;
void reset();
void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
void toggle_and_push_to_queue(netlist_time delay) NL_NOEXCEPT
{
toggle_new_Q();
push_to_queue(delay);
}
void push_to_queue(netlist_time delay) NL_NOEXCEPT;
bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
void update_devs() NL_NOEXCEPT;
netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; }
void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; }
bool isRailNet() const noexcept { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
std::size_t num_cons() const noexcept { return m_core_terms.size(); }
void add_to_active_list(core_terminal_t &term) NL_NOEXCEPT;
void remove_from_active_list(core_terminal_t &term) NL_NOEXCEPT;
/* setup stuff */
void add_terminal(core_terminal_t &terminal);
void remove_terminal(core_terminal_t &terminal);
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
void rebuild_list(); /* rebuild m_list after a load */
void move_connections(net_t &dest_net);
std::vector<core_terminal_t *> &core_terms() { return m_core_terms; }
#if USE_COPY_INSTEAD_OF_REFERENCE
void update_inputs()
{
for (auto & term : m_core_terms)
term->m_Q = m_cur_Q;
}
#else
void update_inputs() const
{
/* nothing needs to be done */
}
#endif
protected:
/* only used for logic nets */
netlist_sig_t Q() const noexcept { return m_cur_Q; }
/* only used for logic nets */
void initial(const netlist_sig_t val) noexcept
{
m_cur_Q = m_new_Q = val;
update_inputs();
}
/* only used for logic nets */
void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
m_new_Q = newQ;
push_to_queue(delay);
}
}
/* only used for logic nets */
void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
m_next_scheduled_time = at;
}
m_cur_Q = m_new_Q = newQ;
update_inputs();
}
/* internal state support
* FIXME: get rid of this and implement export/import in MAME
*/
/* only used for logic nets */
netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); }
private:
state_var<netlist_sig_t> m_new_Q;
state_var<netlist_sig_t> m_cur_Q;
state_var<queue_status> m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
state_var<netlist_time> m_next_scheduled_time;
core_terminal_t * m_railterminal;
plib::linkedlist_t<core_terminal_t> m_list_active;
std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
template <typename T>
void process(const T mask, netlist_sig_t sig);
};
class logic_net_t : public detail::net_t
{

View File

@ -198,7 +198,8 @@ namespace netlist
mutex_type m_lock;
PALIGNAS_CACHELINE()
T * m_end;
std::vector<T> m_list;
//std::vector<T> m_list;
plib::aligned_vector<T> m_list;
public:
// profiling

View File

@ -239,7 +239,7 @@ namespace plib
ops.calc_rhs(Ax, x);
vec_sub(n, rhs, Ax, residual);
vec_sub(n, residual, rhs, Ax);
ops.solve_LU_inplace(residual);
@ -258,7 +258,7 @@ namespace plib
//for (std::size_t i = 0; i < mr + 1; i++)
// vec_set_scalar(mr, m_ht[i], NL_FCONST(0.0));
vec_mult_scalar(n, residual, constants<FT>::one() / rho, m_v[0]);
vec_mult_scalar(n, m_v[0], residual, constants<FT>::one() / rho);
for (std::size_t k = 0; k < RESTART; k++)
{
@ -270,7 +270,7 @@ namespace plib
for (std::size_t j = 0; j <= k; j++)
{
m_ht[j][k] = vec_mult<FT>(n, m_v[kp1], m_v[j]);
vec_add_mult_scalar(n, m_v[j], -m_ht[j][k], m_v[kp1]);
vec_add_mult_scalar(n, m_v[kp1], m_v[j], -m_ht[j][k]);
}
m_ht[kp1][k] = std::sqrt(vec_mult2<FT>(n, m_v[kp1]));
@ -315,7 +315,7 @@ namespace plib
}
for (std::size_t i = 0; i <= last_k; i++)
vec_add_mult_scalar(n, m_v[i], m_y[i], x);
vec_add_mult_scalar(n, x, m_v[i], m_y[i]);
if (rho <= rho_delta)
break;

View File

@ -38,7 +38,7 @@
*/
#ifndef USE_ALIGNED_OPTIMIZATIONS
#define USE_ALIGNED_OPTIMIZATIONS (1)
#define USE_ALIGNED_OPTIMIZATIONS (0)
#endif
#define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS)
@ -48,7 +48,7 @@
*/
#define PALIGN_CACHELINE (64)
#define PALIGN_VECTOROPT (32)
#define PALIGN_VECTOROPT (64)
#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE)
#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT)

View File

@ -34,10 +34,10 @@ public:
using iterator = C *;
using const_iterator = const C *;
uninitialised_array_t() = default;
uninitialised_array_t() noexcept = default;
COPYASSIGNMOVE(uninitialised_array_t, delete)
~uninitialised_array_t()
~uninitialised_array_t() noexcept
{
for (std::size_t i=0; i<N; i++)
(*this)[i].~C();
@ -76,7 +76,7 @@ protected:
private:
/* ensure proper alignment */
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
PALIGNAS_VECTOROPT()
std::array<typename std::aligned_storage<sizeof(C), alignof(C)>::type, N> m_buf;
};
@ -226,10 +226,10 @@ public:
void push_front(LC *elem) noexcept
{
if (m_head)
m_head->m_prev = elem;
elem->m_next = m_head;
elem->m_prev = nullptr;
if (elem->m_next)
elem->m_next->m_prev = elem;
m_head = elem;
}

View File

@ -182,59 +182,6 @@ namespace plib {
};
#if 0
class mempool_default
{
private:
size_t m_min_alloc;
size_t m_min_align;
public:
static constexpr const bool is_stateless = true;
template <class T, std::size_t ALIGN = alignof(T)>
using allocator_type = arena_allocator<mempool_default, T, ALIGN>;
mempool_default(size_t min_alloc = 16, size_t min_align = (1 << 21))
: m_min_alloc(min_alloc), m_min_align(min_align)
{
}
COPYASSIGNMOVE(mempool_default, delete)
~mempool_default() = default;
void *allocate(size_t alignment, size_t size)
{
plib::unused_var(m_min_alloc); // -Wunused-private-field fires without
plib::unused_var(m_min_align);
plib::unused_var(alignment);
return ::operator new(size);
}
static void deallocate(void *ptr)
{
::operator delete(ptr);
}
template <typename T>
using poolptr = plib::owned_ptr<T, arena_deleter<mempool_default, T>>;
template<typename T, typename... Args>
poolptr<T> make_poolptr(Args&&... args)
{
plib::unused_var(m_min_alloc); // -Wunused-private-field fires without
plib::unused_var(m_min_align);
auto *obj = plib::pnew<T>(std::forward<Args>(args)...);
poolptr<T> a(obj, true);
return std::move(a);
}
};
#endif
} // namespace plib
#endif /* PMEMPOOL_H_ */

View File

@ -13,15 +13,6 @@
#include <atomic>
#include <stack>
template <typename T>
std::size_t strlen_mem(const T *s)
{
std::size_t len(0);
while (*s++)
++len;
return len;
}
template<typename F>
int pstring_t<F>::compare(const pstring_t &right) const
{

View File

@ -75,7 +75,7 @@ public:
using string_type = typename traits_type::string_type;
// FIXME: this is ugly
class ref_value_type final
struct ref_value_type final
{
public:
ref_value_type() = delete;
@ -202,11 +202,9 @@ public:
size_type mem_t_size() const { return m_str.size(); }
pstring_t rpad(const pstring_t &ws, const size_type cnt) const;
const string_type &cpp_string() const { return m_str; }
static const size_type npos = static_cast<size_type>(-1);
static constexpr const size_type npos = static_cast<size_type>(-1);
private:
string_type m_str;

View File

@ -26,7 +26,7 @@
namespace plib
{
template<typename VT, typename T>
void vec_set_scalar (const std::size_t n, VT &v, T && scalar)
void vec_set_scalar(const std::size_t n, VT &v, T && scalar)
{
const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
for ( std::size_t i = 0; i < n; i++ )
@ -34,14 +34,14 @@ namespace plib
}
template<typename VT, typename VS>
void vec_set (const std::size_t n, VT &v, const VS & source)
void vec_set(const std::size_t n, VT &v, const VS & source)
{
for ( std::size_t i = 0; i < n; i++ )
v[i] = source[i];
}
template<typename T, typename V1, typename V2>
T vec_mult (const std::size_t n, const V1 & v1, const V2 & v2 )
T vec_mult(const std::size_t n, const V1 & v1, const V2 & v2 )
{
using b8 = T[8];
PALIGNAS_VECTOROPT() b8 value = {0};
@ -53,7 +53,7 @@ namespace plib
}
template<typename T, typename VT>
T vec_mult2 (const std::size_t n, const VT &v)
T vec_mult2(const std::size_t n, const VT &v)
{
using b8 = T[8];
PALIGNAS_VECTOROPT() b8 value = {0};
@ -65,7 +65,7 @@ namespace plib
}
template<typename T, typename VT>
T vec_sum (const std::size_t n, const VT &v)
T vec_sum(const std::size_t n, const VT &v)
{
if (n<8)
{
@ -87,15 +87,15 @@ namespace plib
}
template<typename VV, typename T, typename VR>
void vec_mult_scalar (const std::size_t n, const VV & v, T && scalar, VR & result)
void vec_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
{
const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
for ( std::size_t i = 0; i < n; i++ )
result[i] = s * v[i];
}
template<typename VV, typename T, typename VR>
void vec_add_mult_scalar (const std::size_t n, const VV & v, T && scalar, VR & result)
template<typename VR, typename VV, typename T>
void vec_add_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
{
const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
for ( std::size_t i = 0; i < n; i++ )
@ -103,21 +103,21 @@ namespace plib
}
template<typename T>
void vec_add_mult_scalar_p(const std::size_t & n, const T * v, T scalar, T * result)
void vec_add_mult_scalar_p(const std::size_t n, T * result, const T * v, T scalar)
{
for ( std::size_t i = 0; i < n; i++ )
result[i] += scalar * v[i];
}
template<typename V, typename R>
void vec_add_ip(const std::size_t n, const V & v, R & result)
template<typename R, typename V>
void vec_add_ip(const std::size_t n, R & result, const V & v)
{
for ( std::size_t i = 0; i < n; i++ )
result[i] += v[i];
}
template<typename V1, typename V2, typename VR>
void vec_sub(const std::size_t n, const V1 &v1, const V2 & v2, VR & result)
template<typename VR, typename V1, typename V2>
void vec_sub(const std::size_t n, VR & result, const V1 &v1, const V2 & v2)
{
for ( std::size_t i = 0; i < n; i++ )
result[i] = v1[i] - v2[i];

View File

@ -139,9 +139,9 @@ namespace devices
const FT * pi = &A(i,i+1);
FT * pj = &A(j,i+1);
#if 1
plib::vec_add_mult_scalar_p(kN-i,pi,f1,pj);
plib::vec_add_mult_scalar_p(kN-i,pj, pi,f1);
#else
vec_add_mult_scalar_p(kN-i-1,pj,f1,pi);
vec_add_mult_scalar_p1(kN-i-1,pj,pi,f1);
//for (unsigned k = i+1; k < kN; k++)
// pj[k] = pj[k] + pi[k] * f1;
//for (unsigned k = i+1; k < kN; k++)