mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Separate include file usage for netlist.
Device implementations (all cpp files in netlist/devices) now should only include nl_base.h. Netlist implementation sources should only include "net_lib.h". Refactored netlist.h and netlist.cpp to avoid namespace congestion in netlist.h. Fixed VC2015 build. (nw)
This commit is contained in:
parent
2720512e31
commit
c713f9ed1d
@ -75,11 +75,13 @@ project "netlist"
|
||||
MAME_DIR .. "src/lib/netlist/tools/nl_convert.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_bjt.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_bjt.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_fourterm.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_fourterm.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nlid_fourterm.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nlid_fourterm.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_fourterm.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_switches.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_switches.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_twoterm.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nlid_twoterm.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nlid_twoterm.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_twoterm.h",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_opamps.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/analog/nld_opamps.h",
|
||||
@ -190,8 +192,8 @@ project "netlist"
|
||||
MAME_DIR .. "src/lib/netlist/devices/nld_log.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nld_system.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nld_system.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nld_truthtable.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nld_truthtable.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nlid_truthtable.cpp",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nlid_truthtable.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nlid_cmos.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nlid_system.h",
|
||||
MAME_DIR .. "src/lib/netlist/devices/nlid_proxy.cpp",
|
||||
|
@ -37,6 +37,391 @@ const device_type NETLIST_LOGIC_OUTPUT = &device_creator<netlist_mame_logic_outp
|
||||
const device_type NETLIST_ANALOG_OUTPUT = &device_creator<netlist_mame_analog_output_t>;
|
||||
const device_type NETLIST_STREAM_OUTPUT = &device_creator<netlist_mame_stream_output_t>;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Special netlist extension devices ....
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_mame_device_t;
|
||||
|
||||
class netlist_mame_t : public netlist::netlist_t
|
||||
{
|
||||
public:
|
||||
|
||||
netlist_mame_t(netlist_mame_device_t &parent, const pstring &aname)
|
||||
: netlist::netlist_t(aname),
|
||||
m_parent(parent)
|
||||
{}
|
||||
virtual ~netlist_mame_t() { };
|
||||
|
||||
inline running_machine &machine();
|
||||
|
||||
netlist_mame_device_t &parent() { return m_parent; }
|
||||
|
||||
protected:
|
||||
|
||||
void vlog(const plib::plog_level &l, const pstring &ls) const override;
|
||||
|
||||
private:
|
||||
netlist_mame_device_t &m_parent;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// analog_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(analog_callback) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(analog_callback)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
|
||||
}
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_last = 0.0;
|
||||
}
|
||||
|
||||
ATTR_COLD void register_callback(netlist_analog_output_delegate callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
nl_double cur = m_in();
|
||||
|
||||
// FIXME: make this a parameter
|
||||
// avoid calls due to noise
|
||||
if (std::fabs(cur - m_last) > 1e-6)
|
||||
{
|
||||
m_cpu_device->update_time_x();
|
||||
m_callback(cur, m_cpu_device->local_time());
|
||||
m_cpu_device->check_mame_abort_slice();
|
||||
m_last = cur;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
netlist::analog_input_t m_in;
|
||||
netlist_analog_output_delegate m_callback;
|
||||
netlist_mame_cpu_device_t *m_cpu_device;
|
||||
netlist::state_var<nl_double> m_last;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// logic_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(logic_callback) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(logic_callback)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
|
||||
}
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_last = 0;
|
||||
}
|
||||
|
||||
ATTR_COLD void register_callback(netlist_logic_output_delegate callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
netlist_sig_t cur = m_in();
|
||||
|
||||
// FIXME: make this a parameter
|
||||
// avoid calls due to noise
|
||||
if (cur != m_last)
|
||||
{
|
||||
m_cpu_device->update_time_x();
|
||||
m_callback(cur, m_cpu_device->local_time());
|
||||
m_cpu_device->check_mame_abort_slice();
|
||||
m_last = cur;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
netlist::logic_input_t m_in;
|
||||
netlist_logic_output_delegate m_callback;
|
||||
netlist_mame_cpu_device_t *m_cpu_device;
|
||||
netlist::state_var<netlist_sig_t> m_last;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// sound_out
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(sound_out) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(sound_out)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: netlist::device_t(anetlist, name)
|
||||
, 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())
|
||||
{
|
||||
}
|
||||
|
||||
static const int BUFSIZE = 2048;
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_cur = 0.0;
|
||||
m_last_pos = 0;
|
||||
m_last_buffer = netlist::netlist_time::zero();
|
||||
}
|
||||
|
||||
ATTR_HOT void sound_update(const netlist::netlist_time &upto)
|
||||
{
|
||||
int pos = (upto - m_last_buffer) / m_sample;
|
||||
if (pos >= BUFSIZE)
|
||||
netlist().log().fatal("sound {1}: exceeded BUFSIZE\n", name().c_str());
|
||||
while (m_last_pos < pos )
|
||||
{
|
||||
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
nl_double val = m_in() * m_mult() + m_offset();
|
||||
sound_update(netlist().time());
|
||||
/* ignore spikes */
|
||||
if (std::abs(val) < 32767.0)
|
||||
m_cur = val;
|
||||
else if (val > 0.0)
|
||||
m_cur = 32767.0;
|
||||
else
|
||||
m_cur = -32767.0;
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
ATTR_HOT void buffer_reset(const netlist::netlist_time &upto)
|
||||
{
|
||||
m_last_pos = 0;
|
||||
m_last_buffer = upto;
|
||||
m_cur = 0.0;
|
||||
}
|
||||
|
||||
netlist::param_int_t m_channel;
|
||||
netlist::param_double_t m_mult;
|
||||
netlist::param_double_t m_offset;
|
||||
stream_sample_t *m_buffer;
|
||||
netlist::netlist_time m_sample;
|
||||
|
||||
private:
|
||||
netlist::analog_input_t m_in;
|
||||
double m_cur;
|
||||
int m_last_pos;
|
||||
netlist::state_var<netlist::netlist_time> m_last_buffer;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// sound_in
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(sound_in) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(sound_in)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: netlist::device_t(anetlist, name)
|
||||
, m_feedback(*this, "FB") // clock part
|
||||
, m_Q(*this, "Q")
|
||||
{
|
||||
connect(m_feedback, m_Q);
|
||||
m_inc = netlist::netlist_time::from_nsec(1);
|
||||
|
||||
|
||||
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
|
||||
{
|
||||
m_param_name[i] = std::make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
|
||||
m_param_mult[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
|
||||
m_param_offset[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
|
||||
}
|
||||
m_num_channel = 0;
|
||||
}
|
||||
|
||||
static const int MAX_INPUT_CHANNELS = 10;
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_pos = 0;
|
||||
for (auto & elem : m_buffer)
|
||||
elem = nullptr;
|
||||
}
|
||||
|
||||
ATTR_COLD int resolve()
|
||||
{
|
||||
m_pos = 0;
|
||||
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
|
||||
{
|
||||
if ((*m_param_name[i])() != pstring(""))
|
||||
{
|
||||
if (i != m_num_channel)
|
||||
netlist().log().fatal("sound input numbering has to be sequential!");
|
||||
m_num_channel++;
|
||||
m_param[i] = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_param_name[i])(), true));
|
||||
}
|
||||
}
|
||||
return m_num_channel;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
for (int i=0; i<m_num_channel; i++)
|
||||
{
|
||||
if (m_buffer[i] == nullptr)
|
||||
break; // stop, called outside of stream_update
|
||||
const nl_double v = m_buffer[i][m_pos];
|
||||
m_param[i]->setTo(v * (*m_param_mult[i])() + (*m_param_offset[i])());
|
||||
}
|
||||
m_pos++;
|
||||
m_Q.push(!m_Q.net().new_Q(), m_inc );
|
||||
}
|
||||
|
||||
public:
|
||||
ATTR_HOT void buffer_reset()
|
||||
{
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<netlist::param_str_t> m_param_name[MAX_INPUT_CHANNELS];
|
||||
netlist::param_double_t *m_param[MAX_INPUT_CHANNELS];
|
||||
stream_sample_t *m_buffer[MAX_INPUT_CHANNELS];
|
||||
std::unique_ptr<netlist::param_double_t> m_param_mult[MAX_INPUT_CHANNELS];
|
||||
std::unique_ptr<netlist::param_double_t> m_param_offset[MAX_INPUT_CHANNELS];
|
||||
netlist::netlist_time m_inc;
|
||||
|
||||
private:
|
||||
netlist::logic_input_t m_feedback;
|
||||
netlist::logic_output_t m_Q;
|
||||
|
||||
int m_pos;
|
||||
int m_num_channel;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Extensions to interface netlist with MAME code ....
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_source_memregion_t : public netlist::source_t
|
||||
{
|
||||
public:
|
||||
netlist_source_memregion_t(netlist::setup_t &setup, pstring name)
|
||||
: netlist::source_t(setup), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
|
||||
private:
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
class netlist_data_memregions_t : public netlist::source_t
|
||||
{
|
||||
public:
|
||||
netlist_data_memregions_t(netlist::setup_t &setup);
|
||||
|
||||
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
|
||||
};
|
||||
|
||||
|
||||
netlist::setup_t &netlist_mame_device_t::setup()
|
||||
{
|
||||
return m_netlist->setup();
|
||||
}
|
||||
|
||||
void netlist_mame_device_t::register_memregion_source(netlist::setup_t &setup, const char *name)
|
||||
{
|
||||
setup.register_source(plib::make_unique_base<netlist::source_t, netlist_source_memregion_t>(setup, pstring(name, pstring::UTF8)));
|
||||
}
|
||||
|
||||
running_machine &netlist_mame_t::machine()
|
||||
{
|
||||
return m_parent.machine();
|
||||
}
|
||||
|
||||
void netlist_mame_analog_input_t::write(const double val)
|
||||
{
|
||||
if (is_sound_device())
|
||||
{
|
||||
update_to_current_time();
|
||||
m_param->setTo(val * m_mult + m_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: use device timer ....
|
||||
m_param->setTo(val * m_mult + m_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void netlist_mame_int_input_t::write(const uint32_t val)
|
||||
{
|
||||
const uint32_t v = (val >> m_shift) & m_mask;
|
||||
if (v != (*m_param)())
|
||||
synchronize(0, v);
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::write(const uint32_t val)
|
||||
{
|
||||
const uint32_t v = (val >> m_shift) & 1;
|
||||
if (v != (*m_param)())
|
||||
synchronize(0, v);
|
||||
}
|
||||
|
||||
void netlist_mame_int_input_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (is_sound_device())
|
||||
update_to_current_time();
|
||||
m_param->setTo(param);
|
||||
}
|
||||
|
||||
void netlist_mame_logic_input_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (is_sound_device())
|
||||
update_to_current_time();
|
||||
m_param->setTo(param);
|
||||
}
|
||||
|
||||
void netlist_ram_pointer_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
m_data = (*m_param)();
|
||||
}
|
||||
|
||||
|
||||
void netlist_mame_cpu_device_t::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||
{
|
||||
if (entry.index() >= 0)
|
||||
{
|
||||
if (entry.index() & 1)
|
||||
str = string_format("%10.6f", *((double *)entry.dataptr()));
|
||||
else
|
||||
str = string_format("%d", *((netlist_sig_t *)entry.dataptr()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_analog_input_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -61,17 +446,17 @@ netlist_mame_analog_input_t::netlist_mame_analog_input_t(const machine_config &m
|
||||
void netlist_mame_analog_input_t::static_set_name(device_t &device, const char *param_name)
|
||||
{
|
||||
netlist_mame_analog_input_t &netlist = downcast<netlist_mame_analog_input_t &>(device);
|
||||
netlist.m_param_name = pstring(param_name, pstring::UTF8);
|
||||
netlist.m_param_name = param_name;
|
||||
}
|
||||
|
||||
void netlist_mame_analog_input_t::device_start()
|
||||
{
|
||||
LOG_DEV_CALLS(("start %s\n", tag()));
|
||||
netlist::param_t *p = this->nl_owner().setup().find_param(m_param_name);
|
||||
netlist::param_t *p = this->nl_owner().setup().find_param(pstring(m_param_name, pstring::UTF8));
|
||||
m_param = dynamic_cast<netlist::param_double_t *>(p);
|
||||
if (m_param == nullptr)
|
||||
{
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name);
|
||||
}
|
||||
if (m_mult != 1.0 || m_offset != 0.0)
|
||||
{
|
||||
@ -96,19 +481,20 @@ netlist_mame_analog_output_t::netlist_mame_analog_output_t(const machine_config
|
||||
void netlist_mame_analog_output_t::static_set_params(device_t &device, const char *in_name, netlist_analog_output_delegate adelegate)
|
||||
{
|
||||
netlist_mame_analog_output_t &mame_output = downcast<netlist_mame_analog_output_t &>(device);
|
||||
mame_output.m_in = pstring(in_name, pstring::UTF8);
|
||||
mame_output.m_in = in_name;
|
||||
mame_output.m_delegate = adelegate;
|
||||
}
|
||||
|
||||
void netlist_mame_analog_output_t::custom_netlist_additions(netlist::setup_t &setup)
|
||||
{
|
||||
pstring dname = "OUT_" + m_in;
|
||||
const pstring pin(m_in, pstring::UTF8);
|
||||
pstring dname = "OUT_" + pin;
|
||||
m_delegate.bind_relative_to(owner()->machine().root_device());
|
||||
|
||||
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
|
||||
static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(m_delegate);
|
||||
setup.netlist().register_dev(std::move(dev));
|
||||
setup.register_link(dname + ".IN", m_in);
|
||||
setup.register_link(dname + ".IN", pin);
|
||||
}
|
||||
|
||||
void netlist_mame_analog_output_t::device_start()
|
||||
@ -131,19 +517,20 @@ netlist_mame_logic_output_t::netlist_mame_logic_output_t(const machine_config &m
|
||||
void netlist_mame_logic_output_t::static_set_params(device_t &device, const char *in_name, netlist_logic_output_delegate adelegate)
|
||||
{
|
||||
netlist_mame_logic_output_t &mame_output = downcast<netlist_mame_logic_output_t &>(device);
|
||||
mame_output.m_in = pstring(in_name, pstring::UTF8);
|
||||
mame_output.m_in = in_name;
|
||||
mame_output.m_delegate = adelegate;
|
||||
}
|
||||
|
||||
void netlist_mame_logic_output_t::custom_netlist_additions(netlist::setup_t &setup)
|
||||
{
|
||||
pstring dname = "OUT_" + m_in;
|
||||
pstring pin(m_in, pstring::UTF8);
|
||||
pstring dname = "OUT_" + pin;
|
||||
m_delegate.bind_relative_to(owner()->machine().root_device());
|
||||
|
||||
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(logic_callback)>(setup.netlist(), setup.build_fqn(dname));
|
||||
static_cast<NETLIB_NAME(logic_callback) *>(dev.get())->register_callback(m_delegate);
|
||||
setup.netlist().register_dev(std::move(dev));
|
||||
setup.register_link(dname + ".IN", m_in);
|
||||
setup.register_link(dname + ".IN", pin);
|
||||
}
|
||||
|
||||
void netlist_mame_logic_output_t::device_start()
|
||||
@ -170,7 +557,7 @@ void netlist_mame_int_input_t::static_set_params(device_t &device, const char *p
|
||||
{
|
||||
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 = pstring(param_name, pstring::UTF8);
|
||||
netlist.m_param_name = param_name;
|
||||
netlist.m_shift = shift;
|
||||
netlist.m_mask = mask;
|
||||
}
|
||||
@ -178,11 +565,11 @@ void netlist_mame_int_input_t::static_set_params(device_t &device, const char *p
|
||||
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);
|
||||
netlist::param_t *p = downcast<netlist_mame_device_t *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
|
||||
m_param = dynamic_cast<netlist::param_int_t *>(p);
|
||||
if (m_param == nullptr)
|
||||
{
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,18 +590,18 @@ void netlist_mame_logic_input_t::static_set_params(device_t &device, const char
|
||||
{
|
||||
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 = pstring(param_name, pstring::UTF8);
|
||||
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);
|
||||
netlist::param_t *p = downcast<netlist_mame_device_t *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
|
||||
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.c_str());
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,17 +623,17 @@ void netlist_ram_pointer_t::static_set_params(device_t &device, const char *para
|
||||
{
|
||||
netlist_ram_pointer_t &netlist = downcast<netlist_ram_pointer_t&>(device);
|
||||
LOG_DEV_CALLS(("static_set_params %s\n", device.tag()));
|
||||
netlist.m_param_name = pstring(param_name, pstring::UTF8);
|
||||
netlist.m_param_name = param_name;
|
||||
}
|
||||
|
||||
void netlist_ram_pointer_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);
|
||||
netlist::param_t *p = downcast<netlist_mame_device_t *>(this->owner())->setup().find_param(pstring(m_param_name, pstring::UTF8));
|
||||
m_param = dynamic_cast<netlist::param_ptr_t *>(p);
|
||||
if (m_param == nullptr)
|
||||
{
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
|
||||
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name);
|
||||
}
|
||||
|
||||
m_data = (*m_param)();
|
||||
@ -267,7 +654,7 @@ netlist_mame_stream_input_t::netlist_mame_stream_input_t(const machine_config &m
|
||||
void netlist_mame_stream_input_t::static_set_params(device_t &device, int channel, const char *param_name)
|
||||
{
|
||||
netlist_mame_stream_input_t &netlist = downcast<netlist_mame_stream_input_t &>(device);
|
||||
netlist.m_param_name = pstring(param_name, pstring::UTF8);
|
||||
netlist.m_param_name = param_name;
|
||||
netlist.m_channel = channel;
|
||||
}
|
||||
|
||||
@ -282,7 +669,7 @@ void netlist_mame_stream_input_t::custom_netlist_additions(netlist::setup_t &set
|
||||
setup.register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
|
||||
|
||||
pstring sparam = plib::pfmt("STREAM_INPUT.CHAN{1}")(m_channel);
|
||||
setup.register_param(sparam, m_param_name);
|
||||
setup.register_param(sparam, pstring(m_param_name, pstring::UTF8));
|
||||
sparam = plib::pfmt("STREAM_INPUT.MULT{1}")(m_channel);
|
||||
setup.register_param(sparam, m_mult);
|
||||
sparam = plib::pfmt("STREAM_INPUT.OFFSET{1}")(m_channel);
|
||||
@ -304,7 +691,7 @@ netlist_mame_stream_output_t::netlist_mame_stream_output_t(const machine_config
|
||||
void netlist_mame_stream_output_t::static_set_params(device_t &device, int channel, const char *out_name)
|
||||
{
|
||||
netlist_mame_stream_output_t &netlist = downcast<netlist_mame_stream_output_t &>(device);
|
||||
netlist.m_out_name = pstring(out_name, pstring::UTF8);
|
||||
netlist.m_out_name = out_name;
|
||||
netlist.m_channel = channel;
|
||||
}
|
||||
|
||||
@ -324,7 +711,7 @@ void netlist_mame_stream_output_t::custom_netlist_additions(netlist::setup_t &se
|
||||
setup.register_param(sname + ".CHAN" , m_channel);
|
||||
setup.register_param(sname + ".MULT", m_mult);
|
||||
setup.register_param(sname + ".OFFSET", m_offset);
|
||||
setup.register_link(sname + ".IN", m_out_name);
|
||||
setup.register_link(sname + ".IN", pstring(m_out_name, pstring::UTF8));
|
||||
}
|
||||
|
||||
|
||||
@ -381,6 +768,11 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, devi
|
||||
{
|
||||
}
|
||||
|
||||
netlist_mame_device_t::~netlist_mame_device_t()
|
||||
{
|
||||
pstring::resetmem();
|
||||
}
|
||||
|
||||
void netlist_mame_device_t::static_set_constructor(device_t &device, void (*setup_func)(netlist::setup_t &))
|
||||
{
|
||||
LOG_DEV_CALLS(("static_set_constructor\n"));
|
||||
|
@ -13,8 +13,17 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/nl_setup.h"
|
||||
#include "netlist/nl_time.h"
|
||||
|
||||
class netlist_mame_t;
|
||||
|
||||
namespace netlist {
|
||||
class setup_t;
|
||||
class param_double_t;
|
||||
class param_int_t;
|
||||
class param_logic_t;
|
||||
class param_ptr_t;
|
||||
}
|
||||
|
||||
// MAME specific configuration
|
||||
|
||||
@ -72,7 +81,7 @@
|
||||
|
||||
|
||||
#define MEMREGION_SOURCE(_name) \
|
||||
setup.register_source(plib::make_unique_base<netlist::source_t, netlist_source_memregion_t>(setup, _name));
|
||||
netlist_mame_device_t::register_memregion_source(setup, _name);
|
||||
|
||||
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
|
||||
void _name(const double data, const attotime &time)
|
||||
@ -81,54 +90,6 @@
|
||||
void _name(const int data, const attotime &time)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Extensions to interface netlist with MAME code ....
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class netlist_source_memregion_t : public netlist::source_t
|
||||
{
|
||||
public:
|
||||
netlist_source_memregion_t(netlist::setup_t &setup, pstring name)
|
||||
: netlist::source_t(setup), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
|
||||
private:
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
class netlist_data_memregions_t : public netlist::source_t
|
||||
{
|
||||
public:
|
||||
netlist_data_memregions_t(netlist::setup_t &setup);
|
||||
|
||||
virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
|
||||
};
|
||||
|
||||
class netlist_mame_device_t;
|
||||
|
||||
class netlist_mame_t : public netlist::netlist_t
|
||||
{
|
||||
public:
|
||||
|
||||
netlist_mame_t(netlist_mame_device_t &parent, const pstring &aname)
|
||||
: netlist::netlist_t(aname),
|
||||
m_parent(parent)
|
||||
{}
|
||||
virtual ~netlist_mame_t() { };
|
||||
|
||||
inline running_machine &machine();
|
||||
|
||||
netlist_mame_device_t &parent() { return m_parent; }
|
||||
|
||||
protected:
|
||||
|
||||
void vlog(const plib::plog_level &l, const pstring &ls) const override;
|
||||
|
||||
private:
|
||||
netlist_mame_device_t &m_parent;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_device_t
|
||||
@ -141,17 +102,19 @@ public:
|
||||
// construction/destruction
|
||||
netlist_mame_device_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
netlist_mame_device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *file);
|
||||
virtual ~netlist_mame_device_t() { pstring::resetmem(); }
|
||||
virtual ~netlist_mame_device_t();
|
||||
|
||||
static void static_set_constructor(device_t &device, void (*setup_func)(netlist::setup_t &));
|
||||
|
||||
ATTR_HOT inline netlist::setup_t &setup() { return m_netlist->setup(); }
|
||||
ATTR_HOT inline netlist::setup_t &setup();
|
||||
ATTR_HOT inline netlist_mame_t &netlist() { return *m_netlist; }
|
||||
|
||||
ATTR_HOT inline const netlist::netlist_time last_time_update() { return m_old; }
|
||||
ATTR_HOT void update_time_x();
|
||||
ATTR_HOT void check_mame_abort_slice();
|
||||
|
||||
static void register_memregion_source(netlist::setup_t &setup, const char *name);
|
||||
|
||||
int m_icount;
|
||||
|
||||
protected:
|
||||
@ -184,11 +147,6 @@ private:
|
||||
void (*m_setup_func)(netlist::setup_t &);
|
||||
};
|
||||
|
||||
inline running_machine &netlist_mame_t::machine()
|
||||
{
|
||||
return m_parent.machine();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// netlist_mame_cpu_device_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -246,16 +204,7 @@ protected:
|
||||
|
||||
// device_state_interface overrides
|
||||
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override
|
||||
{
|
||||
if (entry.index() >= 0)
|
||||
{
|
||||
if (entry.index() & 1)
|
||||
str = string_format("%10.6f", *((double *)entry.dataptr()));
|
||||
else
|
||||
str = string_format("%d", *((netlist_sig_t *)entry.dataptr()));
|
||||
}
|
||||
}
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
private:
|
||||
|
||||
@ -365,19 +314,7 @@ public:
|
||||
|
||||
static void static_set_name(device_t &device, const char *param_name);
|
||||
|
||||
inline void write(const double val)
|
||||
{
|
||||
if (is_sound_device())
|
||||
{
|
||||
update_to_current_time();
|
||||
m_param->setTo(val * m_mult + m_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: use device timer ....
|
||||
m_param->setTo(val * m_mult + m_offset);
|
||||
}
|
||||
}
|
||||
void write(const double val);
|
||||
|
||||
inline DECLARE_INPUT_CHANGED_MEMBER(input_changed)
|
||||
{
|
||||
@ -399,7 +336,7 @@ protected:
|
||||
private:
|
||||
netlist::param_double_t *m_param;
|
||||
bool m_auto_port;
|
||||
pstring m_param_name;
|
||||
const char *m_param_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -425,7 +362,7 @@ protected:
|
||||
virtual void custom_netlist_additions(netlist::setup_t &setup) override;
|
||||
|
||||
private:
|
||||
pstring m_in;
|
||||
const char *m_in;
|
||||
netlist_analog_output_delegate m_delegate;
|
||||
};
|
||||
|
||||
@ -452,7 +389,7 @@ protected:
|
||||
virtual void custom_netlist_additions(netlist::setup_t &setup) override;
|
||||
|
||||
private:
|
||||
pstring m_in;
|
||||
const char *m_in;
|
||||
netlist_logic_output_delegate m_delegate;
|
||||
};
|
||||
|
||||
@ -471,12 +408,7 @@ public:
|
||||
|
||||
static void static_set_params(device_t &device, const char *param_name, const uint32_t mask, const uint32_t shift);
|
||||
|
||||
inline void write(const uint32_t val)
|
||||
{
|
||||
const uint32_t v = (val >> m_shift) & m_mask;
|
||||
if (v != (*m_param)())
|
||||
synchronize(0, v);
|
||||
}
|
||||
void write(const uint32_t val);
|
||||
|
||||
inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
|
||||
DECLARE_WRITE_LINE_MEMBER(write_line) { write(state); }
|
||||
@ -488,18 +420,13 @@ public:
|
||||
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);
|
||||
}
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
netlist::param_int_t *m_param;
|
||||
uint32_t m_mask;
|
||||
uint32_t m_shift;
|
||||
pstring m_param_name;
|
||||
const char *m_param_name;
|
||||
};
|
||||
|
||||
|
||||
@ -518,12 +445,7 @@ public:
|
||||
|
||||
static void static_set_params(device_t &device, const char *param_name, const uint32_t shift);
|
||||
|
||||
inline void write(const uint32_t val)
|
||||
{
|
||||
const uint32_t v = (val >> m_shift) & 1;
|
||||
if (v != (*m_param)())
|
||||
synchronize(0, v);
|
||||
}
|
||||
void write(const uint32_t val);
|
||||
|
||||
inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
|
||||
DECLARE_WRITE_LINE_MEMBER(write_line) { write(state); }
|
||||
@ -535,17 +457,12 @@ public:
|
||||
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);
|
||||
}
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
netlist::param_logic_t *m_param;
|
||||
uint32_t m_shift;
|
||||
pstring m_param_name;
|
||||
const char *m_param_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -568,14 +485,11 @@ public:
|
||||
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
|
||||
{
|
||||
m_data = (*m_param)();
|
||||
}
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
netlist::param_ptr_t *m_param;
|
||||
pstring m_param_name;
|
||||
const char *m_param_name;
|
||||
uint8_t* m_data;
|
||||
};
|
||||
|
||||
@ -600,7 +514,7 @@ protected:
|
||||
virtual void custom_netlist_additions(netlist::setup_t &setup) override;
|
||||
private:
|
||||
uint32_t m_channel;
|
||||
pstring m_param_name;
|
||||
const char *m_param_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -624,261 +538,9 @@ protected:
|
||||
virtual void custom_netlist_additions(netlist::setup_t &setup) override;
|
||||
private:
|
||||
uint32_t m_channel;
|
||||
pstring m_out_name;
|
||||
const char *m_out_name;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// analog_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(analog_callback) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(analog_callback)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
|
||||
}
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_last = 0.0;
|
||||
}
|
||||
|
||||
ATTR_COLD void register_callback(netlist_analog_output_delegate callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
nl_double cur = m_in();
|
||||
|
||||
// FIXME: make this a parameter
|
||||
// avoid calls due to noise
|
||||
if (std::fabs(cur - m_last) > 1e-6)
|
||||
{
|
||||
m_cpu_device->update_time_x();
|
||||
m_callback(cur, m_cpu_device->local_time());
|
||||
m_cpu_device->check_mame_abort_slice();
|
||||
m_last = cur;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
netlist::analog_input_t m_in;
|
||||
netlist_analog_output_delegate m_callback;
|
||||
netlist_mame_cpu_device_t *m_cpu_device;
|
||||
netlist::state_var<nl_double> m_last;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// logic_callback
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(logic_callback) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(logic_callback)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
, m_in(*this, "IN")
|
||||
, m_cpu_device(nullptr)
|
||||
, m_last(*this, "m_last", 0)
|
||||
{
|
||||
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
|
||||
}
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_last = 0;
|
||||
}
|
||||
|
||||
ATTR_COLD void register_callback(netlist_logic_output_delegate callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
netlist_sig_t cur = m_in();
|
||||
|
||||
// FIXME: make this a parameter
|
||||
// avoid calls due to noise
|
||||
if (cur != m_last)
|
||||
{
|
||||
m_cpu_device->update_time_x();
|
||||
m_callback(cur, m_cpu_device->local_time());
|
||||
m_cpu_device->check_mame_abort_slice();
|
||||
m_last = cur;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
netlist::logic_input_t m_in;
|
||||
netlist_logic_output_delegate m_callback;
|
||||
netlist_mame_cpu_device_t *m_cpu_device;
|
||||
netlist::state_var<netlist_sig_t> m_last;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// sound_out
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(sound_out) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(sound_out)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: netlist::device_t(anetlist, name)
|
||||
, 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())
|
||||
{
|
||||
}
|
||||
|
||||
static const int BUFSIZE = 2048;
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_cur = 0.0;
|
||||
m_last_pos = 0;
|
||||
m_last_buffer = netlist::netlist_time::zero();
|
||||
}
|
||||
|
||||
ATTR_HOT void sound_update(const netlist::netlist_time &upto)
|
||||
{
|
||||
int pos = (upto - m_last_buffer) / m_sample;
|
||||
if (pos >= BUFSIZE)
|
||||
netlist().log().fatal("sound {1}: exceeded BUFSIZE\n", name().c_str());
|
||||
while (m_last_pos < pos )
|
||||
{
|
||||
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
|
||||
}
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
nl_double val = m_in() * m_mult() + m_offset();
|
||||
sound_update(netlist().time());
|
||||
/* ignore spikes */
|
||||
if (std::abs(val) < 32767.0)
|
||||
m_cur = val;
|
||||
else if (val > 0.0)
|
||||
m_cur = 32767.0;
|
||||
else
|
||||
m_cur = -32767.0;
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
ATTR_HOT void buffer_reset(const netlist::netlist_time &upto)
|
||||
{
|
||||
m_last_pos = 0;
|
||||
m_last_buffer = upto;
|
||||
m_cur = 0.0;
|
||||
}
|
||||
|
||||
netlist::param_int_t m_channel;
|
||||
netlist::param_double_t m_mult;
|
||||
netlist::param_double_t m_offset;
|
||||
stream_sample_t *m_buffer;
|
||||
netlist::netlist_time m_sample;
|
||||
|
||||
private:
|
||||
netlist::analog_input_t m_in;
|
||||
double m_cur;
|
||||
int m_last_pos;
|
||||
netlist::state_var<netlist::netlist_time> m_last_buffer;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// sound_in
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(sound_in) : public netlist::device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(sound_in)(netlist::netlist_t &anetlist, const pstring &name)
|
||||
: netlist::device_t(anetlist, name)
|
||||
, m_feedback(*this, "FB") // clock part
|
||||
, m_Q(*this, "Q")
|
||||
{
|
||||
connect(m_feedback, m_Q);
|
||||
m_inc = netlist::netlist_time::from_nsec(1);
|
||||
|
||||
|
||||
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
|
||||
{
|
||||
m_param_name[i] = std::make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
|
||||
m_param_mult[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
|
||||
m_param_offset[i] = std::make_unique<netlist::param_double_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
|
||||
}
|
||||
m_num_channel = 0;
|
||||
}
|
||||
|
||||
static const int MAX_INPUT_CHANNELS = 10;
|
||||
|
||||
ATTR_COLD void reset() override
|
||||
{
|
||||
m_pos = 0;
|
||||
for (auto & elem : m_buffer)
|
||||
elem = nullptr;
|
||||
}
|
||||
|
||||
ATTR_COLD int resolve()
|
||||
{
|
||||
m_pos = 0;
|
||||
for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
|
||||
{
|
||||
if ((*m_param_name[i])() != pstring(""))
|
||||
{
|
||||
if (i != m_num_channel)
|
||||
netlist().log().fatal("sound input numbering has to be sequential!");
|
||||
m_num_channel++;
|
||||
m_param[i] = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_param_name[i])(), true));
|
||||
}
|
||||
}
|
||||
return m_num_channel;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
for (int i=0; i<m_num_channel; i++)
|
||||
{
|
||||
if (m_buffer[i] == nullptr)
|
||||
break; // stop, called outside of stream_update
|
||||
const nl_double v = m_buffer[i][m_pos];
|
||||
m_param[i]->setTo(v * (*m_param_mult[i])() + (*m_param_offset[i])());
|
||||
}
|
||||
m_pos++;
|
||||
m_Q.push(!m_Q.net().new_Q(), m_inc );
|
||||
}
|
||||
|
||||
public:
|
||||
ATTR_HOT void buffer_reset()
|
||||
{
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<netlist::param_str_t> m_param_name[MAX_INPUT_CHANNELS];
|
||||
netlist::param_double_t *m_param[MAX_INPUT_CHANNELS];
|
||||
stream_sample_t *m_buffer[MAX_INPUT_CHANNELS];
|
||||
std::unique_ptr<netlist::param_double_t> m_param_mult[MAX_INPUT_CHANNELS];
|
||||
std::unique_ptr<netlist::param_double_t> m_param_offset[MAX_INPUT_CHANNELS];
|
||||
netlist::netlist_time m_inc;
|
||||
|
||||
private:
|
||||
netlist::logic_input_t m_feedback;
|
||||
netlist::logic_output_t m_Q;
|
||||
|
||||
int m_pos;
|
||||
int m_num_channel;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type NETLIST_CORE;
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "solver/nld_solver.h"
|
||||
#include "analog/nld_bjt.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
#include <cmath>
|
||||
@ -15,6 +15,7 @@ namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
|
||||
class diode
|
||||
{
|
||||
public:
|
||||
@ -42,6 +43,242 @@ private:
|
||||
nl_double m_VT_inv;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_Q - Base classes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/* FIXME: Make table pretty */
|
||||
|
||||
/*! Class representing the bjt model paramers.
|
||||
* This is the model representation of the bjt model. Typically, SPICE uses
|
||||
* the following parameters. A "Y" in the first column indicates that the
|
||||
* parameter is actually used in netlist.
|
||||
*
|
||||
* |NL? |name |parameter |units|default| example|area |
|
||||
* |:--:|:-----|:--------------------------------|:----|------:|-------:|:----:|
|
||||
* | Y |IS |transport saturation current|A |1E-016|1E-015|* |
|
||||
* | Y |BF |ideal maximum forward beta|- |100|100| |
|
||||
* | Y |NF |forward current emission coefficient|- |1|1| |
|
||||
* | |VAF |forward Early voltage|V |infinite |200| |
|
||||
* | |IKF |corner for forward beta high current roll-off|A |infinite |0.01|* |
|
||||
* | |ISE |B-E leakage saturation current|A |0|0.0000000000001|* |
|
||||
* | |NE |B-E leakage emission coefficient|- |1.5|2| |
|
||||
* | Y |BR |ideal maximum reverse beta |- |1|0.1| |
|
||||
* | Y |NR |reverse current emission coefficient|- |1|1| |
|
||||
* | |VAR |reverse Early voltage|V |infinite |200| |
|
||||
* | |IKR |corner for reverse beta high current roll-off|A |infinite |0.01|* |
|
||||
* | |ISC |leakage saturation current|A |0|8| |
|
||||
* | |NC |leakage emission coefficient|- |2|1.5| |
|
||||
* | |RB |zero bias base resistance| |0|100|* |
|
||||
* | |IRB |current where base resistance falls halfway to its min value|A |infinte |0.1|* |
|
||||
* | |RBM |minimum base resistance at high currents| |RB |10|* |
|
||||
* | |RE |emitter resistance| |0|1|* |
|
||||
* | |RC |collector resistance | |0|10|* |
|
||||
* | |CJE |B-E zero-bias depletion capacitance|F |0|2pF |* |
|
||||
* | |VJE |B-E built-in potential|V |0.75|0.6| |
|
||||
* | |MJE |B-E junction exponential factor |- |0.33|0.33| |
|
||||
* | |TF |ideal forward transit time |sec |0|0.1ns | |
|
||||
* | |XTF|coefficient for bias dependence of TF |- |0| | |
|
||||
* | |VTF |voltage describing VBC dependence of TF |V |infinite | | |
|
||||
* | |ITF |high-current parameter for effect on TF |A |0| |* |
|
||||
* | |PTF |excess phase at freq=1.0/(TF*2PI) Hz |deg |0| | |
|
||||
* | |CJC |B-C zero-bias depletion capacitance |F |0|2pF |* |
|
||||
* | |VJC |B-C built-in potential |V |0.75|0.5| |
|
||||
* | |MJC |B-C junction exponential factor |- |0.33|0.5| |
|
||||
* | |XCJC |fraction of B-C depletion capacitance connected to internal base node |- |1| | |
|
||||
* | |TR |ideal reverse transit time |sec |0|10ns | |
|
||||
* | |CJS |zero-bias collector-substrate capacitance |F |0|2pF |* |
|
||||
* | |VJS |substrate junction built-in potential |V |0.75| | |
|
||||
* | |MJS |substrate junction exponential factor |- |0|0.5| |
|
||||
* | |XTB |forward and reverse beta temperature exponent |- |0| | |
|
||||
* | |EG|energy gap for temperature effect on IS |eV |1.11| | |
|
||||
* | |XTI|temperature exponent for effect on IS |- |3| | |
|
||||
* | |KF |flicker-noise coefficient |- |0| | |
|
||||
* | |AF |flicker-noise exponent |- |1| | |
|
||||
* | |FC |coefficient for forward-bias depletion capacitance formula |- |0.5| | |
|
||||
* | |TNOM |Parameter measurement temperature |C |27|50| |
|
||||
*/
|
||||
|
||||
class bjt_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
bjt_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_IS(*this, "IS")
|
||||
, m_BF(*this, "BF")
|
||||
, m_NF(*this, "NF")
|
||||
, m_BR(*this, "BR")
|
||||
, m_NR(*this, "NR")
|
||||
{}
|
||||
|
||||
value_t m_IS; //!< transport saturation current
|
||||
value_t m_BF; //!< ideal maximum forward beta
|
||||
value_t m_NF; //!< forward current emission coefficient
|
||||
value_t m_BR; //!< ideal maximum reverse beta
|
||||
value_t m_NR; //!< reverse current emission coefficient
|
||||
};
|
||||
|
||||
// Have a common start for transistors
|
||||
|
||||
NETLIB_OBJECT(Q)
|
||||
{
|
||||
public:
|
||||
enum q_type {
|
||||
BJT_NPN,
|
||||
BJT_PNP
|
||||
};
|
||||
|
||||
NETLIB_CONSTRUCTOR(Q)
|
||||
, m_model(*this, "MODEL", "")
|
||||
, m_qtype(BJT_NPN)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
|
||||
//NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
inline q_type qtype() const { return m_qtype; }
|
||||
inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
|
||||
inline void set_qtype(q_type atype) { m_qtype = atype; }
|
||||
protected:
|
||||
|
||||
bjt_model_t m_model;
|
||||
private:
|
||||
q_type m_qtype;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT, Q)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_QBJT_switch
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* + - C
|
||||
* B ----VVV----+ |
|
||||
* | |
|
||||
* Rb Rc
|
||||
* Rb Rc
|
||||
* Rb Rc
|
||||
* | |
|
||||
* +----+----+
|
||||
* |
|
||||
* E
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT)
|
||||
, m_RB(*this, "m_RB", true)
|
||||
, m_RC(*this, "m_RC", true)
|
||||
, m_BC_dummy(*this, "m_BC", true)
|
||||
, m_gB(NETLIST_GMIN_DEFAULT)
|
||||
, m_gC(NETLIST_GMIN_DEFAULT)
|
||||
, m_V(0.0)
|
||||
, m_state_on(*this, "m_state_on", 0)
|
||||
{
|
||||
register_subalias("B", m_RB.m_P);
|
||||
register_subalias("E", m_RB.m_N);
|
||||
register_subalias("C", m_RC.m_P);
|
||||
//register_term("_E1", m_RC.m_N);
|
||||
|
||||
//register_term("_B1", m_BC_dummy.m_P);
|
||||
//register_term("_C1", m_BC_dummy.m_N);
|
||||
|
||||
connect(m_RB.m_N, m_RC.m_N);
|
||||
|
||||
connect(m_RB.m_P, m_BC_dummy.m_P);
|
||||
connect(m_RC.m_P, m_BC_dummy.m_N);
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
nld_twoterm m_RB;
|
||||
nld_twoterm m_RC;
|
||||
|
||||
// FIXME: this is needed so we have all terminals belong to one net list
|
||||
|
||||
nld_twoterm m_BC_dummy;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
nl_double m_gB; // base conductance / switch on
|
||||
nl_double m_gC; // collector conductance / switch on
|
||||
nl_double m_V; // internal voltage source
|
||||
state_var<unsigned> m_state_on;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_QBJT_EB
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
|
||||
, 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
|
||||
|
||||
register_subalias("C", m_D_CB.m_P); // Cathode
|
||||
//register_term("_B1", m_D_CB.m_N); // Anode
|
||||
|
||||
//register_term("_E1", m_D_EC.m_P);
|
||||
//register_term("_C1", m_D_EC.m_N);
|
||||
|
||||
connect(m_D_EB.m_P, m_D_EC.m_P);
|
||||
connect(m_D_EB.m_N, m_D_CB.m_N);
|
||||
connect(m_D_CB.m_P, m_D_EC.m_N);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
generic_diode m_gD_BC;
|
||||
generic_diode m_gD_BE;
|
||||
|
||||
private:
|
||||
nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
|
||||
nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
|
||||
nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
|
||||
|
||||
nl_double m_alpha_f;
|
||||
nl_double m_alpha_r;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -8,15 +8,12 @@
|
||||
#ifndef NLD_BJT_H_
|
||||
#define NLD_BJT_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nld_twoterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define QBJT_SW(name, model) \
|
||||
NET_REGISTER_DEV(QBJT_SW, name) \
|
||||
NETDEV_PARAMI(name, MODEL, model)
|
||||
@ -25,250 +22,4 @@
|
||||
NET_REGISTER_DEV(QBJT_EB, name) \
|
||||
NETDEV_PARAMI(name, MODEL, model)
|
||||
|
||||
#endif
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_Q - Base classes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/* FIXME: Make table pretty */
|
||||
|
||||
/*! Class representing the bjt model paramers.
|
||||
* This is the model representation of the bjt model. Typically, SPICE uses
|
||||
* the following parameters. A "Y" in the first column indicates that the
|
||||
* parameter is actually used in netlist.
|
||||
*
|
||||
* |NL? |name |parameter |units|default| example|area |
|
||||
* |:--:|:-----|:--------------------------------|:----|------:|-------:|:----:|
|
||||
* | Y |IS |transport saturation current|A |1E-016|1E-015|* |
|
||||
* | Y |BF |ideal maximum forward beta|- |100|100| |
|
||||
* | Y |NF |forward current emission coefficient|- |1|1| |
|
||||
* | |VAF |forward Early voltage|V |infinite |200| |
|
||||
* | |IKF |corner for forward beta high current roll-off|A |infinite |0.01|* |
|
||||
* | |ISE |B-E leakage saturation current|A |0|0.0000000000001|* |
|
||||
* | |NE |B-E leakage emission coefficient|- |1.5|2| |
|
||||
* | Y |BR |ideal maximum reverse beta |- |1|0.1| |
|
||||
* | Y |NR |reverse current emission coefficient|- |1|1| |
|
||||
* | |VAR |reverse Early voltage|V |infinite |200| |
|
||||
* | |IKR |corner for reverse beta high current roll-off|A |infinite |0.01|* |
|
||||
* | |ISC |leakage saturation current|A |0|8| |
|
||||
* | |NC |leakage emission coefficient|- |2|1.5| |
|
||||
* | |RB |zero bias base resistance| |0|100|* |
|
||||
* | |IRB |current where base resistance falls halfway to its min value|A |infinte |0.1|* |
|
||||
* | |RBM |minimum base resistance at high currents| |RB |10|* |
|
||||
* | |RE |emitter resistance| |0|1|* |
|
||||
* | |RC |collector resistance | |0|10|* |
|
||||
* | |CJE |B-E zero-bias depletion capacitance|F |0|2pF |* |
|
||||
* | |VJE |B-E built-in potential|V |0.75|0.6| |
|
||||
* | |MJE |B-E junction exponential factor |- |0.33|0.33| |
|
||||
* | |TF |ideal forward transit time |sec |0|0.1ns | |
|
||||
* | |XTF|coefficient for bias dependence of TF |- |0| | |
|
||||
* | |VTF |voltage describing VBC dependence of TF |V |infinite | | |
|
||||
* | |ITF |high-current parameter for effect on TF |A |0| |* |
|
||||
* | |PTF |excess phase at freq=1.0/(TF*2PI) Hz |deg |0| | |
|
||||
* | |CJC |B-C zero-bias depletion capacitance |F |0|2pF |* |
|
||||
* | |VJC |B-C built-in potential |V |0.75|0.5| |
|
||||
* | |MJC |B-C junction exponential factor |- |0.33|0.5| |
|
||||
* | |XCJC |fraction of B-C depletion capacitance connected to internal base node |- |1| | |
|
||||
* | |TR |ideal reverse transit time |sec |0|10ns | |
|
||||
* | |CJS |zero-bias collector-substrate capacitance |F |0|2pF |* |
|
||||
* | |VJS |substrate junction built-in potential |V |0.75| | |
|
||||
* | |MJS |substrate junction exponential factor |- |0|0.5| |
|
||||
* | |XTB |forward and reverse beta temperature exponent |- |0| | |
|
||||
* | |EG|energy gap for temperature effect on IS |eV |1.11| | |
|
||||
* | |XTI|temperature exponent for effect on IS |- |3| | |
|
||||
* | |KF |flicker-noise coefficient |- |0| | |
|
||||
* | |AF |flicker-noise exponent |- |1| | |
|
||||
* | |FC |coefficient for forward-bias depletion capacitance formula |- |0.5| | |
|
||||
* | |TNOM |Parameter measurement temperature |C |27|50| |
|
||||
*/
|
||||
|
||||
class bjt_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
bjt_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_IS(*this, "IS")
|
||||
, m_BF(*this, "BF")
|
||||
, m_NF(*this, "NF")
|
||||
, m_BR(*this, "BR")
|
||||
, m_NR(*this, "NR")
|
||||
{}
|
||||
|
||||
value_t m_IS; //!< transport saturation current
|
||||
value_t m_BF; //!< ideal maximum forward beta
|
||||
value_t m_NF; //!< forward current emission coefficient
|
||||
value_t m_BR; //!< ideal maximum reverse beta
|
||||
value_t m_NR; //!< reverse current emission coefficient
|
||||
};
|
||||
|
||||
// Have a common start for transistors
|
||||
|
||||
NETLIB_OBJECT(Q)
|
||||
{
|
||||
public:
|
||||
enum q_type {
|
||||
BJT_NPN,
|
||||
BJT_PNP
|
||||
};
|
||||
|
||||
NETLIB_CONSTRUCTOR(Q)
|
||||
, m_model(*this, "MODEL", "")
|
||||
, m_qtype(BJT_NPN)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
|
||||
//NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
inline q_type qtype() const { return m_qtype; }
|
||||
inline bool is_qtype(q_type atype) const { return m_qtype == atype; }
|
||||
inline void set_qtype(q_type atype) { m_qtype = atype; }
|
||||
protected:
|
||||
|
||||
bjt_model_t m_model;
|
||||
private:
|
||||
q_type m_qtype;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT, Q)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT, Q)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_QBJT_switch
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* + - C
|
||||
* B ----VVV----+ |
|
||||
* | |
|
||||
* Rb Rc
|
||||
* Rb Rc
|
||||
* Rb Rc
|
||||
* | |
|
||||
* +----+----+
|
||||
* |
|
||||
* E
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT)
|
||||
, m_RB(*this, "m_RB", true)
|
||||
, m_RC(*this, "m_RC", true)
|
||||
, m_BC_dummy(*this, "m_BC", true)
|
||||
, m_gB(NETLIST_GMIN_DEFAULT)
|
||||
, m_gC(NETLIST_GMIN_DEFAULT)
|
||||
, m_V(0.0)
|
||||
, m_state_on(*this, "m_state_on", 0)
|
||||
{
|
||||
register_subalias("B", m_RB.m_P);
|
||||
register_subalias("E", m_RB.m_N);
|
||||
register_subalias("C", m_RC.m_P);
|
||||
//register_term("_E1", m_RC.m_N);
|
||||
|
||||
//register_term("_B1", m_BC_dummy.m_P);
|
||||
//register_term("_C1", m_BC_dummy.m_N);
|
||||
|
||||
connect(m_RB.m_N, m_RC.m_N);
|
||||
|
||||
connect(m_RB.m_P, m_BC_dummy.m_P);
|
||||
connect(m_RC.m_P, m_BC_dummy.m_N);
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
nld_twoterm m_RB;
|
||||
nld_twoterm m_RC;
|
||||
|
||||
// FIXME: this is needed so we have all terminals belong to one net list
|
||||
|
||||
nld_twoterm m_BC_dummy;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
nl_double m_gB; // base conductance / switch on
|
||||
nl_double m_gC; // collector conductance / switch on
|
||||
nl_double m_V; // internal voltage source
|
||||
state_var<unsigned> m_state_on;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_QBJT_EB
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
|
||||
, 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
|
||||
|
||||
register_subalias("C", m_D_CB.m_P); // Cathode
|
||||
//register_term("_B1", m_D_CB.m_N); // Anode
|
||||
|
||||
//register_term("_E1", m_D_EC.m_P);
|
||||
//register_term("_C1", m_D_EC.m_N);
|
||||
|
||||
connect(m_D_EB.m_P, m_D_EC.m_P);
|
||||
connect(m_D_EB.m_N, m_D_CB.m_N);
|
||||
connect(m_D_CB.m_P, m_D_EC.m_N);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
generic_diode m_gD_BC;
|
||||
generic_diode m_gD_BE;
|
||||
|
||||
private:
|
||||
nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
|
||||
nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
|
||||
nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
|
||||
|
||||
nl_double m_alpha_f;
|
||||
nl_double m_alpha_r;
|
||||
|
||||
};
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_BJT_H_ */
|
||||
|
@ -9,13 +9,11 @@
|
||||
#define NLD_FOURTERM_H_
|
||||
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nld_twoterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
// ----------------------------------------------------------------------------------------
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define VCCS(name) \
|
||||
NET_REGISTER_DEV(VCCS, name)
|
||||
@ -29,206 +27,4 @@
|
||||
#define LVCCS(name) \
|
||||
NET_REGISTER_DEV(LVCCS, name)
|
||||
|
||||
#endif
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled current source
|
||||
*
|
||||
* IP ---+ +------> OP
|
||||
* | |
|
||||
* RI I
|
||||
* RI => G => I IOut = (V(IP)-V(IN)) * G
|
||||
* RI I
|
||||
* | |
|
||||
* IN ---+ +------< ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1A
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT(VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR(VCCS)
|
||||
, m_G(*this, "G", 1.0)
|
||||
, m_RI(*this, "RI", 1e9)
|
||||
, m_OP(*this, "OP")
|
||||
, m_ON(*this, "ON")
|
||||
, m_IP(*this, "IP")
|
||||
, m_IN(*this, "IN")
|
||||
, m_OP1(*this, "_OP1")
|
||||
, m_ON1(*this, "_ON1")
|
||||
, m_gfac(1.0)
|
||||
{
|
||||
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
|
||||
m_OP.m_otherterm = &m_IP;
|
||||
m_OP1.m_otherterm = &m_IN;
|
||||
|
||||
m_ON.m_otherterm = &m_IP;
|
||||
m_ON1.m_otherterm = &m_IN;
|
||||
|
||||
connect(m_OP, m_OP1);
|
||||
connect(m_ON, m_ON1);
|
||||
m_gfac = NL_FCONST(1.0);
|
||||
}
|
||||
|
||||
param_double_t m_G;
|
||||
param_double_t m_RI;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI()
|
||||
{
|
||||
NETLIB_NAME(VCCS)::reset();
|
||||
}
|
||||
|
||||
terminal_t m_OP;
|
||||
terminal_t m_ON;
|
||||
|
||||
terminal_t m_IP;
|
||||
terminal_t m_IN;
|
||||
|
||||
terminal_t m_OP1;
|
||||
terminal_t m_ON1;
|
||||
|
||||
nl_double m_gfac;
|
||||
};
|
||||
|
||||
/* Limited Current source*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(LVCCS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(LVCCS, VCCS)
|
||||
, m_cur_limit(*this, "CURLIM", 1000.0)
|
||||
, m_vi(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
|
||||
param_double_t m_cur_limit; /* current limit */
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
nl_double m_vi;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_CCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Current controlled current source
|
||||
*
|
||||
* IP ---+ +------> OP
|
||||
* | |
|
||||
* RI I
|
||||
* RI => G => I IOut = (V(IP)-V(IN)) / RI * G
|
||||
* RI I
|
||||
* | |
|
||||
* IN ---+ +------< ON
|
||||
*
|
||||
* G=1 ==> 1A ==> 1A
|
||||
*
|
||||
* RI = 1
|
||||
*
|
||||
* This needs high levels of accuracy to work with 1 Ohm RI.
|
||||
*
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(CCCS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS)
|
||||
, m_gfac(1.0)
|
||||
{
|
||||
m_gfac = NL_FCONST(1.0) / m_RI();
|
||||
}
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
nl_double m_gfac;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCVS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled voltage source
|
||||
*
|
||||
* Parameters:
|
||||
* G Default: 1
|
||||
* RO Default: 1 (would be typically 50 for an op-amp
|
||||
*
|
||||
* IP ---+ +--+---- OP
|
||||
* | | |
|
||||
* RI I RO
|
||||
* RI => G => I RO V(OP) - V(ON) = (V(IP)-V(IN)) * G
|
||||
* RI I RO
|
||||
* | | |
|
||||
* IN ---+ +--+---- ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1V
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
* Internal GI = G / RO
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
NETLIB_OBJECT_DERIVED(VCVS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS)
|
||||
, m_RO(*this, "RO", 1.0)
|
||||
, m_OP2(*this, "_OP2")
|
||||
, m_ON2(*this, "_ON2")
|
||||
{
|
||||
m_OP2.m_otherterm = &m_ON2;
|
||||
m_ON2.m_otherterm = &m_OP2;
|
||||
|
||||
connect(m_OP2, m_OP1);
|
||||
connect(m_ON2, m_ON1);
|
||||
}
|
||||
|
||||
param_double_t m_RO;
|
||||
|
||||
protected:
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
//NETLIB_UPDATE_PARAMI();
|
||||
|
||||
terminal_t m_OP2;
|
||||
terminal_t m_ON2;
|
||||
|
||||
};
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
|
||||
#endif /* NLD_FOURTERM_H_ */
|
||||
|
@ -5,10 +5,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "devices/net_lib.h"
|
||||
|
||||
#include "nld_opamps.h"
|
||||
#include "nl_base.h"
|
||||
#include "nl_errstr.h"
|
||||
#include "nlid_twoterm.h"
|
||||
#include "nlid_fourterm.h"
|
||||
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -45,6 +47,61 @@ namespace netlist
|
||||
*
|
||||
* */
|
||||
|
||||
/*! Class representing the opamp model parameters.
|
||||
* The opamp model was designed based on designs from
|
||||
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm.
|
||||
* Currently 2 different types are supported: Type 1 and Type 3. Type 1
|
||||
* is less complex and should run faster than Type 3.
|
||||
*
|
||||
* This is an extension to the traditional SPICE approach which
|
||||
* assumes that you will be using an manufacturer model. These models may
|
||||
* have copyrights incompatible with the netlist license. Thus they may not
|
||||
* be suitable for certain implementations of netlist.
|
||||
*
|
||||
* For the typical use cases in low frequency (< 100 KHz) applications at
|
||||
* which netlist is targeted, this model is certainly suitable. All parameters
|
||||
* can be determined from a typical opamp datasheet.
|
||||
*
|
||||
* |Type|name |parameter |units|default| example|
|
||||
* |:--:|:-----|:----------------------------------------------|:----|------:|-------:|
|
||||
* | 3 |TYPE |Model Type, 1 and 3 are supported | | | |
|
||||
* |1,3 |FPF |frequency of first pole |Hz | |100 |
|
||||
* | 3 |SLEW |unity gain slew rate |V/s | | 1|
|
||||
* |1,3 |RI |input resistance |Ohm | |1M |
|
||||
* |1,3 |RO |output resistance |Ohm | |50 |
|
||||
* |1,3 |UGF |unity gain frequency (transition frequency) |Hz | |1000 |
|
||||
* | 3 |VLL |low output swing minus low supply rail |V | |1.5 |
|
||||
* | 3 |VLH |high supply rail minus high output swing |V | |1.5 |
|
||||
* | 3 |DAB |Differential Amp Bias - total quiescent current|A | |0.001 |
|
||||
*/
|
||||
|
||||
class opamp_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
opamp_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_TYPE(*this, "TYPE")
|
||||
, m_FPF(*this, "FPF")
|
||||
, m_SLEW(*this, "SLEW")
|
||||
, m_RI(*this, "RI")
|
||||
, m_RO(*this, "RO")
|
||||
, m_UGF(*this, "UGF")
|
||||
, m_VLL(*this, "VLL")
|
||||
, m_VLH(*this, "VLH")
|
||||
, m_DAB(*this, "DAB")
|
||||
{}
|
||||
|
||||
value_t m_TYPE; //!< Model Type, 1 and 3 are supported
|
||||
value_t m_FPF; //!< frequency of first pole
|
||||
value_t m_SLEW; //!< unity gain slew rate
|
||||
value_t m_RI; //!< input resistance
|
||||
value_t m_RO; //!< output resistance
|
||||
value_t m_UGF; //!< unity gain frequency (transition frequency)
|
||||
value_t m_VLL; //!< low output swing minus low supply rail
|
||||
value_t m_VLH; //!< high supply rail minus high output swing
|
||||
value_t m_DAB; //!< Differential Amp Bias - total quiescent current
|
||||
};
|
||||
|
||||
|
||||
NETLIB_OBJECT(opamp)
|
||||
{
|
||||
|
@ -10,87 +10,15 @@
|
||||
#ifndef NLD_OPAMPS_H_
|
||||
#define NLD_OPAMPS_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nld_twoterm.h"
|
||||
#include "nld_fourterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define OPAMP(name, model) \
|
||||
NET_REGISTER_DEV(OPAMP, name) \
|
||||
NETDEV_PARAMI(name, MODEL, model)
|
||||
|
||||
#endif
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Devices ...
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
|
||||
/*! Class representing the opamp model parameters.
|
||||
* The opamp model was designed based on designs from
|
||||
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm.
|
||||
* Currently 2 different types are supported: Type 1 and Type 3. Type 1
|
||||
* is less complex and should run faster than Type 3.
|
||||
*
|
||||
* This is an extension to the traditional SPICE approach which
|
||||
* assumes that you will be using an manufacturer model. These models may
|
||||
* have copyrights incompatible with the netlist license. Thus they may not
|
||||
* be suitable for certain implementations of netlist.
|
||||
*
|
||||
* For the typical use cases in low frequency (< 100 KHz) applications at
|
||||
* which netlist is targeted, this model is certainly suitable. All parameters
|
||||
* can be determined from a typical opamp datasheet.
|
||||
*
|
||||
* |Type|name |parameter |units|default| example|
|
||||
* |:--:|:-----|:----------------------------------------------|:----|------:|-------:|
|
||||
* | 3 |TYPE |Model Type, 1 and 3 are supported | | | |
|
||||
* |1,3 |FPF |frequency of first pole |Hz | |100 |
|
||||
* | 3 |SLEW |unity gain slew rate |V/s | | 1|
|
||||
* |1,3 |RI |input resistance |Ohm | |1M |
|
||||
* |1,3 |RO |output resistance |Ohm | |50 |
|
||||
* |1,3 |UGF |unity gain frequency (transition frequency) |Hz | |1000 |
|
||||
* | 3 |VLL |low output swing minus low supply rail |V | |1.5 |
|
||||
* | 3 |VLH |high supply rail minus high output swing |V | |1.5 |
|
||||
* | 3 |DAB |Differential Amp Bias - total quiescent current|A | |0.001 |
|
||||
*/
|
||||
|
||||
class opamp_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
opamp_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_TYPE(*this, "TYPE")
|
||||
, m_FPF(*this, "FPF")
|
||||
, m_SLEW(*this, "SLEW")
|
||||
, m_RI(*this, "RI")
|
||||
, m_RO(*this, "RO")
|
||||
, m_UGF(*this, "UGF")
|
||||
, m_VLL(*this, "VLL")
|
||||
, m_VLH(*this, "VLH")
|
||||
, m_DAB(*this, "DAB")
|
||||
{}
|
||||
|
||||
value_t m_TYPE; //!< Model Type, 1 and 3 are supported
|
||||
value_t m_FPF; //!< frequency of first pole
|
||||
value_t m_SLEW; //!< unity gain slew rate
|
||||
value_t m_RI; //!< input resistance
|
||||
value_t m_RO; //!< output resistance
|
||||
value_t m_UGF; //!< unity gain frequency (transition frequency)
|
||||
value_t m_VLL; //!< low output swing minus low supply rail
|
||||
value_t m_VLH; //!< high supply rail minus high output swing
|
||||
value_t m_DAB; //!< Differential Amp Bias - total quiescent current
|
||||
};
|
||||
|
||||
|
||||
} //namespace analog
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_OPAMPS_H_ */
|
||||
|
@ -5,8 +5,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nld_switches.h"
|
||||
#include "nl_setup.h"
|
||||
#include "nlid_twoterm.h"
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
|
||||
#define R_OFF (1.0 / netlist().gmin())
|
||||
#define R_ON 0.01
|
||||
|
@ -10,21 +10,16 @@
|
||||
#ifndef NLD_SWITCHES_H_
|
||||
#define NLD_SWITCHES_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nld_twoterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define SWITCH(name) \
|
||||
NET_REGISTER_DEV(SWITCH, name)
|
||||
|
||||
#define SWITCH2(name) \
|
||||
NET_REGISTER_DEV(SWITCH2, name)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* NLD_SWITCHES_H_ */
|
||||
|
@ -1,47 +1,15 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nld_twoterm.h
|
||||
*
|
||||
* Devices with two terminals ...
|
||||
*
|
||||
*
|
||||
* (k)
|
||||
* +-----T-----+
|
||||
* | | |
|
||||
* | +--+--+ |
|
||||
* | | | |
|
||||
* | R | |
|
||||
* | R | |
|
||||
* | R I |
|
||||
* | | I | Device n
|
||||
* | V+ I |
|
||||
* | V | |
|
||||
* | V- | |
|
||||
* | | | |
|
||||
* | +--+--+ |
|
||||
* | | |
|
||||
* +-----T-----+
|
||||
* (l)
|
||||
*
|
||||
* This is a resistance in series to a voltage source and paralleled by a
|
||||
* current source. This is suitable to model voltage sources, current sources,
|
||||
* resistors, capacitors, inductances and diodes.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NLD_TWOTERM_H_
|
||||
#define NLD_TWOTERM_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "plib/pfunction.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define RES(name, p_R) \
|
||||
NET_REGISTER_DEV(RES, name) \
|
||||
NETDEV_PARAMI(name, R, p_R)
|
||||
@ -77,8 +45,6 @@
|
||||
NET_REGISTER_DEV(CS, name) \
|
||||
NETDEV_PARAMI(name, I, pI)
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Generic macros
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -100,412 +66,4 @@
|
||||
#define IND_P(ind) (static_cast<double>(ind) * 1e-12)
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_twoterm
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT(twoterm)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false)
|
||||
, m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1")
|
||||
, m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2")
|
||||
{
|
||||
m_P.m_otherterm = &m_N;
|
||||
m_N.m_otherterm = &m_P;
|
||||
}
|
||||
|
||||
terminal_t m_P;
|
||||
terminal_t m_N;
|
||||
|
||||
//NETLIB_UPDATE_TERMINALSI() { }
|
||||
//NETLIB_RESETI() { }
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
/* inline */ void set(const nl_double G, const nl_double V, const nl_double I)
|
||||
{
|
||||
/* GO, GT, I */
|
||||
m_P.set( G, G, ( V) * G - I);
|
||||
m_N.set( G, G, ( -V) * G + I);
|
||||
}
|
||||
|
||||
/* inline */ nl_double deltaV() const
|
||||
{
|
||||
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
|
||||
}
|
||||
|
||||
void set_mat(const nl_double a11, const nl_double a12, const nl_double r1,
|
||||
const nl_double a21, const nl_double a22, const nl_double r2)
|
||||
{
|
||||
/* GO, GT, I */
|
||||
m_P.set(-a12, a11, r1);
|
||||
m_N.set(-a21, a22, r2);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class C>
|
||||
static core_device_t &bselect(bool b, C &d1, core_device_t &d2)
|
||||
{
|
||||
core_device_t *h = dynamic_cast<core_device_t *>(&d1);
|
||||
return b ? *h : d2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_R
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(R_base, twoterm)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(R_base, twoterm)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline void set_R(const nl_double R)
|
||||
{
|
||||
const nl_double G = NL_FCONST(1.0) / R;
|
||||
set_mat( G, -G, 0.0,
|
||||
-G, G, 0.0);
|
||||
}
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(R, R_base)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(R, R_base)
|
||||
, m_R(*this, "R", 1e9)
|
||||
{
|
||||
}
|
||||
|
||||
param_double_t m_R;
|
||||
|
||||
protected:
|
||||
|
||||
NETLIB_RESETI();
|
||||
//NETLIB_UPDATEI() { }
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
/* protect set_R ... it's a recipe to desaster when used to bypass the parameter */
|
||||
using NETLIB_NAME(R_base)::set_R;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_POT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT(POT)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(POT)
|
||||
, m_R1(*this, "_R1")
|
||||
, m_R2(*this, "_R2")
|
||||
, m_R(*this, "R", 10000)
|
||||
, m_Dial(*this, "DIAL", 0.5)
|
||||
, m_DialIsLog(*this, "DIALLOG", 0)
|
||||
{
|
||||
register_subalias("1", m_R1.m_P);
|
||||
register_subalias("2", m_R1.m_N);
|
||||
register_subalias("3", m_R2.m_N);
|
||||
|
||||
connect(m_R2.m_P, m_R1.m_N);
|
||||
|
||||
}
|
||||
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
NETLIB_SUB(R_base) m_R1;
|
||||
NETLIB_SUB(R_base) m_R2;
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_Dial;
|
||||
param_logic_t m_DialIsLog;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(POT2)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(POT2)
|
||||
, m_R1(*this, "_R1")
|
||||
, m_R(*this, "R", 10000)
|
||||
, m_Dial(*this, "DIAL", 0.5)
|
||||
, m_DialIsLog(*this, "DIALLOG", 0)
|
||||
, m_Reverse(*this, "REVERSE", 0)
|
||||
{
|
||||
register_subalias("1", m_R1.m_P);
|
||||
register_subalias("2", m_R1.m_N);
|
||||
|
||||
}
|
||||
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
NETLIB_SUB(R_base) m_R1;
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_Dial;
|
||||
param_logic_t m_DialIsLog;
|
||||
param_logic_t m_Reverse;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_C
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(C, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(C, twoterm)
|
||||
, m_C(*this, "C", 1e-6)
|
||||
, m_GParallel(0.0)
|
||||
{
|
||||
//register_term("1", m_P);
|
||||
//register_term("2", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(true)
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
param_double_t m_C;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
nl_double m_GParallel;
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_L
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(L, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(L, twoterm)
|
||||
, m_L(*this, "L", 1e-6)
|
||||
, m_GParallel(0.0)
|
||||
, m_G(0.0)
|
||||
, m_I(0.0)
|
||||
{
|
||||
//register_term("1", m_P);
|
||||
//register_term("2", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(true)
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
param_double_t m_L;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
nl_double m_GParallel;
|
||||
nl_double m_G;
|
||||
nl_double m_I;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// A generic diode model to be used in other devices (Diode, BJT ...)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class generic_diode
|
||||
{
|
||||
public:
|
||||
generic_diode(device_t &dev, pstring name);
|
||||
|
||||
void update_diode(const double nVd);
|
||||
|
||||
void set_param(const double Is, const double n, double gmin);
|
||||
|
||||
inline double I() const { return m_Id; }
|
||||
inline double G() const { return m_G; }
|
||||
inline double Ieq() const { return (m_Id - m_Vd * m_G); }
|
||||
inline double Vd() const { return m_Vd; }
|
||||
|
||||
/* owning object must save those ... */
|
||||
|
||||
private:
|
||||
state_var<double> m_Vd;
|
||||
state_var<double> m_Id;
|
||||
state_var<double> m_G;
|
||||
|
||||
double m_Vt;
|
||||
double m_Vmin;
|
||||
double m_Is;
|
||||
double m_n;
|
||||
double m_gmin;
|
||||
|
||||
double m_VtInv;
|
||||
double m_Vcrit;
|
||||
};
|
||||
|
||||
/*! Class representing the diode model paramers.
|
||||
* This is the model representation of the diode model. Typically, SPICE uses
|
||||
* the following parameters. A "Y" in the first column indicates that the
|
||||
* parameter is actually used in netlist.
|
||||
*
|
||||
* |NL? |name |parameter |units|default| example|area |
|
||||
* |:--:|:-----|:--------------------------------|:----|------:|-------:|:----:|
|
||||
* | Y |IS |saturation current |A |1.0e-14| 1.0e-14| * |
|
||||
* | |RS |ohmic resistanc |Ohm | 0| 10| * |
|
||||
* | Y |N |emission coefficient |- | 1| 1| |
|
||||
* | |TT |transit-time |sec | 0| 0.1ns| |
|
||||
* | |CJO |zero-bias junction capacitance |F | 0| 2pF| * |
|
||||
* | |VJ |junction potential |V | 1| 0.6| |
|
||||
* | |M |grading coefficient |- | 0.5| 0.5| |
|
||||
* | |EG |band-gap energy |eV | 1.11| 1.11 Si| |
|
||||
* | |XTI |saturation-current temp.exp |- | 3|3.0 pn. 2.0 Schottky| |
|
||||
* | |KF |flicker noise coefficient |- | 0| | |
|
||||
* | |AF |flicker noise exponent |- | 1| | |
|
||||
* | |FC |coefficient for forward-bias depletion capacitance formula|-|0.5|| |
|
||||
* | |BV |reverse breakdown voltage |V |infinite| 40| |
|
||||
* | |IBV |current at breakdown voltage |V | 0.001| | |
|
||||
* | |TNOM |parameter measurement temperature|deg C| 27| 50| |
|
||||
*
|
||||
*/
|
||||
|
||||
class diode_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
diode_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_IS(*this, "IS")
|
||||
, m_N(*this, "N")
|
||||
{}
|
||||
|
||||
value_t m_IS; //!< saturation current.
|
||||
value_t m_N; //!< emission coefficient.
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_D
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <class CLASS>
|
||||
NETLIB_NAME(D)(CLASS &owner, const pstring name, const pstring model)
|
||||
: NETLIB_NAME(twoterm)(owner, name)
|
||||
, m_model(*this, "MODEL", model)
|
||||
, m_D(*this, "m_D")
|
||||
{
|
||||
register_subalias("A", m_P);
|
||||
register_subalias("K", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
diode_model_t m_model;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
generic_diode m_D;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_VS - Voltage source
|
||||
//
|
||||
// netlist voltage source must have inner resistance
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(VS, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(VS, twoterm)
|
||||
, m_R(*this, "R", 0.1)
|
||||
, m_V(*this, "V", 0.0)
|
||||
, m_func(*this,"FUNC", "")
|
||||
{
|
||||
register_subalias("P", m_P);
|
||||
register_subalias("N", m_N);
|
||||
if (m_func() != "")
|
||||
m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_V;
|
||||
param_str_t m_func;
|
||||
plib::pfunction m_compiled;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_CS - Current source
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(CS, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
|
||||
, m_I(*this, "I", 1.0)
|
||||
, m_func(*this,"FUNC", "")
|
||||
{
|
||||
register_subalias("P", m_P);
|
||||
register_subalias("N", m_N);
|
||||
if (m_func() != "")
|
||||
m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_TIMESTEPI();
|
||||
protected:
|
||||
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
|
||||
param_double_t m_I;
|
||||
param_str_t m_func;
|
||||
plib::pfunction m_compiled;
|
||||
};
|
||||
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_TWOTERM_H_ */
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "solver/nld_solver.h"
|
||||
#include "nld_fourterm.h"
|
||||
#include "nlid_fourterm.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
#include <cmath>
|
||||
@ -15,6 +15,8 @@ namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCCS
|
||||
// ----------------------------------------------------------------------------------------
|
211
src/lib/netlist/analog/nlid_fourterm.h
Normal file
211
src/lib/netlist/analog/nlid_fourterm.h
Normal file
@ -0,0 +1,211 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nlid_fourterm.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NLID_FOURTERM_H_
|
||||
#define NLID_FOURTERM_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist {
|
||||
namespace analog {
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled current source
|
||||
*
|
||||
* IP ---+ +------> OP
|
||||
* | |
|
||||
* RI I
|
||||
* RI => G => I IOut = (V(IP)-V(IN)) * G
|
||||
* RI I
|
||||
* | |
|
||||
* IN ---+ +------< ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1A
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT(VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR(VCCS)
|
||||
, m_G(*this, "G", 1.0)
|
||||
, m_RI(*this, "RI", 1e9)
|
||||
, m_OP(*this, "OP")
|
||||
, m_ON(*this, "ON")
|
||||
, m_IP(*this, "IP")
|
||||
, m_IN(*this, "IN")
|
||||
, m_OP1(*this, "_OP1")
|
||||
, m_ON1(*this, "_ON1")
|
||||
, m_gfac(1.0)
|
||||
{
|
||||
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
|
||||
m_OP.m_otherterm = &m_IP;
|
||||
m_OP1.m_otherterm = &m_IN;
|
||||
|
||||
m_ON.m_otherterm = &m_IP;
|
||||
m_ON1.m_otherterm = &m_IN;
|
||||
|
||||
connect(m_OP, m_OP1);
|
||||
connect(m_ON, m_ON1);
|
||||
m_gfac = NL_FCONST(1.0);
|
||||
}
|
||||
|
||||
param_double_t m_G;
|
||||
param_double_t m_RI;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI()
|
||||
{
|
||||
NETLIB_NAME(VCCS)::reset();
|
||||
}
|
||||
|
||||
terminal_t m_OP;
|
||||
terminal_t m_ON;
|
||||
|
||||
terminal_t m_IP;
|
||||
terminal_t m_IN;
|
||||
|
||||
terminal_t m_OP1;
|
||||
terminal_t m_ON1;
|
||||
|
||||
nl_double m_gfac;
|
||||
};
|
||||
|
||||
/* Limited Current source*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(LVCCS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(LVCCS, VCCS)
|
||||
, m_cur_limit(*this, "CURLIM", 1000.0)
|
||||
, m_vi(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
|
||||
param_double_t m_cur_limit; /* current limit */
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
nl_double m_vi;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_CCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Current controlled current source
|
||||
*
|
||||
* IP ---+ +------> OP
|
||||
* | |
|
||||
* RI I
|
||||
* RI => G => I IOut = (V(IP)-V(IN)) / RI * G
|
||||
* RI I
|
||||
* | |
|
||||
* IN ---+ +------< ON
|
||||
*
|
||||
* G=1 ==> 1A ==> 1A
|
||||
*
|
||||
* RI = 1
|
||||
*
|
||||
* This needs high levels of accuracy to work with 1 Ohm RI.
|
||||
*
|
||||
*/
|
||||
|
||||
NETLIB_OBJECT_DERIVED(CCCS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS)
|
||||
, m_gfac(1.0)
|
||||
{
|
||||
m_gfac = NL_FCONST(1.0) / m_RI();
|
||||
}
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
nl_double m_gfac;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCVS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled voltage source
|
||||
*
|
||||
* Parameters:
|
||||
* G Default: 1
|
||||
* RO Default: 1 (would be typically 50 for an op-amp
|
||||
*
|
||||
* IP ---+ +--+---- OP
|
||||
* | | |
|
||||
* RI I RO
|
||||
* RI => G => I RO V(OP) - V(ON) = (V(IP)-V(IN)) * G
|
||||
* RI I RO
|
||||
* | | |
|
||||
* IN ---+ +--+---- ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1V
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
* Internal GI = G / RO
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
NETLIB_OBJECT_DERIVED(VCVS, VCCS)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS)
|
||||
, m_RO(*this, "RO", 1.0)
|
||||
, m_OP2(*this, "_OP2")
|
||||
, m_ON2(*this, "_ON2")
|
||||
{
|
||||
m_OP2.m_otherterm = &m_ON2;
|
||||
m_ON2.m_otherterm = &m_OP2;
|
||||
|
||||
connect(m_OP2, m_OP1);
|
||||
connect(m_ON2, m_ON1);
|
||||
}
|
||||
|
||||
param_double_t m_RO;
|
||||
|
||||
protected:
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
//NETLIB_UPDATE_PARAMI();
|
||||
|
||||
terminal_t m_OP2;
|
||||
terminal_t m_ON2;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NLD_FOURTERM_H_ */
|
@ -7,7 +7,8 @@
|
||||
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#include "nld_twoterm.h"
|
||||
#include "nlid_twoterm.h"
|
||||
#include "nl_factory.h"
|
||||
|
||||
#include <cmath>
|
||||
|
447
src/lib/netlist/analog/nlid_twoterm.h
Normal file
447
src/lib/netlist/analog/nlid_twoterm.h
Normal file
@ -0,0 +1,447 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nld_twoterm.h
|
||||
*
|
||||
* Devices with two terminals ...
|
||||
*
|
||||
*
|
||||
* (k)
|
||||
* +-----T-----+
|
||||
* | | |
|
||||
* | +--+--+ |
|
||||
* | | | |
|
||||
* | R | |
|
||||
* | R | |
|
||||
* | R I |
|
||||
* | | I | Device n
|
||||
* | V+ I |
|
||||
* | V | |
|
||||
* | V- | |
|
||||
* | | | |
|
||||
* | +--+--+ |
|
||||
* | | |
|
||||
* +-----T-----+
|
||||
* (l)
|
||||
*
|
||||
* This is a resistance in series to a voltage source and paralleled by a
|
||||
* current source. This is suitable to model voltage sources, current sources,
|
||||
* resistors, capacitors, inductances and diodes.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NLID_TWOTERM_H_
|
||||
#define NLID_TWOTERM_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "plib/pfunction.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Implementation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_twoterm
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT(twoterm)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false)
|
||||
, m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1")
|
||||
, m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2")
|
||||
{
|
||||
m_P.m_otherterm = &m_N;
|
||||
m_N.m_otherterm = &m_P;
|
||||
}
|
||||
|
||||
terminal_t m_P;
|
||||
terminal_t m_N;
|
||||
|
||||
//NETLIB_UPDATE_TERMINALSI() { }
|
||||
//NETLIB_RESETI() { }
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
/* inline */ void set(const nl_double G, const nl_double V, const nl_double I)
|
||||
{
|
||||
/* GO, GT, I */
|
||||
m_P.set( G, G, ( V) * G - I);
|
||||
m_N.set( G, G, ( -V) * G + I);
|
||||
}
|
||||
|
||||
/* inline */ nl_double deltaV() const
|
||||
{
|
||||
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
|
||||
}
|
||||
|
||||
void set_mat(const nl_double a11, const nl_double a12, const nl_double r1,
|
||||
const nl_double a21, const nl_double a22, const nl_double r2)
|
||||
{
|
||||
/* GO, GT, I */
|
||||
m_P.set(-a12, a11, r1);
|
||||
m_N.set(-a21, a22, r2);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class C>
|
||||
static core_device_t &bselect(bool b, C &d1, core_device_t &d2)
|
||||
{
|
||||
core_device_t *h = dynamic_cast<core_device_t *>(&d1);
|
||||
return b ? *h : d2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_R
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(R_base, twoterm)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(R_base, twoterm)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline void set_R(const nl_double R)
|
||||
{
|
||||
const nl_double G = NL_FCONST(1.0) / R;
|
||||
set_mat( G, -G, 0.0,
|
||||
-G, G, 0.0);
|
||||
}
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
};
|
||||
|
||||
NETLIB_OBJECT_DERIVED(R, R_base)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR_DERIVED(R, R_base)
|
||||
, m_R(*this, "R", 1e9)
|
||||
{
|
||||
}
|
||||
|
||||
param_double_t m_R;
|
||||
|
||||
protected:
|
||||
|
||||
NETLIB_RESETI();
|
||||
//NETLIB_UPDATEI() { }
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
/* protect set_R ... it's a recipe to desaster when used to bypass the parameter */
|
||||
using NETLIB_NAME(R_base)::set_R;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_POT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT(POT)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(POT)
|
||||
, m_R1(*this, "_R1")
|
||||
, m_R2(*this, "_R2")
|
||||
, m_R(*this, "R", 10000)
|
||||
, m_Dial(*this, "DIAL", 0.5)
|
||||
, m_DialIsLog(*this, "DIALLOG", 0)
|
||||
{
|
||||
register_subalias("1", m_R1.m_P);
|
||||
register_subalias("2", m_R1.m_N);
|
||||
register_subalias("3", m_R2.m_N);
|
||||
|
||||
connect(m_R2.m_P, m_R1.m_N);
|
||||
|
||||
}
|
||||
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
NETLIB_SUB(R_base) m_R1;
|
||||
NETLIB_SUB(R_base) m_R2;
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_Dial;
|
||||
param_logic_t m_DialIsLog;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(POT2)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(POT2)
|
||||
, m_R1(*this, "_R1")
|
||||
, m_R(*this, "R", 10000)
|
||||
, m_Dial(*this, "DIAL", 0.5)
|
||||
, m_DialIsLog(*this, "DIALLOG", 0)
|
||||
, m_Reverse(*this, "REVERSE", 0)
|
||||
{
|
||||
register_subalias("1", m_R1.m_P);
|
||||
register_subalias("2", m_R1.m_N);
|
||||
|
||||
}
|
||||
|
||||
//NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
NETLIB_SUB(R_base) m_R1;
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_Dial;
|
||||
param_logic_t m_DialIsLog;
|
||||
param_logic_t m_Reverse;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_C
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(C, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(C, twoterm)
|
||||
, m_C(*this, "C", 1e-6)
|
||||
, m_GParallel(0.0)
|
||||
{
|
||||
//register_term("1", m_P);
|
||||
//register_term("2", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(true)
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
param_double_t m_C;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
nl_double m_GParallel;
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_L
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(L, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(L, twoterm)
|
||||
, m_L(*this, "L", 1e-6)
|
||||
, m_GParallel(0.0)
|
||||
, m_G(0.0)
|
||||
, m_I(0.0)
|
||||
{
|
||||
//register_term("1", m_P);
|
||||
//register_term("2", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(true)
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
param_double_t m_L;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
private:
|
||||
nl_double m_GParallel;
|
||||
nl_double m_G;
|
||||
nl_double m_I;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// A generic diode model to be used in other devices (Diode, BJT ...)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class generic_diode
|
||||
{
|
||||
public:
|
||||
generic_diode(device_t &dev, pstring name);
|
||||
|
||||
void update_diode(const double nVd);
|
||||
|
||||
void set_param(const double Is, const double n, double gmin);
|
||||
|
||||
inline double I() const { return m_Id; }
|
||||
inline double G() const { return m_G; }
|
||||
inline double Ieq() const { return (m_Id - m_Vd * m_G); }
|
||||
inline double Vd() const { return m_Vd; }
|
||||
|
||||
/* owning object must save those ... */
|
||||
|
||||
private:
|
||||
state_var<double> m_Vd;
|
||||
state_var<double> m_Id;
|
||||
state_var<double> m_G;
|
||||
|
||||
double m_Vt;
|
||||
double m_Vmin;
|
||||
double m_Is;
|
||||
double m_n;
|
||||
double m_gmin;
|
||||
|
||||
double m_VtInv;
|
||||
double m_Vcrit;
|
||||
};
|
||||
|
||||
/*! Class representing the diode model paramers.
|
||||
* This is the model representation of the diode model. Typically, SPICE uses
|
||||
* the following parameters. A "Y" in the first column indicates that the
|
||||
* parameter is actually used in netlist.
|
||||
*
|
||||
* |NL? |name |parameter |units|default| example|area |
|
||||
* |:--:|:-----|:--------------------------------|:----|------:|-------:|:----:|
|
||||
* | Y |IS |saturation current |A |1.0e-14| 1.0e-14| * |
|
||||
* | |RS |ohmic resistanc |Ohm | 0| 10| * |
|
||||
* | Y |N |emission coefficient |- | 1| 1| |
|
||||
* | |TT |transit-time |sec | 0| 0.1ns| |
|
||||
* | |CJO |zero-bias junction capacitance |F | 0| 2pF| * |
|
||||
* | |VJ |junction potential |V | 1| 0.6| |
|
||||
* | |M |grading coefficient |- | 0.5| 0.5| |
|
||||
* | |EG |band-gap energy |eV | 1.11| 1.11 Si| |
|
||||
* | |XTI |saturation-current temp.exp |- | 3|3.0 pn. 2.0 Schottky| |
|
||||
* | |KF |flicker noise coefficient |- | 0| | |
|
||||
* | |AF |flicker noise exponent |- | 1| | |
|
||||
* | |FC |coefficient for forward-bias depletion capacitance formula|-|0.5|| |
|
||||
* | |BV |reverse breakdown voltage |V |infinite| 40| |
|
||||
* | |IBV |current at breakdown voltage |V | 0.001| | |
|
||||
* | |TNOM |parameter measurement temperature|deg C| 27| 50| |
|
||||
*
|
||||
*/
|
||||
|
||||
class diode_model_t : public param_model_t
|
||||
{
|
||||
public:
|
||||
diode_model_t(device_t &device, const pstring name, const pstring val)
|
||||
: param_model_t(device, name, val)
|
||||
, m_IS(*this, "IS")
|
||||
, m_N(*this, "N")
|
||||
{}
|
||||
|
||||
value_t m_IS; //!< saturation current.
|
||||
value_t m_N; //!< emission coefficient.
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_D
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <class CLASS>
|
||||
NETLIB_NAME(D)(CLASS &owner, const pstring name, const pstring model)
|
||||
: NETLIB_NAME(twoterm)(owner, name)
|
||||
, m_model(*this, "MODEL", model)
|
||||
, m_D(*this, "m_D")
|
||||
{
|
||||
register_subalias("A", m_P);
|
||||
register_subalias("K", m_N);
|
||||
}
|
||||
|
||||
NETLIB_IS_DYNAMIC(true)
|
||||
NETLIB_UPDATE_TERMINALSI();
|
||||
|
||||
diode_model_t m_model;
|
||||
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_UPDATE_PARAMI();
|
||||
|
||||
generic_diode m_D;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_VS - Voltage source
|
||||
//
|
||||
// netlist voltage source must have inner resistance
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(VS, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(VS, twoterm)
|
||||
, m_R(*this, "R", 0.1)
|
||||
, m_V(*this, "V", 0.0)
|
||||
, m_func(*this,"FUNC", "")
|
||||
{
|
||||
register_subalias("P", m_P);
|
||||
register_subalias("N", m_N);
|
||||
if (m_func() != "")
|
||||
m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_TIMESTEPI();
|
||||
|
||||
protected:
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
|
||||
param_double_t m_R;
|
||||
param_double_t m_V;
|
||||
param_str_t m_func;
|
||||
plib::pfunction m_compiled;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_CS - Current source
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT_DERIVED(CS, twoterm)
|
||||
{
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
|
||||
, m_I(*this, "I", 1.0)
|
||||
, m_func(*this,"FUNC", "")
|
||||
{
|
||||
register_subalias("P", m_P);
|
||||
register_subalias("N", m_N);
|
||||
if (m_func() != "")
|
||||
m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
|
||||
}
|
||||
|
||||
NETLIB_IS_TIMESTEP(m_func() != "")
|
||||
NETLIB_TIMESTEPI();
|
||||
protected:
|
||||
|
||||
NETLIB_UPDATEI();
|
||||
NETLIB_RESETI();
|
||||
|
||||
param_double_t m_I;
|
||||
param_str_t m_func;
|
||||
plib::pfunction m_compiled;
|
||||
};
|
||||
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_TWOTERM_H_ */
|
@ -64,9 +64,9 @@ NLOBJS := \
|
||||
$(NLOBJ)/nl_setup.o \
|
||||
$(NLOBJ)/nl_factory.o \
|
||||
$(NLOBJ)/analog/nld_bjt.o \
|
||||
$(NLOBJ)/analog/nld_fourterm.o \
|
||||
$(NLOBJ)/analog/nlid_fourterm.o \
|
||||
$(NLOBJ)/analog/nld_switches.o \
|
||||
$(NLOBJ)/analog/nld_twoterm.o \
|
||||
$(NLOBJ)/analog/nlid_twoterm.o \
|
||||
$(NLOBJ)/analog/nld_opamps.o \
|
||||
$(NLOBJ)/devices/nld_2102A.o \
|
||||
$(NLOBJ)/devices/nld_2716.o \
|
||||
@ -115,7 +115,7 @@ NLOBJS := \
|
||||
$(NLOBJ)/devices/nld_log.o \
|
||||
$(NLOBJ)/devices/nlid_proxy.o \
|
||||
$(NLOBJ)/devices/nld_system.o \
|
||||
$(NLOBJ)/devices/nld_truthtable.o \
|
||||
$(NLOBJ)/devices/nlid_truthtable.o \
|
||||
$(NLOBJ)/macro/nlm_base.o \
|
||||
$(NLOBJ)/macro/nlm_cd4xxx.o \
|
||||
$(NLOBJ)/macro/nlm_opamp.o \
|
||||
|
@ -28,11 +28,9 @@
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
using namespace netlist::analog;
|
||||
|
||||
namespace devices
|
||||
{
|
||||
static void initialize_factory(factory::list_t &factory)
|
||||
void initialize_factory(factory::list_t &factory)
|
||||
{
|
||||
ENTRYX(R, RES, "R")
|
||||
ENTRYX(POT, POT, "R")
|
||||
@ -162,10 +160,3 @@ static void initialize_factory(factory::list_t &factory)
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
void initialize_factory(factory::list_t &factory)
|
||||
{
|
||||
devices::initialize_factory(factory);
|
||||
}
|
||||
}
|
||||
|
@ -11,18 +11,13 @@
|
||||
#ifndef NET_LIB_H
|
||||
#define NET_LIB_H
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
//#define NL_AUTO_DEVICES 1
|
||||
|
||||
#ifdef NL_AUTO_DEVICES
|
||||
#include "nld_devinc.h"
|
||||
|
||||
#include "analog/nld_bjt.h"
|
||||
#include "analog/nld_fourterm.h"
|
||||
#include "analog/nld_switches.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nld_opamps.h"
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#include "macro/nlm_cd4xxx.h"
|
||||
@ -33,6 +28,11 @@
|
||||
#include "nld_7448.h"
|
||||
|
||||
#else
|
||||
|
||||
#define SOLVER(name, freq) \
|
||||
NET_REGISTER_DEV(SOLVER, name) \
|
||||
PARAM(name.FREQ, freq)
|
||||
|
||||
#include "nld_system.h"
|
||||
|
||||
#include "nld_2102A.h"
|
||||
@ -93,13 +93,8 @@
|
||||
#include "analog/nld_switches.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nld_opamps.h"
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#include "nld_legacy.h"
|
||||
#endif
|
||||
|
||||
namespace netlist {
|
||||
void initialize_factory(factory::list_t &factory);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_2102A.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
#define ADDR2BYTE(a) ((a) >> 3)
|
||||
#define ADDR2BIT(a) ((a) & 0x7)
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_2716.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "devices/nlid_cmos.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
#include "nld_4066.h"
|
||||
|
||||
namespace netlist
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "devices/nlid_cmos.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
#include "nld_4316.h"
|
||||
|
||||
namespace netlist { namespace devices {
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74107.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -5,10 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nld_74123.h"
|
||||
|
||||
#include "nlid_system.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74153.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define MAXCNT 15
|
||||
|
||||
#include "nld_74161.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74165.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74166.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74174.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74175.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define MAXCNT 9
|
||||
|
||||
#include "nld_74192.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define MAXCNT 15
|
||||
|
||||
#include "nld_74193.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74194.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -5,8 +5,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nlid_truthtable.h"
|
||||
#include "nld_74279.h"
|
||||
#include "nld_truthtable.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74365.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -5,8 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nlid_truthtable.h"
|
||||
#include "nld_7448.h"
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -24,7 +24,7 @@
|
||||
#ifndef NLD_7448_H_
|
||||
#define NLD_7448_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_setup.h"
|
||||
|
||||
/*
|
||||
* FIXME: Using truthtable is a lot slower than the explicit device
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7450.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7473.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7474.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7475.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7483.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7485.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7490.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7493.h"
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
|
||||
#include "nld_74ls629.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_82S115.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_82S123.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_82S126.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_82S16.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_9310.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
#define MAXCNT 9
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
* | 1 | 1 | 1 | 0 || D7|D7Q|
|
||||
* +---+---+---+---++---+---+
|
||||
*/
|
||||
#include "nlid_truthtable.h"
|
||||
#include "nld_9312.h"
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_9316.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
#define MAXCNT 15
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_9322.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_am2847.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_dm9334.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_legacy.h"
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "nld_mm5837.h"
|
||||
#include "solver/nld_matrix_solver.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
|
||||
#define R_LOW (1000.0)
|
||||
#define R_HIGH (1000.0)
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_ne555.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#define R_OFF (1E20)
|
||||
|
@ -5,8 +5,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nld_r2r_dac.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_tristate.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define NLID_CMOS_H_
|
||||
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -112,9 +112,9 @@ namespace netlist
|
||||
{
|
||||
pstring devname = out_proxied->device().name();
|
||||
auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
|
||||
detail::core_terminal_t::type_t::INPUT, false);
|
||||
detail::terminal_type::INPUT, false);
|
||||
auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
|
||||
detail::core_terminal_t::type_t::INPUT, false);
|
||||
detail::terminal_type::INPUT, false);
|
||||
if (tp != nullptr && tn != nullptr)
|
||||
{
|
||||
/* alternative logic */
|
||||
@ -127,7 +127,7 @@ namespace netlist
|
||||
log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
|
||||
#if (0)
|
||||
printf("%s %s\n", out_proxied->name().c_str(), out_proxied->device().name().c_str());
|
||||
auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::type_t::OUTPUT, false);
|
||||
auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::terminal_type::OUTPUT, false);
|
||||
if (x) printf("==> %s\n", x->name().c_str());
|
||||
#endif
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define NLID_PROXY_H_
|
||||
|
||||
#include "nl_setup.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -11,8 +11,9 @@
|
||||
#ifndef NLID_SYSTEM_H_
|
||||
#define NLID_SYSTEM_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_setup.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "analog/nlid_twoterm.h"
|
||||
#include "plib/putil.h"
|
||||
|
||||
namespace netlist
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nld_truthtable.h"
|
||||
#include "nlid_truthtable.h"
|
||||
#include "plib/plists.h"
|
||||
#include "nl_setup.h"
|
||||
#include "plib/palloc.h"
|
@ -7,10 +7,11 @@
|
||||
* Author: andre
|
||||
*/
|
||||
|
||||
#ifndef NLD_TRUTHTABLE_H_
|
||||
#define NLD_TRUTHTABLE_H_
|
||||
#ifndef NLID_TRUTHTABLE_H_
|
||||
#define NLID_TRUTHTABLE_H_
|
||||
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
#include "plib/putil.h"
|
||||
|
||||
#define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \
|
||||
@ -381,4 +382,4 @@ namespace netlist
|
||||
|
||||
|
||||
|
||||
#endif /* NLD_TRUTHTABLE_H_ */
|
||||
#endif /* NLID_TRUTHTABLE_H_ */
|
@ -2,7 +2,6 @@
|
||||
// copyright-holders:Couriersud
|
||||
#include "nlm_cd4xxx.h"
|
||||
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "devices/nld_system.h"
|
||||
#include "devices/nld_4020.h"
|
||||
#include "devices/nld_4066.h"
|
||||
|
@ -1,9 +1,7 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
#include "nlm_opamp.h"
|
||||
|
||||
#include "analog/nld_opamps.h"
|
||||
#include "devices/nld_system.h"
|
||||
#include "devices/net_lib.h"
|
||||
|
||||
/*
|
||||
* Generic layout with 4 opamps, VCC on pin 4 and GND on pin 11
|
||||
|
@ -2,7 +2,6 @@
|
||||
// copyright-holders:Couriersud
|
||||
#include "nlm_other.h"
|
||||
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "devices/nld_system.h"
|
||||
|
||||
/*
|
||||
|
@ -2,7 +2,6 @@
|
||||
// copyright-holders:Couriersud
|
||||
#include "nlm_ttl74xx.h"
|
||||
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "devices/nld_system.h"
|
||||
|
||||
|
||||
|
@ -216,22 +216,22 @@ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &anam
|
||||
{
|
||||
}
|
||||
|
||||
detail::core_terminal_t::type_t detail::core_terminal_t::type() const
|
||||
detail::terminal_type detail::core_terminal_t::type() const
|
||||
{
|
||||
if (dynamic_cast<const terminal_t *>(this) != nullptr)
|
||||
return type_t::TERMINAL;
|
||||
return terminal_type::TERMINAL;
|
||||
else if (dynamic_cast<const logic_input_t *>(this) != nullptr)
|
||||
return type_t::INPUT;
|
||||
return terminal_type::INPUT;
|
||||
else if (dynamic_cast<const logic_output_t *>(this) != nullptr)
|
||||
return type_t::OUTPUT;
|
||||
return terminal_type::OUTPUT;
|
||||
else if (dynamic_cast<const analog_input_t *>(this) != nullptr)
|
||||
return type_t::INPUT;
|
||||
return terminal_type::INPUT;
|
||||
else if (dynamic_cast<const analog_output_t *>(this) != nullptr)
|
||||
return type_t::OUTPUT;
|
||||
return terminal_type::OUTPUT;
|
||||
else
|
||||
{
|
||||
netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
|
||||
return type_t::TERMINAL; // please compiler
|
||||
return terminal_type::TERMINAL; // please compiler
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef NL_PROHIBIT_BASEH_INCLUDE
|
||||
#error "nl_base.h included. Please correct."
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Type definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -224,11 +228,6 @@ namespace netlist
|
||||
class core_device_t;
|
||||
class device_t;
|
||||
|
||||
/*! Type of the model map used.
|
||||
* This is used to hold all #Models in an unordered map
|
||||
*/
|
||||
using model_map_t = std::unordered_map<pstring, pstring>;
|
||||
|
||||
/*! Logic families descriptors are used to create proxy devices.
|
||||
* The logic family describes the analog capabilities of logic devices,
|
||||
* inputs and outputs.
|
||||
@ -481,25 +480,18 @@ namespace netlist
|
||||
STATE_BIDIR = 256
|
||||
};
|
||||
|
||||
/*! Enum specifying the type of object */
|
||||
enum type_t {
|
||||
TERMINAL = 0, /*!< object is an analog terminal */
|
||||
INPUT = 1, /*!< object is an input */
|
||||
OUTPUT = 2, /*!< object is an output */
|
||||
};
|
||||
|
||||
core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state);
|
||||
virtual ~core_terminal_t();
|
||||
|
||||
/*! The object type.
|
||||
* \returns type of the object
|
||||
*/
|
||||
type_t type() const;
|
||||
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 type_t atype) const { return (type() == atype); }
|
||||
bool is_type(const terminal_type atype) const { return (type() == atype); }
|
||||
|
||||
void set_net(net_t *anet);
|
||||
void clear_net();
|
||||
@ -980,7 +972,7 @@ namespace netlist
|
||||
private:
|
||||
/* hide this */
|
||||
void setTo(const pstring ¶m) = delete;
|
||||
model_map_t m_map;
|
||||
detail::model_map_t m_map;
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,10 +9,7 @@
|
||||
#ifndef NLCONFIG_H_
|
||||
#define NLCONFIG_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "plib/pconfig.h"
|
||||
#include "plib/pchrono.h"
|
||||
|
||||
//============================================================
|
||||
// SETUP
|
||||
@ -66,20 +63,6 @@
|
||||
#define HAS_OPENMP (0)
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// Performance tracking
|
||||
//============================================================
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
#if NL_KEEP_STATISTICS
|
||||
using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, true>;
|
||||
using nperfcount_t = plib::chrono::counter<true>;
|
||||
#else
|
||||
using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, false>;
|
||||
using nperfcount_t = plib::chrono::counter<false>;
|
||||
#endif
|
||||
}
|
||||
//============================================================
|
||||
// General
|
||||
//============================================================
|
||||
|
@ -9,6 +9,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "nl_factory.h"
|
||||
#include "nl_base.h"
|
||||
#include "nl_setup.h"
|
||||
#include "plib/putil.h"
|
||||
#include "nl_errstr.h"
|
||||
@ -16,6 +17,20 @@
|
||||
namespace netlist { namespace factory
|
||||
{
|
||||
|
||||
class NETLIB_NAME(wrapper) : public device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(wrapper)(netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
};
|
||||
|
||||
|
||||
|
||||
element_t::element_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param, const pstring &sourcefile)
|
||||
: m_name(name), m_classname(classname), m_def_param(def_param),
|
||||
|
@ -9,7 +9,8 @@
|
||||
#ifndef NLFACTORY_H_
|
||||
#define NLFACTORY_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "plib/palloc.h"
|
||||
#include "plib/ptypes.h"
|
||||
|
||||
#define NETLIB_DEVICE_IMPL(chip) \
|
||||
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
|
||||
@ -27,8 +28,12 @@
|
||||
} \
|
||||
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
|
||||
|
||||
namespace netlist { namespace factory
|
||||
{
|
||||
namespace netlist {
|
||||
class netlist_t;
|
||||
class device_t;
|
||||
class setup_t;
|
||||
|
||||
namespace factory {
|
||||
// -----------------------------------------------------------------------------
|
||||
// net_dev class factory
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -99,7 +104,7 @@ namespace netlist { namespace factory
|
||||
|
||||
private:
|
||||
setup_t &m_setup;
|
||||
};
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// factory_creator_ptr_t
|
||||
@ -119,18 +124,6 @@ namespace netlist { namespace factory
|
||||
// factory_lib_entry_t: factory class to wrap macro based chips/elements
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class NETLIB_NAME(wrapper) : public device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(wrapper)(netlist_t &anetlist, const pstring &name)
|
||||
: device_t(anetlist, name)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
NETLIB_RESETI();
|
||||
NETLIB_UPDATEI();
|
||||
};
|
||||
|
||||
class library_element_t : public element_t
|
||||
{
|
||||
public:
|
||||
@ -146,6 +139,11 @@ namespace netlist { namespace factory
|
||||
private:
|
||||
};
|
||||
|
||||
} }
|
||||
}
|
||||
|
||||
namespace devices {
|
||||
void initialize_factory(factory::list_t &factory);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NLFACTORY_H_ */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "nl_types.h"
|
||||
#include "plib/plists.h"
|
||||
#include "plib/pchrono.h"
|
||||
#include "plib/ptypes.h"
|
||||
@ -26,7 +27,6 @@
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
||||
//FIXME: move to an appropriate place
|
||||
template<bool enabled_ = true>
|
||||
class pspin_mutex
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "nl_parser.h"
|
||||
#include "nl_factory.h"
|
||||
#include "nl_errstr.h"
|
||||
#include "devices/nld_truthtable.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
@ -187,7 +186,7 @@ void parser_t::net_truthtable_start(const pstring &nlname)
|
||||
require_token(token, m_tok_TRUTHTABLE_END);
|
||||
require_token(m_tok_param_left);
|
||||
require_token(m_tok_param_right);
|
||||
netlist::devices::tt_factory_create(m_setup, desc, nlname);
|
||||
m_setup.tt_factory_create(desc, nlname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,11 @@
|
||||
#include "nl_setup.h"
|
||||
#include "nl_parser.h"
|
||||
#include "nl_factory.h"
|
||||
#include "devices/net_lib.h"
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "devices/nlid_system.h"
|
||||
#include "devices/nlid_proxy.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "solver/nld_solver.h"
|
||||
#include "devices/nlid_truthtable.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// setup_t
|
||||
@ -30,7 +29,7 @@ setup_t::setup_t(netlist_t &netlist)
|
||||
, m_proxy_cnt(0)
|
||||
, m_frontier_cnt(0)
|
||||
{
|
||||
initialize_factory(m_factory);
|
||||
devices::initialize_factory(m_factory);
|
||||
}
|
||||
|
||||
setup_t::~setup_t()
|
||||
@ -137,11 +136,11 @@ pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
|
||||
{
|
||||
switch (in.type())
|
||||
{
|
||||
case terminal_t::TERMINAL:
|
||||
case detail::terminal_type::TERMINAL:
|
||||
return pstring("TERMINAL");
|
||||
case terminal_t::INPUT:
|
||||
case detail::terminal_type::INPUT:
|
||||
return pstring("INPUT");
|
||||
case terminal_t::OUTPUT:
|
||||
case detail::terminal_type::OUTPUT:
|
||||
return pstring("OUTPUT");
|
||||
}
|
||||
// FIXME: noreturn
|
||||
@ -336,12 +335,12 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool
|
||||
}
|
||||
|
||||
detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
|
||||
detail::core_terminal_t::type_t atype, bool required)
|
||||
detail::terminal_type atype, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
auto ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret == m_terminals.end() && atype == detail::core_terminal_t::OUTPUT)
|
||||
if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
ret = m_terminals.find(tname + ".Q");
|
||||
@ -603,7 +602,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term
|
||||
{
|
||||
for (auto & t : t1.net().m_core_terms)
|
||||
{
|
||||
if (t->is_type(detail::core_terminal_t::TERMINAL))
|
||||
if (t->is_type(detail::terminal_type::TERMINAL))
|
||||
ret = connect(t2, *t);
|
||||
if (ret)
|
||||
break;
|
||||
@ -618,7 +617,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term
|
||||
{
|
||||
for (auto & t : t2.net().m_core_terms)
|
||||
{
|
||||
if (t->is_type(detail::core_terminal_t::TERMINAL))
|
||||
if (t->is_type(detail::terminal_type::TERMINAL))
|
||||
ret = connect(t1, *t);
|
||||
if (ret)
|
||||
break;
|
||||
@ -637,39 +636,39 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t
|
||||
detail::core_terminal_t &t2 = resolve_proxy(t2_in);
|
||||
bool ret = true;
|
||||
|
||||
if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::INPUT))
|
||||
if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT))
|
||||
{
|
||||
if (t2.has_net() && t2.net().isRailNet())
|
||||
log().fatal(MF_1_INPUT_1_ALREADY_CONNECTED, t2.name());
|
||||
connect_input_output(t2, t1);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::OUTPUT))
|
||||
else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT))
|
||||
{
|
||||
if (t1.has_net() && t1.net().isRailNet())
|
||||
log().fatal(MF_1_INPUT_1_ALREADY_CONNECTED, t1.name());
|
||||
connect_input_output(t1, t2);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::TERMINAL))
|
||||
else if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::TERMINAL))
|
||||
{
|
||||
connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::OUTPUT))
|
||||
else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::OUTPUT))
|
||||
{
|
||||
connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::TERMINAL))
|
||||
else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::TERMINAL))
|
||||
{
|
||||
connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::INPUT))
|
||||
else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::INPUT))
|
||||
{
|
||||
connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2);
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::TERMINAL))
|
||||
else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::TERMINAL))
|
||||
{
|
||||
connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2));
|
||||
}
|
||||
else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::INPUT))
|
||||
else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT))
|
||||
{
|
||||
ret = connect_input_input(t1, t2);
|
||||
}
|
||||
@ -782,7 +781,7 @@ const plib::plog_base<NL_DEBUG> &setup_t::log() const
|
||||
// Model
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
static pstring model_string(model_map_t &map)
|
||||
static pstring model_string(detail::model_map_t &map)
|
||||
{
|
||||
pstring ret = map["COREMODEL"] + "(";
|
||||
for (auto & i : map)
|
||||
@ -791,7 +790,7 @@ static pstring model_string(model_map_t &map)
|
||||
return ret + ")";
|
||||
}
|
||||
|
||||
void setup_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
|
||||
{
|
||||
pstring model = model_in;
|
||||
pstring::iterator pos(nullptr);
|
||||
@ -837,7 +836,7 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
}
|
||||
}
|
||||
|
||||
const pstring setup_t::model_value_str(model_map_t &map, const pstring &entity)
|
||||
const pstring setup_t::model_value_str(detail::model_map_t &map, const pstring &entity)
|
||||
{
|
||||
pstring ret;
|
||||
|
||||
@ -852,7 +851,7 @@ const pstring setup_t::model_value_str(model_map_t &map, const pstring &entity)
|
||||
return ret;
|
||||
}
|
||||
|
||||
nl_double setup_t::model_value(model_map_t &map, const pstring &entity)
|
||||
nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
|
||||
{
|
||||
pstring tmp = model_value_str(map, entity);
|
||||
|
||||
@ -899,7 +898,7 @@ plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create
|
||||
|
||||
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
{
|
||||
model_map_t map;
|
||||
detail::model_map_t map;
|
||||
model_parse(model, map);
|
||||
|
||||
if (model_value_str(map, "TYPE") == "TTL")
|
||||
|
@ -8,11 +8,18 @@
|
||||
#ifndef NLSETUP_H_
|
||||
#define NLSETUP_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
#include "plib/pstring.h"
|
||||
#include "plib/putil.h"
|
||||
#include "plib/pstream.h"
|
||||
#include "plib/pparser.h"
|
||||
|
||||
#include "nl_factory.h"
|
||||
#include "nl_config.h"
|
||||
#include "nl_types.h"
|
||||
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
//============================================================
|
||||
// MACROS / inline netlist definitions
|
||||
@ -100,12 +107,29 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \
|
||||
desc.family = x;
|
||||
|
||||
#define TRUTHTABLE_END() \
|
||||
netlist::devices::tt_factory_create(setup, desc, __FILE__); \
|
||||
setup.tt_factory_create(desc, __FILE__); \
|
||||
}
|
||||
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
||||
namespace detail {
|
||||
class core_terminal_t;
|
||||
class net_t;
|
||||
}
|
||||
|
||||
namespace devices {
|
||||
class nld_base_proxy;
|
||||
}
|
||||
|
||||
class core_device_t;
|
||||
class param_t;
|
||||
class setup_t;
|
||||
class netlist_t;
|
||||
class logic_family_desc_t;
|
||||
class terminal_t;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// truthtable desc
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -252,10 +276,10 @@ namespace netlist
|
||||
|
||||
/* model / family related */
|
||||
|
||||
const pstring model_value_str(model_map_t &map, const pstring &entity);
|
||||
nl_double model_value(model_map_t &map, const pstring &entity);
|
||||
const pstring model_value_str(detail::model_map_t &map, const pstring &entity);
|
||||
double model_value(detail::model_map_t &map, const pstring &entity);
|
||||
|
||||
void model_parse(const pstring &model, model_map_t &map);
|
||||
void model_parse(const pstring &model, detail::model_map_t &map);
|
||||
|
||||
const logic_family_desc_t *family_from_model(const pstring &model);
|
||||
|
||||
@ -276,7 +300,7 @@ namespace netlist
|
||||
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
|
||||
|
||||
/* needed by proxy */
|
||||
detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::core_terminal_t::type_t atype, bool required = true);
|
||||
detail::core_terminal_t *find_terminal(const pstring &outname_in, const detail::terminal_type atype, bool required = true);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "plib/ptypes.h"
|
||||
#include "plib/pstate.h"
|
||||
|
||||
//============================================================
|
||||
|
54
src/lib/netlist/nl_types.h
Normal file
54
src/lib/netlist/nl_types.h
Normal file
@ -0,0 +1,54 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*!
|
||||
*
|
||||
* \file nl_types.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NLTYPES_H_
|
||||
#define NLTYPES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "plib/pchrono.h"
|
||||
#include "plib/pstring.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
//============================================================
|
||||
// Performance tracking
|
||||
//============================================================
|
||||
|
||||
#if NL_KEEP_STATISTICS
|
||||
using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, true>;
|
||||
using nperfcount_t = plib::chrono::counter<true>;
|
||||
#else
|
||||
using nperftime_t = plib::chrono::timer<plib::chrono::exact_ticks, false>;
|
||||
using nperfcount_t = plib::chrono::counter<false>;
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// Types needed by various includes
|
||||
//============================================================
|
||||
|
||||
namespace detail {
|
||||
|
||||
/*! Enum specifying the type of object */
|
||||
enum terminal_type {
|
||||
TERMINAL = 0, /*!< object is an analog terminal */
|
||||
INPUT = 1, /*!< object is an input */
|
||||
OUTPUT = 2, /*!< object is an output */
|
||||
};
|
||||
|
||||
/*! Type of the model map used.
|
||||
* This is used to hold all #Models in an unordered map
|
||||
*/
|
||||
using model_map_t = std::unordered_map<pstring, pstring>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NLTYPES_H_ */
|
@ -13,6 +13,7 @@
|
||||
#include "nl_parser.h"
|
||||
#include "devices/net_lib.h"
|
||||
#include "tools/nl_convert.h"
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
class tool_options_t : public plib::options
|
||||
{
|
||||
|
@ -20,10 +20,10 @@ struct mat_cr_t
|
||||
typedef C index_type;
|
||||
typedef T value_type;
|
||||
|
||||
C RESTRICT diag[N]; // diagonal index pointer n
|
||||
C RESTRICT ia[N+1]; // row index pointer n + 1
|
||||
C RESTRICT ja[N*N]; // column index array nz_num, initially (n * n)
|
||||
T RESTRICT A[N*N]; // Matrix elements nz_num, initially (n * n)
|
||||
C diag[N]; // diagonal index pointer n
|
||||
C ia[N+1]; // row index pointer n + 1
|
||||
C ja[N*N]; // column index array nz_num, initially (n * n)
|
||||
T A[N*N]; // Matrix elements nz_num, initially (n * n)
|
||||
|
||||
std::size_t size;
|
||||
std::size_t nz_num;
|
||||
|
@ -123,7 +123,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
log().debug("{1} {2} {3}\n", p->name(), net->name(), net->isRailNet());
|
||||
switch (p->type())
|
||||
{
|
||||
case terminal_t::TERMINAL:
|
||||
case detail::terminal_type::TERMINAL:
|
||||
if (p->device().is_timestep())
|
||||
if (!plib::container::contains(m_step_devices, &p->device()))
|
||||
m_step_devices.push_back(&p->device());
|
||||
@ -136,7 +136,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
}
|
||||
log().debug("Added terminal {1}\n", p->name());
|
||||
break;
|
||||
case terminal_t::INPUT:
|
||||
case detail::terminal_type::INPUT:
|
||||
{
|
||||
proxied_analog_output_t *net_proxy_output = nullptr;
|
||||
for (auto & input : m_inps)
|
||||
@ -160,7 +160,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
log().debug("Added input\n");
|
||||
}
|
||||
break;
|
||||
case terminal_t::OUTPUT:
|
||||
case detail::terminal_type::OUTPUT:
|
||||
log().fatal(MF_1_UNHANDLED_ELEMENT_1_FOUND,
|
||||
p->name());
|
||||
break;
|
||||
|
@ -280,9 +280,9 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_solve()
|
||||
const nl_double * RESTRICT pi = &A(i,i+1);
|
||||
nl_double * RESTRICT pj = &A(j,i+1);
|
||||
#if 1
|
||||
vec_add_mult_scalar(kN-i,pi,f1,pj);
|
||||
vec_add_mult_scalar_p(kN-i,pi,f1,pj);
|
||||
#else
|
||||
vec_add_mult_scalar(kN-i-1,pj,f1,pi);
|
||||
vec_add_mult_scalar_p(kN-i-1,pj,f1,pi);
|
||||
//for (unsigned k = i+1; k < kN; k++)
|
||||
// pj[k] = pj[k] + pi[k] * f1;
|
||||
//for (unsigned k = i+1; k < kN; k++)
|
||||
|
@ -319,7 +319,7 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt
|
||||
m_A[mat.diag[k]] += gtot_t;
|
||||
}
|
||||
#endif
|
||||
mat.ia[iN] = mat.nz_num;
|
||||
mat.ia[iN] = static_cast<mattype>(mat.nz_num);
|
||||
|
||||
/* now solve it */
|
||||
|
||||
|
@ -166,7 +166,7 @@ unsigned matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool ne
|
||||
mat.A[pi] -= go[i];
|
||||
}
|
||||
}
|
||||
mat.ia[iN] = mat.nz_num;
|
||||
mat.ia[iN] = static_cast<mattype>(mat.nz_num);
|
||||
|
||||
const nl_double accuracy = this->m_params.m_accuracy;
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "omp.h"
|
||||
#endif
|
||||
|
||||
#include "nl_factory.h"
|
||||
|
||||
#include "nld_solver.h"
|
||||
#include "nld_matrix_solver.h"
|
||||
|
||||
@ -215,7 +217,7 @@ struct net_splitter
|
||||
groups.back().push_back(n);
|
||||
for (auto &p : n->m_core_terms)
|
||||
{
|
||||
if (p->is_type(terminal_t::TERMINAL))
|
||||
if (p->is_type(detail::terminal_type::TERMINAL))
|
||||
{
|
||||
terminal_t *pt = static_cast<terminal_t *>(p);
|
||||
analog_net_t *other_net = &pt->m_otherterm->net();
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "nl_setup.h"
|
||||
#include "nl_base.h"
|
||||
#include "plib/pstream.h"
|
||||
#include "solver/nld_matrix_solver.h"
|
||||
@ -18,17 +17,6 @@
|
||||
//#define ATTR_ALIGNED(N) __attribute__((aligned(N)))
|
||||
#define ATTR_ALIGNED(N) ATTR_ALIGN
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef NL_AUTO_DEVICES
|
||||
|
||||
#define SOLVER(name, freq) \
|
||||
NET_REGISTER_DEV(SOLVER, name) \
|
||||
PARAM(name.FREQ, freq)
|
||||
|
||||
#endif
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// solver
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
2
src/lib/netlist/solver/vector_base.h
Normal file → Executable file
2
src/lib/netlist/solver/vector_base.h
Normal file → Executable file
@ -86,7 +86,7 @@ inline static void vec_add_mult_scalar (const std::size_t n, const T (& RESTRICT
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static void vec_add_mult_scalar (const std::size_t & n, const T * RESTRICT v, const T scalar, T * RESTRICT result)
|
||||
inline static void vec_add_mult_scalar_p(const std::size_t & n, const T * RESTRICT v, const T scalar, T * RESTRICT result)
|
||||
{
|
||||
for ( std::size_t i = 0; i < n; i++ )
|
||||
result[i] += scalar * v[i];
|
||||
|
@ -1,4 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrew Gardner, Couriersud
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
NETLIST_EXTERNAL(kidniki)
|
||||
|
@ -1,4 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
NETLIST_EXTERNAL(hazelvid)
|
||||
|
@ -7,13 +7,13 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "netlist/devices/net_lib.h"
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
#define NL_PROHIBIT_BASEH_INCLUDE 1
|
||||
#include "netlist/devices/net_lib.h"
|
||||
#endif
|
||||
|
||||
#define FAST_CLOCK (1)
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
#endif
|
||||
|
||||
NETLIST_START(pong_fast)
|
||||
|
||||
SOLVER(Solver, 48000)
|
||||
|
@ -1,4 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
NETLIST_EXTERNAL(stuntcyc)
|
||||
|
Loading…
Reference in New Issue
Block a user