Razavi模电设计习题10_11

以OOP风格写了一个(大概)可以复用的针对文献[1]课后题的python代码,虽说这门课好像快上完了。。。


代码:

(博客上看似乎有显示不全的问题,代码已上传GitHub,Github地址

(或者Ubuntu Pastebin地址

(代码显示不全的问题以后再改。。。)

'''
A python code calculating the solution to Problem 10.11 of [1]
Coded by zevmre
[1]Behzad Razavi. Design of analog CMOS integrated circuits[M]. 陈贵灿, 程军等, 译. 陈贵灿, 审. 2版. 西安: 西安交通大学出版社, 2019: 408
'''
from math import sqrt,log10,fabs,atan
epsSiO2=3.9
eps0=8.854187817e-12
tox=9e-9
Cox=epsSiO2*eps0/tox
VDD=3

class MOS:
    def __init__(self,W,L,mu,VTO,gamma,PHI,lam,I=0,VGS=0,VDS=0,VSB=0):
        self.W,self.L,self.WL=W,L,W/L
        self.k=mu*Cox
        self.VTO=VTO
        self.gamma,self.PHI,self.lam=gamma,PHI,lam
        self.I=I
        self.VGS,self.VDS,self.VSB=VGS,VDS,VSB
        self.VTH=0
        self.VGT=0
    def updateI(self):
        #Calc I_D given VGS (perhaps with VSB, VDS)
        self.VTH=self.VTO+self.gamma*(sqrt(fabs(self.PHI+self.VSB))-sqrt(self.PHI))
        self.VGT=self.VGS-self.VTH
        self.I=0.5*self.k*self.WL*(self.VGT)**2*(1+self.lam*self.VDS)
    def updateV(self):
        #Calc VGS given I_D (perhaps with VSB, VDS)
        self.VTH=self.VTO+self.gamma*(sqrt(fabs(self.PHI+self.VSB))-sqrt(self.PHI))
        self.VGT=sqrt((2*self.I)/(self.k*self.WL*(1+self.lam*self.VDS)))
        self.VGS=self.VGT+self.VTH
    def updateWL(self):
        #Calc W/L given I & V_GT (assuming critical saturation)
        self.WL=(2*self.I)/(self.k*self.VGT**2*(1+self.lam*self.VGT))
    @property
    def gm(self):
        return (2*self.I)/(self.VGT)
    @property
    def gmb(self):
        return (self.gamma/(2*sqrt(self.PB+self.VSB)))*self.gm()
    @property
    def ro(self):
        return 1/(self.lam*self.I)
    def init_cap(self,CJ,CJSW,CGDO,CGSO,MJ,MJSW,PB,VRS,VRD):
        self.CGD=self.W*1e-6*CGDO
        self.CGS=self.W*1e-6*CGSO+2/3*self.W*1e-6*self.L*1e-6*Cox
        LSD=1.5e-6
        self.CDB=(CJ*self.W*1e-6*LSD)/(1+VRD/PB)**MJ+(CJSW*(2*self.W+2*LSD)*1e-6)/(1+VRD/PB)**MJSW
        self.CSB=(CJ*self.W*1e-6*LSD)/(1+VRS/PB)**MJ+(CJSW*(2*self.W+2*LSD)*1e-6)/(1+VRS/PB)**MJSW
    
class NMOS(MOS):
    def __init__(self,W,L,I=0,VGS=0,VDS=0,VSB=0,gamma=0.45,lam=0.1,LD=0.08):
        MOS.__init__(self,W,L-2*LD,350e-4,0.7,gamma,0.9,lam,I,VGS,VDS,VSB)
    def init_cap(self,VRD=0,VRS=0):
        MOS.init_cap(self,0.56e-3,0.35e-11,0.4e-9,0.4e-9,0.45,0.2,0.9,VRS,VRD)

class PMOS(MOS):
    def __init__(self,W,L,I=0,VGS=0,VDS=0,VSB=0,gamma=0.4,lam=0.2,LD=0.09):
        MOS.__init__(self,W,L-2*LD,100e-4,0.8,gamma,0.8,lam,I,VGS,VDS,VSB)
    def init_cap(self,VRD=0,VRS=0):
        MOS.init_cap(self,0.94e-3,0.32e-11,0.3e-9,0.3e-9,0.5,0.3,0.9,VRS,VRD)

def PA(a,b):
    #Parallel
    return (a*b)/(a+b)

Iout=1e-3
M5=PMOS(60,0.5,Iout,gamma=0)
M5.updateV()
VX=VDD-M5.VGS
#print("%g"%(VX))

M7=NMOS(50,0.5,Iout,gamma=0)
M7.updateV()
Vout_max=VDD-M5.VGT
Vout_min=M7.VGT
#print(Vout_max-Vout_min)

Vout_cm=0.5*(Vout_max+Vout_min)
Iin=0.5*0.25e-3
M3=PMOS(50,0.5,Iin,gamma=0,VDS=VDD-VX)
M3.updateV()
M1=NMOS(50,0.5,Iin,gamma=0)
M1.updateV()
M1.init_cap(VX)
M3.init_cap(VDD-VX)
M5.init_cap(VDD-Vout_cm)
M7.init_cap(Vout_cm)
RX=PA(M3.ro,M1.ro)
Rout=PA(M5.ro,M7.ro)
Av1=M1.gm*RX
Av2=M5.gm*Rout
CX=M1.CGD+M1.CDB+M3.CGD+M3.CDB+M5.CGS+M5.CGD*(1+Av2)
CL=1e-12
Cout=M7.CGD+M7.CDB+M5.CDB+M5.CGD*(1+1/Av2)+CL
omega_X=1/(RX*CX)
omega_out=1/(Rout*Cout)
print("Dominant:%g\nSecond:%g\n-------After-------"%(omega_X,omega_out))

omega_p2_after=M5.gm/(CX+Cout)
omega_GX_after=omega_p2_after*(1/sqrt(3))
omega_p1_after=omega_GX_after/(10**(20*log10(Av1*Av2)/20))
#print("%g"%(omega_p1_after))

CC=(1/(omega_p1_after*RX)-CX)/(1+Av2)
omega_z=M5.gm/(CC+M5.CGD)
print("Dominant:%g\nSecond:%g\nZero:%g\n"%(omega_p1_after,omega_p2_after,omega_z))
#print(CC+M5.CGD,CX)

Rz=1/M5.gm+1/(omega_p2_after*CC)
print(Rz)

参考文献

[1]Behzad Razavi. Design of analog CMOS integrated circuits[M]. 陈贵灿, 程军等, 译. 陈贵灿, 审. 2版. 西安: 西安交通大学出版社, 2019: 408

Leave a comment