How to configure fgoalattain correctly for a multiple functions multiple variables problem?

2 views (last 30 days)
I am trying to design an operational amplifier (OpAmp) and prepared some functions that gives me the [Gain, Phase Margin (PM), Bandwidth (BW)] of an OpAmp given some devices as input. The devices affect the OpAmp parameters (Gain, PM, BW), and the devices are affected by changing 4 variables [Compensation Capacitors/Resistor (Cc/Rc), OpAmp Load Capacitance (C_Load), OpAmp Total Bias Current (Ib)].
Without going into details; I need to setup the following:
Make => [Gain > 71 dB, PM > 45 degrees, BW > 6.24e5], by minimizing (Ib), and choosing any bounded values for Cc/Rc and C_Load.
I am using fgoalattain to solve my problem, but I am not getting any solutions. However, trial and error shows me that if I set [Cc=150e-15, Rc=80e3, C_Load=10e-15, Ib=4.3e-6], I get [Gain = 71.2 dB, PM = 47 degrees, BW = 6.27e5]. This means that a solution exists, but I think I am not configuring my problem correctly. My code is shown below:
%% CMOS Fully-Differential Two-Stage Amplifier Analysis Optimization Module:
% -------------------------------------------------------------------------
% Clear workspace data:
clear;clc;close all;
% Load and prepare PDK devices data (gm/Id curves):
pdk_devices = get_pdk_devices();
%% -----------------------------------------
% Prepare required devices init parameters:
% -----------------------------------------
% Initialize devices structure:
% -----------------------------
devices = struct('M2',{0}, 'M4',{0}, 'M5',{0}, 'M6',{0}, 'M8',{0}, 'M10',{0});
%% --------------------
% Optimization Module:
% --------------------
fun = @(parameters)[get_2s_gain(pdk_devices, devices, parameters); get_2s_pm(pdk_devices, devices, parameters); get_2s_bw(pdk_devices, devices, parameters)];
goal = [71, 45, 6.24e5]; % [Gain >= 71 dB, PM >= 45 degrees, BW >= 6.24e7]
weight = [1 1 1e3];
parameters0 = [20e-15 1e3 200e-15 3e-6]; % [CC Rc C_Load Ib]
lb = [0 0 0 100e-9];
ub = [20e-12 10e6 40e-12 30e-6];
options = optimoptions('fgoalattain');
options.MaxFunctionEvaluations = 60000;
options.MaxIterations = 60000;
options.ConstraintTolerance = 0*1e-15;
options.OptimalityTolerance = 1e-15;
options.StepTolerance = 0*1e-15;
options.FunctionTolerance = 1e-15;
options.FiniteDifferenceStepSize = 1e-15;
options.UseParallel = 1;
[parameters, fval, attainfc, exitflag] = fgoalattain(fun,parameters0,goal,weight,[],[],[],[],lb,ub,[],options);
fprintf('\nCc: %d \nRc: %d \nC_Load: %d\nIb: %d',parameters(1), parameters(2), parameters(3), parameters(4));
fprintf('\n\nGain: %f \nPM: %f \nBW: %d\n',fval(1), fval(2), fval(3));
fprintf('\nAttain_factor: %f\nExit Flag: %d\n',attainfc, exitflag);
My outputs are usually, no matter how large I change the limits:
Solver stopped prematurely.
fgoalattain stopped because it exceeded the function evaluation limit,
options.MaxFunctionEvaluations = 6.000000e+04.
Cc: 2.000000e-14
Rc: 1000
C_Load: 2.000000e-13
Ib: 3.000000e-06
Gain: 71.161912
PM: -7.906930
BW: 1.556654e+05
Attain_factor: 0.161912
Exit Flag: 0
My questions are:
1) How do I program fgoalattain to know that I care about minimizing (Id) only and it can choose any values for (Rc, Cc, & C_Load)?
2) Is there a better way to address this optimization problem?

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!