BSIM4 4.8.2 MOSFET amplifier

load "spice/bsim4v8.osdi"
load "resistor.osdi"
include "bsim4v82.inc"

model v vsource
model r resistor
vdd (vdd 0) v dc=1.2
  
subckt namp()
  m1 (3 2 0 0) n1 l=0.1u w=2u $mfactor=2 nrs=1 nrd=1
  rsource (1 2) r r=100k
  rload (3 vdd) r r=25k
  vin (1 0) v mag=1 type="sine" sinedc=0.35 ampl=10m freq=100M
ends

subckt pamp()
  m1 (3 2 vdd vdd) p1 l=0.1u w=2u $mfactor=2 nrs=1 nrd=1
  rsource (1 2) r r=100k
  rload (3 0) r r=25k
  vin (1 0) v mag=1 type="sine" sinedc=0.77 ampl=10m freq=100M
ends

control
  print devices
  print device("sp_bsim4v8")
  
  elaborate circuit("namp")
  
  analysis op1 op

  analysis tran1 tran step=10p stop=40n maxstep=10p

  analysis ac1 ac from=10 to=1T mode="dec" points=50
  
  save full
  analysis noise1 noise out=["3"] in="vin" from=1 to=1T mode="dec" points=50


  elaborate circuit("pamp")
  
  analysis op2 op

  analysis tran2 tran step=10p stop=40n maxstep=10p

  analysis ac2 ac from=10 to=1T mode="dec" points=50

  save full
  analysis noise2 noise out=["3"] in="vin" from=1 to=1T 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


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


fig1 = plt.figure(figsize=(8,10), dpi=100)
fig1.suptitle('BSIM4 4.8.2 NMOS amplifier')
ax_dict = fig1.subplot_mosaic("""
AC
BD
EE
""", gridspec_kw={"height_ratios": [1, 1, 2]})

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

ax_dict["A"].set_title('Input')
ax_dict["A"].set_ylabel('Vin [V]')
ax_dict["A"].set_xlabel('time [ns]')
ax_dict["A"].plot(plot['time']*1e9, plot['2'])

ax_dict["B"].set_title('Output')
ax_dict["B"].set_ylabel('Vout [V]')
ax_dict["B"].set_xlabel('time [ns]')
ax_dict["B"].plot(plot['time']*1e9, plot['3'])

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

ax_dict["C"].set_title('Gain')
ax_dict["C"].set_ylabel('gain [dB]')
ax_dict["C"].set_xlabel('f [MHz]')
ax_dict["C"].semilogx(np.real(plot['frequency'])/1e6, 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 [MHz]')
ax_dict["D"].semilogx(np.real(plot['frequency'])/1e6, 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 [MHz]')
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,flicker)'], label="M1,flicker")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,id)'], label="M1,Id")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rs)'], label="M1,Rs")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rd)'], label="M1,Rd")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rg)'], label="M1,Rg")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbsb)'], label="M1,Rbsb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbdb)'], label="M1,Rbdb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbps)'], label="M1,Rbps")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbpd)'], label="M1,Rbpd")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbpb)'], label="M1,Rbpb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igb)'], label="M1,Igb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igs)'], label="M1,Igs")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igd)'], label="M1,Igd")
# rg3 (rgatemod=3), corl (tnoimod=2)
ax_dict["E"].loglog(plot['frequency']/1e6, 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])


fig1 = plt.figure(figsize=(8,10), dpi=100)
fig1.suptitle('BSIM4 4.8.2 PMOS amplifier')
ax_dict = fig1.subplot_mosaic("""
AC
BD
EE
""", gridspec_kw={"height_ratios": [1, 1, 2]})

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

ax_dict["A"].set_title('Input')
ax_dict["A"].set_ylabel('Vin [V]')
ax_dict["A"].set_xlabel('time [ns]')
ax_dict["A"].plot(plot['time']*1e9, plot['2'])

ax_dict["B"].set_title('Output')
ax_dict["B"].set_ylabel('Vout [V]')
ax_dict["B"].set_xlabel('time [ns]')
ax_dict["B"].plot(plot['time']*1e9, plot['3'])


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

ax_dict["C"].set_title('Gain')
ax_dict["C"].set_ylabel('gain [dB]')
ax_dict["C"].set_xlabel('f [MHz]')
ax_dict["C"].semilogx(np.real(plot['frequency'])/1e6, 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 [MHz]')
ax_dict["D"].semilogx(np.real(plot['frequency'])/1e6, 180/np.pi*np.unwrap(np.angle(h)))

raw = rawread('noise2.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 [MHz]')
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,flicker)'], label="M1,flicker")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,id)'], label="M1,Id")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rs)'], label="M1,Rs")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rd)'], label="M1,Rd")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rg)'], label="M1,Rg")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbsb)'], label="M1,Rbsb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbdb)'], label="M1,Rbdb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbps)'], label="M1,Rbps")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbpd)'], label="M1,Rbpd")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,rbpb)'], label="M1,Rbpb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igb)'], label="M1,Igb")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igs)'], label="M1,Igs")
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1,igd)'], label="M1,Igd")
# rg3 (rgatemod=3), corl (tnoimod=2)
ax_dict["E"].loglog(plot['frequency']/1e6, plot['n(m1)'], label="M1")
ax_dict["E"].legend(loc='upper right')

fig1.tight_layout()

plt.show()
>>>FILE


