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)

Categories

Find more on Get Started with Optimization Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!