mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
netlist: code maintenance. (nw)
- more doxygen \file annotations - moved MAINCLOCK back to nl_base.h - remove some const from simple function parameters
This commit is contained in:
parent
86280620e4
commit
f60ed79ed6
@ -55,7 +55,7 @@ namespace analog
|
||||
/// |:---:|------|-----------------------------------------------------------------------|-------|---------:|----------------:|:----:|
|
||||
/// | 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 | |
|
||||
/// | 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 | * |
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define NLD_GENERIC_MODELS_H_
|
||||
|
||||
///
|
||||
/// \file nl_generic_models.h
|
||||
/// \file nld_generic_models.h
|
||||
///
|
||||
|
||||
#include "netlist/nl_base.h"
|
||||
@ -210,7 +210,7 @@ namespace analog
|
||||
m_Vmin = nlconst::magic(-5.0) * m_Vt;
|
||||
|
||||
m_Vcrit = m_Vt * plib::log(m_Vt / m_Is / nlconst::sqrt2());
|
||||
m_VtInv = nlconst::one() / m_Vt;
|
||||
m_VtInv = plib::reciprocal(m_Vt);
|
||||
//printf("%g %g\n", m_Vmin, m_Vcrit);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace netlist
|
||||
NETLIB_RESET(VCCS)
|
||||
{
|
||||
const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
|
||||
const nl_fptype GI = nlconst::one() / m_RI();
|
||||
const nl_fptype GI = plib::reciprocal(m_RI());
|
||||
|
||||
m_IP.set_conductivity(GI);
|
||||
m_IN.set_conductivity(GI);
|
||||
@ -69,10 +69,10 @@ NETLIB_UPDATE_TERMINALS(LVCCS)
|
||||
m_vi = vi;
|
||||
|
||||
const nl_fptype x = m_mult / m_cur_limit() * m_vi;
|
||||
const nl_fptype X = plib::tanh(x);
|
||||
const nl_fptype tanhx = plib::tanh(x);
|
||||
|
||||
const nl_fptype beta = m_mult * (nlconst::one() - X*X);
|
||||
const nl_fptype I = m_cur_limit() * X - beta * m_vi;
|
||||
const nl_fptype beta = m_mult * (nlconst::one() - tanhx*tanhx);
|
||||
const nl_fptype I = m_cur_limit() * tanhx - beta * m_vi;
|
||||
|
||||
m_OP.set_go_gt_I(-beta, nlconst::zero(), I);
|
||||
m_OP1.set_go_gt(beta, nlconst::zero());
|
||||
@ -101,11 +101,11 @@ NETLIB_UPDATE_PARAM(CCCS)
|
||||
|
||||
NETLIB_RESET(VCVS)
|
||||
{
|
||||
m_gfac = nlconst::one() / m_RO();
|
||||
m_gfac = plib::reciprocal(m_RO());
|
||||
NETLIB_NAME(VCCS)::reset();
|
||||
|
||||
m_OP2.set_conductivity(nlconst::one() / m_RO());
|
||||
m_ON2.set_conductivity(nlconst::one() / m_RO());
|
||||
m_OP2.set_conductivity(m_gfac);
|
||||
m_ON2.set_conductivity(m_gfac);
|
||||
}
|
||||
|
||||
} //namespace analog
|
||||
|
@ -128,7 +128,7 @@ namespace analog {
|
||||
public:
|
||||
NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS)
|
||||
{
|
||||
m_gfac = nlconst::one() / m_RI();
|
||||
m_gfac = plib::reciprocal(m_RI());
|
||||
}
|
||||
|
||||
NETLIB_RESETI();
|
||||
|
@ -8,176 +8,176 @@
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace analog
|
||||
namespace analog
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_twoterm
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void NETLIB_NAME(twoterm)::solve_now()
|
||||
{
|
||||
// we only need to call the non-rail terminal
|
||||
if (m_P.has_net() && !m_P.net().isRailNet())
|
||||
m_P.solve_now();
|
||||
else if (m_N.has_net() && !m_N.net().isRailNet())
|
||||
m_N.solve_now();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_twoterm
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void NETLIB_NAME(twoterm)::solve_now()
|
||||
{
|
||||
// we only need to call the non-rail terminal
|
||||
if (m_P.has_net() && !m_P.net().isRailNet())
|
||||
m_P.solve_now();
|
||||
else if (m_N.has_net() && !m_N.net().isRailNet())
|
||||
m_N.solve_now();
|
||||
}
|
||||
|
||||
void NETLIB_NAME(twoterm)::solve_later(netlist_time delay)
|
||||
{
|
||||
// we only need to call the non-rail terminal
|
||||
if (m_P.has_net() && !m_P.net().isRailNet())
|
||||
m_P.schedule_solve_after(delay);
|
||||
else if (m_N.has_net() && !m_N.net().isRailNet())
|
||||
m_N.schedule_solve_after(delay);
|
||||
}
|
||||
void NETLIB_NAME(twoterm)::solve_later(netlist_time delay)
|
||||
{
|
||||
// we only need to call the non-rail terminal
|
||||
if (m_P.has_net() && !m_P.net().isRailNet())
|
||||
m_P.schedule_solve_after(delay);
|
||||
else if (m_N.has_net() && !m_N.net().isRailNet())
|
||||
m_N.schedule_solve_after(delay);
|
||||
}
|
||||
|
||||
|
||||
NETLIB_UPDATE(twoterm)
|
||||
{
|
||||
// only called if connected to a rail net ==> notify the solver to recalculate
|
||||
solve_now();
|
||||
}
|
||||
NETLIB_UPDATE(twoterm)
|
||||
{
|
||||
// only called if connected to a rail net ==> notify the solver to recalculate
|
||||
solve_now();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_R_base
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_R_base
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_RESET(R_base)
|
||||
{
|
||||
NETLIB_NAME(twoterm)::reset();
|
||||
set_R(plib::reciprocal(exec().gmin()));
|
||||
}
|
||||
NETLIB_RESET(R_base)
|
||||
{
|
||||
NETLIB_NAME(twoterm)::reset();
|
||||
set_R(plib::reciprocal(exec().gmin()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_POT
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_POT
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_RESET(POT)
|
||||
{
|
||||
nl_fptype v = m_Dial();
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
NETLIB_RESET(POT)
|
||||
{
|
||||
nl_fptype v = m_Dial();
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
|
||||
}
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(POT)
|
||||
{
|
||||
m_R1.solve_now();
|
||||
m_R2.solve_now();
|
||||
NETLIB_UPDATE_PARAM(POT)
|
||||
{
|
||||
m_R1.solve_now();
|
||||
m_R2.solve_now();
|
||||
|
||||
nl_fptype v = m_Dial();
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
|
||||
nl_fptype v = m_Dial();
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_POT2
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_POT2
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_RESET(POT2)
|
||||
{
|
||||
nl_fptype v = m_Dial();
|
||||
NETLIB_RESET(POT2)
|
||||
{
|
||||
nl_fptype v = m_Dial();
|
||||
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
}
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
}
|
||||
|
||||
|
||||
NETLIB_UPDATE_PARAM(POT2)
|
||||
{
|
||||
m_R1.solve_now();
|
||||
NETLIB_UPDATE_PARAM(POT2)
|
||||
{
|
||||
m_R1.solve_now();
|
||||
|
||||
nl_fptype v = m_Dial();
|
||||
nl_fptype v = m_Dial();
|
||||
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
}
|
||||
if (m_DialIsLog())
|
||||
v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
|
||||
if (m_Reverse())
|
||||
v = nlconst::one() - v;
|
||||
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_L
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_L
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_RESET(L)
|
||||
{
|
||||
m_gmin = exec().gmin();
|
||||
m_I = nlconst::zero();
|
||||
m_G = m_gmin;
|
||||
set_mat( m_G, -m_G, -m_I,
|
||||
-m_G, m_G, m_I);
|
||||
//set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
|
||||
}
|
||||
NETLIB_RESET(L)
|
||||
{
|
||||
m_gmin = exec().gmin();
|
||||
m_I = nlconst::zero();
|
||||
m_G = m_gmin;
|
||||
set_mat( m_G, -m_G, -m_I,
|
||||
-m_G, m_G, m_I);
|
||||
//set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(L)
|
||||
{
|
||||
}
|
||||
NETLIB_UPDATE_PARAM(L)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_TIMESTEP(L)
|
||||
{
|
||||
// Gpar should support convergence
|
||||
m_I += m_I + m_G * deltaV();
|
||||
m_G = step / m_L() + m_gmin;
|
||||
set_mat( m_G, -m_G, -m_I,
|
||||
-m_G, m_G, m_I);
|
||||
}
|
||||
NETLIB_TIMESTEP(L)
|
||||
{
|
||||
// Gpar should support convergence
|
||||
m_I += m_I + m_G * deltaV();
|
||||
m_G = step / m_L() + m_gmin;
|
||||
set_mat( m_G, -m_G, -m_I,
|
||||
-m_G, m_G, m_I);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_D
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_D
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_RESET(D)
|
||||
{
|
||||
nl_fptype Is = m_model.m_IS;
|
||||
nl_fptype n = m_model.m_N;
|
||||
NETLIB_RESET(D)
|
||||
{
|
||||
nl_fptype Is = m_model.m_IS;
|
||||
nl_fptype n = m_model.m_N;
|
||||
|
||||
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
|
||||
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
|
||||
}
|
||||
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
|
||||
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(D)
|
||||
{
|
||||
nl_fptype Is = m_model.m_IS;
|
||||
nl_fptype n = m_model.m_N;
|
||||
NETLIB_UPDATE_PARAM(D)
|
||||
{
|
||||
nl_fptype Is = m_model.m_IS;
|
||||
nl_fptype n = m_model.m_N;
|
||||
|
||||
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
|
||||
}
|
||||
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_TERMINALS(D)
|
||||
{
|
||||
m_D.update_diode(deltaV());
|
||||
const nl_fptype G = m_D.G();
|
||||
const nl_fptype I = m_D.Ieq();
|
||||
set_mat( G, -G, -I,
|
||||
-G, G, I);
|
||||
//set(m_D.G(), 0.0, m_D.Ieq());
|
||||
}
|
||||
NETLIB_UPDATE_TERMINALS(D)
|
||||
{
|
||||
m_D.update_diode(deltaV());
|
||||
const nl_fptype G = m_D.G();
|
||||
const nl_fptype I = m_D.Ieq();
|
||||
set_mat( G, -G, -I,
|
||||
-G, G, I);
|
||||
//set(m_D.G(), 0.0, m_D.Ieq());
|
||||
}
|
||||
|
||||
|
||||
} //namespace analog
|
||||
} //namespace analog
|
||||
|
||||
namespace devices {
|
||||
NETLIB_DEVICE_IMPL_NS(analog, R, "RES", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, POT, "POT", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, POT2, "POT2", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, C, "CAP", "C")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, L, "IND", "L")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, D, "DIODE", "MODEL")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I")
|
||||
} // namespace devices
|
||||
namespace devices {
|
||||
NETLIB_DEVICE_IMPL_NS(analog, R, "RES", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, POT, "POT", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, POT2, "POT2", "R")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, C, "CAP", "C")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, L, "IND", "L")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, D, "DIODE", "MODEL")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V")
|
||||
NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I")
|
||||
} // namespace devices
|
||||
|
||||
} // namespace netlist
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define NLID_TWOTERM_H_
|
||||
|
||||
///
|
||||
/// \file nld_twoterm.h
|
||||
/// \file nlid_twoterm.h
|
||||
///
|
||||
/// Devices with two terminals ...
|
||||
///
|
||||
@ -124,9 +124,9 @@ namespace analog
|
||||
{
|
||||
}
|
||||
|
||||
void set_R(const nl_fptype R)
|
||||
void set_R(nl_fptype R)
|
||||
{
|
||||
const nl_fptype G = nlconst::one() / R;
|
||||
const nl_fptype G = plib::reciprocal(R);
|
||||
set_mat( G, -G, nlconst::zero(),
|
||||
-G, G, nlconst::zero());
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace netlist
|
||||
{
|
||||
// Start in off condition
|
||||
// FIXME: is ROFF correct?
|
||||
m_R.set_R(nlconst::one() / exec().gmin());
|
||||
m_R.set_R(plib::reciprocal(exec().gmin()));
|
||||
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ namespace netlist
|
||||
|
||||
if (in < low)
|
||||
{
|
||||
R = nlconst::one() / exec().gmin();
|
||||
R = plib::reciprocal(exec().gmin());
|
||||
}
|
||||
else if (in > high)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace netlist { namespace devices {
|
||||
|
||||
NETLIB_RESET(CD4316_GATE)
|
||||
{
|
||||
m_R.set_R(nlconst::one() / exec().gmin());
|
||||
m_R.set_R(plib::reciprocal(exec().gmin()));
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(CD4316_GATE)
|
||||
@ -47,7 +47,7 @@ namespace netlist { namespace devices {
|
||||
if (m_S() && !m_E())
|
||||
m_R.set_R(m_base_r());
|
||||
else
|
||||
m_R.set_R(nlconst::one() / exec().gmin());
|
||||
m_R.set_R(plib::reciprocal(exec().gmin()));
|
||||
m_R.solve_later(NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,6 @@
|
||||
#include "netlist/analog/nlid_twoterm.h"
|
||||
#include "netlist/solver/nld_matrix_solver.h"
|
||||
|
||||
#define R_LOW (1000.0)
|
||||
#define R_HIGH (1000.0)
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
@ -24,6 +21,8 @@ namespace netlist
|
||||
, m_VGG(*this, "2")
|
||||
, m_VSS(*this, "4")
|
||||
, m_FREQ(*this, "FREQ", 24000)
|
||||
, m_R_LOW(*this, "R_LOW", 1000)
|
||||
, m_R_HIGH(*this, "R_HIGH", 1000)
|
||||
/* clock */
|
||||
, m_feedback(*this, "_FB")
|
||||
, m_Q(*this, "_Q")
|
||||
@ -52,6 +51,8 @@ namespace netlist
|
||||
analog_input_t m_VGG;
|
||||
analog_input_t m_VSS;
|
||||
param_fp_t m_FREQ;
|
||||
param_fp_t m_R_LOW;
|
||||
param_fp_t m_R_HIGH;
|
||||
|
||||
/* clock stage */
|
||||
logic_input_t m_feedback;
|
||||
@ -69,7 +70,7 @@ namespace netlist
|
||||
{
|
||||
//m_V0.initial(0.0);
|
||||
//m_RV.do_reset();
|
||||
m_RV.set_G_V_I(nlconst::one() / nlconst::magic(R_LOW),
|
||||
m_RV.set_G_V_I(plib::reciprocal(m_R_LOW()),
|
||||
nlconst::zero(),
|
||||
nlconst::zero());
|
||||
m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
|
||||
@ -104,13 +105,13 @@ namespace netlist
|
||||
|
||||
if (state != last_state)
|
||||
{
|
||||
const nl_fptype R = nlconst::magic(state ? R_HIGH : R_LOW);
|
||||
const nl_fptype R = state ? m_R_HIGH : m_R_LOW;
|
||||
const nl_fptype V = state ? m_VDD() : m_VSS();
|
||||
|
||||
// We only need to update the net first if this is a time stepping net
|
||||
if (m_is_timestep)
|
||||
m_RV.update();
|
||||
m_RV.set_G_V_I(nlconst::one() / R, V, nlconst::zero());
|
||||
m_RV.set_G_V_I(plib::reciprocal(R), V, nlconst::zero());
|
||||
m_RV.solve_later(NLTIME_FROM_NS(1));
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,8 @@ namespace netlist
|
||||
m_RVI.reset();
|
||||
m_RVO.reset();
|
||||
m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices();
|
||||
m_RVI.set_G_V_I(nlconst::one() / m_model.m_RI, m_model.m_VI, nlconst::zero());
|
||||
m_RVO.set_G_V_I(nlconst::one() / m_model.m_ROL, m_model.m_VOL, nlconst::zero());
|
||||
m_RVI.set_G_V_I(plib::reciprocal(m_model.m_RI()), m_model.m_VI, nlconst::zero());
|
||||
m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROL()), m_model.m_VOL, nlconst::zero());
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
@ -95,7 +95,7 @@ namespace netlist
|
||||
m_last_state = 0;
|
||||
if (m_is_timestep)
|
||||
m_RVO.update();
|
||||
m_RVO.set_G_V_I(nlconst::one() / m_model.m_ROH, m_model.m_VOH, nlconst::zero());
|
||||
m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROH()), m_model.m_VOH, nlconst::zero());
|
||||
m_RVO.solve_later();
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ namespace netlist
|
||||
m_last_state = 1;
|
||||
if (m_is_timestep)
|
||||
m_RVO.update();
|
||||
m_RVO.set_G_V_I(nlconst::one() / m_model.m_ROL, m_model.m_VOL, nlconst::zero());
|
||||
m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROL()), m_model.m_VOL, nlconst::zero());
|
||||
m_RVO.solve_later();
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace devices
|
||||
{
|
||||
m_cnt = 0;
|
||||
m_off = netlist_time::from_fp<decltype(m_offset())>(m_offset());
|
||||
m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update);
|
||||
m_feedback.set_delegate(NETLIB_DELEGATE(extclock, update));
|
||||
|
||||
//m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this);
|
||||
//m_Q.initial(0);
|
||||
@ -55,9 +55,9 @@ namespace devices
|
||||
// continue with optimized clock handlers ....
|
||||
|
||||
if ((m_size & (m_size-1)) == 0) // power of 2?
|
||||
m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this);
|
||||
m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2_pow2, this));
|
||||
else
|
||||
m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this);
|
||||
m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2, this));
|
||||
}
|
||||
|
||||
|
||||
|
@ -161,7 +161,7 @@ namespace netlist
|
||||
if (m_VCCHack)
|
||||
m_VCCHack->initial(supply_V);
|
||||
m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices();
|
||||
m_RN.set_G_V_I(nlconst::one() / logic_family()->R_low(),
|
||||
m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
|
||||
logic_family()->low_offset_V(), nlconst::zero());
|
||||
m_RP.set_G_V_I(G_OFF,
|
||||
nlconst::zero(),
|
||||
@ -183,12 +183,12 @@ namespace netlist
|
||||
m_RN.set_G_V_I(G_OFF,
|
||||
nlconst::zero(),
|
||||
nlconst::zero());
|
||||
m_RP.set_G_V_I(nlconst::one() / logic_family()->R_high(),
|
||||
m_RP.set_G_V_I(plib::reciprocal(logic_family()->R_high()),
|
||||
logic_family()->high_offset_V(), nlconst::zero());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RN.set_G_V_I(nlconst::one() / logic_family()->R_low(),
|
||||
m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
|
||||
logic_family()->low_offset_V(), nlconst::zero());
|
||||
m_RP.set_G_V_I(G_OFF,
|
||||
nlconst::zero(),
|
||||
|
@ -1,16 +1,12 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
/*
|
||||
* nlid_system.h
|
||||
*
|
||||
* netlist devices defined in the core
|
||||
*
|
||||
* This file contains internal headers
|
||||
*/
|
||||
|
||||
#ifndef NLID_SYSTEM_H_
|
||||
#define NLID_SYSTEM_H_
|
||||
|
||||
///
|
||||
/// \file nlid_system.h
|
||||
///
|
||||
|
||||
#include "netlist/analog/nlid_twoterm.h"
|
||||
#include "netlist/nl_base.h"
|
||||
#include "netlist/nl_setup.h"
|
||||
@ -44,6 +40,7 @@ namespace devices
|
||||
param_num_t<unsigned> m_max_link_loops;
|
||||
};
|
||||
|
||||
#if 0
|
||||
// -----------------------------------------------------------------------------
|
||||
// mainclock
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -81,7 +78,7 @@ namespace devices
|
||||
private:
|
||||
param_fp_t m_freq;
|
||||
};
|
||||
|
||||
#endif
|
||||
// -----------------------------------------------------------------------------
|
||||
// clock
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -228,7 +225,7 @@ namespace devices
|
||||
NETLIB_CONSTRUCTOR(logic_input)
|
||||
, m_Q(*this, "Q")
|
||||
, m_IN(*this, "IN", false)
|
||||
/* make sure we get the family first */
|
||||
// make sure we get the family first
|
||||
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
|
||||
{
|
||||
set_logic_family(state().setup().family_from_model(m_FAMILY()));
|
||||
@ -342,7 +339,7 @@ namespace devices
|
||||
|
||||
private:
|
||||
analog::NETLIB_NAME(twoterm) m_RIN;
|
||||
/* Fixme: only works if the device is time-stepped - need to rework */
|
||||
// Fixme: only works if the device is time-stepped - need to rework
|
||||
analog::NETLIB_NAME(twoterm) m_ROUT;
|
||||
analog_input_t m_I;
|
||||
analog_output_t m_Q;
|
||||
@ -456,10 +453,10 @@ namespace devices
|
||||
// power pins - not a device, but a helper
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Power Pins are passive inputs. Delegate noop will silently ignore any
|
||||
* updates.
|
||||
*/
|
||||
/// \brief Power pins class.
|
||||
///
|
||||
/// Power Pins are passive inputs. Delegate noop will silently ignore any
|
||||
/// updates.
|
||||
class nld_power_pins
|
||||
{
|
||||
public:
|
||||
@ -479,7 +476,7 @@ namespace devices
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: this will seg-fault if force_analog_input = false */
|
||||
// FIXME: this will seg-fault if force_analog_input = false
|
||||
nl_fptype VCC() const NL_NOEXCEPT { return m_VCC->Q_Analog(); }
|
||||
nl_fptype GND() const NL_NOEXCEPT { return m_GND->Q_Analog(); }
|
||||
|
||||
@ -494,4 +491,4 @@ namespace devices
|
||||
} // namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_SYSTEM_H_ */
|
||||
#endif // NLD_SYSTEM_H_
|
||||
|
@ -1,8 +1,13 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
#ifndef NLM_OPAMP_H_
|
||||
#define NLM_OPAMP_H_
|
||||
|
||||
///
|
||||
/// \file nlm_opamp.h
|
||||
///
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
|
@ -1,8 +1,13 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
#ifndef NLM_OTHER_H_
|
||||
#define NLM_OTHER_H_
|
||||
|
||||
///
|
||||
/// \file nlm_other.h
|
||||
///
|
||||
///
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
|
@ -1,7 +1,12 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
#ifndef NLD_TTL74XX_H_
|
||||
#define NLD_TTL74XX_H_
|
||||
|
||||
#ifndef NLM_TTL74XX_H_
|
||||
#define NLM_TTL74XX_H_
|
||||
|
||||
///
|
||||
/// \file nlm_ttl74xx.h
|
||||
///
|
||||
|
||||
#include "netlist/nl_setup.h"
|
||||
|
||||
@ -308,6 +313,6 @@
|
||||
|
||||
NETLIST_EXTERNAL(TTL74XX_lib)
|
||||
|
||||
#endif
|
||||
#endif // NL_AUTO_DEVICES
|
||||
|
||||
#endif
|
||||
#endif // NLM_TTL74XX
|
||||
|
@ -256,6 +256,7 @@ namespace netlist
|
||||
ENTRY(PUSE_ALIGNED_OPTIMIZATIONS)
|
||||
ENTRY(PHAS_OPENMP)
|
||||
ENTRY(PUSE_OPENMP)
|
||||
ENTRY(PUSE_FLOAT128)
|
||||
ENTRY(PPMF_TYPE)
|
||||
ENTRY(PHAS_PMF_INTERNAL)
|
||||
ENTRY(NL_USE_MEMPOOL)
|
||||
@ -263,6 +264,9 @@ namespace netlist
|
||||
ENTRY(NL_USE_COPY_INSTEAD_OF_REFERENCE)
|
||||
ENTRY(NL_USE_TRUTHTABLE_7448)
|
||||
ENTRY(NL_AUTO_DEVICES)
|
||||
ENTRY(NL_USE_FLOAT128)
|
||||
ENTRY(NL_USE_FLOAT_MATRIX)
|
||||
ENTRY(NL_USE_LONG_DOUBLE_MATRIX)
|
||||
ENTRY(NL_DEBUG)
|
||||
ENTRY(NVCCBUILD)
|
||||
|
||||
@ -350,14 +354,14 @@ namespace netlist
|
||||
log().verbose("Using default startup strategy");
|
||||
for (auto &n : m_nets)
|
||||
for (auto & term : n->core_terms())
|
||||
if (term->m_delegate.has_object())
|
||||
if (term->delegate().has_object())
|
||||
{
|
||||
if (!plib::container::contains(t, &term->m_delegate))
|
||||
if (!plib::container::contains(t, &term->delegate()))
|
||||
{
|
||||
t.push_back(&term->m_delegate);
|
||||
term->m_delegate();
|
||||
t.push_back(&term->delegate());
|
||||
term->run_delegate();
|
||||
}
|
||||
auto *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
|
||||
auto *dev = reinterpret_cast<core_device_t *>(term->delegate().object());
|
||||
if (!plib::container::contains(d, dev))
|
||||
d.push_back(dev);
|
||||
}
|
||||
@ -536,8 +540,8 @@ namespace netlist
|
||||
|
||||
void core_device_t::set_default_delegate(detail::core_terminal_t &term)
|
||||
{
|
||||
if (!term.m_delegate.is_set())
|
||||
term.m_delegate.set(&core_device_t::update, this);
|
||||
if (!term.delegate().is_set())
|
||||
term.set_delegate(nldelegate(&core_device_t::update, this));
|
||||
}
|
||||
|
||||
log_type & core_device_t::log()
|
||||
@ -632,14 +636,14 @@ namespace netlist
|
||||
// net_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr)
|
||||
detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal)
|
||||
: object_t(aname)
|
||||
, netlist_ref(nl)
|
||||
, m_new_Q(*this, "m_new_Q", 0)
|
||||
, m_cur_Q (*this, "m_cur_Q", 0)
|
||||
, m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
|
||||
, m_next_scheduled_time(*this, "m_time", netlist_time::zero())
|
||||
, m_railterminal(mr)
|
||||
, m_railterminal(railterminal)
|
||||
{
|
||||
}
|
||||
|
||||
@ -721,8 +725,8 @@ namespace netlist
|
||||
// logic_net_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
|
||||
: net_t(nl, aname, mr)
|
||||
logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal)
|
||||
: net_t(nl, aname, railterminal)
|
||||
{
|
||||
}
|
||||
|
||||
@ -730,8 +734,8 @@ namespace netlist
|
||||
// analog_net_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
|
||||
: net_t(nl, aname, mr)
|
||||
analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal)
|
||||
: net_t(nl, aname, railterminal)
|
||||
, m_cur_Analog(*this, "m_cur_Analog", nlconst::zero())
|
||||
, m_solver(nullptr)
|
||||
{
|
||||
@ -745,10 +749,10 @@ namespace netlist
|
||||
const state_e state, nldelegate delegate)
|
||||
: device_object_t(dev, dev.name() + "." + aname)
|
||||
, plib::linkedlist_t<core_terminal_t>::element_t()
|
||||
, m_delegate(delegate)
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
, m_Q(*this, "m_Q", 0)
|
||||
#endif
|
||||
, m_delegate(delegate)
|
||||
, m_net(nullptr)
|
||||
, m_state(*this, "m_state", state)
|
||||
{
|
||||
@ -852,7 +856,7 @@ namespace netlist
|
||||
state().setup().register_term(*this);
|
||||
}
|
||||
|
||||
void analog_output_t::initial(const nl_fptype val) noexcept
|
||||
void analog_output_t::initial(nl_fptype val) noexcept
|
||||
{
|
||||
net().set_Q_Analog(val);
|
||||
}
|
||||
@ -899,11 +903,6 @@ namespace netlist
|
||||
}
|
||||
|
||||
|
||||
void param_t::update_param() noexcept
|
||||
{
|
||||
device().update_param();
|
||||
}
|
||||
|
||||
pstring param_t::get_initial(const device_t &dev, bool *found)
|
||||
{
|
||||
pstring res = dev.state().setup().get_initial_param_val(this->name(), "");
|
||||
@ -994,15 +993,4 @@ namespace netlist
|
||||
return dynamic_cast<const analog_net_t *>(this) != nullptr;
|
||||
}
|
||||
|
||||
void netlist_t::process_queue(const netlist_time delta) noexcept
|
||||
{
|
||||
if (!m_use_stats)
|
||||
process_queue_stats<false>(delta, m_mainclock);
|
||||
else
|
||||
{
|
||||
auto sm_guard(m_stat_mainloop.guard());
|
||||
process_queue_stats<true>(delta, m_mainclock);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace netlist
|
||||
|
@ -189,7 +189,6 @@ namespace netlist
|
||||
{
|
||||
/// \brief Delegate type for device notification.
|
||||
///
|
||||
|
||||
using nldelegate = plib::pmfp<void>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -220,6 +219,11 @@ namespace netlist
|
||||
class core_device_t;
|
||||
class device_t;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class net_t;
|
||||
} // namespace detail
|
||||
|
||||
//============================================================
|
||||
// Exceptions
|
||||
//============================================================
|
||||
@ -266,8 +270,8 @@ namespace netlist
|
||||
logic_input_t *proxied) const = 0;
|
||||
|
||||
nl_fptype fixed_V() const noexcept{ return m_fixed_V; }
|
||||
nl_fptype low_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; }
|
||||
nl_fptype high_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; }
|
||||
nl_fptype low_thresh_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; }
|
||||
nl_fptype high_thresh_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; }
|
||||
nl_fptype low_offset_V() const noexcept{ return m_low_VO; }
|
||||
nl_fptype high_offset_V() const noexcept{ return m_high_VO; }
|
||||
nl_fptype R_low() const noexcept{ return m_R_low; }
|
||||
@ -551,10 +555,6 @@ namespace netlist
|
||||
///
|
||||
/// All terminals are derived from this class.
|
||||
///
|
||||
|
||||
|
||||
class net_t;
|
||||
|
||||
class core_terminal_t : public device_object_t,
|
||||
public plib::linkedlist_t<core_terminal_t>::element_t
|
||||
{
|
||||
@ -608,7 +608,6 @@ namespace netlist
|
||||
|
||||
void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
|
||||
|
||||
nldelegate m_delegate;
|
||||
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
|
||||
void set_copied_input(netlist_sig_t val) noexcept
|
||||
{
|
||||
@ -620,7 +619,12 @@ namespace netlist
|
||||
void set_copied_input(netlist_sig_t val) const noexcept { plib::unused_var(val); }
|
||||
#endif
|
||||
|
||||
void set_delegate(const nldelegate &delegate) noexcept { m_delegate = delegate; }
|
||||
nldelegate &delegate() noexcept { return m_delegate; }
|
||||
const nldelegate &delegate() const noexcept { return m_delegate; }
|
||||
void run_delegate() noexcept { m_delegate(); }
|
||||
private:
|
||||
nldelegate m_delegate;
|
||||
net_t * m_net;
|
||||
state_var<state_e> m_state;
|
||||
};
|
||||
@ -642,7 +646,7 @@ namespace netlist
|
||||
DELIVERED
|
||||
};
|
||||
|
||||
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
|
||||
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal = nullptr);
|
||||
|
||||
COPYASSIGNMOVE(net_t, delete)
|
||||
|
||||
@ -729,9 +733,14 @@ namespace netlist
|
||||
{
|
||||
m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
|
||||
m_next_scheduled_time = at;
|
||||
m_cur_Q = m_new_Q = newQ;
|
||||
update_inputs();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cur_Q = newQ;
|
||||
update_inputs();
|
||||
}
|
||||
m_cur_Q = m_new_Q = newQ;
|
||||
update_inputs();
|
||||
}
|
||||
|
||||
// internal state support
|
||||
@ -751,7 +760,7 @@ namespace netlist
|
||||
std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
|
||||
template <bool KEEP_STATS, typename T>
|
||||
void process(const T mask, netlist_sig_t sig) noexcept;
|
||||
void process(T mask, netlist_sig_t sig) noexcept;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@ -815,7 +824,7 @@ namespace netlist
|
||||
nl_fptype *m_go1; // conductance for Voltage from other term
|
||||
nl_fptype *m_gt1; // conductance for total conductance
|
||||
|
||||
terminal_t *m_connected_terminal;
|
||||
terminal_t *m_connected_terminal; // FIXME: only used during setup
|
||||
|
||||
};
|
||||
|
||||
@ -840,7 +849,7 @@ namespace netlist
|
||||
protected:
|
||||
|
||||
private:
|
||||
devices::nld_base_proxy *m_proxy;
|
||||
devices::nld_base_proxy *m_proxy; // FIXME: only used during setup
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -886,14 +895,11 @@ namespace netlist
|
||||
|
||||
/// \brief returns voltage at terminal.
|
||||
/// \returns voltage at terminal.
|
||||
|
||||
nl_fptype operator()() const noexcept { return Q_Analog(); }
|
||||
|
||||
/// \brief returns voltage at terminal.
|
||||
/// \returns voltage at terminal.
|
||||
|
||||
nl_fptype Q_Analog() const noexcept;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -901,7 +907,7 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
|
||||
logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
|
||||
logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
|
||||
|
||||
using detail::net_t::Q;
|
||||
using detail::net_t::initial;
|
||||
@ -919,7 +925,7 @@ namespace netlist
|
||||
|
||||
friend class detail::net_t;
|
||||
|
||||
analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
|
||||
analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
|
||||
|
||||
nl_fptype Q_Analog() const noexcept { return m_cur_Analog; }
|
||||
void set_Q_Analog(const nl_fptype v) noexcept { m_cur_Analog = v; }
|
||||
@ -965,211 +971,14 @@ namespace netlist
|
||||
public:
|
||||
analog_output_t(core_device_t &dev, const pstring &aname);
|
||||
|
||||
void push(const nl_fptype val) noexcept { set_Q(val); }
|
||||
void initial(const nl_fptype val) noexcept;
|
||||
void push(nl_fptype val) noexcept { set_Q(val); }
|
||||
void initial(nl_fptype val) noexcept;
|
||||
|
||||
private:
|
||||
void set_Q(const nl_fptype newQ) noexcept;
|
||||
void set_Q(nl_fptype newQ) noexcept;
|
||||
analog_net_t m_my_net;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// param_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_t : public detail::device_object_t
|
||||
{
|
||||
public:
|
||||
|
||||
enum param_type_t {
|
||||
STRING,
|
||||
DOUBLE,
|
||||
INTEGER,
|
||||
LOGIC,
|
||||
POINTER // Special-case which is always initialized at MAME startup time
|
||||
};
|
||||
|
||||
param_t(device_t &device, const pstring &name);
|
||||
|
||||
COPYASSIGNMOVE(param_t, delete)
|
||||
|
||||
param_type_t param_type() const noexcept(false);
|
||||
|
||||
protected:
|
||||
virtual ~param_t() noexcept = default; // not intended to be destroyed
|
||||
|
||||
void update_param() noexcept;
|
||||
|
||||
pstring get_initial(const device_t &dev, bool *found);
|
||||
|
||||
template<typename C>
|
||||
void set(C &p, const C v) noexcept
|
||||
{
|
||||
if (p != v)
|
||||
{
|
||||
p = v;
|
||||
update_param();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// numeric parameter template
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
class param_num_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_num_t(device_t &device, const pstring &name, const T val);
|
||||
|
||||
T operator()() const noexcept { return m_param; }
|
||||
operator T() const noexcept { return m_param; }
|
||||
|
||||
void setTo(const T ¶m) noexcept { set(m_param, param); }
|
||||
private:
|
||||
T m_param;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class param_enum_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_enum_t(device_t &device, const pstring &name, const T val);
|
||||
|
||||
T operator()() const noexcept { return T(m_param); }
|
||||
operator T() const noexcept { return T(m_param); }
|
||||
void setTo(const T ¶m) noexcept { set(m_param, static_cast<int>(param)); }
|
||||
private:
|
||||
int m_param;
|
||||
};
|
||||
|
||||
// FIXME: these should go as well
|
||||
using param_logic_t = param_num_t<bool>;
|
||||
using param_int_t = param_num_t<int>;
|
||||
using param_fp_t = param_num_t<nl_fptype>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// pointer parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_ptr_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_ptr_t(device_t &device, const pstring &name, std::uint8_t* val);
|
||||
std::uint8_t * operator()() const noexcept { return m_param; }
|
||||
void setTo(std::uint8_t *param) noexcept { set(m_param, param); }
|
||||
private:
|
||||
std::uint8_t* m_param;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// string parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_str_t : public param_t
|
||||
{
|
||||
public:
|
||||
param_str_t(device_t &device, const pstring &name, const pstring &val);
|
||||
|
||||
const pstring &operator()() const noexcept { return str(); }
|
||||
void setTo(const pstring ¶m) noexcept
|
||||
{
|
||||
if (m_param != param)
|
||||
{
|
||||
m_param = param;
|
||||
changed();
|
||||
update_param();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
virtual void changed() noexcept;
|
||||
const pstring &str() const noexcept { return m_param; }
|
||||
private:
|
||||
PALIGNAS_CACHELINE()
|
||||
pstring m_param;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// model parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_model_t : public param_str_t
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
class value_base_t
|
||||
{
|
||||
public:
|
||||
value_base_t(param_model_t ¶m, const pstring &name)
|
||||
: m_value(static_cast<T>(param.value(name)))
|
||||
{
|
||||
}
|
||||
T operator()() const noexcept { return m_value; }
|
||||
operator T() const noexcept { return m_value; }
|
||||
private:
|
||||
const T m_value;
|
||||
};
|
||||
|
||||
using value_t = value_base_t<nl_fptype>;
|
||||
|
||||
template <typename T>
|
||||
friend class value_base_t;
|
||||
|
||||
param_model_t(device_t &device, const pstring &name, const pstring &val)
|
||||
: param_str_t(device, name, val) { }
|
||||
|
||||
pstring value_str(const pstring &entity);
|
||||
nl_fptype value(const pstring &entity);
|
||||
const pstring type();
|
||||
// hide this
|
||||
void setTo(const pstring ¶m) = delete;
|
||||
protected:
|
||||
void changed() noexcept override;
|
||||
private:
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// data parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_data_t : public param_str_t
|
||||
{
|
||||
public:
|
||||
param_data_t(device_t &device, const pstring &name)
|
||||
: param_str_t(device, name, "")
|
||||
{
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> stream();
|
||||
protected:
|
||||
void changed() noexcept override { }
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// rom parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template <typename ST, std::size_t AW, std::size_t DW>
|
||||
class param_rom_t final: public param_data_t
|
||||
{
|
||||
public:
|
||||
|
||||
param_rom_t(device_t &device, const pstring &name);
|
||||
|
||||
ST operator[] (std::size_t n) const noexcept { return m_data[n]; }
|
||||
protected:
|
||||
void changed() noexcept override
|
||||
{
|
||||
stream()->read(reinterpret_cast<std::istream::char_type *>(&m_data[0]),1<<AW);
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<ST, 1 << AW> m_data;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// core_device_t
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1285,6 +1094,206 @@ namespace netlist
|
||||
private:
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// param_t
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_t : public detail::device_object_t
|
||||
{
|
||||
public:
|
||||
|
||||
enum param_type_t {
|
||||
STRING,
|
||||
DOUBLE,
|
||||
INTEGER,
|
||||
LOGIC,
|
||||
POINTER // Special-case which is always initialized at MAME startup time
|
||||
};
|
||||
|
||||
param_t(device_t &device, const pstring &name);
|
||||
|
||||
COPYASSIGNMOVE(param_t, delete)
|
||||
|
||||
param_type_t param_type() const noexcept(false);
|
||||
|
||||
protected:
|
||||
virtual ~param_t() noexcept = default; // not intended to be destroyed
|
||||
|
||||
void update_param() noexcept
|
||||
{
|
||||
device().update_param();
|
||||
}
|
||||
|
||||
pstring get_initial(const device_t &dev, bool *found);
|
||||
|
||||
template<typename C>
|
||||
void set(C &p, const C v) noexcept
|
||||
{
|
||||
if (p != v)
|
||||
{
|
||||
p = v;
|
||||
update_param();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// numeric parameter template
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
class param_num_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_num_t(device_t &device, const pstring &name, const T val);
|
||||
|
||||
T operator()() const noexcept { return m_param; }
|
||||
operator T() const noexcept { return m_param; }
|
||||
|
||||
void setTo(const T ¶m) noexcept { set(m_param, param); }
|
||||
private:
|
||||
T m_param;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class param_enum_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_enum_t(device_t &device, const pstring &name, const T val);
|
||||
|
||||
T operator()() const noexcept { return T(m_param); }
|
||||
operator T() const noexcept { return T(m_param); }
|
||||
void setTo(const T ¶m) noexcept { set(m_param, static_cast<int>(param)); }
|
||||
private:
|
||||
int m_param;
|
||||
};
|
||||
|
||||
// FIXME: these should go as well
|
||||
using param_logic_t = param_num_t<bool>;
|
||||
using param_int_t = param_num_t<int>;
|
||||
using param_fp_t = param_num_t<nl_fptype>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// pointer parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_ptr_t final: public param_t
|
||||
{
|
||||
public:
|
||||
param_ptr_t(device_t &device, const pstring &name, std::uint8_t* val);
|
||||
std::uint8_t * operator()() const noexcept { return m_param; }
|
||||
void setTo(std::uint8_t *param) noexcept { set(m_param, param); }
|
||||
private:
|
||||
std::uint8_t* m_param;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// string parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_str_t : public param_t
|
||||
{
|
||||
public:
|
||||
param_str_t(device_t &device, const pstring &name, const pstring &val);
|
||||
|
||||
pstring operator()() const noexcept { return str(); }
|
||||
void setTo(const pstring ¶m) noexcept
|
||||
{
|
||||
if (m_param != param)
|
||||
{
|
||||
m_param = param;
|
||||
changed();
|
||||
update_param();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
virtual void changed() noexcept;
|
||||
pstring str() const noexcept { return m_param; }
|
||||
private:
|
||||
PALIGNAS_CACHELINE()
|
||||
pstring m_param;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// model parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_model_t : public param_str_t
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
class value_base_t
|
||||
{
|
||||
public:
|
||||
value_base_t(param_model_t ¶m, const pstring &name)
|
||||
: m_value(static_cast<T>(param.value(name)))
|
||||
{
|
||||
}
|
||||
T operator()() const noexcept { return m_value; }
|
||||
operator T() const noexcept { return m_value; }
|
||||
private:
|
||||
const T m_value;
|
||||
};
|
||||
|
||||
using value_t = value_base_t<nl_fptype>;
|
||||
|
||||
template <typename T>
|
||||
friend class value_base_t;
|
||||
|
||||
param_model_t(device_t &device, const pstring &name, const pstring &val)
|
||||
: param_str_t(device, name, val) { }
|
||||
|
||||
pstring value_str(const pstring &entity);
|
||||
nl_fptype value(const pstring &entity);
|
||||
const pstring type();
|
||||
// hide this
|
||||
void setTo(const pstring ¶m) = delete;
|
||||
protected:
|
||||
void changed() noexcept override;
|
||||
private:
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// data parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class param_data_t : public param_str_t
|
||||
{
|
||||
public:
|
||||
param_data_t(device_t &device, const pstring &name)
|
||||
: param_str_t(device, name, "")
|
||||
{
|
||||
}
|
||||
|
||||
plib::unique_ptr<std::istream> stream();
|
||||
protected:
|
||||
void changed() noexcept override { }
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// rom parameter
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template <typename ST, std::size_t AW, std::size_t DW>
|
||||
class param_rom_t final: public param_data_t
|
||||
{
|
||||
public:
|
||||
|
||||
param_rom_t(device_t &device, const pstring &name);
|
||||
|
||||
ST operator[] (std::size_t n) const noexcept { return m_data[n]; }
|
||||
protected:
|
||||
void changed() noexcept override
|
||||
{
|
||||
stream()->read(reinterpret_cast<std::istream::char_type *>(&m_data[0]),1<<AW);
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<ST, 1 << AW> m_data;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// family_setter_t
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1314,7 +1323,7 @@ namespace netlist
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// We don't need a thread-safe queue currently. Parallel processing of
|
||||
/// solvers will update inputs after parallel processing.
|
||||
// solvers will update inputs after parallel processing.
|
||||
|
||||
class queue_t :
|
||||
//public timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
|
||||
@ -1541,11 +1550,46 @@ namespace netlist
|
||||
nets_collection_type m_nets;
|
||||
// sole use is to manage lifetime of net objects
|
||||
devices_collection_type m_devices;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
namespace devices
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
// mainclock
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
NETLIB_OBJECT(mainclock)
|
||||
{
|
||||
NETLIB_CONSTRUCTOR(mainclock)
|
||||
, m_Q(*this, "Q")
|
||||
, m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5))
|
||||
{
|
||||
m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
m_Q.net().set_next_scheduled_time(netlist_time::zero());
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAMI()
|
||||
{
|
||||
m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
// only called during start up.
|
||||
// mainclock will step forced by main loop
|
||||
}
|
||||
|
||||
public:
|
||||
logic_output_t m_Q;
|
||||
netlist_time m_inc;
|
||||
private:
|
||||
param_fp_t m_freq;
|
||||
};
|
||||
} // namespace devices
|
||||
// -----------------------------------------------------------------------------
|
||||
// netlist_t
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1626,8 +1670,8 @@ namespace netlist
|
||||
|
||||
private:
|
||||
|
||||
template <bool KEEP_STATS, typename MCT>
|
||||
void process_queue_stats(netlist_time delta, MCT *mainclock) noexcept;
|
||||
template <bool KEEP_STATS>
|
||||
void process_queue_stats(netlist_time delta) noexcept;
|
||||
|
||||
plib::unique_ptr<netlist_state_t> m_state;
|
||||
devices::NETLIB_NAME(solver) * m_solver;
|
||||
@ -1644,7 +1688,7 @@ namespace netlist
|
||||
// performance
|
||||
plib::pperftime_t<true> m_stat_mainloop;
|
||||
plib::pperfcount_t<true> m_perf_out_processed;
|
||||
};
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Support classes for devices
|
||||
@ -1885,7 +1929,7 @@ namespace netlist
|
||||
return net().Q_Analog();
|
||||
}
|
||||
|
||||
inline void analog_output_t::set_Q(const nl_fptype newQ) noexcept
|
||||
inline void analog_output_t::set_Q(nl_fptype newQ) noexcept
|
||||
{
|
||||
if (newQ != m_my_net.Q_Analog())
|
||||
{
|
||||
@ -1962,7 +2006,7 @@ namespace netlist
|
||||
if ((p.terminal_state() & mask))
|
||||
{
|
||||
auto g(stats->m_stat_total_time.guard());
|
||||
p.m_delegate();
|
||||
p.run_delegate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1972,7 +2016,7 @@ namespace netlist
|
||||
{
|
||||
p.set_copied_input(sig);
|
||||
if ((p.terminal_state() & mask))
|
||||
p.m_delegate();
|
||||
p.run_delegate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1988,8 +2032,8 @@ namespace netlist
|
||||
| (m_cur_Q << core_terminal_t::INP_HL_SHIFT), m_new_Q);
|
||||
}
|
||||
|
||||
template <bool KEEP_STATS, typename MCT>
|
||||
inline void netlist_t::process_queue_stats(const netlist_time delta, MCT *mainclock) noexcept
|
||||
template <bool KEEP_STATS>
|
||||
inline void netlist_t::process_queue_stats(const netlist_time delta) noexcept
|
||||
{
|
||||
netlist_time stop(m_time + delta);
|
||||
|
||||
@ -2010,8 +2054,8 @@ namespace netlist
|
||||
}
|
||||
else
|
||||
{
|
||||
logic_net_t &mc_net(mainclock->m_Q.net());
|
||||
const netlist_time inc(mainclock->m_inc);
|
||||
logic_net_t &mc_net(m_mainclock->m_Q.net());
|
||||
const netlist_time inc(m_mainclock->m_inc);
|
||||
netlist_time mc_time(mc_net.next_scheduled_time());
|
||||
|
||||
do
|
||||
@ -2039,6 +2083,16 @@ namespace netlist
|
||||
}
|
||||
}
|
||||
|
||||
inline void netlist_t::process_queue(netlist_time delta) noexcept
|
||||
{
|
||||
if (!m_use_stats)
|
||||
process_queue_stats<false>(delta);
|
||||
else
|
||||
{
|
||||
auto sm_guard(m_stat_mainloop.guard());
|
||||
process_queue_stats<true>(delta);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace netlist
|
||||
|
||||
|
@ -82,6 +82,22 @@
|
||||
#define NL_USE_FLOAT128 PUSE_FLOAT128
|
||||
#endif
|
||||
|
||||
/// \brief Support float type for matrix calculations.
|
||||
///
|
||||
/// Defaults to off to provide faster build times
|
||||
|
||||
#ifndef NL_USE_FLOAT_MATRIX
|
||||
#define NL_USE_FLOAT_MATRIX (0)
|
||||
#endif
|
||||
|
||||
/// \brief Support long double type for matrix calculations.
|
||||
///
|
||||
/// Defaults to off to provide faster build times
|
||||
|
||||
#ifndef NL_USE_LONG_DOUBLE_MATRIX
|
||||
#define NL_USE_LONG_DOUBLE_MATRIX (0)
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// DEBUGGING
|
||||
//============================================================
|
||||
|
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Couriersud
|
||||
|
||||
///
|
||||
/// \file nl_parser.c
|
||||
/// \file nl_parser.h
|
||||
///
|
||||
|
||||
#ifndef NL_PARSER_H_
|
||||
|
@ -38,20 +38,12 @@ namespace solver
|
||||
GMRES
|
||||
)
|
||||
|
||||
#if (NL_USE_FLOAT128)
|
||||
P_ENUM(matrix_fp_type_e,
|
||||
FLOAT
|
||||
, DOUBLE
|
||||
, LONGDOUBLE
|
||||
, FLOAT128
|
||||
)
|
||||
#else
|
||||
P_ENUM(matrix_fp_type_e,
|
||||
FLOAT
|
||||
, DOUBLE
|
||||
, LONGDOUBLE
|
||||
)
|
||||
#endif
|
||||
|
||||
struct solver_parameters_t
|
||||
{
|
||||
|
@ -329,19 +329,29 @@ namespace devices
|
||||
switch (m_params.m_fp_type())
|
||||
{
|
||||
case solver::matrix_fp_type_e::FLOAT:
|
||||
#if (NL_USE_FLOAT_MATRIX)
|
||||
ms = create_solvers<float>(sname, grp);
|
||||
#else
|
||||
ms = create_solvers<double>(sname, grp);
|
||||
#endif
|
||||
break;
|
||||
case solver::matrix_fp_type_e::DOUBLE:
|
||||
ms = create_solvers<double>(sname, grp);
|
||||
break;
|
||||
case solver::matrix_fp_type_e::LONGDOUBLE:
|
||||
#if (NL_USE_LONG_DOUBLE_MATRIX)
|
||||
ms = create_solvers<long double>(sname, grp);
|
||||
break;
|
||||
#if (NL_USE_FLOAT128)
|
||||
case solver::matrix_fp_type_e::FLOAT128:
|
||||
ms = create_solvers<__float128>(sname, grp);
|
||||
break;
|
||||
#else
|
||||
ms = create_solvers<double>(sname, grp);
|
||||
#endif
|
||||
break;
|
||||
case solver::matrix_fp_type_e::FLOAT128:
|
||||
#if (NL_USE_FLOAT128)
|
||||
ms = create_solvers<__float128>(sname, grp);
|
||||
#else
|
||||
ms = create_solvers<double>(sname, grp);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
log().verbose("Solver {1}", ms->name());
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "netlist/nl_base.h"
|
||||
#include "nld_matrix_solver.h"
|
||||
#include "plib/pstream.h"
|
||||
#include "../plib/pstream.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
Loading…
Reference in New Issue
Block a user