So far I don't see any issues with the `I` curve. ...
# analog-design
p
So far I don't see any issues with the
I
curve. Should I try other
w
and
h
ranges?
l
I had problems simulating transistors outside the bin values, but for monte carlo. The other simulations are ok.
t
@proppy: To see the issue, you will need to choose some parameter and plot the value while looping over device width or length. I expect to see discontinuities at the boundary between binned width and/or length. I doubt that all parameters will show a discontinuity, but some of them will. You can try this with
Id
at a fixed
Vg
and
Vds
, plotted vs. width. I think this can be done with the ngspice
alter
command.
s
@proppy @Tim Edwards This is a test i ran sweeping the length of a nfet_01v8 to 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, while keeping W=1. Drain voltage is 0.1V and sweep variable is the gate voltage. As you can see the shorter length (highest current) crosses the other curves. I don't know if this i srealistic. I also copy here the teshbench in case you want to use it.
Copy code
* this option enables mos model bin 
* selection based on W/NF instead of W
.option wnflag=1 
.option savecurrents
.param VGATE=0
.param VDRAIN=0.1
.param WIDTH=1.0
.param LENGTH=0.15
vd d 0 {VDRAIN}
vg g 0 {VGATE}
vs s 0 0
vb b 0 0
.control
  save all
  let par=0.15
  dowhile par <= 1
    alterparam LENGTH=$&par
    reset
    dc vg 0 1.8 0.01
    remzerovec
    write test_mos_binning.raw
    set appendwrite
    let par = par + 0.15
  end
.endc
p
you will need to choose some parameter and plot the value while looping over device width or length.
Sorry for the not being very descriptive, I think that's what I'm doing here: each color represent a different
W
.
added more plots to the issue.
@Stefan Schippers would you mind adding the plot + test bench to the issue?
I think I saw something similar on
L
(also less distinctly): https://colab.research.google.com/gist/proppy/57b19edd0c40b49c0f6df497990de69d/sky130-pyspice-playground.ipynb#scrollTo=q0XHBAt1jGmQ
Vg: 0 → 1.8V += 0.01
Vd: 1.8V
L: 0.15 → 0.30 += 0.02
W: 10
l
See this simulation. It is only a nmos, diode connected with a 1 V Vgs. I'm sweeping the L parameter.
Copy code
* id testbench

* Include SkyWater sky130 device models
*.lib "~/git/open_pdks/sources/sky130-pdk/libraries/sky130_fd_pr/latest/models/sky130.lib.spice" tt

.lib "/usr/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice" tt
.param mc_mm_switch=0

.param xl = 0.15

vx x 0 1
X0 x x 0 0 sky130_fd_pr__nfet_01v8 ad=4e+11p pd=2.8e+06u as=4e+11p ps=2.8e+06u w=1.0 l=xl

.option gmin=1e-12
.control

	echo "# xl,id" > char.csv

	let i_i = 0.15
	let i_f = 1.0
	let i_s  = 0.01
	
	let i = i_i 

	dowhile i <= i_f
		alterparam xl=$&i
		reset 
		op
		let id = i(vx)
		print i id
		echo "$&i,$&id" >> char.csv
		let i = i+i_s
	end
	
	exit    
.endc

.end
This is the output drain current Id and its derivative, dI/dL. As you can see, it is discontinuous.
👍 2
🙌 1
t
@proppy: The way Luis did the simulation is the proper/best way to capture the behavior across bin boundaries. Use a very small step size, and do it in a loop inside ngspice using the
alter
command so you don't have to run hundreds of individual simulations and collate the results.
p
Nice! Thanks for sharing @Luis Henrique Rodovalho, would you posting it to the issue?
l
Unfortunately, if I use the same code, but use the mc corner and the mc_mm_switch=1, for any sizing outside the bins, the simulation crashes.
@proppy, it's not really a issue. Models are this way. May experience with TSMC 180 is the same. The underlying problem is that each bin has a bsim parameter that models VT variation with transistor dimensions. Sooner or later, there will be discontinuities. At least, these PDKs use bsim4, which are much better than the open models we used to find out in the open.
t
@Luis Henrique Rodovalho: The
mc
set is different from the corner models and I think is the one that is only defined for exact, specific transistor widths and lengths. Anything outside of those specific values is not modeled.
p
@Luis Henrique Rodovalho yep, I agree it's not really a bug per see; what we are trying to do on https://github.com/google/skywater-pdk/issues/380 is to document the behavior with the binned models, so that we can run the same simulations w/ the continuous models and quantify how much they improve the situation.
@Tim Edwards what does
mc
stand for?
l
My experience with the open PDK from GF180 is much better, and they have bins. The only difference is that everything is in the same file. mc is for monte carlo, by the way
t
@Luis Henrique Rodovalho: The problem as I understand it is that the models really are just characterized for certain discrete widths and lengths. The base set of models (the one used by the
mc
corner) is defined this way. The "corner" models, from what I've been told, have taken the same models and just stretched the bin boundaries out so that they cover a continuous range---but that doesn't mean that the models are actually valid outside of the original W, L values! So what I expect to see based on that understanding is that there may be very sharp discontinuities in some parameters across the bin boundaries because there has been no attempt made to make the models match at the boundaries.
@proppy:
mc
(for "Monte Carlo") is the name of the corner passed to the
.lib
statement; the set of models that get included for that corner name will have stochastic variation over process. So parameters that vary among different wafer runs (process variation) will be modeled with a gaussian function in the parameter definition, with a mean and standard variation that is supposed to be the same as the random distribution of that parameter value over many wafer runs. By contrast, a fixed corner like
ff
(fast-fast) or
ss
(slow-slow) have parameter values that are pegged at the 3-sigma point on the same gaussian distribution (upper or lower, depending on which is appropriate for the fast or slow corner), while at the typical (
tt
) corner, all values are centered exactly on the gaussian mean.
🧑‍🎓 1
l
See the same testbench for GF180
Copy code
* id testbench

* Include GF180MCU device models
.include "~/git/open_pdks/gf180mcu/gf180mcuC/libs.tech/ngspice/design.ngspice"
.lib "~/git/open_pdks/gf180mcu//gf180mcuC/libs.tech/ngspice/sm141064.ngspice" typical
.temp 27

.param
+  sw_stat_global = 0
+  sw_stat_mismatch = 0

.param xl = 0.28u

vx x 0 1
X0 x x 0 0 nmos_3p3 w=1.8u l=xl

.option gmin=1e-12
.control

	echo "# xl,id" > charGF180.csv

	let i_i = 0.28u
	let i_f = 1.0u
	let i_s  = 0.01u
	
	let i = i_i 

	dowhile i <= i_f
		alterparam xl=$&i
		reset 
		op
		let id = i(vx)
		print i id
		echo "$&i,$&id" >> charGF180.csv
		let i = i+i_s
	end
	
	exit    
.endc

.end
It also has a discontinuity. But it is an older process with larger minimum L. Models are very tricky, as smaller the transistors get.
GF180_disxl.jpg,GF180_isxl.jpg,GF180_didxl.jpg,GF180_idxl.jpg
SKY130_disxl.jpg,SKY130_isxl.jpg,SKY130_didxl.jpg,SKY130_idxl.jpg
p
@Luis Henrique Rodovalho neat! Please include those in https://github.com/google/skywater-pdk/issues/380 if you can
Looks like the last one where generated with matplotlib?
And you exporting the raw data and then plotting them separately?
using your testbed with ngspice!
It didnt' seems that PySpice exposes
alterparam
and I could find a way to make it work similarly with
alter <device>
s
@Luis Henrique Rodovalho for the nfet_01v8 with w=1 and sweeping L. @Vgs = Vds = 1V, I get a dI/dL that is 100 times higher. Did you have some scaling factor applied?
l
Copy code
clear
clc
graphics_toolkit("fltk")
tmp = dlmread('charSKY130.csv',',',1,0);
l = tmp(:,1);
i = -tmp(:,2);
di = diff(i)/diff(l);
w = 1e-6

is = i.*l./w;
dis = diff(is)/diff(l);

figure(1)
plot(l,i)
title('SKY130 NMOS1.8 VGS = VDS = 1, VBS=0')
xlabel("L")
ylabel("ID")
print SKY130_idxl.jpg

figure(2)
plot(l(2:end),di)
title('SKY130 NMOS1.8 VGS = VDS = 1, VBS=0')
xlabel("L")
ylabel('dID/dL')
print SKY130_didxl.jpg

figure(3)
plot(l,is)
title("SKY130 NMOS1.8 VGS = VDS = 1, VBS=0")
xlabel("L")
ylabel('ID*(L/W)')
print SKY130_isxl.jpg

figure(4)
plot(l(2:end),dis)
title('SKY130 NMOS1.8 VGS = VDS = 1, VBS=0')
xlabel('L')
ylabel('d(ID*(L/W))/dL')
print SKY130_disxl.jpg
This is my code for GNU Octave. Matlab should run it.