Back to Article
Conversion of TXT to MAT for gm/ID result files for SG13G2
Download Notebook

Conversion of TXT to MAT for gm/ID result files for SG13G2

(c) 2024 Boris Murmann and Harald Pretl

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

In [1]:
import pandas as pd
import numpy as np
from numpy.core.records import fromarrays
from scipy.io import savemat
In [2]:
choice = 0  #start from 0
devices = ['sg13_lv_nmos', 'sg13_lv_pmos']

# widths used for characterization and fringe cap parameters (fringe caps are not included in ngspice output)
w = np.array([5, 5])
nfing = np.array([1, 1])
In [3]:
df_raw = pd.read_csv('techsweep_'+devices[choice]+'.txt', sep=r'\s+')
par_names = df_raw.columns.to_list()
par_prefix = par_names[1].split('[')[0]
In [4]:
# remove extra headers in file body and unwanted columns
df = df_raw.drop(['frequency', 'frequency.1'], axis=1)
df = df.apply(pd.to_numeric)

# rename columns for readability
df.columns = df.columns.str.removeprefix(par_prefix+'[')
df.columns = df.columns.str.replace(par_prefix[1:], '')
df.columns = df.columns.str.removesuffix(']')

# round sweep vectors to easily addressable values
df['l'] = df['l'].apply(lambda x: round(x*1e6, 3))
df['vgs'] = df['vgs'].apply(lambda x: round(x, 3))
df['vds'] = df['vds'].apply(lambda x: round(x, 3))
df['vsb'] = df['vsb'].apply(lambda x: round(x, 3))
df
cdd cgb cgd cgdol cgg cgs cgsol cjd cjs css ... ids l rg sfl sid vds vdss vgs vsb vth
0 6.818000e-21 4.501000e-16 1.732000e-19 3.025000e-15 4.504000e-16 1.732000e-19 3.025000e-15 1.998000e-15 1.998000e-15 6.818000e-21 ... 0.000000e+00 0.13 20.0400 0.000000e+00 2.834000e-29 0.000 0.1245 0.0 0.0 0.4360
1 1.367000e-21 3.647000e-16 6.294000e-20 3.025000e-15 3.648000e-16 6.294000e-20 3.025000e-15 1.727000e-15 1.727000e-15 1.367000e-21 ... 0.000000e+00 0.13 20.0400 0.000000e+00 5.621000e-30 0.000 0.1245 -0.0 0.4 0.4746
2 3.731000e-22 3.156000e-16 3.074000e-20 3.025000e-15 3.157000e-16 3.074000e-20 3.025000e-15 1.565000e-15 1.565000e-15 3.731000e-22 ... 0.000000e+00 0.13 20.0400 0.000000e+00 1.519000e-30 0.000 0.1245 -0.0 0.8 0.5078
3 1.222000e-22 2.827000e-16 1.767000e-20 3.025000e-15 2.827000e-16 1.767000e-20 3.025000e-15 1.453000e-15 1.453000e-15 1.222000e-22 ... 0.000000e+00 0.13 20.0400 0.000000e+00 4.927000e-31 0.000 0.1245 -0.0 1.2 0.5375
4 2.974000e-21 4.501000e-16 -2.534000e-19 3.018000e-15 4.504000e-16 5.849000e-19 3.025000e-15 1.975000e-15 1.998000e-15 6.916000e-21 ... 2.946000e-11 0.13 20.0400 1.046000e-28 2.090000e-29 0.025 0.1245 0.0 0.0 0.4360
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
119067 8.308000e-16 1.355000e-14 1.016000e-15 3.032000e-15 4.518000e-13 4.372000e-13 3.235000e-15 1.211000e-15 1.453000e-15 2.724000e-13 ... 1.135000e-04 10.00 0.2605 2.918000e-19 2.417000e-24 1.475 0.9454 1.5 1.2 0.2935
119068 1.033000e-15 1.514000e-14 1.240000e-15 3.025000e-15 4.575000e-13 4.411000e-13 3.235000e-15 1.387000e-15 1.998000e-15 2.808000e-13 ... 1.360000e-04 10.00 0.2605 3.562000e-19 2.708000e-24 1.500 1.0030 1.5 0.0 0.1808
119069 9.320000e-16 1.471000e-14 1.128000e-15 3.025000e-15 4.552000e-13 4.394000e-13 3.235000e-15 1.316000e-15 1.727000e-15 2.771000e-13 ... 1.274000e-04 10.00 0.2605 3.321000e-19 2.595000e-24 1.500 0.9838 1.5 0.4 0.2238
119070 8.504000e-16 1.413000e-14 1.035000e-15 3.025000e-15 4.533000e-13 4.382000e-13 3.235000e-15 1.257000e-15 1.565000e-15 2.744000e-13 ... 1.200000e-04 10.00 0.2605 3.109000e-19 2.501000e-24 1.500 0.9644 1.5 0.8 0.2607
119071 7.841000e-16 1.356000e-14 9.578000e-16 3.025000e-15 4.517000e-13 4.372000e-13 3.235000e-15 1.208000e-15 1.453000e-15 2.724000e-13 ... 1.135000e-04 10.00 0.2605 2.920000e-19 2.418000e-24 1.500 0.9454 1.5 1.2 0.2935

119072 rows × 24 columns

In [5]:
# sweep variable vectors
l = np.unique(abs(df['l']))
vgs = np.unique(abs(df['vgs']))
vds = np.unique(abs(df['vds']))
vsb = np.unique(abs(df['vsb']))
In [6]:
# data
# ngspice sweep order is l, vgs, vds, vsb
dims = [len(l), len(vgs), len(vds), len(vsb)]
id = np.reshape(df['ids'].values, dims, order='C')
vt = np.reshape(df['vth'].values, dims, order='C')
gm = np.reshape(df['gm'].values, dims, order='C')
gmb = np.reshape(df['gmb'].values, dims, order='C')
gds = np.reshape(df['gds'].values, dims, order='C')
cgsol = np.reshape(df['cgsol'].values, dims, order='C')
cgg = np.reshape(df['cgg'].values, dims, order='C') \
      + np.reshape(df['cgdol'].values, dims, order='C') \
      + np.reshape(df['cgsol'].values, dims, order='C')
cgb = -np.reshape(df['cgb'].values, dims, order='C')
cgd = -np.reshape(df['cgd'].values, dims, order='C') \
      + np.reshape(df['cgdol'].values, dims, order='C')
cgs = -np.reshape(df['cgs'].values, dims, order='C') \
      + np.reshape(df['cgsol'].values, dims, order='C')
cdd = np.reshape(df['cdd'].values, dims, order='C') \
      + np.reshape(df['cjd'].values, dims, order='C') \
      + np.reshape(df['cgdol'].values, dims, order='C')
css = np.reshape(df['css'].values, dims, order='C') \
      + np.reshape(df['cjs'].values, dims, order='C') \
      + np.reshape(df['cgsol'].values, dims, order='C')
sth = np.reshape(df['sid'].values, dims, order='C')
sfl = np.reshape(df['sfl'].values, dims, order='C')
In [7]:
dic = {
  "INFO": "IHP SG13G2, 130nm CMOS, PSP",
  "CORNER": "NOM",
  "TEMP": 300.0,
  "VGS": vgs,
  "VDS": vds,
  "VSB": vsb,
  "L": l,
  "W": w[choice],
  "NFING": nfing[choice],
  "ID": id,
  "VT": vt,
  "GM": gm,
  "GMB": gmb,
  "GDS": gds,
  "CGG": cgg,
  "CGB": cgb,
  "CGD": cgd,
  "CGS": cgs,
  "CDD": cdd,
  "CSS": css,
  "STH": sth,
  "SFL": sfl
}

savemat(devices[choice]+'.mat', {devices[choice]: dic})