Chapter10: Digital CMOS Logic Circuits

Ex10.1:pg-962

In [17]:
# Consider CMOS inverter
import math
C_ox=6*10.0**-15; # (F/um**2)
uC_n=115.0*10**-6; #uC_n=u_n*C_ox (A/V**2)
uC_p=30.0*10**-6; #uC_p=u_p*C_ox (A/V**2)
V_tn=0.4; # (V)
V_tp=-0.4; # (V)
V_DD=2.5; # (V)
W_n=0.375*10**-6; # W for Q_N
L_n=0.25*10**-6; # L for Q_N
W_p=1.125*10**-6; # W for Q_P
L_p=0.25*10**-6; # L for Q_P
C_gd1=0.3*W_n*10**-9; # (F)
C_gd2=0.3*W_p*10**-9; # (F)
C_db1=10**-15; # (F)
C_db2=10**-15; # (F)
C_g3= 0.375*0.25*6*10**-15+2*0.3*0.375*10**-15; # (F)
C_g4=1.125*0.25*6*10**-15+2*0.3*1.125*10**-15; # (F)
C_w=0.2*10**-15; # (F)
C=2*C_gd1+2.0*C_gd2+C_db1+C_db2+C_g3+C_g4+C_w; # (F)
i_DN0=uC_n*W_n*(V_DD-V_tn)**2/(2*L_n); # i_DN0 = i_DN(0) (A)
i_DNtPHL=uC_n*W_n*((V_DD-V_tn)*V_DD/2-((V_DD/2.0)**2)/2.0)/L_n; # i_DNtPHL = i_DN(t_PHL) (A)
i_DNav=(i_DN0+i_DNtPHL)/2; # i_DN|av (A)
t_PHL=C*(V_DD/2)*1e12/i_DNav;
print math.ceil(t_PHL),"= t_PHL (picoseconds)"
t_PLH=1.3*t_PHL; # Since W_p/W_n=3 and u_n/u_p=3.83 thus t_PLH is greater than t_PHL by 3.83/3
print round(t_PLH,-1),"= t_PLH (picoseconds)"
t_P=(t_PHL+t_PLH)/2; 
print round(t_P),"= t_P (picoseconds)"

 # the answer in the textbook is slightly dirfferent due to approximation
23.0 = t_PHL (picoseconds)
30.0 = t_PLH (picoseconds)
26.0 = t_P (picoseconds)

Ex10.2:pg-972

In [18]:
#For basic inverter
n=1.5;
p=5;
L=0.25*10**-6; # (m)
WbyL=2*n; # W/L for Q_NB , Q_NC , Q_ND
print WbyL,"= W/L ratio for Q_NB"
print WbyL,"= W/L ratio for Q_NC"
print WbyL,"= W/L ratio for Q_ND"
WbyL=n; # W/L ratio for Q_NA
print WbyL,"= W/L ratio for Q_NA"
WbyL=3*p; # W/L for Q_PA, Q_PC , Q_PD
print WbyL,"= W/L ratio for Q_PA" 
print WbyL,"= W/L ratio for Q_PC"
print WbyL,"= W/L ratio for Q_PD"
3.0 = W/L ratio for Q_NB
3.0 = W/L ratio for Q_NC
3.0 = W/L ratio for Q_ND
1.5 = W/L ratio for Q_NA
15 = W/L ratio for Q_PA
15 = W/L ratio for Q_PC
15 = W/L ratio for Q_PD

Ex10.3:pg-981

In [24]:
# Consider a pseudo NMOS inverter
uC_n=115.0*10**-6; #uC_n=u_n*C_ox (A/V**2)
uC_p=30*10.0**-6; #uC_p=u_p*C_ox (A/V**2)
V_tn=0.4; # (V)
V_tp=-0.4; # (V)
V_DD=2.5; # (V)
W_n=0.375*10**-6; # W for Q_N (m)
L_n=0.25*10**-6; # L for Q_N (m)
r=9.0;

# 10.3a
V_OH=V_DD;
print round(V_OH,2),"= V_OH (V)"
V_OL=(V_DD-V_tn)*(1-math.sqrt(1.0-1/r));
print round(V_OL,2),"= V_OL (V)"
V_IL=V_tn+(V_DD-V_tn)/math.sqrt(r*(r+1.0));
print round(V_IL,2),"=V_IL (V)"
V_IH=V_tn+2*(V_DD-V_tn)/(math.sqrt(3.0*r));
print round(V_IH,2),"= V_IH (V)"
V_M=V_tn+(V_DD-V_tn)/math.sqrt(r+1.0);
print round(V_M,2),"= V_M (V)"
NM_H=V_OH-V_IH;
NM_L=V_IL-V_OL;
print round(NM_H,2),"=The highest and the lowest values of allowable noise margin (V)=",round(NM_L,2)

# 10.3b
WbyL_p=uC_n*(W_n/L_n)/(uC_p*r); # WbyL_p=(W/L)_p
print round(WbyL_p,2),"=(W/L)_p"

#10.3c
I_stat=(uC_p*WbyL_p*(V_DD-V_tn)**2)/2;
print round(I_stat*1e6,1),"=I_stat (microA)"
P_D=I_stat*V_DD;
print round(P_D*1e6),"=Static power dissipation P_D (microW)"

#10.3d
C=7*10**-15;
t_PLH=1.7*C/(uC_p*WbyL_p*V_DD);
print round(t_PLH*1e9,2),"=t_PLH (ns)"
t_PHL=1.7*C/(uC_n*(W_n/L_n)*math.sqrt(1-0.46/r)*V_DD);
print round(t_PHL*1e9,2),"= t_PHL (ns)"
t_p=(t_PHL+t_PLH)/2.0;
print round(t_p*1e9,2),"= t_p (ns)"
2.5 = V_OH (V)
0.12 = V_OL (V)
0.62 =V_IL (V)
1.21 = V_IH (V)
1.06 = V_M (V)
1.29 =The highest and the lowest values of allowable noise margin (V)= 0.5
0.64 =(W/L)_p
42.3 =I_stat (microA)
106.0 =Static power dissipation P_D (microW)
0.25 =t_PLH (ns)
0.03 = t_PHL (ns)
0.14 = t_p (ns)

Ex10.4:pg-985

In [34]:
# Consider NMOS transistor switch
uC_n=50.0*10**-6; #uC_n=u_n*C_ox (A/V**2)
uC_p=20.0*10.0**-6; #uC_px    `=u_p*C_ox (A/V**2)
V_tO=1.0; # (V)
y=0.5; # (V**1/2)
fie_f=0.6/2; # (V)
V_DD=5; # (V)
W_n=4*10.0**-6; # (m)
L_n=2*10.0**-6; # (m)
C=50*10.0**-15; # (F)

# 10.4a
V_t=1.6; # (V)
V_OH=V_DD-V_t; # V_OH is the value of v_O at which Q stops conducting (V)
print V_OH,"= V_OH (V)"
 
# 10.4b
W_p=10.0*10**-6; # (m)
L_p=2*10.0**-6; # (m)
i_DP=uC_p*W_p*((V_DD-V_OH-V_tO)**2)/(2*L_p);
print round(i_DP*1e6),"= Static current of the inverter (microA)"
P_D=V_DD*i_DP;
print round(P_D*1e6),"= Power dissipated (microW)"
V_O=0.08; # Output voltage (V) found by equating the current of Q_N=18uA
print round(V_O,2),"= The output voltage of the inverter (V) "

# 10.4c
i_D0=uC_n*W_n*((V_DD-V_tO)**2)/(2*2*10**-6); # i_D0=i_D(0) (A) current i_D at t=0
v_O=2.5; # (V)
V_t=V_tO+0.5*(math.sqrt(v_O+2*fie_f)-math.sqrt(2*fie_f)); # at v_O=2.5V
i_DtPLH=(uC_n*W_n*(V_DD-v_O-V_t)**2)/(2*L_n); # i_DtPLH=i_D(t_PLH) (A) current i_D at t=t_PLH
i_Dav=(i_D0+i_DtPLH)/2; # i_Dav=i_D|av (A) average discharge current
t_PLH=C*(V_DD/2)/i_Dav;
print round(t_PLH*1e9,2),"t_PHL (ns)"

# 10.4d
# Case with v_t going low
i_D0=uC_n*W_n*((V_DD-V_tO)**2)/(2*2*10**-6); # i_D0=i_D(0) (A) current i_D at t=0
i_DtPHL=uC_n*W_n*((V_DD-V_tO)*v_O-(v_O**2)/2.0)/(L_n); # i_DtPHL=i_D(t_PHL) (A) current i_D at t=T_PHL
i_Dav=(i_D0+i_DtPHL)/2; # i_Dav=i_D|av (A) average discarge current
t_PHL=C*(V_DD/2)/i_Dav;
print round(t_PHL*1e9,2),"= t_PHL (ns)"

# 10.4e
t_P=(t_PHL+t_PLH)/2;
print round(t_P*1e9,2),"= t_P (ns)"
 # the answer in the textbook is slightly dirfferent due to approximation
3.4 = V_OH (V)
18.0 = Static current of the inverter (microA)
90.0 = Power dissipated (microW)
0.08 = The output voltage of the inverter (V) 
0.24 t_PHL (ns)
0.13 = t_PHL (ns)
0.18 = t_P (ns)