netlist: more family/model alignment. (nw)

Also remove dead code and dead comments.
This commit is contained in:
couriersud 2020-05-10 20:38:14 +02:00
parent 227ab3025e
commit c4381db330
17 changed files with 142 additions and 102 deletions

View File

@ -178,7 +178,7 @@ namespace analog
, m_gB(nlconst::cgmin())
, m_gC(nlconst::cgmin())
, m_V(nlconst::zero())
, m_state_on(*this, "m_state_on", 0u)
, m_state_on(*this, "m_state_on", 0U)
{
register_subalias("B", m_RB.P());
register_subalias("E", m_RB.N());

View File

@ -33,7 +33,6 @@ namespace netlist
friend class NETLIB_NAME(74107_dip);
friend class NETLIB_NAME(74107);
//friend class NETLIB_NAME(74107A_dip);
NETLIB_RESETI();
NETLIB_UPDATEI();

View File

@ -64,19 +64,19 @@
// FIXME ... remove parameters
#define SYS_DSW(name, pI, p1, p2) \
NET_REGISTER_DEVEXT(SYS_DSW, name, pI, p1, p2)
NET_REGISTER_DEVEXT(SYS_DSW, name, pI, p1, p2)
#define SYS_DSW2(name) \
NET_REGISTER_DEV(SYS_DSW2, name)
NET_REGISTER_DEV(SYS_DSW2, name)
#define SYS_COMPD(name) \
NET_REGISTER_DEV(SYS_COMPD, name)
NET_REGISTER_DEV(SYS_COMPD, name)
#define SYS_NOISE_MT_U(name, pSIGMA) \
NET_REGISTER_DEVEXT(SYS_NOISE_MT_U, name, pSIGMA)
NET_REGISTER_DEVEXT(SYS_NOISE_MT_U, name, pSIGMA)
#define SYS_NOISE_MT_N(name, pSIGMA) \
NET_REGISTER_DEVEXT(SYS_NOISE_MT_N, name, pSIGMA)
NET_REGISTER_DEVEXT(SYS_NOISE_MT_N, name, pSIGMA)
/* Default device to hold netlist parameters */
#define PARAMETERS(name) \

View File

@ -75,7 +75,9 @@ NETLIST_END()
* ---------------------------------------------------------------------------*/
static NETLIST_START(family_models)
NET_MODEL("FAMILY _(TYPE=CUSTOM IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130.0)")
// FAMILIES always need a type. UNKNOWN below will break
NET_MODEL("FAMILY _(TYPE=UNKNOWN IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130.0)")
NET_MODEL("OPAMP _()")
NET_MODEL("SCHMITT_TRIGGER _()")

View File

@ -96,7 +96,7 @@ static NETLIST_START(NE566_DIP)
RES(ROSQ, 5200)
PARAM(VO.RO, 50)
PARAM(COMP.MODEL, "FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.1 ORL=50 ORH=50)")
PARAM(COMP.MODEL, "FAMILY(TYPE=CUSTOM IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.1 ORL=50 ORH=50)")
PARAM(SW.GOFF, 0) // This has to be zero to block current sources
NET_C(CI2.IN, VI.OP)

View File

@ -448,7 +448,7 @@ namespace netlist
}
auto trigger = total_count * 200 / 1000000; // 200 ppm
for (auto &entry : this->m_devices)
for (const auto &entry : this->m_devices)
{
auto *ep = entry.second.get();
auto *stats = ep->stats();
@ -876,11 +876,6 @@ namespace netlist
return res;
}
pstring param_model_t::type()
{
return state().setup().models().type(str());
}
param_str_t::param_str_t(core_device_t &device, const pstring &name, const pstring &val)
: param_t(device, name)
{
@ -902,14 +897,20 @@ namespace netlist
{
}
pstring param_model_t::type()
{
auto mod = state().setup().models().get_model(str());
return mod.type();
}
pstring param_model_t::value_str(const pstring &entity)
{
return state().setup().models().value_str(str(), entity);
return state().setup().models().get_model(str()).value_str(entity);
}
nl_fptype param_model_t::value(const pstring &entity)
{
return state().setup().models().value(str(), entity);
return state().setup().models().get_model(str()).value(entity);
}

View File

@ -1160,10 +1160,16 @@ namespace netlist
class value_base_t
{
public:
value_base_t(param_model_t &param, const pstring &name)
template <typename P, typename Y=T, typename DUMMY = typename std::enable_if<plib::is_arithmetic<Y>::value>::type>
value_base_t(P &param, const pstring &name)
: m_value(static_cast<T>(param.value(name)))
{
}
template <typename P, typename Y=T, typename std::enable_if<!plib::is_arithmetic<Y>::value, int>::type = 0>
value_base_t(P &param, const pstring &name)
: m_value(static_cast<T>(param.value_str(name)))
{
}
T operator()() const noexcept { return m_value; }
operator T() const noexcept { return m_value; }
private:
@ -1171,6 +1177,7 @@ namespace netlist
};
using value_t = value_base_t<nl_fptype>;
using value_str_t = value_base_t<pstring>;
param_model_t(core_device_t &device, const pstring &name, const pstring &val)
: param_str_t(device, name, val) { }
@ -1307,7 +1314,7 @@ namespace netlist
// base_device_t
// -----------------------------------------------------------------------------
class base_device_t : public core_device_t
class base_device_t : public core_device_t
{
public:
base_device_t(netlist_state_t &owner, const pstring &name);
@ -1337,7 +1344,7 @@ namespace netlist
// device_t
// -----------------------------------------------------------------------------
class device_t : public base_device_t,
class device_t : public base_device_t,
public logic_family_t
{
public:
@ -1626,7 +1633,7 @@ namespace netlist
struct stats_info
{
const detail::queue_t &m_queue;// performance
const detail::queue_t &m_queue;// performance
const plib::pperftime_t<true> &m_stat_mainloop;
const plib::pperfcount_t<true> &m_perf_out_processed;
};
@ -1645,7 +1652,7 @@ namespace netlist
pstring m_name;
unique_pool_ptr<netlist_t> m_netlist;
plib::unique_ptr<plib::dynlib_base> m_lib; // external lib needs to be loaded as long as netlist exists
plib::unique_ptr<plib::dynlib_base> m_lib;
plib::state_manager_t m_state;
plib::unique_ptr<callbacks_t> m_callbacks;
log_type m_log;
@ -1655,8 +1662,8 @@ namespace netlist
// sole use is to manage lifetime of net objects
devices_collection_type m_devices;
// sole use is to manage lifetime of family objects
family_collection_type m_family_cache;
bool m_extended_validation;
family_collection_type m_family_cache;
bool m_extended_validation;
// dummy version
int m_dummy_version;

View File

@ -1115,7 +1115,7 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map)
}
}
pstring models_t::model_string(const model_map_t &map)
pstring models_t::model_t::model_string(const model_map_t &map)
{
// operator [] has no const implementation
pstring ret = map.at("COREMODEL") + "(";
@ -1125,29 +1125,30 @@ pstring models_t::model_string(const model_map_t &map)
return ret + ")";
}
pstring models_t::value_str(const pstring &model, const pstring &entity)
models_t::model_t models_t::get_model(const pstring &model)
{
model_map_t &map = m_cache[model];
if (map.empty())
model_parse(model , map);
if (entity != plib::ucase(entity))
throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(map)));
if (map.find(entity) == map.end())
throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(map)));
return map[entity];
return model_t(model, map);
}
nl_fptype models_t::value(const pstring &model, const pstring &entity)
pstring models_t::model_t::value_str(const pstring &entity) const
{
model_map_t &map = m_cache[model];
if (entity != plib::ucase(entity))
throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(m_map)));
const auto it(m_map.find(entity));
if ( it == m_map.end())
throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map)));
if (map.empty())
model_parse(model , map);
return it->second;
}
pstring tmp = value_str(model, entity);
nl_fptype models_t::model_t::value(const pstring &entity) const
{
pstring tmp = value_str(entity);
nl_fptype factor = nlconst::one();
auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
@ -1164,7 +1165,7 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity)
case 'a': factor = nlconst::magic(1e-18); break; // NOLINT
default:
if (*p < '0' || *p > '9')
throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(model, entity));
throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity));
}
if (factor != nlconst::one())
tmp = plib::left(tmp, tmp.size() - 1);
@ -1173,10 +1174,11 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity)
bool err(false);
auto val = plib::pstonum_ne<nl_fptype>(tmp, err);
if (err)
throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", model));
throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", m_model));
return val * factor;
}
// FIXME: all this belongs elsewhere
P_ENUM(family_type,
@ -1185,7 +1187,7 @@ P_ENUM(family_type,
MOS,
CMOS,
NMOS,
PMOS);
PMOS)
class logic_family_std_proxy_t : public logic_family_desc_t
{
@ -1199,11 +1201,31 @@ public:
unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist,
const pstring &name, const logic_output_t *proxied) const override
{
switch(m_family_type)
{
case family_type::CUSTOM:
case family_type::TTL:
case family_type::MOS:
case family_type::CMOS:
case family_type::NMOS:
case family_type::PMOS:
return anetlist.make_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
return anetlist.make_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
unique_pool_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override
{
switch(m_family_type)
{
case family_type::CUSTOM:
case family_type::TTL:
case family_type::MOS:
case family_type::CMOS:
case family_type::NMOS:
case family_type::PMOS:
return anetlist.make_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
}
return anetlist.make_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
}
private:
@ -1229,8 +1251,10 @@ private:
class family_model_t
{
public:
family_model_t(param_model_t &model)
: m_IVL(model, "IVL")
template <typename P>
family_model_t(P &model)
: m_TYPE(model, "TYPE")
, m_IVL(model, "IVL")
, m_IVH(model, "IVH")
, m_OVL(model, "OVL")
, m_OVH(model, "OVH")
@ -1238,12 +1262,13 @@ public:
, m_ORH(model, "ORH")
{}
param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage
param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage
param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage
param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage
param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
param_model_t::value_str_t m_TYPE; //!< Family type (TTL, CMOS, ...)
param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage
param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage
param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage
param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage
param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
};
@ -1251,8 +1276,11 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
{
family_type ft(family_type::CUSTOM);
if (!ft.set_from_string(models().value_str(model, "TYPE")) || ft == family_type::CUSTOM)
throw nl_exception(MF_UNKNOWN_FAMILY_TYPE_1(models().value_str(model, "TYPE"), model));
auto mod(models().get_model(model));
family_model_t modv(mod);
if (!ft.set_from_string(modv.m_TYPE()))
throw nl_exception(MF_UNKNOWN_FAMILY_TYPE_1(modv.m_TYPE(), model));
auto it = m_nlstate.family_cache().find(model);
if (it != m_nlstate.family_cache().end())
@ -1260,12 +1288,12 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
auto ret = plib::make_unique<logic_family_std_proxy_t>(ft);
ret->m_low_thresh_PCNT = models().value(model, "IVL");
ret->m_high_thresh_PCNT = models().value(model, "IVH");
ret->m_low_VO = models().value(model, "OVL");
ret->m_high_VO = models(). value(model, "OVH");
ret->m_R_low = models().value(model, "ORL");
ret->m_R_high = models().value(model, "ORH");
ret->m_low_thresh_PCNT = modv.m_IVL();
ret->m_high_thresh_PCNT = modv.m_IVH();
ret->m_low_VO = modv.m_OVL();
ret->m_high_VO = modv.m_OVH();
ret->m_R_low = modv.m_ORL();
ret->m_R_high = modv.m_ORH();
auto *retp = ret.get();

View File

@ -68,7 +68,7 @@
#define NETLIST_START(name) \
void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
{ \
{ \
plib::unused_var(setup);
#define NETLIST_END() }
@ -183,8 +183,6 @@ namespace netlist
{
public:
friend class setup_t;
source_netlist_t() = default;
PCOPYASSIGNMOVE(source_netlist_t, delete)
@ -197,8 +195,6 @@ namespace netlist
{
public:
friend class setup_t;
source_data_t() = default;
PCOPYASSIGNMOVE(source_data_t, delete)
@ -212,20 +208,33 @@ namespace netlist
class models_t
{
public:
using model_map_t = std::unordered_map<pstring, pstring>;
class model_t
{
public:
model_t(const pstring &model, const model_map_t &map)
: m_model(model), m_map(map) { }
pstring value_str(const pstring &entity) const;
nl_fptype value(const pstring &entity) const;
pstring type() const { return value_str("COREMODEL"); }
private:
static pstring model_string(const model_map_t &map);
const pstring m_model; // only for error messages
const model_map_t &m_map;
};
void register_model(const pstring &model_in);
// model / family related
pstring value_str(const pstring &model, const pstring &entity);
nl_fptype value(const pstring &model, const pstring &entity);
pstring type(const pstring &model) { return value_str(model, "COREMODEL"); }
model_t get_model(const pstring &model);
private:
using model_map_t = std::unordered_map<pstring, pstring>;
void model_parse(const pstring &model, model_map_t &map);
static pstring model_string(const model_map_t &map);
std::unordered_map<pstring, pstring> m_models;
std::unordered_map<pstring, model_map_t> m_cache;

View File

@ -202,8 +202,6 @@ namespace plib {
timer &m_m;
};
friend struct guard_t;
timer() : m_time(0), m_count(0) { }
type operator()() const { return m_time; }

View File

@ -24,11 +24,11 @@ namespace plib
/// This is a Mersenne Twister implementation which is state saveable.
/// It has been written following this wikipedia entry:
///
/// https://en.wikipedia.org/wiki/Mersenne_Twister
/// https://en.wikipedia.org/wiki/Mersenne_Twister
///
/// The implementation has basic support for the interface described here
///
/// https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
/// https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
///
/// so that it can be used with the C++11 random environment
///
@ -187,27 +187,27 @@ namespace plib
FT s;
FT v1;
FT v2;
do
{
v1 = normalize_uniform(p, constants<FT>::two(), constants<FT>::one()); // [-1..1[
v2 = normalize_uniform(p, constants<FT>::two(), constants<FT>::one()); // [-1..1[
s = v1 * v1 + v2 * v2;
} while (s >= constants<FT>::one());
if (s == constants<FT>::zero())
{
m_buf[i] = s;
m_buf[i+1] = s;
}
else
{
// last value without error for log(s)/s
// double: 1.000000e-305
// float: 9.999999e-37
// FIXME: with 128 bit randoms log(s)/w will fail 1/(2^128) ~ 2.9e-39
const auto m(m_stddev * plib::sqrt(-constants<FT>::two() * plib::log(s)/s));
m_buf[i] = /*mean+*/ m * v1;
m_buf[i+1] = /*mean+*/ m * v2;
}
do
{
v1 = normalize_uniform(p, constants<FT>::two(), constants<FT>::one()); // [-1..1[
v2 = normalize_uniform(p, constants<FT>::two(), constants<FT>::one()); // [-1..1[
s = v1 * v1 + v2 * v2;
} while (s >= constants<FT>::one());
if (s == constants<FT>::zero())
{
m_buf[i] = s;
m_buf[i+1] = s;
}
else
{
// last value without error for log(s)/s
// double: 1.000000e-305
// float: 9.999999e-37
// FIXME: with 128 bit randoms log(s)/w will fail 1/(2^128) ~ 2.9e-39
const auto m(m_stddev * plib::sqrt(-constants<FT>::two() * plib::log(s)/s));
m_buf[i] = /*mean+*/ m * v1;
m_buf[i+1] = /*mean+*/ m * v2;
}
}
m_p = 0;
}

View File

@ -69,6 +69,10 @@ namespace plib
template<typename T> struct is_floating_point : public std::is_floating_point<T> { };
template< class T >
struct is_arithmetic : std::integral_constant<bool,
plib::is_integral<T>::value || plib::is_floating_point<T>::value> {};
#if PUSE_FLOAT128
template<> struct is_floating_point<FLOAT128> { static constexpr bool value = true; };
template<> struct numeric_limits<FLOAT128>

View File

@ -329,7 +329,6 @@ namespace solver
template <typename FT, int SIZE>
class matrix_solver_ext_t: public matrix_solver_t
{
friend class matrix_solver_t;
public:
using float_type = FT;

View File

@ -23,7 +23,6 @@ namespace solver
template <typename FT, int SIZE>
class matrix_solver_direct_t: public matrix_solver_ext_t<FT, SIZE>
{
friend class matrix_solver_t;
public:
using float_type = FT;

View File

@ -46,8 +46,6 @@ namespace solver
template <typename FT, int SIZE>
class matrix_solver_sm_t: public matrix_solver_ext_t<FT, SIZE>
{
friend class matrix_solver_t;
public:
using float_ext_type = FT;

View File

@ -26,8 +26,6 @@ namespace solver
template <typename FT, int SIZE>
class matrix_solver_SOR_mat_t: public matrix_solver_direct_t<FT, SIZE>
{
friend class matrix_solver_t;
public:
using float_type = FT;

View File

@ -54,8 +54,6 @@ namespace solver
template <typename FT, int SIZE>
class matrix_solver_w_t: public matrix_solver_ext_t<FT, SIZE>
{
friend class matrix_solver_t;
public:
using float_ext_type = FT;
using float_type = FT;