blob: b081f92269623e7d6b9aed6d336303a51e0f5571 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_opamps.c
*
*/
#include "nld_opamps.h"
#include "devices/net_lib.h"
namespace netlist
{
namespace devices
{
/*
* Type = 0: Impedance changer
* 1; Idealized opamp
* 2; opamp with first pole
* 3: opamp with first pole + output limit
* 4: opamp with input stage, first pole + output limit
*
* Type 1 parameters:
* FPF = frequency of first pole in Hz (ony used for open-loop gain)
* UGF = unity gain frequency in Hz (only used for open-loop gain)
* RI = input resistance in Ohms
* RO = output resistance in Ohms
*
* Type 3 parameters:
* VLH = high supply rail minus high output swing in V
* VLL = low output swing minus low supply rail in V
* FPF = frequency of first pole in Hz
* UGF = unity gain frequency (transition frequency) in Hz
* SLEW = unity gain slew rate in V/s
* RI = input resistance in Ohms
* RO = output resistance in Ohms
* 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)
*
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
*
* */
NETLIB_UPDATE(OPAMP)
{
const double cVt = 0.0258 * 1.0; // * m_n;
const double cId = m_model.model_value("DAB"); // 3 mA
const double cVd = cVt * std::log(cId / 1e-15 + 1.0);
m_VH.push(m_VCC() - m_model.model_value("VLH") - cVd);
m_VL.push(m_GND() + m_model.model_value("VLL") + cVd);
m_VREF.push((m_VCC() + m_GND()) / 2.0);
}
NETLIB_RESET(OPAMP)
{
m_G1.do_reset();
m_G1.m_RI.setTo(m_model.model_value("RI"));
if (m_type == 1)
{
double RO = m_model.model_value("RO");
double G = m_model.model_value("UGF") / m_model.model_value("FPF") / RO;
m_RP.set_R(RO);
m_G1.m_G.setTo(G);
}
else if (m_type == 3)
{
m_EBUF->do_reset();
m_DP->do_reset();
m_DN->do_reset();
m_CP->do_reset();
m_RP.do_reset();
m_EBUF->m_G.setTo(1.0);
m_EBUF->m_RO.setTo(m_model.model_value("RO"));
double CP = m_model.model_value("DAB") / m_model.model_value("SLEW");
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;
//printf("Min Freq %s: %f\n", name().c_str(), 1.0 / (CP*RP / (G*RP)));
m_CP->m_C.setTo(CP);
m_RP.set_R(RP);
m_G1.m_G.setTo(G);
}
}
/*
NETLIB_DEVICE_WITH_PARAMS(OPAMPx,
NETLIB_NAME(R) m_RP;
NETLIB_NAME(C) m_CP;
NETLIB_NAME(VCCS) m_G1;
NETLIB_NAME(VCVS) m_EBUF;
param_model_t m_model;
analog_input_t m_VH;
analog_input_t m_VL;
analog_input_t m_VREF;
);
*/
} //namespace devices
} // namespace netlist
|