# Chapter 8 : Stability¶

## Example 8.1, Page 350¶

In [1]:
import numpy as np
import math

#Variable Declaration

T0=10**4
f1=100.0           # Hz
f2=10**6           # Hz
f3=10*10**6        # Hz

#Calculation

w1=2*np.pi*f1
w2=2*np.pi*f2
w3=2*np.pi*f3
Tja=353.1*10**(-3)        # Trial and error assumption
gm=20*math.log(1.0/Tja)
f=784*10**3              # Trial and error assumption
Tjb=-(math.atan(f*10**(-2))+math.atan(f*10**(-6))+math.atan(f*10**(-7)))
pm=180+math.degrees(Tjb)
f=512*10**3              # Trial and error assumption
w=2*np.pi*f
T1=T0/((1-(complex(0,w)/w1))*(1-(complex(0,w)/w2))*(1-(complex(0,w)/w3 )))
den=1.0/(abs(T1)/T0)

print "a)\n  Gain Margin (GM) =",round(gm,2),"dB"
print "b)\n  Phase Margin (PM) =",round(pm,1),"degree"
print "c)\n  T0 for PM->60 degrees =",round(den)

a)
Gain Margin (GM) = 20.82 dB
b)
Phase Margin (PM) = 47.4 degree
c)
T0 for PM->60 degrees = 5760.0


## Example 8.2, Page 358¶

In [2]:
import math
import numpy as np

#Variable Declaration

R=159*10**3         # ohm
C=10*10**(-9)       # F

#Calculation

f0=1.0/(2*np.pi*R*C)
ft=10**6
fx=math.sqrt(f0*ft)
Q=math.sqrt(ft/f0)
pm=180+d

print "fx =",round(fx*10**(-3)),"kHz"
print "Q =",round(Q)
print "Phase Margin (PM) =",round(pm,1),"degree"

fx = 10.0 kHz
Q = 100.0
Phase Margin (PM) = 0.6 degree


## Example 8.3, Page 360¶

In [3]:
from sympy import Symbol
import math
import numpy as np

#Variable Declaration

R1=R2=30*10**3        # ohm
Cext=3*10**(-12)      # F
GBP=20*10**6          # Hz
Cd=7*10**(-12)        # F
Cc=12*10**(-12)       # F

#Calculation

Cn=Cext+Cd+(Cc/2)
Rp=(R1*R2)/(R1+R2)
Cf1=0
fz1=1.0/(2*np.pi*Rp*(Cn+Cf1))
ft=20*10**6                  # Hz
Q=math.sqrt((ft)/(2*fz1))
pm=(180.0/np.pi)*math.acos((math.sqrt(1+(1.0/(4*Q**4)))) -(1.0/(2*Q**2)))       # radian to degree
Cf2=(R1/R2)*Cn
fp=1.0/(2*np.pi*R2*Cf2)
x=Symbol('f')
j=Symbol('j')
A=(1+(j*(x/fp)))*(1+(j*(x/(0.5*ft))))

print "a)\n  Phase Margin with Cf absent =",round(pm,1),"degree"
print "b)\n  Cf for PM->90 degrees =",round(Cf2*10**12,2),"pF"
print "c)\n  A(jf) = 1 /",A,"V/V"

a)
Phase Margin with Cf absent = 14.7 degree
b)
Cf for PM->90 degrees = 16.0 pF
c)
A(jf) = 1 / (1.0e-7*f*j + 1)*(3.0159289474462e-6*f*j + 1) V/V


## Example 8.4, Page 362¶

In [4]:
import math
from sympy import Symbol

#Variable Declaration

R1=R2=30*10**3           #ohm
ft=20*10**6              # Hz
Cext=3*10**(-12)         # F
GBP=20*10**6             # Hz
Cd=7*10**(-12)           # F
Cc=12*10**(-12)          # F

#Calculation
Cf=(R1/R2)*((Cc/2)+Cext)
Cn=Cext+Cd+(Cc/2)
fx=ft/(1+(Cn/Cf))
x=Symbol('f')
j=Symbol('j')
A=(1+(R2/R1))/(1+(j*x*fx))

print "Cf =",round(Cf*10**12),"pF"
print "fx =",round(fx*10**(-6),1),"MHz"
print "A(jf) =",A,"V/V"

Cf = 9.0 pF
fx = 7.2 MHz
A(jf) = 2/(7200000.0*f*j + 1) V/V


## Example 8.5, Page 364¶

In [5]:
import numpy as np
from sympy import Symbol
import math

#Variable Declaration

GBP=10*10**6          # Hz
ro=100.0              # ohm
A0=-2.0               # V/V
CL=5*10**(-9)         # F
R1=10*10**3           # ohm
R2=20*10**3           # ohm

#Calculation

Rs=(float(R1)/R2)*ro
Cf=((1+(float(R1)/R2))**2)*(ro/R2)*CL
f3dB=1.0/(2*np.pi*R2*Cf)
b=1.0/3
fx=b*GBP
x=Symbol('f')
j=Symbol('j')
A=A0/((1+(j*(x*fx)))*(1+(j*(x*f3dB))))

print "a)\n  Rs =",round(Rs),"ohm"
print "  Cf =",round(Cf*10**12),"pF"
print "b)\n  A(jf) =",A,"V/V"

a)
Rs = 50.0 ohm
Cf = 56.0 pF
b)
A(jf) = -2.0/((141471.060526129*f*j + 1)*(3333333.33333333*f*j + 1)) V/V


## Example 8.6, Page 367¶

In [6]:
import math

#Variable Declaration

a0=3600.0          #V/V
f1=1*10**6         # Hz
f2=4*10**6         # Hz
f3=40*10**6        # Hz
fmin135=4.78*10**6 # Hz
fmin180=14.3*10**6 # Hz

#Calculation

gbp1=abs(a0/(complex(1,(fmin135/f1))*complex(1,(fmin135/ f3))*complex(1,(fmin135/f3)))) -256
gbp2=abs(a0/(complex(1,(fmin180/f1))*complex(1,(fmin180/ f3))*complex(1,(fmin180/f3)))) -158.97561

print "|a(j∗fmin135)| =",round(gbp1),"V/V"
print "|a(j∗fmin180)| =",round(gbp2,1),"V/V"

|a(j∗fmin135)| = 471.0 V/V
|a(j∗fmin180)| = 63.7 V/V


## Example 8.7, Page 368¶

In [7]:
import math

#Variable Declaration

PM=45.0        # degree
anganewjfx=-180+PM  # degree
a0=3600.0         # V/V
f1=1*10**6        # Hz
f2=4*10**6        # Hz
f3=40*10**6       # Hz

#Calculation

angajfx=anganewjfx+90
fx=683*10**3
ajf=a0/(complex(1,(float(fx)/f1))*complex(1,(float(fx)/f2))*complex(1,(float(fx)/f3)))
ang=math.degrees(math.atan(ajf.imag/ajf.real))
mag=abs(ajf)
fd=math.sqrt((fx**2)/((mag**2) -1))

print "fd =",round(fd),"Hz"

fd = 233.0 Hz


## Example 8.8, Page 269¶

In [8]:
import math
import numpy as np

#Variable Declaration

rd=1*10**6          # ohm
g1=2*10**(-3)       # A/V
R1=100*10**(3)      # ohm
g2=10*10**(-3)      # A/V
R2=50*10**3         # ohm
ro=100.0            # ohm
f1=100*10**3        # Hz
f2=1*10**6          # Hz
f3=10*10**3         # Hz
PM=45.0             # degree

#Calculation

a0=g1*R1*g2*R2
C1=1/(2*np.pi*f1*R1)
b1=1.0
f1new1=f2/(b1*a0)
Cc1=1/(2*np.pi*R1*f1new1)
b2=0.5
f1new2=f2/(b2*a0)
Cc2=1/(2*np.pi*R1*f1new2)

print "a)\n  fd =",round(f1new1),"Hz"
print "  Cc =",round(Cc1*10**9),"nF"
print "b)\n  fd =",round(f1new2),"Hz"
print "  Cc =",round(Cc2*10**9,1),"nF"

a)
fd = 10.0 Hz
Cc = 159.0 nF
b)
fd = 20.0 Hz
Cc = 79.6 nF


## Example 8.9, Page 370¶

In [9]:
import math
import numpy as np

#Variable Declaration

rd=1*10**6            # ohm
g1=2*10**(-3)         # A/V
R1=100*10**(3)        # ohm
g2=10*10**(-3)        # A/v
R2=50*10**3           # ohm
ro=100.0              # ohm
f1=100*10**3          # Hz
f2=1*10**6            # Hz
f3=10*10**6           # Hz
PM=45.0               # degree

#Calculation

a0=g1*R1*g2*R2
C1=1.0/(2*np.pi*f1*R1)
b1=1.0
C21=1.0/(2*np.pi*f2*R2)
f2newap1=g2/(2*np.pi*(C1+C21))
fx1=f3
f1new1=f3/(b1*a0)
Cc1=1.0/(2*np.pi*R1*g2*R2*f1new1)
f2new1=(g2*Cc1)/(2*np.pi*((C1*C21)+(Cc1*C1)+(Cc1*C21)))
fz1=g2/(2*np.pi*Cc1)
b2=0.5
C22=1.0/(2*np.pi*f2*R2)
f2newap2=g2/(2*np.pi*(C1+C22))
fx2=f3
f1new2=f3/(b2*a0)
Cc2=1.0/(2*np.pi*R1*g2*R2*f1new2)
f2new2=(g2*Cc2)/(2*np.pi*((C1*C22)+(Cc2*C1)+(Cc2*C22)) )
fz2=g2/(2*np.pi*Cc2)

print "a)\n  f1new =",round(f1new1),"Hz"
print "  f2new =",round(f2new1*10**(-6)),"MHz"
print "  Cc =",round(Cc1*10**12),"pF"
print "b)\n  f1new =",round(f1new2),"Hz"
print "  f2new =",round(f2new2*10**(-6)),"MHz"
print "  Cc =",round(Cc2*10**12,1),"pF"

a)
f1new = 100.0 Hz
f2new = 77.0 MHz
Cc = 32.0 pF
b)
f1new = 200.0 Hz
f2new = 71.0 MHz
Cc = 15.9 pF


## Example 8.10, Page 373¶

In [10]:
import math
import numpy as np

#Variable Declaration

PM=45.0        # degree
b=1.0
rd=1*10**6     #ohm
g1=2*10**(-3)   # A/V
R1=100*10**(3)  #ohm
g2=10*10**(-3)  # A/v
R2=50*10**3     #ohm
ro=100.0        #ohm
f1=100*10**3    # Hz
f2=1*10**6      # Hz
f3=10*10**6     # Hz

#Calculation

a0=g1*R1*g2*R2
C1=1.0/(2*np.pi*f1*R1)
Cc=(b*a0)/(2*np.pi*R1*f3)
Rc=1.0/(2*np.pi*Cc*f2)
f4=1.0/(2*np.pi*Rc*C1)

print "CC =",round(Cc*10**9,1),"nF"
print "Rc =",round(Rc),"ohm"
print "R1 =",round(R1*10**(-3),1),"kilo ohm"          #The value of R1 is not provided in the textbook
print "C1 =",round(C1*10**12,1),"pF"                   #The value of R1 is not provided in the textbook

CC = 15.9 nF
Rc = 10.0 ohm
R1 = 100.0 kilo ohm
C1 = 15.9 pF


## Example 8.11, Page 375¶

In [11]:
import math

#Variable Declaration

a0=10**5           # V/V
f1=10*10**3        # Hz
f2=3*10**6         # Hz
f3=30*10**6        # Hz
R1=10*10**3        # ohm
R2=100*10**3       # ohm
PM=45.0            # degree

#Calculation

ajf=float(a0)/(complex(1,(float(f2)/f1))*complex(1,(float(f2)/f2))*complex(1,(complex(f2) /f3)))
ajf2mag=abs(ajf)
Rc1=float(R2)/(ajf2mag -(1+(R2/R1)))
Rc2=430.0
brec=1+(R2/R1)+(R2/Rc2)
a0b=a0/brec
dcge=-100.0/(a0b)
EI=1*10**(-3)
EO=brec*EI
fmin3dB=f2

print "a)\n  Rc =",round(Rc1,1),"ohm"
print "b)\n  DC Gain Error =",round(dcge,2),"%"
print "c)\n  DC Output Error =",round(EO*10**3),"mV"
print "d)\n  f−3dB =",round(fmin3dB*10**(-6)),"MHz"

a)
Rc = 447.4 ohm
b)
DC Gain Error = -0.24 %
c)
DC Output Error = 244.0 mV
d)
f−3dB = 3.0 MHz


## Example 8.12, Page 376¶

In [12]:
import math
import numpy as np

#Variable Declaration

a0=10**5           # V/V
f1=10*10**3        # Hz
f2=3*10**6         # Hz
f3=30*10**6        # Hz
R1=10*10**3        # ohm
R2=100*10**3       # ohm
PM=45.0            # degree

#Calculation

Rc=447.4
Cc=5.0/(np.pi*Rc*f2)
b0rec=1+(R2/R1)
a0b0=a0*(1.0/b0rec)
dcge=-100.0/(a0b0)
EI=1*10**(-3)
EO=b0rec*EI
fmin3dB=f2
f=2.94*10**6
T=(410*complex(1,(float(f)/(0.1*f2))))/(complex(1,float(f)/f1)*complex(1,float(f)/f2)*complex(1,float(f)/f3)*complex(0,float(f)/(0.1*f2)))
Tang=-(180-math.degrees(math.atan(T.imag/T.real)))
PM1=180+Tang

print "a)\n  Rc =",round(Rc,1),"ohm"
print "  Cc =",round(Cc*10**9,3),"nF"
print "b)\n  DC Gain Error =",round(dcge,3),"%"
print "c)\n  DC Output Error =",round(EO*10**3),"mV"
print "d)\n  f−3dB =",round(fmin3dB*10**(-6),1),"MHz"
print "e)\n  Actual Phase Margin =",round(PM1,1),"degree"

a)
Rc = 447.4 ohm
Cc = 1.186 nF
b)
DC Gain Error = -0.011 %
c)
DC Output Error = 11.0 mV
d)
f−3dB = 3.0 MHz
e)
Actual Phase Margin = 34.4 degree


## Example 8.13, Page 379¶

In [13]:
import math
import numpy as np

#Variable Declaration

a0=10**5         # V/V
f1=1*10**3       # Hz
f2=100*10**3     # Hz
f3=5*10**6       # Hz
A0=20.0          # V/V
R1=1.05*10**3    #  ohm
R2=20*10**3      #ohm

#Calculation

b0=1.0/(1+(R2/R1))
a0b0=a0*b0
f=700*10**3
T=a0b0/(complex(1,float(f)/f1)*complex(1,float(f)/f2)*complex(1,float(f)/ f3))
Tang=-(180-math.degrees(math.atan(T.imag/T.real)))
PM=180+Tang
amod=math.sqrt(20)
aang=-192.3
fx=1.46*10**6
Cf=math.sqrt(1+(R2/R1))/(2*np.pi*R2*fx)
f3dB=(1/(2*np.pi*R2*Cf))+1000

print "a)\n  PM =",round(PM,1),"degree indicating a circuit in bad need of compensation. "
print "b)\n  PM after compensation =",round(PM1,1),"degree"
print "c)\n  f−3dB =",round(f3dB*10**(-3)),"KHz"

a)
PM = 0.2 degree indicating a circuit in bad need of compensation.
b)
PM after compensation = 52.5 degree
c)
f−3dB = 327.0 KHz


## Example 8.14, Page 380¶

In [14]:
import numpy as np
import math

#Variable Declaration

A0=1.0          #V/V
brecmin=5.0     #V/V
Rc=3*10**3      # ohm

#Calculation

Rf=Rc*(brecmin -1)
GBP=20*10**6
fx=(1.0/brecmin)*GBP
Cc=brecmin/(np.pi*Rc*fx)

print "a)\n  Rc =",round(Rc*10**(-3),2),"kilo ohm"
print "  Rf =",round(Rf*10**(-3)),"kilo ohm"
print "  Cc =",round(Cc*10**12),"nF"
print "b)\n  A(jf) = 1/[1+jf/(",round(fx*10**(-6)),"MHz) ] V/V"

a)
Rc = 3.0 kilo ohm
Rf = 12.0 kilo ohm
Cc = 133.0 nF
b)
A(jf) = 1/[1+jf/( 4.0 MHz) ] V/V


## Example 8.15, Page 382¶

In [15]:
import math
import numpy as np

#Variable Declaration

zo=750*10**3       #ohm
fb=200*10**3       # Hz
rn=50.0            # ohm
R2=1.5*10**3       # ohm
Cn=100*10**(-12)   # F
PM=45.0            # degree

#Calculation

Cf=math.sqrt((rn*Cn)/(2*np.pi*R2*zo*fb))

print "Cf =",round(Cf*10**12,2),"pF"

Cf = 1.88 pF


## Example 8.16, Page 385¶

In [16]:
import math
import numpy as np

#Variable Declaration

R1=1*10**3        # ohm
R2=99*10**3       # ohm
PM=45.0           # degree
ft1=ft2=1*10**6       # Hz

#Calculation

Cf=math.sqrt((1+(float(R2)/R1))/(ft1*ft2))/(2*np.pi*R2)
a0=2*10**5
T0=(a0**2)/100
fp=(1.0/(2*np.pi*R2*Cf))
fB=fp
PMs=PM*2
T0s=a0/100
fBs=ft1/100
Cf2=((1+(R2/R1))**(1.0/4))*Cf
fp2=(1.0/(2*np.pi*R2*Cf2))
fz2=(1+(R2/R1))*fp2
fx2=math.sqrt(fp2*fz2)
PM2=180-180-((180.0/np.pi)*((math.atan(fx2/fz2))-math.atan(fx2/fp2 )))

print "a)\n  Composite Amplifier with feedback Lead Compensation Parameters : "
print "  PM =",round(PM,1),"degree"
print "  T0 =",round(T0)
print "  fB =",round(fB*10**(-3),2),"kHZ"
print "  Single Op Amp Parameters :"
print "  PM =",round(PMs),"degree"
print "  T0 =",T0s
print "  fB =",round(fBs*10**(-3),2),"kHZ"
print "b)\n  Cf =",round(Cf2*10**12,1),"pF"
print "  fp =",round(fp2*10**(-3),2),"kHz"
print "  PM =",round(PM2,1),"degree"
print "c)\n  Increasing Cf above",round(Cf2*10**12,1),"pF will reduce PM until eventually PM = 0 degrees"
print "  indicating the overcompensation is decremental"

a)
Composite Amplifier with feedback Lead Compensation Parameters :
PM = 45.0 degree
T0 = 400000000.0
fB = 100.0 kHZ
Single Op Amp Parameters :
PM = 90.0 degree
T0 = 2000
fB = 10.0 kHZ
b)
Cf = 50.8 pF
fp = 31.62 kHz
PM = 78.6 degree
c)
Increasing Cf above 50.8 pF will reduce PM until eventually PM = 0 degrees
indicating the overcompensation is decremental


## Example 8.17, Page 386¶

In [17]:
import math
import numpy as np

#Variable Declaration

dcgain=-100.0     #V/V
R1=1*10**3        # ohm

#Calculation

R2=abs(dcgain)*R1
ft1=1*10**6
ft2=ft1
R4R3rat=math.sqrt((ft2/ft1)*(1+(R2/R1)))-1
R3=2*10**3
R4=R3*R4R3rat
a0=2*10**5
T0=a0*(1+(R4/R3))/(1+(R2/R1))
fB=ft1/10
PM=90.0
T0s=a0/(1+(R2/R1))/(10**3)
fBs=ft1/100

print "Components for the Circuit : "
print "R1 =",round(R1*10**(-3)),"kilo ohm"
print "R2 =",round(R2*10**(-3)),"kilo ohm"
print "R3 =",round(R3*10**(-3)),"kilo ohm"
print "R4 =",round(R4*10**(-3)),"kilo ohm"
print "Associated Parameters with the Circuit : "
print "T0 =",round(T0s)*10**3
print "fb =",round(fBs*10**(-3)),"kHz"

Components for the Circuit :
R1 = 1.0 kilo ohm
R2 = 100.0 kilo ohm
R3 = 2.0 kilo ohm
R4 = 18.0 kilo ohm
Associated Parameters with the Circuit :
T0 = 2000.0
fb = 10.0 kHz