SPICE MOSFET level 3 amplifier

load "spice/mos3.osdi"
load "resistor.osdi"
load "capacitor.osdi"

model v vsource
model r resistor
model c capacitor

subckt namp()
  model nm sp_mos3 ( type=1 
    phi=0.600000 tox=2.1200e-08
    xj=0.200000u tpg=1 vto=1 delta=6.9670e-01
    ld=1.6470e-07 kp=9.6379e-05 uo=591.7 theta=8.1220e-02
    rsh=8.5450e+01 gamma=0.5863 nsub=1.6160e+16
    nfs=5.0000e+12 vmax=2.0820e+05 eta=7.0660e-02
    kappa=1.3960e-01 cgdo=4.0241e-10 cgso=4.0241e-10
    cgbo=3.6144e-10 cj=3.8541e-04 mj=1.1854
    cjsw=1.3940e-10 mjsw=0.125195 pb=0.800000
    kf=0.032f af=1
  )
  vdd (1 0) v dc=10
  vd (1 10) v dc=0
  rd (10 d) r r=25k
  m1 (d g 0 0) nm w=200u l=50u $mfactor=2 nrs=1 nrd=1
  r1 (1 g) r r=81k
  r2 (g 0) r r=19k
  c1 (in g) c c=1u
  vin (in 0) v dc=0 mag=1 type="sine" ampl=10m freq=1k 
ends

subckt pamp()
  model pm sp_mos3 ( type=-1 
    phi=0.600000 tox=2.1200e-08
    xj=0.200000u tpg=1 vto=-1 delta=6.9670e-01
    ld=1.6470e-07 kp=9.6379e-05 uo=591.7 theta=8.1220e-02
    rsh=8.5450e+01 gamma=0.5863 nsub=1.6160e+16
    nfs=5.0000e+12 vmax=2.0820e+05 eta=7.0660e-02
    kappa=1.3960e-01 cgdo=4.0241e-10 cgso=4.0241e-10
    cgbo=3.6144e-10 cj=3.8541e-04 mj=1.1854
    cjsw=1.3940e-10 mjsw=0.125195 pb=0.800000
    kf=0.032f af=1
  )
  vdd (1 0) v dc=10
  vd (10 0) v dc=0
  rd (10 d) r r=25k
  m1 (d g 1 1) pm w=200u l=50u $mfactor=2 nrs=1 nrd=1
  r1 (1 g) r r=19k
  r2 (g 0) r r=81k
  c1 (in g) c c=1u
  vin (in 0) v dc=0 mag=1 type="sine" ampl=10m freq=1k 
ends

control
  elaborate circuit("namp")
  clear saves
  save default p(m1,gm) p(m1,vds) p(m1,vgs) p(m1,ibd) p(m1,ibs)
  analysis op1 op

  clear saves
  analysis tran1 tran step=0.01m stop=8m
 
  analysis ac1 ac from=0.1 to=10G mode="dec" points=50
  
  save full
  options smsig_debug=0
  analysis noise1 noise out=["d"] in="vin" from=1 to=10G mode="dec" points=50

  
  elaborate circuit("pamp")
  clear saves
  save default p(m1,gm) p(m1,vds) p(m1,vgs) p(m1,ibd) p(m1,ibs)
  analysis op2 op
 
  clear saves
  analysis tran2 tran step=0.01m stop=8m
 
  analysis ac2 ac from=0.1 to=10G mode="dec" points=50
  
  save full
  analysis noise2 noise out=["d"] in="vin" from=1 to=10G mode="dec" points=50
  
  
  postprocess(PYTHON, "runme.py")
endc

embed "runme.py" <<<FILE
from rawfile import rawread
import numpy as np
import matplotlib.pyplot as plt
import sys

raw = rawread('op1.raw')
plot = raw.get()
for name in plot.names:
    print(name, plot[name])

raw = rawread('tran1.raw')
plot = raw.get()

fig1 = plt.figure(figsize=(8,8), dpi=100)
fig1.suptitle('Level 3 NMOS amplifier')
ax_dict = fig1.subplot_mosaic("""
AC
BD
EE
""")

ax_dict["A"].set_title('Input')
ax_dict["A"].set_ylabel('Vin [V]')
ax_dict["A"].set_xlabel('time [ms]')
ax_dict["A"].plot(plot['time']*1e3, plot['in'])

ax_dict["B"].set_title('Output')
ax_dict["B"].set_ylabel('Vout [V]')
ax_dict["B"].set_xlabel('time [ms]')
ax_dict["B"].plot(plot['time']*1e3, plot['d'])

raw = rawread('ac1.raw')
plot = raw.get()
h = plot['d']

ax_dict["C"].set_title('Gain')
ax_dict["C"].set_ylabel('gain [dB]')
ax_dict["C"].set_xlabel('f [kHz]')
ax_dict["C"].semilogx(np.real(plot['frequency'])/1e3, 20*np.log10(np.abs(h)))

ax_dict["D"].set_title('Phase')
ax_dict["D"].set_ylabel('phase [deg]')
ax_dict["D"].set_xlabel('f [kHz]')
ax_dict["D"].semilogx(np.real(plot['frequency'])/1e3, 180/np.pi*np.unwrap(np.angle(h)))

raw = rawread('noise1.raw')
plot = raw.get()

ax_dict["E"].set_title('Output noise')
ax_dict["E"].set_ylabel('PSD [V^2/Hz]')
ax_dict["E"].set_xlabel('f [kHz]')
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,flicker)'], label="M1,flicker")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,id)'], label="M1,Id")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,rs)'], label="M1,Rs")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,rd)'], label="M1,Rd")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1)'], label="M1")
ax_dict["E"].legend(loc='upper right')

fig1.tight_layout()


raw = rawread('op2.raw')
plot = raw.get()
for name in plot.names:
    print(name, plot[name])

raw = rawread('tran2.raw')
plot = raw.get()

fig2 = plt.figure(figsize=(8,8), dpi=100)
fig2.suptitle('Level 3 PMOS amplifier')
ax_dict = fig2.subplot_mosaic("""
AC
BD
EE
""")

ax_dict["A"].set_title('Input')
ax_dict["A"].set_ylabel('Vin [V]')
ax_dict["A"].set_xlabel('time [ms]')
ax_dict["A"].plot(plot['time']*1e3, plot['in'])

ax_dict["B"].set_title('Output')
ax_dict["B"].set_ylabel('Vout [V]')
ax_dict["B"].set_xlabel('time [ms]')
ax_dict["B"].plot(plot['time']*1e3, plot['d'])

raw = rawread('ac2.raw')
plot = raw.get()
h = plot['d']

ax_dict["C"].set_title('Gain')
ax_dict["C"].set_ylabel('gain [dB]')
ax_dict["C"].set_xlabel('f [kHz]')
ax_dict["C"].semilogx(np.real(plot['frequency'])/1e3, 20*np.log10(np.abs(h)))

ax_dict["D"].set_title('Phase')
ax_dict["D"].set_ylabel('phase [deg]')
ax_dict["D"].set_xlabel('f [kHz]')
ax_dict["D"].semilogx(np.real(plot['frequency'])/1e3, 180/np.pi*np.unwrap(np.angle(h)))

raw = rawread('noise2.raw')
plot = raw.get()
print(plot.names)

ax_dict["E"].set_title('Output noise')
ax_dict["E"].set_ylabel('PSD [V^2/Hz]')
ax_dict["E"].set_xlabel('f [kHz]')
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,flicker)'], label="M1,flicker")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,id)'], label="M1,Id")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,rs)'], label="M1,Rs")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1,rd)'], label="M1,Rd")
ax_dict["E"].loglog(plot['frequency']/1e3, plot['n(m1)'], label="M1")
ax_dict["E"].legend(loc='upper right')

fig2.tight_layout()

plt.show()
>>>FILE


