As a complement to one of my lectures on compensation of operational amplifiers, I wrote a crude MATLAB example for testing stability and ability to loop for example currents, voltages, etc. In some sense, this could be done using veriloga blocks and slighlty more accurate circuit descriptions. But yet — this is a quite good way of understanding the operation of something as simple as a two-pole system.

I’m referring to a standard two-stage amplifier with a differential-pair in the first stage and a common-source at the output. Attached is also a plot result from `octave`

illustrating the pole/zero placement.

And you get some results in raw format:

octave:1> antikPoleZero

f_ug = 3.0917e+08

phi_m = 54.465

p_1 = -1.1171e+05

p_2 = -3.2733e+09

p_3 = -7.7695e+12

z_1 = 2.2957e+10

So, just an example/suggestion of simple ways to get some more understanding of the operation of the circuit.

%

% Mainly, this "demo" concentrates on the classical two-stage

% amplifier. This implies also that we have not employed the

% suggested technique by J. Baker, et al.

%

% Some of the design rules:

```
```% Miller

% z_1 approx 10*w_ug => gm_II = 10*gm_I

% p_2 approx 2.2*w_ug => C_C = 0.22 * C_II

% or more generically => C_C = 2.2*C_II/(gm_II/gm_I)

% Nulling resistor:

% And then (nulling resistor option 2, where z_1 -> inf):

% p_2 approx 1.73*w_ug => C_C = 1.73 * C_II / (gm_II/gm_I)

% p_3 > 10 * w_ug

% R_Z = 1/gm_II

% Setting up the frequencies

% No need to touch this

% =========================================================

N = 256;

f = logspace(1, 11, N);

w = 2*pi*f;

s = j*w;

% Some "process"-dependent parameters. Assuming a relatively

% strong channel-length modulation.

lambda = 0.05;

% =========================================================

% =========================================================

% Do your changes here. Why not a for loop on top? You can

% characterize the phase margin as function of tail current,

% or similar.

% =========================================================

% =========================================================

% =========================================================

% Going to a more circuit-level representation:

% Tail current through the differential pair.

I_0 = 100e-6;

% Effective input voltage on diff-pair transistors:

Veff_I = 0.2;

% The second-stage driving capacitor. For sake of argument,

% the effective is slightly higher here.

Veff_II = 0.4;

% The mirror ratio between the output stage and the input

% stage, i.e., the output stage drives K times more current

% than the differential pair.

% Notice that the gm_II = gm_I * K * Veff_I / Veff_II;

K = 20;

% Internal stage capacitance. For sake of modeling, we have

% assumed that the drive transistor in the second stage also

% scales with K (given a constant current and Veff_II).

% C_I is approximately the CGS of the drive transistor.

% Assuming some fF-cap on the gate:

C_I = K*10e-15;

% C_II is the load capacitance.

C_II = 2e-12;

% Some tentative compensation network to start with.

C_C = 0.22 * C_II;

R_Z = 1 ; % AND ALSO SEE BELOW!

% =========================================================

% =========================================================

% =========================================================

% We can now form the different parameters, etc.

% Given the parameters above, calculate the transfer function:

% No need to touch this.

% =============================================================

% First stage:

gm_I = 2*I_0 / Veff_I;

g_I = lambda*I_0;

% Second stage:

gm_II = 2*K*I_0/Veff_II;

g_II = lambda*K*I_0;

A_I = gm_I / g_I;

A_II = gm_II / g_II;

a = A_I * A_II;

b = (C_II + C_C)/g_II + (C_I+C_C)/g_I + a*C_C/gm_I + R_Z*C_C;

c = ((1/(g_I*g_II))*(C_I*C_II + C_C*C_I + C_C*C_II) + ...

R_Z*C_C*(C_I/g_I + C_II/g_II));

d = R_Z*C_I*C_II*C_C/g_I/g_II;

z_1 = 1/(C_C/gm_II - R_Z*C_C);

% =========================================================

% =========================================================

% =========================================================

R_Z = 1 /gm_II;

% =========================================================

% =========================================================

% =========================================================

A_s = a * ( 1 - s /z_1) ./ ...

( 1 + b*s + c*s.^2 + d*s.^3);

% Derive the roots as:

p = roots([1 c/d b/d 1/d ]);

% Just for some pretty-printing.

p_1 = p(3);

p_2 = p(2);

p_3 = p(1);

% Amplitude and phase characteristics

log_A = 20*log10(abs(A_s));

ang_A = 180*unwrap(angle(A_s))/pi;

% Find the unity-gain frequency (in Hz) and phase margin

f_ug = mean(f(find(abs(log_A)==min(abs(log_A)))));

phi_m = mean(ang_A(find(abs(log_A)==min(abs(log_A)))))+180;

% the mean-thing is there to avoid some numerical issues.

fh = figure(1);

subplot(2,1,1);

sh(1) = semilogx(f, log_A);

hold on;

ph(1) = plot(abs(p_1/2/pi), 0, 'x');

ph(2) = plot(abs(p_2/2/pi), 0, 'x');

ph(3) = plot(abs(p_3/2/pi), 0, 'x');

ph(4) = plot(abs(z_1/2/pi), 0, 'o');

lh = line(f_ug*[1 1], [20*log10(abs(A_s(1))) -150]);

tl(1) = title('Amplitude characteristics');

tl(2) = ylabel('|A^2(j \omega )|');

hold off;

subplot(2,1,2);

sh(2) = semilogx(f, ang_A);

hold on;

ph(5) = plot(abs(p_1/2/pi), 0, 'x');

ph(6) = plot(abs(p_2/2/pi), 0, 'x');

ph(7) = plot(abs(p_3/2/pi), 0, 'x');

ph(8) = plot(abs(z_1/2/pi), 0, 'o');

lh = line(f_ug*[1 1], [0 -180]);

tl(3) = ylabel('arg{ A(j \omega )}');

tl(4) = xlabel('Frequency [Hz]');

hold off;

set(tl,'FontSize',18);

set(ph,'LineWidth',4);

set(sh,'LineWidth',4);

% =============================================================

% Dumping some data in raw format

f_ug

phi_m

p_1

p_2

p_3

z_1

`% =============================================================`

tats a great timing !! I am designing a wide-band OPAMP for my BAN Transceiver.. this will be helpful.

Pingback: Why doesn’t the gain change in my CMOS current-mirror amplifier? | Mixed-Signal Comments