mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
netlist: code maintenance. (nw)
Simplification, remove some trampolines.
This commit is contained in:
parent
3ff1066d43
commit
beab34006a
@ -522,7 +522,7 @@ public:
|
||||
if (i != m_num_channels)
|
||||
state().log().fatal("sound input numbering has to be sequential!");
|
||||
m_num_channels++;
|
||||
m_channels[i].m_param = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_channels[i].m_param_name)(), true));
|
||||
m_channels[i].m_param = dynamic_cast<netlist::param_double_t *>(state().setup().find_param((*m_channels[i].m_param_name)(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace netlist
|
||||
|
||||
logic_output_t m_DO;
|
||||
|
||||
state_array<uint8_t, 128> m_ram; // 1024x1 bits
|
||||
state_container<std::array<uint8_t, 128>> m_ram; // 1024x1 bits
|
||||
param_ptr_t m_RAM;
|
||||
nld_power_pins m_power_pins;
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ namespace netlist
|
||||
logic_input_t m_DIN;
|
||||
logic_output_t m_DOUTQ;
|
||||
|
||||
state_array<uint64_t, 4> m_ram; // 256 bits
|
||||
state_container<std::array<uint64_t, 4>> m_ram; // 256 bits
|
||||
state_var_u8 m_addr; // 256 bits
|
||||
state_var_sig m_enq;
|
||||
nld_power_pins m_power_pins;
|
||||
|
@ -32,7 +32,7 @@ namespace netlist
|
||||
logic_input_t m_RC;
|
||||
logic_input_t m_IN;
|
||||
|
||||
state_array<uint16_t, 5> m_buffer;
|
||||
state_container<std::array<uint16_t, 5>> m_buffer;
|
||||
|
||||
logic_output_t m_OUT;
|
||||
nld_power_pins m_power_pins;
|
||||
|
@ -92,9 +92,9 @@ namespace netlist
|
||||
for (auto & pwr_sym : power_syms)
|
||||
{
|
||||
pstring devname = out_proxied->device().name();
|
||||
auto tp_t = setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
auto tp_t = state().setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
auto tn_t = setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
auto tn_t = state().setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(out_proxied->device().name(),
|
||||
@ -113,9 +113,9 @@ namespace netlist
|
||||
if (!f)
|
||||
{
|
||||
if (logic_family()->fixed_V() == 0.0)
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(setup().de_alias(out_proxied->device().name())));
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name())));
|
||||
else
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(setup().de_alias(out_proxied->device().name())));
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name())));
|
||||
m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
|
||||
m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
|
||||
|
||||
@ -126,7 +126,7 @@ namespace netlist
|
||||
else
|
||||
{
|
||||
log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
|
||||
if (setup().is_extended_validation())
|
||||
if (state().setup().is_extended_validation())
|
||||
{
|
||||
// During validation, don't connect to terminals found
|
||||
// This will cause terminals not connected to a rail net to
|
||||
|
@ -231,7 +231,7 @@ namespace devices
|
||||
/* make sure we get the family first */
|
||||
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
|
||||
{
|
||||
set_logic_family(setup().family_from_model(m_FAMILY()));
|
||||
set_logic_family(state().setup().family_from_model(m_FAMILY()));
|
||||
m_Q.set_logic_family(this->logic_family());
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ namespace devices
|
||||
nld_power_pins(device_t &owner, const pstring &sVCC = "VCC",
|
||||
const pstring &sGND = "GND", bool force_analog_input = false)
|
||||
{
|
||||
if (owner.setup().is_extended_validation() || force_analog_input)
|
||||
if (owner.state().setup().is_extended_validation() || force_analog_input)
|
||||
{
|
||||
m_GND = plib::make_unique<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
|
||||
m_VCC = plib::make_unique<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop));
|
||||
|
@ -561,7 +561,7 @@ namespace netlist
|
||||
: core_device_t(owner, name)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
setup_t &device_t::setup() noexcept
|
||||
{
|
||||
return state().setup();
|
||||
@ -571,13 +571,14 @@ namespace netlist
|
||||
{
|
||||
return state().setup();
|
||||
}
|
||||
#endif
|
||||
|
||||
void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term)
|
||||
{
|
||||
pstring alias = this->name() + "." + name;
|
||||
|
||||
// everything already fully qualified
|
||||
setup().register_alias_nofqn(alias, term.name());
|
||||
state().setup().register_alias_nofqn(alias, term.name());
|
||||
}
|
||||
|
||||
void device_t::register_subalias(const pstring &name, const pstring &aliased)
|
||||
@ -586,17 +587,17 @@ namespace netlist
|
||||
pstring aliased_fqn = this->name() + "." + aliased;
|
||||
|
||||
// everything already fully qualified
|
||||
setup().register_alias_nofqn(alias, aliased_fqn);
|
||||
state().setup().register_alias_nofqn(alias, aliased_fqn);
|
||||
}
|
||||
|
||||
void device_t::connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
|
||||
{
|
||||
setup().register_link_fqn(t1.name(), t2.name());
|
||||
state().setup().register_link_fqn(t1.name(), t2.name());
|
||||
}
|
||||
|
||||
void device_t::connect(const pstring &t1, const pstring &t2)
|
||||
{
|
||||
setup().register_link_fqn(name() + "." + t1, name() + "." + t2);
|
||||
state().setup().register_link_fqn(name() + "." + t1, name() + "." + t2);
|
||||
}
|
||||
|
||||
/* FIXME: this is only used by solver code since matrix solvers are started in
|
||||
@ -604,7 +605,7 @@ namespace netlist
|
||||
*/
|
||||
void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
|
||||
{
|
||||
if (!setup().connect(t1, t2))
|
||||
if (!state().setup().connect(t1, t2))
|
||||
log().fatal(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name()));
|
||||
}
|
||||
|
||||
@ -620,7 +621,7 @@ namespace netlist
|
||||
|
||||
detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc)
|
||||
{
|
||||
dev.set_logic_family(dev.setup().family_from_model(desc));
|
||||
dev.set_logic_family(dev.state().setup().family_from_model(desc));
|
||||
}
|
||||
|
||||
detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc)
|
||||
@ -870,7 +871,7 @@ namespace netlist
|
||||
param_t::param_t(device_t &device, const pstring &name)
|
||||
: device_object_t(device, device.name() + "." + name)
|
||||
{
|
||||
device.setup().register_param_t(this->name(), *this);
|
||||
device.state().setup().register_param_t(this->name(), *this);
|
||||
}
|
||||
|
||||
param_t::param_type_t param_t::param_type() const
|
||||
@ -900,7 +901,7 @@ namespace netlist
|
||||
|
||||
pstring param_t::get_initial(const device_t &dev, bool *found)
|
||||
{
|
||||
pstring res = dev.setup().get_initial_param_val(this->name(), "");
|
||||
pstring res = dev.state().setup().get_initial_param_val(this->name(), "");
|
||||
*found = (res != "");
|
||||
return res;
|
||||
}
|
||||
@ -913,7 +914,7 @@ namespace netlist
|
||||
param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val)
|
||||
: param_t(device, name)
|
||||
{
|
||||
m_param = device.setup().get_initial_param_val(this->name(),val);
|
||||
m_param = device.state().setup().get_initial_param_val(this->name(),val);
|
||||
}
|
||||
|
||||
void param_str_t::changed()
|
||||
@ -945,7 +946,7 @@ namespace netlist
|
||||
|
||||
plib::unique_ptr<std::istream> param_data_t::stream()
|
||||
{
|
||||
return device().setup().get_data_stream(str());
|
||||
return device().state().setup().get_data_stream(str());
|
||||
}
|
||||
|
||||
bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
|
||||
|
@ -187,20 +187,13 @@ namespace netlist
|
||||
namespace devices
|
||||
{
|
||||
class matrix_solver_t;
|
||||
class NETLIB_NAME(gnd);
|
||||
class NETLIB_NAME(solver);
|
||||
class NETLIB_NAME(mainclock);
|
||||
class NETLIB_NAME(netlistparams);
|
||||
class NETLIB_NAME(base_proxy);
|
||||
class NETLIB_NAME(base_d_to_a_proxy);
|
||||
class NETLIB_NAME(base_a_to_d_proxy);
|
||||
} // namespace devices
|
||||
|
||||
namespace detail {
|
||||
struct family_setter_t;
|
||||
class queue_t;
|
||||
} // namespace detail
|
||||
|
||||
class logic_output_t;
|
||||
class logic_input_t;
|
||||
class analog_net_t;
|
||||
@ -210,7 +203,6 @@ namespace netlist
|
||||
class netlist_state_t;
|
||||
class core_device_t;
|
||||
class device_t;
|
||||
class callbacks_t;
|
||||
|
||||
//============================================================
|
||||
// Exceptions
|
||||
@ -351,24 +343,32 @@ namespace netlist
|
||||
* Use this state_var template to define an array whose contents are saved.
|
||||
* Please refer to \ref state_var.
|
||||
*/
|
||||
template <typename T, std::size_t N>
|
||||
struct state_array : public std::array<T, N>
|
||||
template <typename C>
|
||||
struct state_container : public C
|
||||
{
|
||||
public:
|
||||
using value_type = typename C::value_type;
|
||||
//! Constructor.
|
||||
template <typename O>
|
||||
state_array(O &owner, //!< owner must have a netlist() method.
|
||||
const pstring &name, //!< identifier/name for this state variable
|
||||
const T &value //!< Initial value after construction
|
||||
state_container(O &owner, //!< owner must have a netlist() method.
|
||||
const pstring &name, //!< identifier/name for this state variable
|
||||
const value_type &value //!< Initial value after construction
|
||||
);
|
||||
//! Constructor.
|
||||
template <typename O>
|
||||
state_container(O &owner, //!< owner must have a netlist() method.
|
||||
const pstring &name, //!< identifier/name for this state variable
|
||||
std::size_t n, //!< number of elements to allocate
|
||||
const value_type &value //!< Initial value after construction
|
||||
);
|
||||
//! Copy Constructor.
|
||||
state_array(const state_array &rhs) noexcept = default;
|
||||
state_container(const state_container &rhs) noexcept = default;
|
||||
//! Destructor.
|
||||
~state_array() noexcept = default;
|
||||
~state_container() noexcept = default;
|
||||
//! Move Constructor.
|
||||
state_array(state_array &&rhs) noexcept = default;
|
||||
state_array &operator=(const state_array &rhs) noexcept = default;
|
||||
state_array &operator=(state_array &&rhs) noexcept = default;
|
||||
state_container(state_container &&rhs) noexcept = default;
|
||||
state_container &operator=(const state_container &rhs) noexcept = default;
|
||||
state_container &operator=(state_container &&rhs) noexcept = default;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -471,9 +471,6 @@ namespace netlist
|
||||
netlist_state_t & state() noexcept;
|
||||
const netlist_state_t & state() const noexcept;
|
||||
|
||||
setup_t & setup() noexcept;
|
||||
const setup_t & setup() const noexcept;
|
||||
|
||||
netlist_t & exec() noexcept { return m_netlist; }
|
||||
const netlist_t & exec() const noexcept { return m_netlist; }
|
||||
|
||||
@ -1244,9 +1241,6 @@ namespace netlist
|
||||
|
||||
~device_t() noexcept override = default;
|
||||
|
||||
setup_t &setup() noexcept;
|
||||
const setup_t &setup() const noexcept;
|
||||
|
||||
template<class C, typename... Args>
|
||||
void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args)
|
||||
{
|
||||
@ -1271,62 +1265,66 @@ namespace netlist
|
||||
// family_setter_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct detail::family_setter_t
|
||||
{
|
||||
/* clang will complain about an unused private field if
|
||||
* a defaulted constructor is used
|
||||
namespace detail {
|
||||
|
||||
struct family_setter_t
|
||||
{
|
||||
/* clang will complain about an unused private field if
|
||||
* a defaulted constructor is used
|
||||
*/
|
||||
// NOLINTNEXTLINE(modernize-use-equals-default)
|
||||
family_setter_t();
|
||||
family_setter_t(core_device_t &dev, const pstring &desc);
|
||||
family_setter_t(core_device_t &dev, const logic_family_desc_t *desc);
|
||||
};
|
||||
|
||||
template <class T, bool TS>
|
||||
using timed_queue = plib::timed_queue_linear<T, TS>;
|
||||
|
||||
/* Use timed_queue_heap to use stdc++ heap functions instead of linear processing.
|
||||
* This slows down processing by about 25% on a Kaby Lake.
|
||||
*/
|
||||
// NOLINTNEXTLINE(modernize-use-equals-default)
|
||||
family_setter_t();
|
||||
family_setter_t(core_device_t &dev, const pstring &desc);
|
||||
family_setter_t(core_device_t &dev, const logic_family_desc_t *desc);
|
||||
};
|
||||
|
||||
template <class T, bool TS>
|
||||
using timed_queue = plib::timed_queue_linear<T, TS>;
|
||||
//template <class T, bool TS>
|
||||
//using timed_queue = timed_queue_heap<T, TS>;
|
||||
|
||||
/* Use timed_queue_heap to use stdc++ heap functions instead of linear processing.
|
||||
* This slows down processing by about 25% on a Kaby Lake.
|
||||
*/
|
||||
// -----------------------------------------------------------------------------
|
||||
// queue_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//template <class T, bool TS>
|
||||
//using timed_queue = timed_queue_heap<T, TS>;
|
||||
/* We don't need a thread-safe queue currently. Parallel processing of
|
||||
* solvers will update inputs after parallel processing.
|
||||
*/
|
||||
class queue_t :
|
||||
//public timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
|
||||
public timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>,
|
||||
public netlist_ref,
|
||||
public plib::state_manager_t::callback_t
|
||||
{
|
||||
public:
|
||||
using base_queue = timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>;
|
||||
using entry_t = plib::pqentry_t<net_t *, netlist_time>;
|
||||
explicit queue_t(netlist_state_t &nl);
|
||||
virtual ~queue_t() noexcept = default;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// queue_t
|
||||
// -----------------------------------------------------------------------------
|
||||
queue_t(const queue_t &) = delete;
|
||||
queue_t(queue_t &&) = delete;
|
||||
queue_t &operator=(const queue_t &) = delete;
|
||||
queue_t &operator=(queue_t &&) = delete;
|
||||
|
||||
/* We don't need a thread-safe queue currently. Parallel processing of
|
||||
* solvers will update inputs after parallel processing.
|
||||
*/
|
||||
class detail::queue_t :
|
||||
//public timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
|
||||
public timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>,
|
||||
public detail::netlist_ref,
|
||||
public plib::state_manager_t::callback_t
|
||||
{
|
||||
public:
|
||||
using base_queue = timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>;
|
||||
using entry_t = plib::pqentry_t<net_t *, netlist_time>;
|
||||
explicit queue_t(netlist_state_t &nl);
|
||||
virtual ~queue_t() noexcept = default;
|
||||
protected:
|
||||
|
||||
queue_t(const queue_t &) = delete;
|
||||
queue_t(queue_t &&) = delete;
|
||||
queue_t &operator=(const queue_t &) = delete;
|
||||
queue_t &operator=(queue_t &&) = delete;
|
||||
void register_state(plib::state_manager_t &manager, const pstring &module) override;
|
||||
void on_pre_save(plib::state_manager_t &manager) override;
|
||||
void on_post_load(plib::state_manager_t &manager) override;
|
||||
|
||||
protected:
|
||||
private:
|
||||
std::size_t m_qsize;
|
||||
std::vector<netlist_time::internal_type> m_times;
|
||||
std::vector<std::size_t> m_net_ids;
|
||||
};
|
||||
|
||||
void register_state(plib::state_manager_t &manager, const pstring &module) override;
|
||||
void on_pre_save(plib::state_manager_t &manager) override;
|
||||
void on_post_load(plib::state_manager_t &manager) override;
|
||||
|
||||
private:
|
||||
std::size_t m_qsize;
|
||||
std::vector<netlist_time::internal_type> m_times;
|
||||
std::vector<std::size_t> m_net_ids;
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// netlist_state__t
|
||||
@ -1666,16 +1664,6 @@ namespace netlist
|
||||
return m_netlist.nlstate();
|
||||
}
|
||||
|
||||
inline setup_t & detail::netlist_ref::setup() noexcept
|
||||
{
|
||||
return m_netlist.nlstate().setup();
|
||||
}
|
||||
|
||||
inline const setup_t & detail::netlist_ref::setup() const noexcept
|
||||
{
|
||||
return m_netlist.nlstate().setup();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
param_num_t<T>::param_num_t(device_t &device, const pstring &name, const T val)
|
||||
: param_t(device, name)
|
||||
@ -1909,15 +1897,25 @@ namespace netlist
|
||||
owner.state().save(owner, m_value, owner.name(), name);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
template <typename C>
|
||||
template <typename O>
|
||||
state_array<T,N>::state_array(O &owner, const pstring &name, const T & value)
|
||||
state_container<C>::state_container(O &owner, const pstring &name,
|
||||
const state_container<C>::value_type & value)
|
||||
{
|
||||
owner.state().save(owner, *static_cast<std::array<T, N> *>(this), owner.name(), name);
|
||||
for (std::size_t i=0; i<N; i++)
|
||||
owner.state().save(owner, *static_cast<C *>(this), owner.name(), name);
|
||||
for (std::size_t i=0; i < this->size(); i++)
|
||||
(*this)[i] = value;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
template <typename O>
|
||||
state_container<C>::state_container(O &owner, const pstring &name,
|
||||
std::size_t n, const state_container<C>::value_type & value)
|
||||
: C(n, value)
|
||||
{
|
||||
owner.state().save(owner, *static_cast<C *>(this), owner.name(), name);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Hot section
|
||||
//
|
||||
|
@ -94,15 +94,8 @@
|
||||
// Use nano-second resolution - Sufficient for now
|
||||
|
||||
static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
|
||||
//static constexpr const auto NETLIST_INTERNAL_RES = 1000000000000;
|
||||
static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
|
||||
|
||||
//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000))
|
||||
//#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
|
||||
//#define NETLIST_INTERNAL_RES (UINT64_C(1000000000000))
|
||||
//#define NETLIST_CLOCK (UINT64_C(1000000000))
|
||||
|
||||
|
||||
//#define nl_double float
|
||||
using nl_double = double;
|
||||
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
|
||||
state_manager_t() = default;
|
||||
|
||||
template<typename C>
|
||||
template<typename C> //, typename std::enable_if<std::is_integral<C>::value || std::is_floating_point<C>::value>::type>
|
||||
void save_item(const void *owner, C &state, const pstring &stname)
|
||||
{
|
||||
save_state_ptr( owner, stname, dtype<C>(), 1, &state);
|
||||
@ -101,8 +101,8 @@ public:
|
||||
save_state_ptr(owner, stname, dtype<C>(), count, state);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
void save_item(const void *owner, std::vector<C> &v, const pstring &stname)
|
||||
template<typename C, typename A>
|
||||
void save_item(const void *owner, std::vector<C, A> &v, const pstring &stname)
|
||||
{
|
||||
save_state_ptr(owner, stname, dtype<C>(), v.size(), v.data());
|
||||
}
|
||||
|
@ -16,10 +16,7 @@ namespace devices
|
||||
{
|
||||
|
||||
terms_for_net_t::terms_for_net_t(analog_net_t * net)
|
||||
: m_last_V(0.0)
|
||||
, m_DD_n_m_1(0.0)
|
||||
, m_h_n_m_1(1e-12)
|
||||
, m_net(net)
|
||||
: m_net(net)
|
||||
, m_railstart(0)
|
||||
{
|
||||
}
|
||||
@ -342,14 +339,19 @@ namespace devices
|
||||
/*
|
||||
* save states
|
||||
*/
|
||||
|
||||
m_last_V.resize(iN, plib::constants<nl_double>::zero());
|
||||
m_DD_n_m_1.resize(iN, plib::constants<nl_double>::zero());
|
||||
m_h_n_m_1.resize(iN, plib::constants<nl_double>::zero());
|
||||
|
||||
state().save(*this, m_last_V.as_base(), this->name(), "m_last_V");
|
||||
state().save(*this, m_DD_n_m_1.as_base(), this->name(), "m_DD_n_m_1");
|
||||
state().save(*this, m_h_n_m_1.as_base(), this->name(), "m_h_n_m_1");
|
||||
|
||||
for (std::size_t k = 0; k < iN; k++)
|
||||
{
|
||||
pstring num = plib::pfmt("{1}")(k);
|
||||
|
||||
state().save(*this, m_terms[k].m_last_V, this->name(), "lastV." + num);
|
||||
state().save(*this, m_terms[k].m_DD_n_m_1, this->name(), "m_DD_n_m_1." + num);
|
||||
state().save(*this, m_terms[k].m_h_n_m_1, this->name(), "m_h_n_m_1." + num);
|
||||
|
||||
// FIXME: This shouldn't be necessary, recalculate on each entry ...
|
||||
state().save(*this, m_gonn[k],"GO" + num, this->name(), m_terms[k].count());
|
||||
state().save(*this, m_gtn[k],"GT" + num, this->name(), m_terms[k].count());
|
||||
@ -559,19 +561,21 @@ namespace devices
|
||||
|
||||
if (m_params.m_dynamic_ts)
|
||||
{
|
||||
for (auto &t : m_terms)
|
||||
for (std::size_t k = 0; k < m_terms.size(); k++)
|
||||
{
|
||||
auto &t = m_terms[k];
|
||||
//const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
|
||||
// avoid floating point exceptions
|
||||
const nl_double DD_n = std::max(-1e100, std::min(1e100,(t.getV() - t.m_last_V)));
|
||||
|
||||
const nl_double DD_n = std::max(-1e100, std::min(1e100,(t.getV() - m_last_V[k])));
|
||||
const nl_double hn = cur_ts;
|
||||
|
||||
//printf("%g %g %g %g\n", DD_n, hn, t.m_DD_n_m_1, t.m_h_n_m_1);
|
||||
nl_double DD2 = (DD_n / hn - t.m_DD_n_m_1 / t.m_h_n_m_1) / (hn + t.m_h_n_m_1);
|
||||
nl_double DD2 = (DD_n / hn - m_DD_n_m_1[k] / m_h_n_m_1[k]) / (hn + m_h_n_m_1[k]);
|
||||
nl_double new_net_timestep(0);
|
||||
|
||||
t.m_h_n_m_1 = hn;
|
||||
t.m_DD_n_m_1 = DD_n;
|
||||
m_h_n_m_1[k] = hn;
|
||||
m_DD_n_m_1[k] = DD_n;
|
||||
if (std::fabs(DD2) > plib::constants<nl_double>::cast(1e-60)) // avoid div-by-zero
|
||||
new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::fabs(plib::constants<nl_double>::cast(0.5)*DD2));
|
||||
else
|
||||
@ -580,7 +584,7 @@ namespace devices
|
||||
if (new_net_timestep < new_solver_timestep)
|
||||
new_solver_timestep = new_net_timestep;
|
||||
|
||||
t.m_last_V = t.getV();
|
||||
m_last_V[k] = t.getV();
|
||||
}
|
||||
if (new_solver_timestep < m_params.m_min_timestep)
|
||||
{
|
||||
|
@ -136,11 +136,6 @@ namespace devices
|
||||
plib::aligned_vector<unsigned> m_nzrd; /* non zero right of the diagonal for elimination, may include RHS element */
|
||||
plib::aligned_vector<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
|
||||
|
||||
/* state */
|
||||
nl_double m_last_V;
|
||||
nl_double m_DD_n_m_1;
|
||||
nl_double m_h_n_m_1;
|
||||
|
||||
plib::aligned_vector<int> m_connected_net_idx;
|
||||
private:
|
||||
analog_net_t * m_net;
|
||||
@ -375,6 +370,17 @@ namespace devices
|
||||
plib::aligned_vector<terms_for_net_t> m_terms;
|
||||
plib::aligned_vector<terms_for_net_t> m_rails_temp;
|
||||
|
||||
/* state - variable time_stepping */
|
||||
plib::aligned_vector<nl_double> m_last_V;
|
||||
plib::aligned_vector<nl_double> m_DD_n_m_1;
|
||||
plib::aligned_vector<nl_double> m_h_n_m_1;
|
||||
|
||||
// FIXME: it should be like this, however dimensions are determined
|
||||
// in vsetup.
|
||||
//state_container<std::vector<nl_double>> m_last_V;
|
||||
//state_container<std::vector<nl_double>> m_DD_n_m_1;
|
||||
//state_container<std::vector<nl_double>> m_h_n_m_1;
|
||||
|
||||
std::vector<unique_pool_ptr<proxied_analog_output_t>> m_inps;
|
||||
|
||||
const solver_parameters_t &m_params;
|
||||
@ -385,6 +391,9 @@ namespace devices
|
||||
state_var<int> m_iterative_fail;
|
||||
state_var<int> m_iterative_total;
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
state_var<netlist_time> m_last_step;
|
||||
|
@ -24,10 +24,6 @@ namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
{
|
||||
class NETLIB_NAME(solver);
|
||||
|
||||
class matrix_solver_t;
|
||||
|
||||
NETLIB_OBJECT(solver)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(solver)
|
||||
|
Loading…
Reference in New Issue
Block a user