Ejemplo n.º 1
0
import matplotlib
from glob import glob

rc('text', usetex=True)
font = {'family' : 'sans-serif',
'weight' : 'bold',
'size' : 18}
rc('font', **font)

allvbgs = np.empty((3,400))
for i, temp in enumerate(['0', '27', '70']):
    fig = plt.figure(i)
    fig.tight_layout()
    runs = glob('../sims/tbtran_tt_mm_1_mc_1_{}degc_run_[0-9]*.raw'.format(temp))
    runs2 = [x for x in runs if 'randomseed' not in x] 
    vbgs = [np.asarray(s3r.read(run)['v(vbg)']) for run in runs2]
    vbgfinals = [vbg.flatten()[-1]*1.0e3 for vbg in vbgs] #in mV
    allvbgs[i]=(vbgfinals)
    mean = np.mean(vbgfinals)
    stdev = np.std(vbgfinals)
    hist = np.histogram(vbgfinals)
    plt.hist(vbgfinals, bins='auto',ec='black')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.grid(True)
    plt.xlabel(r"$V_{out}$ (mV)")
    plt.ylabel(r"Sample Count")
    plt.title("Monte Carlo Simulation on Reference Voltage"
    "\n"
    "temp = ${}^\circ$C"
    "\n"
Ejemplo n.º 2
0
sys.path.append('/tmp/kustinj/ee272b/pyMOSChar')
import spice3read as s3r
import numpy as np
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
from scipy import constants
import model_bgvr

q = constants.e
k = constants.k
xVar = 'temp-sweep'
yVar = 'v(e2)'
dVar = 'v(deriv(e2))'
plotDat = s3r.read(
    '/home/users/kustinj/.xschem/simulations/bipolar_char_temp_vbe_current_3p40.raw'
)
current = np.arange(0.1156, 115.6, 0.1)  # in units of uA

dVbe = plotDat[dVar]
steadiestdVbes = np.std(dVbe, axis=1)
mostConstantdVbe = np.argmin(
    np.abs(steadiestdVbes
           ))  # choose most constant dVbe to have easiest TC cancellation
T = plotDat[xVar]
targI = mostConstantdVbe  #16.4 #
indx = (np.abs(current - targI)).argmin(
)  # https://philbull.wordpress.com/2012/01/11/numpy-tip-getting-index-of-an-array-element-nearest-to-some-value/
# interp Vbe to find its value when T=27degC
VbeNominal = np.interp(27, plotDat[xVar][indx], plotDat[yVar][indx])
print('interpolated Vbe at 27degC: {} mV'.format(VbeNominal * 1e3))
Ejemplo n.º 3
0
import sys
sys.path.append('/tmp/kustinj/ee272b/pyMOSChar')
import spice3read as s3r
import matplotlib.pyplot as plt
import os
from glob import glob
import numpy as np
import matplotlib

plotDat = []
for fname in glob('*.raw'):
    plotDat.append(
        (s3r.read(fname), fname.strip('.raw').replace('tsmc_bandgap_', '')))
xvar = 'temp-sweep'
yvar = 'v(vbg)'

matplotlib.rc('xtick', labelsize=15)
matplotlib.rc('ytick', labelsize=15)
for x in plotDat:
    data = x[0]
    lab = x[1]
    upperx = np.where(data[xvar][0] >= 0.)
    lowerx = np.where(data[xvar][0] <= 70.)
    rangex = np.intersect1d(upperx, lowerx)
    xdat = data[xvar][0][rangex]
    ydat = data[yvar][0][rangex]
    plt.plot(xdat, ydat * 1e3, label=lab)
plt.grid()
plt.legend()
plt.xlabel('Temperature (degC)')
plt.ylabel('Vref (mV)')
Ejemplo n.º 4
0
import sys
sys.path.append('../pyMOSChar')
import spice3read as s3r
import numpy as np

opdat = s3r.read('../sims/tsmc_bandgap_real_op.raw')

gms = [entry for entry in opdat.keys() if '[gm]' in entry]
ids = [entry for entry in opdat.keys() if '[id]' in entry]
ids.remove('i(@m.xm10.msky130_fd_pr__nfet_01v8_lvt[id])')
gms.sort()
ids.sort()
vdsats = []
for i, x in enumerate(gms):
    gm = opdat[x]
    id = opdat[ids[i]]
    vdsats.append(2 / (gm / id))

indx = range(1, 10)
indx.insert(1, 13)
vdsats = np.asarray(vdsats).flatten()
print('vdsats')
for i, n in enumerate(indx):
    print('vdsat{} = {}'.format(n, vdsats[i]))

vdd = opdat['v(vdd)']
va = opdat['v(va)']
vb = opdat['v(vb)']
vbg = opdat['v(vbg)']
vgate = opdat['v(vgate)']
vq = opdat['v(vq)']
Ejemplo n.º 5
0
import sys
sys.path.append('../pyMOSChar')
import spice3read as s3r
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
from scipy import interpolate

rc('text', usetex=True)
font = {'family': 'sans-serif', 'weight': 'bold', 'size': 14}
rc('font', **font)

for i, corner in enumerate(['tt', 'ss', 'ff']):
    tran27 = s3r.read('../sims/tbtran_{}_mm_0_27degc_vbg.raw'.format(corner))
    tran0 = s3r.read('../sims/tbtran_{}_mm_0_0degc_vbg.raw'.format(corner))
    tran70 = s3r.read('../sims/tbtran_{}_mm_0_70degc_vbg.raw'.format(corner))
    randomseed = np.asarray(
        s3r.read('../sims/tbtran_{}_mm_0_randomseed.raw'.format(corner))
        ['randomseed']).flatten()[0]
    vbg27 = tran27['v(vbg)'][0][-1]
    vbg0 = tran0['v(vbg)'][0][-1]
    vbg70 = tran70['v(vbg)'][0][-1]
    idleTime = 4.0e-6
    ppm = (vbg70 - vbg0) / vbg27 / 70 * 1e6
    print('0, 27, 70 degC')
    print('{} {} {}'.format(vbg0, vbg27, vbg70))
    print(ppm)
    times = [tran0['time'][0], tran27['time'][0], tran70['time'][0]]
    maxtime = times[np.asarray([len(x) for x in times]).argmax()]
    tranvbg27 = np.interp(maxtime, times[1], tran27['v(vbg)'][0])
    tranvbg0 = np.interp(maxtime, times[0], tran0['v(vbg)'][0])
Ejemplo n.º 6
0
import sys
sys.path.append('../pyMOSChar')
import spice3read as s3r
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.lines as mlines
import matplotlib

matplotlib.rc('xtick',labelsize=15)
matplotlib.rc('ytick',labelsize=15)
plotDat = s3r.read('../sims/bipolar_char_temp_vbe_current_3p40.raw')
current = np.arange(0.01,146,step=20) # in units of uA
fig, ax1 = plt.subplots(1)
ax1.set_xlabel('Temp (degC)')
ax1.set_ylabel('Veb (V)')
ax1.set_title('PNP CTAT Behavior')
xVar = 'temp-sweep'
yVar = 'v(e2)'
zVar = 'i(v1)'
ax1.grid()
lns = []
colors = []
for i in range(np.shape(plotDat[xVar])[0]):
    lns.append(ax1.plot(plotDat[xVar][i], plotDat[yVar][i], label=np.format_float_scientific(current[i], precision=3)))
    colors.append(lns[i][0].get_c())
    #print(np.format_float_scientific(current[i],precision=3))
labs = [l[0].get_label() for l in lns]
lg1 = ax1.legend(labs, loc=3, title='Ic (uA)', prop={'size':15})
lg1.get_title().set_fontsize(15)
dT = plotDat[xVar][0][1] - plotDat[xVar][0][0]
dVbe = [np.gradient(plotDat[yVar][i], dT)*1E3 for i in range(np.shape(plotDat[xVar])[0])] 
Ejemplo n.º 7
0
biascurrent = current / 5
activeloadwidth = (biascurrent / 2) / JDpmos[activeloadgmindex]
print('activeloadwidth {}'.format(activeloadwidth))

nmoscurrentmirrorwidth = biascurrent / JDnmos[gmidnmosof20index]
print('nmoscurrentmirrorwidth {}'.format(nmoscurrentmirrorwidth))

nmosamplifierwidth = (biascurrent / 2) / JDnmos[gmidnmosof25index]
print('nmosamplifierwidth {}'.format(nmosamplifierwidth))

if os.path.exists(
        '/home/users/kustinj/.xschem/simulations/tsmc_bandgap_real.raw'):
    print('sim results')

    opdat = s3r.read(
        '/home/users/kustinj/.xschem/simulations/tsmc_bandgap_real.raw')

    gms = [entry for entry in opdat.keys() if '[gm]' in entry]
    ids = [entry for entry in opdat.keys() if '[id]' in entry]
    ids.remove('i(@m.xm10.msky130_fd_pr__nfet_01v8_lvt[id])')
    gms.sort()
    ids.sort()
    gmids = np.asarray([opdat[gm] / opdat[ids[i]]
                        for i, gm in enumerate(gms)]).flatten()
    vdsats = []
    for i, x in enumerate(gms):
        gm = opdat[x]
        id = opdat[ids[i]]
        vdsats.append(2 / (gm / id))

    gmidm1 = gmids[0]
Ejemplo n.º 8
0
def genDB():

    if (simulator == "ngspice"):
        genNetlistNngspice()
        genNetlistPngspice()
    elif (simulator == "spectre"):
        genNetlistSpectre()
    else:
        print "ERROR: Invalid/Unsupported simulator specified"
        sys.exit(0)

    progTotal = len(mosLengths) * len(vsb)
    progCurr = 0
    print("Data generation in progress. Go have a coffee...")
    for idxL in range(len(mosLengths)):
        for idxVSB in range(len(vsb)):

            if (simulator == "ngspice"):
                genSimParams(mosLengths[idxL], vsb[idxVSB])

                myfile = open("charMOSpy.log", "a")
                myfile.write("charMOS: Simulating for L={0}, VSB={1}\n".format(
                    idxL, idxVSB))
                myfile.close()

                runSim("charNMOS.net", "ngspice")
                simDat = spice3read.read('outN.raw')

                mosDat['nfet']['id'][idxL][idxVSB] = simDat['i(id)']
                mosDat['nfet']['vt'][idxL][idxVSB] = simDat['vt']
                mosDat['nfet']['gm'][idxL][idxVSB] = simDat['gm']
                mosDat['nfet']['gmb'][idxL][idxVSB] = simDat['gmb']
                mosDat['nfet']['gds'][idxL][idxVSB] = simDat['gds']
                mosDat['nfet']['cgg'][idxL][idxVSB] = simDat['cgg']
                mosDat['nfet']['cgs'][idxL][idxVSB] = simDat['cgs']
                mosDat['nfet']['cgd'][idxL][idxVSB] = simDat['cgd']
                mosDat['nfet']['cgb'][idxL][idxVSB] = simDat['cgb']
                mosDat['nfet']['cdd'][idxL][idxVSB] = simDat['cdd']
                mosDat['nfet']['css'][idxL][idxVSB] = simDat['css']

                runSim("charPMOS.net", "ngspice")
                simDat = spice3read.read('outP.raw')

                mosDat['pfet']['id'][idxL][idxVSB] = simDat['i(id)']
                mosDat['pfet']['vt'][idxL][idxVSB] = simDat['vt']
                mosDat['pfet']['gm'][idxL][idxVSB] = simDat['gm']
                mosDat['pfet']['gmb'][idxL][idxVSB] = simDat['gmb']
                mosDat['pfet']['gds'][idxL][idxVSB] = simDat['gds']
                mosDat['pfet']['cgg'][idxL][idxVSB] = simDat['cgg']
                mosDat['pfet']['cgs'][idxL][idxVSB] = simDat['cgs']
                mosDat['pfet']['cgd'][idxL][idxVSB] = simDat['cgd']
                mosDat['pfet']['cgb'][idxL][idxVSB] = simDat['cgb']
                mosDat['pfet']['cdd'][idxL][idxVSB] = simDat['cdd']
                mosDat['pfet']['css'][idxL][idxVSB] = simDat['css']

            elif (simulator == "spectre"):
                genSimParamsSpectre(mosLengths[idxL], vsb[idxVSB])

                runSim("charMOS.scs", "spectre")
                simDat = spice3read.read('charMOS.raw', 'spectre')

                if (subcktPath == ""):
                    nmos = "mn"
                    pmos = "mp"
                else:
                    nmos = "mn." + subcktPath
                    pmos = "mp." + subcktPath

                mosDat['nfet']['id'][idxL][idxVSB] = simDat['{0}:ids'.format(
                    nmos)]
                mosDat['nfet']['vt'][idxL][idxVSB] = simDat['{0}:vth'.format(
                    nmos)]
                mosDat['nfet']['gm'][idxL][idxVSB] = simDat['{0}:gm'.format(
                    nmos)]
                mosDat['nfet']['gmb'][idxL][idxVSB] = simDat['{0}:gmbs'.format(
                    nmos)]
                mosDat['nfet']['gds'][idxL][idxVSB] = simDat['{0}:gds'.format(
                    nmos)]
                mosDat['nfet']['cgg'][idxL][idxVSB] = simDat['{0}:cgg'.format(
                    nmos)]
                mosDat['nfet']['cgs'][idxL][idxVSB] = simDat['{0}:cgs'.format(
                    nmos)]
                mosDat['nfet']['cgd'][idxL][idxVSB] = simDat['{0}:cgd'.format(
                    nmos)]
                mosDat['nfet']['cgb'][idxL][idxVSB] = simDat['{0}:cgb'.format(
                    nmos)]
                mosDat['nfet']['cdd'][idxL][idxVSB] = simDat['{0}:cdd'.format(
                    nmos)]
                mosDat['nfet']['css'][idxL][idxVSB] = simDat['{0}:css'.format(
                    nmos)]

                mosDat['pfet']['id'][idxL][idxVSB] = simDat['{0}:ids'.format(
                    pmos)]
                mosDat['pfet']['vt'][idxL][idxVSB] = simDat['{0}:vth'.format(
                    pmos)]
                mosDat['pfet']['gm'][idxL][idxVSB] = simDat['{0}:gm'.format(
                    pmos)]
                mosDat['pfet']['gmb'][idxL][idxVSB] = simDat['{0}:gmbs'.format(
                    pmos)]
                mosDat['pfet']['gds'][idxL][idxVSB] = simDat['{0}:gds'.format(
                    pmos)]
                mosDat['pfet']['cgg'][idxL][idxVSB] = simDat['{0}:cgg'.format(
                    pmos)]
                mosDat['pfet']['cgs'][idxL][idxVSB] = simDat['{0}:cgs'.format(
                    pmos)]
                mosDat['pfet']['cgd'][idxL][idxVSB] = simDat['{0}:cgd'.format(
                    pmos)]
                mosDat['pfet']['cgb'][idxL][idxVSB] = simDat['{0}:cgb'.format(
                    pmos)]
                mosDat['pfet']['cdd'][idxL][idxVSB] = simDat['{0}:cdd'.format(
                    pmos)]
                mosDat['pfet']['css'][idxL][idxVSB] = simDat['{0}:css'.format(
                    pmos)]

            rows, columns = os.popen('stty size', 'r').read().split()
            columns = int(columns) - 10
            progCurr += 1
            progPercent = 100 * progCurr / progTotal
            progLen = int(progPercent * columns / 100)
            sys.stdout.write("\r[{0}{1}] {2}%".format(
                "#" * progLen, " " * (columns - progLen), progPercent))
            sys.stdout.flush()

    os.system(
        'rm -fr charNMOS.net charPMOS.net simParams.net outN.raw outP.raw b3v33check.log charMOS.scs simParams.scs charMOS.raw charMOS.raw.psf charMOS.ahdlSimDB charMOS.log'
    )
    print
    print("Data generated. Saving...")
    pickle.dump(mosDat, open(datFileName, "wb"), pickle.HIGHEST_PROTOCOL)
    print("Done! Data saved in " + datFileName)
Ejemplo n.º 9
0
import sys
sys.path.append('../pyMOSChar')
import spice3read as s3r
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc

rc('text', usetex=True)
rc('font', family='serif')

data = s3r.read('../sims/tsmc_bandgap_real_tempsweep.raw')
vbg = data['v(vbg)'][0]
temp = data['temp-sweep'][0]
vbg0 = np.interp(0, temp, vbg)
vbg27 = np.interp(27, temp, vbg)
vbg70 = np.interp(70, temp, vbg)
ppm = (vbg70-vbg0)/vbg27/70*1e6
fig, ax = plt.subplots()
ax.plot(temp, vbg)
ax.plot(0, vbg0, '-bo', label='{} mV'.format(np.around(vbg0*1e3,3)))
ax.plot(27, vbg27, '-ro', label='{} mV'.format(np.around(vbg27*1e3,3)))
ax.plot(70, vbg70, '-yo', label='{} mV'.format(np.around(vbg70*1e3, )))
ax.grid()
ax.set_title('DC Temperature Sweep. Vref = {} mV. ppm = {}'.format(np.around(vbg27*1e3, 3), np.around(ppm, 3)))
ax.set_xlabel("Temperature $^\circ$C")
ax.set_ylabel('Vout (V)')
ax.legend()
plt.show()