Fix timing issue in CD4538. Add "pow" (power) to the function model.
Minor documentation updates. Slight improvement of gorilla sound. (nw)master
parent
5b4026d13f
commit
c8c7e9a770
|
@ -367,97 +367,13 @@ NETLIST_START(CongoBongo_schematics)
|
||||||
NET_C(C61.1, R94.2)
|
NET_C(C61.1, R94.2)
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
NETLIST_START(opamp_mod)
|
|
||||||
|
|
||||||
/* Opamp model from
|
|
||||||
*
|
|
||||||
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
|
|
||||||
*
|
|
||||||
* MB3614 Unit Gain frequency is about 500 kHz and the first pole frequency
|
|
||||||
* about 5 Hz. We have to keep the Unity Gain Frequency below our sampling
|
|
||||||
* frequency of 24 Khz.
|
|
||||||
*
|
|
||||||
* Simple Opamp Model Calculation
|
|
||||||
*
|
|
||||||
* First Pole Frequency 5 Hz
|
|
||||||
* Unity Gain Frequency 11,000 Hz
|
|
||||||
* RP 100,000 Ohm
|
|
||||||
* DC Gain / Aol 2200
|
|
||||||
* CP 0.318 uF
|
|
||||||
* KG 0.022
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Terminal definitions for calling netlists */
|
|
||||||
|
|
||||||
ALIAS(PLUS, G1.IP) // Positive input
|
|
||||||
ALIAS(MINUS, G1.IN) // Negative input
|
|
||||||
ALIAS(OUT, EBUF.OP) // Opamp output ...
|
|
||||||
|
|
||||||
AFUNC(fUH, 1, "A0 1.2 -")
|
|
||||||
AFUNC(fUL, 1, "A0 1.2 +")
|
|
||||||
|
|
||||||
ALIAS(VCC, fUH.A0) // VCC terminal
|
|
||||||
ALIAS(GND, fUL.A0) // VGND terminal
|
|
||||||
|
|
||||||
AFUNC(fVREF, 2, "A0 A1 + 0.5 *")
|
|
||||||
NET_C(fUH.A0, fVREF.A0)
|
|
||||||
NET_C(fUL.A0, fVREF.A1)
|
|
||||||
|
|
||||||
NET_C(EBUF.ON, fVREF)
|
|
||||||
/* The opamp model */
|
|
||||||
|
|
||||||
LVCCS(G1)
|
|
||||||
PARAM(G1.RI, RES_K(1000))
|
|
||||||
#if 0
|
|
||||||
PARAM(G1.G, 0.0022)
|
|
||||||
RES(RP1, 1e6)
|
|
||||||
CAP(CP1, 0.0318e-6)
|
|
||||||
#else
|
|
||||||
PARAM(G1.G, 0.002)
|
|
||||||
PARAM(G1.CURLIM, 0.002)
|
|
||||||
RES(RP1, 9.5e6)
|
|
||||||
CAP(CP1, 0.0033e-6)
|
|
||||||
#endif
|
|
||||||
VCVS(EBUF)
|
|
||||||
PARAM(EBUF.RO, 50)
|
|
||||||
PARAM(EBUF.G, 1)
|
|
||||||
|
|
||||||
NET_C(G1.ON, fVREF)
|
|
||||||
NET_C(RP1.2, fVREF)
|
|
||||||
NET_C(CP1.2, fVREF)
|
|
||||||
NET_C(EBUF.IN, fVREF)
|
|
||||||
|
|
||||||
NET_C(RP1.1, G1.OP)
|
|
||||||
NET_C(CP1.1, RP1.1)
|
|
||||||
|
|
||||||
DIODE(DP,"D(IS=1e-15 N=1)")
|
|
||||||
DIODE(DN,"D(IS=1e-15 N=1)")
|
|
||||||
#if 1
|
|
||||||
NET_C(DP.K, fUH.Q)
|
|
||||||
NET_C(fUL.Q, DN.A)
|
|
||||||
NET_C(DP.A, DN.K, RP1.1)
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* This doesn't add any performance by decreasing iteration loops.
|
|
||||||
* To the contrary, it significantly decreases iterations
|
|
||||||
*/
|
|
||||||
RES(RH1, 0.1)
|
|
||||||
RES(RL1, 0.1)
|
|
||||||
NET_C(DP.K, RH1.1)
|
|
||||||
NET_C(RH1.2, fUH.Q)
|
|
||||||
NET_C(fUL.Q, RL1.1)
|
|
||||||
NET_C(RL1.2, DN.A)
|
|
||||||
NET_C(DP.A, DN.K, RP1.1)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
NET_C(EBUF.IP, RP1.1)
|
|
||||||
|
|
||||||
NETLIST_END()
|
|
||||||
|
|
||||||
|
|
||||||
NETLIST_START(G501534_DIP)
|
NETLIST_START(G501534_DIP)
|
||||||
AFUNC(f, 2, "A0 A1 0.2 * *")
|
//AFUNC(f, 2, "A0 A1 A1 A1 * * 0.01 * *")
|
||||||
|
//AFUNC(f, 2, "A0")
|
||||||
|
//AFUNC(f, 2, "A0 6 - A1 3 pow * 0.02 * 6 +")
|
||||||
|
AFUNC(f, 2, "A0 A1 3 pow * 0.02 *")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 12: VCC
|
* 12: VCC
|
||||||
|
|
|
@ -97,3 +97,91 @@ NETLIST_START(opamp)
|
||||||
NET_C(EBUF.IP, RP1.1)
|
NET_C(EBUF.IP, RP1.1)
|
||||||
|
|
||||||
NETLIST_END()
|
NETLIST_END()
|
||||||
|
|
||||||
|
NETLIST_START(opamp_mod)
|
||||||
|
|
||||||
|
/* Opamp model from
|
||||||
|
*
|
||||||
|
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
|
||||||
|
*
|
||||||
|
* MB3614 Unit Gain frequency is about 500 kHz and the first pole frequency
|
||||||
|
* about 5 Hz. We have to keep the Unity Gain Frequency below our sampling
|
||||||
|
* frequency of 24 Khz.
|
||||||
|
*
|
||||||
|
* Simple Opamp Model Calculation
|
||||||
|
*
|
||||||
|
* First Pole Frequency 5 Hz
|
||||||
|
* Unity Gain Frequency 11,000 Hz
|
||||||
|
* RP 100,000 Ohm
|
||||||
|
* DC Gain / Aol 2200
|
||||||
|
* CP 0.318 uF
|
||||||
|
* KG 0.022
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Terminal definitions for calling netlists */
|
||||||
|
|
||||||
|
ALIAS(PLUS, G1.IP) // Positive input
|
||||||
|
ALIAS(MINUS, G1.IN) // Negative input
|
||||||
|
ALIAS(OUT, EBUF.OP) // Opamp output ...
|
||||||
|
|
||||||
|
AFUNC(fUH, 1, "A0 1.2 -")
|
||||||
|
AFUNC(fUL, 1, "A0 1.2 +")
|
||||||
|
|
||||||
|
ALIAS(VCC, fUH.A0) // VCC terminal
|
||||||
|
ALIAS(GND, fUL.A0) // VGND terminal
|
||||||
|
|
||||||
|
AFUNC(fVREF, 2, "A0 A1 + 0.5 *")
|
||||||
|
NET_C(fUH.A0, fVREF.A0)
|
||||||
|
NET_C(fUL.A0, fVREF.A1)
|
||||||
|
|
||||||
|
NET_C(EBUF.ON, fVREF)
|
||||||
|
/* The opamp model */
|
||||||
|
|
||||||
|
LVCCS(G1)
|
||||||
|
PARAM(G1.RI, RES_K(1000))
|
||||||
|
#if 0
|
||||||
|
PARAM(G1.G, 0.0022)
|
||||||
|
RES(RP1, 1e6)
|
||||||
|
CAP(CP1, 0.0318e-6)
|
||||||
|
#else
|
||||||
|
PARAM(G1.G, 0.002)
|
||||||
|
PARAM(G1.CURLIM, 0.002)
|
||||||
|
RES(RP1, 9.5e6)
|
||||||
|
CAP(CP1, 0.0033e-6)
|
||||||
|
#endif
|
||||||
|
VCVS(EBUF)
|
||||||
|
PARAM(EBUF.RO, 50)
|
||||||
|
PARAM(EBUF.G, 1)
|
||||||
|
|
||||||
|
NET_C(G1.ON, fVREF)
|
||||||
|
NET_C(RP1.2, fVREF)
|
||||||
|
NET_C(CP1.2, fVREF)
|
||||||
|
NET_C(EBUF.IN, fVREF)
|
||||||
|
|
||||||
|
NET_C(RP1.1, G1.OP)
|
||||||
|
NET_C(CP1.1, RP1.1)
|
||||||
|
|
||||||
|
DIODE(DP,"D(IS=1e-15 N=1)")
|
||||||
|
DIODE(DN,"D(IS=1e-15 N=1)")
|
||||||
|
#if 1
|
||||||
|
NET_C(DP.K, fUH.Q)
|
||||||
|
NET_C(fUL.Q, DN.A)
|
||||||
|
NET_C(DP.A, DN.K, RP1.1)
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* This doesn't add any performance by decreasing iteration loops.
|
||||||
|
* To the contrary, it significantly decreases iterations
|
||||||
|
*/
|
||||||
|
RES(RH1, 0.1)
|
||||||
|
RES(RL1, 0.1)
|
||||||
|
NET_C(DP.K, RH1.1)
|
||||||
|
NET_C(RH1.2, fUH.Q)
|
||||||
|
NET_C(fUL.Q, RL1.1)
|
||||||
|
NET_C(RL1.2, DN.A)
|
||||||
|
NET_C(DP.A, DN.K, RP1.1)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
NET_C(EBUF.IP, RP1.1)
|
||||||
|
|
||||||
|
NETLIST_END()
|
||||||
|
|
|
@ -34,12 +34,12 @@ namespace netlist
|
||||||
* SLEW = unity gain slew rate in V/s
|
* SLEW = unity gain slew rate in V/s
|
||||||
* RI = input resistance in Ohms
|
* RI = input resistance in Ohms
|
||||||
* RO = output resistance in Ohms
|
* RO = output resistance in Ohms
|
||||||
* DAB = quiescent supply current in A
|
* DAB = Differential Amp Bias ~ op amp's total quiescent current.
|
||||||
*/
|
*
|
||||||
|
* .model abc OPAMP(VLH=2.0 VLL=0.2 FPF=5 UGF=10k SLEW=0.6u RI=1000k RO=50 DAB=0.002)
|
||||||
/* .model abc OPAMP(VLH=2.0 VLL=0.2 FPF=5 UGF=10k SLEW=0.6u RI=1000k RO=50 DAB=0.002)
|
*
|
||||||
|
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
|
||||||
*
|
*
|
||||||
* Differential Amp Bias ~ op amp's total quiescent current.
|
|
||||||
* */
|
* */
|
||||||
|
|
||||||
NETLIB_UPDATE(OPAMP)
|
NETLIB_UPDATE(OPAMP)
|
||||||
|
@ -79,7 +79,7 @@ NETLIB_RESET(OPAMP)
|
||||||
double RP = 0.5 / 3.1459 / CP / m_model.model_value("FPF");
|
double RP = 0.5 / 3.1459 / CP / m_model.model_value("FPF");
|
||||||
double G = m_model.model_value("UGF") / m_model.model_value("FPF") / RP;
|
double G = m_model.model_value("UGF") / m_model.model_value("FPF") / RP;
|
||||||
|
|
||||||
printf("Min Freq %s: %f\n", name().c_str(), 1.0 / (CP*RP / (G*RP)));
|
//printf("Min Freq %s: %f\n", name().c_str(), 1.0 / (CP*RP / (G*RP)));
|
||||||
|
|
||||||
m_CP->m_C.setTo(CP);
|
m_CP->m_C.setTo(CP);
|
||||||
m_RP.set_R(RP);
|
m_RP.set_R(RP);
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace netlist
|
||||||
, m_last_trig(*this, "m_last_trig", 0)
|
, m_last_trig(*this, "m_last_trig", 0)
|
||||||
, m_state(*this, "m_state", 0)
|
, m_state(*this, "m_state", 0)
|
||||||
, m_KP(*this, "m_KP", 0)
|
, m_KP(*this, "m_KP", 0)
|
||||||
, m_K(*this, "K", (m_dev_type == 4538) ? 0.4 : 0.4)
|
, m_K(*this, "K", (m_dev_type == 4538) ? 1.0 : 0.4) // CD4538 datasheet states PW=RC
|
||||||
, m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
|
, m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
|
||||||
{
|
{
|
||||||
if ((m_dev_type != 9602) && (m_dev_type != 4538) )
|
if ((m_dev_type != 9602) && (m_dev_type != 4538) )
|
||||||
|
|
|
@ -158,6 +158,10 @@ namespace netlist
|
||||||
ptr--;
|
ptr--;
|
||||||
stack[ptr-1] = stack[ptr-1] / stack[ptr];
|
stack[ptr-1] = stack[ptr-1] / stack[ptr];
|
||||||
break;
|
break;
|
||||||
|
case POW:
|
||||||
|
ptr--;
|
||||||
|
stack[ptr-1] = std::pow(stack[ptr-1], stack[ptr]);
|
||||||
|
break;
|
||||||
case PUSH_INPUT:
|
case PUSH_INPUT:
|
||||||
stack[ptr++] = (*m_I[static_cast<unsigned>(rc.m_param)])();
|
stack[ptr++] = (*m_I[static_cast<unsigned>(rc.m_param)])();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -327,6 +327,8 @@ namespace netlist
|
||||||
rc.m_cmd = MULT;
|
rc.m_cmd = MULT;
|
||||||
else if (cmd == "/")
|
else if (cmd == "/")
|
||||||
rc.m_cmd = DIV;
|
rc.m_cmd = DIV;
|
||||||
|
else if (cmd == "pow")
|
||||||
|
rc.m_cmd = POW;
|
||||||
else if (cmd.startsWith("A"))
|
else if (cmd.startsWith("A"))
|
||||||
{
|
{
|
||||||
rc.m_cmd = PUSH_INPUT;
|
rc.m_cmd = PUSH_INPUT;
|
||||||
|
@ -359,6 +361,7 @@ namespace netlist
|
||||||
MULT,
|
MULT,
|
||||||
SUB,
|
SUB,
|
||||||
DIV,
|
DIV,
|
||||||
|
POW,
|
||||||
PUSH_CONST,
|
PUSH_CONST,
|
||||||
PUSH_INPUT
|
PUSH_INPUT
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue