model OpAmpDetailed "Detailed model of an operational amplifier"
import Modelica.Constants.pi;
parameter SI.Resistance Rdm = 2e+6 "Input resistance (differential input mode)";
parameter SI.Resistance Rcm = 2e+9 "Input resistance (common mode)";
parameter SI.Capacitance Cin = 1.4e-12 "Input capacitance";
parameter SI.Voltage Vos = 0.001 "Input offset voltage";
parameter SI.Current Ib = 8e-8 "Input bias current";
parameter SI.Current Ios = 2e-8 "Input offset current";
parameter SI.Voltage vcp = 0 "Correction value for limiting by p_supply";
parameter SI.Voltage vcm = 0 "Correction value for limiting by msupply";
parameter Real Avd0 = 106 "Differential amplifier [dB]";
parameter Real CMRR = 90 "Common-mode rejection [dB]";
parameter SI.Frequency fp1 = 5 "Dominant pole";
parameter SI.Frequency fp2 = 2e+6 "Pole frequency";
parameter SI.Frequency fp3 = 2e+7 "Pole frequency";
parameter SI.Frequency fp4 = 1e+8 "Pole frequency";
parameter SI.Frequency fz = 5e+6 "Zero frequency";
parameter SI.VoltageSlope sr_p = 500000 "Slew rate for increase";
parameter SI.VoltageSlope sr_m = 500000 "Slew rate for decrease";
parameter SI.Resistance Rout = 75 "Output resistance";
parameter SI.Current Imaxso = 0.025 "Maximal output current (source current)";
parameter SI.Current Imaxsi = 0.025 "Maximal output current (sink current)";
parameter SI.Time Ts = 1.2e-6 "Sampling time";
constant Real Pi = 3.141592654 "Obsolete constant pi; will be removed in future release";
final parameter SI.Voltage vcp_abs = abs(vcp) "Positive correction value for limiting by p_supply";
final parameter SI.Voltage vcm_abs = abs(vcm) "Positive correction value for limiting by msupply";
final parameter SI.Current I1 = Ib + 0.5 * Ios "Current of internal source I1";
final parameter SI.Current I2 = Ib - 0.5 * Ios "Current of internal source I2";
final parameter Real Avd0_val = 10 ^ (0.05 * Avd0) "Differential mode gain";
final parameter Real Avcm_val = 0.5 * (Avd0_val / 10 ^ (0.05 * CMRR)) "Common mode gain";
final parameter SI.VoltageSlope sr_p_val = abs(sr_p) "Value of slew rate for increase";
final parameter SI.VoltageSlope sr_m_val = -abs(sr_m) "Negative alue of slew rate for increase";
final parameter SI.Current Imaxso_val = abs(Imaxso) "Orientation out outp";
final parameter SI.Current Imaxsi_val = abs(Imaxsi) "Orientation into outp";
Modelica.Electrical.Analog.Interfaces.PositivePin p "Positive pin of the input port"
annotation (Placement(
transformation(extent = {
{-110, -70},
{-90, -50}}),
iconTransformation(extent = {
{-110, -70},
{-90, -50}})));
Modelica.Electrical.Analog.Interfaces.NegativePin m "Negative pin of the input port"
annotation (Placement(
transformation(extent = {
{-90, 50},
{-110, 70}}),
iconTransformation(extent = {
{-90, 50},
{-110, 70}})));
Modelica.Electrical.Analog.Interfaces.PositivePin outp "Output pin"
annotation (Placement(
transformation(extent = {
{110, -10},
{90, 10}}),
iconTransformation(extent = {
{110, -10},
{90, 10}})));
Modelica.Electrical.Analog.Interfaces.PositivePin p_supply "Positive output voltage limitation"
annotation (Placement(
transformation(extent = {
{-10, 90},
{10, 110}}),
iconTransformation(extent = {
{-10, 90},
{10, 110}})));
Modelica.Electrical.Analog.Interfaces.NegativePin m_supply "Negative output voltage limitation"
annotation (Placement(
transformation(extent = {
{-10, -110},
{10, -90}}),
iconTransformation(extent = {
{-10, -110},
{10, -90}})));
SI.Voltage v_pos;
SI.Voltage v_neg;
SI.Voltage v_vos;
SI.Voltage v_3;
SI.Voltage v_in;
SI.Voltage v_4;
SI.Current i_vos;
SI.Current i_3;
SI.Current i_r2;
SI.Current i_c3;
SI.Current i_4;
Real q_fr1;
Real q_fr2;
Real q_fr3;
SI.Voltage q_sum;
SI.Voltage q_sum_help;
SI.Voltage q_fp1;
SI.Voltage v_source;
SI.Voltage x "Auxiliary variable for slew rate";
SI.Voltage v_out;
SI.Current i_out;
function FCNiout_limit "Internal limitation function"
extends Modelica.Icons.Function;
input SI.Voltage v_source;
input SI.Voltage v_out;
input SI.Resistance Rout;
input SI.Current Imaxsi_val;
input SI.Current Imaxso_val;
output SI.Current result;
algorithm
if v_source + Rout * Imaxsi_val < v_out then
result := Imaxsi_val;
elseif v_out < v_source - Rout * Imaxso_val then
result := -Imaxso_val;
else
result := (v_out - v_source) / Rout;
end if;
return;
annotation (Documentation(info = "<html>\n<p>Internal limitation function, designed for OpAmpDetailed, not for purpose of external usage.</p>\n</html>"));
end FCNiout_limit;
function FCNq_sum_limit "Internal limitation function"
extends Modelica.Icons.Function;
input SI.Voltage q_sum;
input SI.Voltage q_sum_ltf;
input SI.Voltage v_pos;
input SI.Voltage v_neg;
input SI.Voltage vcp;
input SI.Voltage vcm;
output SI.Voltage result;
algorithm
if v_pos - vcp < q_sum and v_pos - vcp <= q_sum_ltf then
result := v_pos - vcp;
elseif q_sum < v_neg + vcm and q_sum_ltf <= v_neg + vcm then
result := v_neg + vcm;
else
result := q_sum;
end if;
return;
annotation (Documentation(info = "<html>\n<p>Internal limitation function, designed for OpAmpDetailed, not for purpose of external usage.</p>\n</html>"));
end FCNq_sum_limit;
initial equation
x = 0;
v_source = q_fp1;
equation
assert(0 < Rout, "Rout must be > 0.0.");
0 = i_3 + i_r2 + i_c3 - i_vos;
q_fr2 + (2 * pi * fp3) ^ (-1) * der(q_fr2) = q_fr1 + (2 * pi * fz) ^ (-1) * der(q_fr1);
i_3 = I1 + v_3 / Rcm;
i_4 = I2 + v_4 / Rcm;
i_c3 = Cin * der(v_in);
i_out = outp.i;
i_out = FCNiout_limit(v_source, v_out, Rout, Imaxsi_val, Imaxso_val);
q_sum = Avd0_val * q_fr3 + Avcm_val * (v_3 + v_4);
v_3 = p.v - v_vos;
v_4 = m.v;
v_in = Rdm * i_r2;
v_neg = m_supply.v;
v_out = outp.v;
v_pos = p_supply.v;
v_vos = Vos;
q_sum_help = FCNq_sum_limit(q_sum, q_fp1, v_pos, v_neg, vcp_abs, vcm_abs);
m.i = i_4 - i_r2 - i_c3;
p.i = i_vos;
m_supply.i = 0;
p_supply.i = 0;
p.v - m.v = v_vos + v_in;
der(x) = (q_fp1 - v_source) / Ts;
der(q_fp1) = 2 * pi * fp1 * (q_sum_help - q_fp1);
der(q_fr1) = 2 * pi * fp2 * (v_in - q_fr1);
der(q_fr3) = 2 * pi * fp4 * (q_fr2 - q_fr3);
der(v_source) = smooth(0, noEvent(if sr_p_val < der(x) then sr_p_val else if der(x) < sr_m_val then sr_m_val else der(x)));
annotation (
defaultComponentName = "opAmp",
Documentation(
info = "<html>\n<p>The OpAmpDetailed model is a general operational amplifier model. The emphasis is on separating each important data sheet parameter into a sub-circuit independent of the other parameters. The model is broken down into five functional stages <strong>input</strong>, <strong>frequency response</strong>, <strong>gain</strong>, <strong>slew rate</strong> and an <strong>output</strong> stage. Each stage contains data sheet parameters to be modeled. This partitioning and the modelling of the separate submodels are based on the description in <strong>[CP92]</strong>.</p>\n<p>Using <strong>[CP92]</strong> Joachim Haase (Fraunhofer Institute for Integrated Circuits, Design Automation Division) transferred 2001 operational amplifier models into VHDL-AMS. Now one of these models, the model "amp(macro)" was transferred into Modelica.</p>\n<dl><dt><strong>Reference:</strong> </dt>\n<dd><strong>[CP92]</strong> Conelly, J.A.; Choi, P.: Macromodelling with SPICE. Englewood Cliffs: Prentice-Hall, 1992 </dd>\n</dl></html>",
revisions = "<html>\n<dl>\n<dt><em>June 17, 2009</em></dt>\n<dd>by Susann Wolf initially implemented</dd>\n</dl>\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Text(
extent = {
{-150, 150},
{150, 110}},
textString = "%name",
lineColor = {0, 0, 255}),
Polygon(
points = {
{70, 0},
{-70, 80},
{-70, -80},
{70, 0}},
fillColor = {255, 255, 255},
fillPattern = FillPattern.Solid,
lineColor = {0, 0, 255}),
Line(
points = {
{0, 40},
{0, 110}},
color = {0, 0, 255}),
Line(
points = {
{0, -40},
{0, -90}},
color = {0, 0, 255}),
Line(
points = {
{-90, 60},
{-70, 60}},
color = {0, 0, 255}),
Line(
points = {
{-90, -60},
{-70, -60}},
color = {0, 0, 255}),
Line(
points = {
{70, 0},
{90, 0}},
color = {0, 0, 255}),
Line(
points = {
{-58, 50},
{-38, 50}},
color = {0, 0, 255}),
Line(
points = {
{-60, -51},
{-38, -51}},
color = {0, 0, 255}),
Line(
points = {
{-49, -40},
{-49, -61}},
color = {0, 0, 255})}));
end OpAmpDetailed;