Some preparation for future changes on proxies and chip families. (nw)

This commit is contained in:
couriersud 2016-12-28 02:15:34 +01:00
parent 63f4e52dae
commit 1983580e26
7 changed files with 71 additions and 27 deletions

View File

@ -50,10 +50,10 @@ NETLIST_START(bjt_models)
NETLIST_END()
NETLIST_START(family_models)
NET_MODEL("FAMILY _(TYPE=CUSTOM IVL=0.8 IVH=2.0 OVL=0.1 OVH=4.0 ORL=1.0 ORH=130.0)")
NET_MODEL("FAMILY _(TYPE=CUSTOM FV=5 IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130.0)")
NET_MODEL("OPAMP _()")
NET_MODEL("74XXOC FAMILY(IVL=0.8 IVH=2.0 OVL=0.1 OVH=4.95 ORL=10.0 ORH=1.0e8)")
NET_MODEL("74XXOC FAMILY(FV=5 IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)")
NET_MODEL("74XX FAMILY(TYPE=TTL)")
NET_MODEL("CD4XXX FAMILY(TYPE=CD4XXX)")
NETLIST_END()

View File

@ -28,6 +28,7 @@ namespace netlist
, m_last_state(*this, "m_last_var", -1)
, m_is_timestep(false)
{
const char *power_syms[3][2] ={ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
//register_sub(m_RV);
//register_term("1", m_RV.m_P);
//register_term("2", m_RV.m_N);
@ -35,19 +36,42 @@ namespace netlist
register_subalias("Q", m_RV.m_P);
connect_late(m_RV.m_N, m_GNDHack);
bool f = false;
for (int i = 0; i < 3; i++)
{
pstring devname = out_proxied->device().name();
auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0], detail::device_object_t::type_t::INPUT, false);
auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1], detail::device_object_t::type_t::INPUT, false);
if (tp != nullptr && tn != nullptr)
{
/* alternative logic */
f = true;
}
}
if (!f)
netlist().log().warning("D/A Proxy: Found no valid combination of power terminals on device {1}", out_proxied->device().name());
else
netlist().log().warning("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
#if (0)
printf("%s %s\n", out_proxied->name().cstr(), out_proxied->device().name().cstr());
auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::type_t::OUTPUT, false);
if (x) printf("==> %s\n", x->name().cstr());
#endif
}
void nld_d_to_a_proxy::reset()
{
// FIXME: Variable voltage
double supply_V = logic_family().fixed_V();
if (supply_V == 0.0) supply_V = 5.0;
//m_Q.initial(0.0);
m_last_state = -1;
m_RV.do_reset();
m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0);
m_RV.set(NL_FCONST(1.0) / logic_family().R_low(),
logic_family().low_V(0.0, supply_V), 0.0);
}
NETLIB_UPDATE(d_to_a_proxy)
@ -55,9 +79,12 @@ namespace netlist
const int state = static_cast<int>(m_I());
if (state != m_last_state)
{
// FIXME: Variable voltage
double supply_V = logic_family().fixed_V();
if (supply_V == 0.0) supply_V = 5.0;
m_last_state = state;
const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low;
const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V;
const nl_double R = state ? logic_family().R_high() : logic_family().R_low();
const nl_double V = state ? logic_family().high_V(0.0, supply_V) : logic_family().low_V(0.0, supply_V);
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)

View File

@ -83,9 +83,13 @@ namespace netlist
NETLIB_UPDATEI()
{
nl_assert(m_logic_family != nullptr);
if (m_I.Q_Analog() > logic_family().m_high_thresh_V)
// FIXME: Variable supply voltage!
double supply_V = logic_family().fixed_V();
if (supply_V == 0.0) supply_V = 5.0;
if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V))
m_Q.push(1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < logic_family().m_low_thresh_V)
else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V))
m_Q.push(0, NLTIME_FROM_NS(1));
else
{

View File

@ -36,7 +36,7 @@ static NETLIST_START(MC14584B_DIP)
s1.A, /* A1 |1 ++ 14| VCC */ VCC.I,
s1.Q, /* Y1 |2 13| A6 */ s6.A,
s2.A, /* A2 |3 12| Y6 */ s6.Q,
s2.Q, /* Y2 |4 7416 11| A5 */ s5.A,
s2.Q, /* Y2 |4 MC14584B 11| A5 */ s5.A,
s3.A, /* A3 |5 10| Y5 */ s5.Q,
s3.Q, /* Y3 |6 9| A4 */ s4.A,
GND.I, /* GND |7 8| Y4 */ s4.Q
@ -49,7 +49,8 @@ NETLIST_START(otheric_lib)
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |100")
TT_LINE(" 1 | 0 |100")
TT_FAMILY("FAMILY(IVL=2.1 IVH=2.7 OVL=0.05 OVH=4.95 ORL=10.0 ORH=10.0)")
// 2.1V negative going and 2.7V positive going at 5V
TT_FAMILY("FAMILY(FV=0 IVL=0.42 IVH=0.54 OVL=0.05 OVH=0.05 ORL=10.0 ORH=10.0)")
TRUTHTABLE_END()
LOCAL_LIB_ENTRY(MC14584B_DIP)

View File

@ -58,11 +58,12 @@ class logic_family_ttl_t : public logic_family_desc_t
public:
logic_family_ttl_t() : logic_family_desc_t()
{
m_low_thresh_V = 0.8;
m_high_thresh_V = 2.0;
m_fixed_V = 5.0;
m_low_thresh_PCNT = 0.8 / 5.0;
m_high_thresh_PCNT = 2.0 / 5.0;
// m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
m_low_V = 0.1;
m_high_V = 4.0;
m_low_VO = 0.1;
m_high_VO = 1.0; // 4.0
m_R_low = 1.0;
m_R_high = 130.0;
}
@ -77,11 +78,12 @@ class logic_family_cd4xxx_t : public logic_family_desc_t
public:
logic_family_cd4xxx_t() : logic_family_desc_t()
{
m_low_thresh_V = 0.8;
m_high_thresh_V = 2.0;
m_fixed_V = 0.0;
m_low_thresh_PCNT = 1.5 / 5.0;
m_high_thresh_PCNT = 3.5 / 5.0;
// m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
m_low_V = 0.05;
m_high_V = 4.95;
m_low_VO = 0.05;
m_high_VO = 0.05; // 4.95
m_R_low = 10.0;
m_R_high = 10.0;
}

View File

@ -228,12 +228,21 @@ namespace netlist
virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *proxied) const = 0;
nl_double m_low_thresh_V; //!< low input threshhold. If the input voltage is below this value, a "0" input is signalled
nl_double m_high_thresh_V; //!< high input threshhold. If the input voltage is above this value, a "0" input is signalled
nl_double m_low_V; //!< low output voltage. This voltage is output if the ouput is "0"
nl_double m_high_V; //!< high output voltage. This voltage is output if the ouput is "1"
nl_double m_R_low; //!< low output resistance. Value of series resistor used for low output
nl_double m_R_high; //!< high output resistance. Value of series resistor used for high output
double fixed_V() const { return m_fixed_V; }
double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; }
double high_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_high_thresh_PCNT; }
double low_V(const double VN, const double VP) const { return VN + m_low_VO; }
double high_V(const double VN, const double VP) const { return VP - m_high_VO; }
double R_low() const { return m_R_low; }
double R_high() const { return m_R_high; }
double m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */
double m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
double m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
double m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0"
double m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1"
double m_R_low; //!< low output resistance. Value of series resistor used for low output
double m_R_high; //!< high output resistance. Value of series resistor used for high output
};
/*! Base class for devices, terminals, outputs and inputs which support

View File

@ -854,10 +854,11 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
auto ret = plib::make_unique_base<logic_family_desc_t, logic_family_std_proxy_t>();
ret->m_low_thresh_V = setup_t::model_value(map, "IVL");
ret->m_high_thresh_V = setup_t::model_value(map, "IVH");
ret->m_low_V = setup_t::model_value(map, "OVL");
ret->m_high_V = setup_t::model_value(map, "OVH");
ret->m_fixed_V = setup_t::model_value(map, "FV");
ret->m_low_thresh_PCNT = setup_t::model_value(map, "IVL");
ret->m_high_thresh_PCNT = setup_t::model_value(map, "IVH");
ret->m_low_VO = setup_t::model_value(map, "OVL");
ret->m_high_VO = setup_t::model_value(map, "OVH");
ret->m_R_low = setup_t::model_value(map, "ORL");
ret->m_R_high = setup_t::model_value(map, "ORH");