I’m encountering a problem with the MOS models and...
# sky130
c
I’m encountering a problem with the MOS models and params. I have been using the models
?fet_xxx_nf
, i.e., what I assume are the models which calculate correct areas and perimeters for fingered FETs. I have been using them no problem with numerical values for width and length. But I tried using params as shown in the attached image, and get lots of errors in ngspice. (I know I haven’t enabled multiple fingers yet) ngspice output (there are many similar)
Copy code
Undefined parameter [len_3p3]
Netlist line no. 26:
 Formula() error.
      |m=1; sd=0; sb=0; sa=0; nf=1; mult=1; l=len_3p3; w=(wid)*1 ; ad=int((1+1)/2)*(wid)*0.29; as=int((1+2)/2)*(wid)*0.29; pd=2*int((1+1)/2)*((wid)+0.29); ps=2*int((1+2)/2)*((wid)+0.29); swx_vth=sw_vth0_sky130_fd_pr__nfet_g5v0d10v5+sw_vth0_sky130_fd_pr__nfet_g5v0d10v5_mc; nrd=0.29/(wid)/1 ; nrs=0.29/(wid)/1 ; swx_nrds=89.1*nf/w+443.5;| : |l|=|len_3p3|
This is the section of the netlist that starts with the offending instance.
Copy code
XM9 net10 net12 GND GND sky130_fd_pr__nfet_g5v0d10v5 L={LEN_3P3} W='{WID} * 1 ' nf=1 ad='int((1 + 1)/2) * {WID} * 0.29' as='int((1 + 2)/2) * {WID} * 0.29'
+ pd='2*int((1 + 1)/2) * ({WID} + 0.29)' ps='2*int((1 + 2)/2) * ({WID} + 0.29)' nrd='0.29 / {WID} / 1 ' nrs='0.29 / {WID} / 1 ' sa=0
+ sb=0 sd=0 mult=1 m=1
E4 net11 GND ctrl_vds GND 1
Vvds_ctrl ctrl_vds GND {VDS}
Vvgs_ctrl ctrl_vgs GND dc {VGS} ac 1
R1 net11 src_n1p8lvt 1 m=1
R2 net11 src_n1p8 1 m=1
R3 net11 src_n3p3nvt 1 m=1
R5 net11 src_ng5p0d10p5 1 m=1
R6 src_p1p8lvt net5 1 m=1
R7 src_p1p8 net5 1 m=1
R8 src_p1p8hvt net5 1 m=1
R9 src_pg5p0d10p5 net5 1 m=1
**** begin user architecture code

.param WID=0.5
.param LEN_1P8=0.15
.param LEN_PLVT=0.35
.param LEN_3P3=0.5
.param VGS=0.9
.param VDS=0.6
.options sparse
.probe alli
I think I’m using
param
correctly, because other parameters like the voltage source values have been simulating fine. Is there anything special I need to do when parameterizing device model parameters?
b
This was a bug that I reported a few months ago, and I thought it was fixed. Which exact model path and PDK version are you using?
c
I installed the PDK from git://opencircuitdesign.com/open_pdks, tag 1.0.512 (Jan 30, 2025). I followed the instructions at .http://opencircuitdesign.com/~tim/reference/analog_mixed_signal_flow/analog_design_flow.html Once installed, the model path is
/usr/local/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice
b
Have you tried getting rid of the *1 in the W field? This could be the culprit. I have a working example here: https://github.com/bmurmann/Chipathon2024/blob/main/diffpair/sizing_diffpair.spice
You may want to point to the new continuous models, located under libs.tech/combined/sky130.lib.spice.
c
My mistake, I am already using the continuous models, I misread the line that was commented out. I will try your script shortly. I too am puzzled by the
* 1
in the W factor in the netlist, but I can’t figure out how it gets in there. It’s not present in the instance properties but it somehow gets into the generated netlist…
Your example worked, so I dug deeper and realized there was a silent error earlier in the code, I did
let wid_curr = wid_mult * WID_MIN
instead of
$wid_mult
and it didn’t flag that. Thanks!
s
@Colin Weltin-Wu Looking at the offending line there is a double level of quoting. The transistor netlist uses quoting characters (
'
or
{}
are used by ngspice ) for ad, as, pd, ps formulas. The
WID
parameter is itself also quoted so we have a quoted parameter inside a quoted expression. Remove the braces around WID (
{WID}
-->
WID
) .
[Edit] I have tested some netlist examples with quoted parameters inside quoted expressions and seems to work. So the above is not true.
@Colin Weltin-Wu I dont know if you have this line enabled in your `.spiceinit`:
set skywaterpdk
If you comment this line:
# set skywaterpdk
ngspice will be more tolerant to parametrized elements in the netlist.
c
Ah, so commenting out the skywaterpdk makes ngspice MORE tolerant? Usually the PDK is the one that does a lot of parametrization :)
@Stefan One more question, can you please tell me what controls the addition of the
* 1
in the width expression in my netlist? As far as I can tell, it is added when I netlist within xschem. It happens with all the FETs I have tested so far.
Copy code
XM9 net10 net12 GND GND sky130_fd_pr__nfet_g5v0d10v5 L={LEN_3P3} W='{WID} * 1 ' nf=1 ad='int((1 + 1)/2) * {WID} * 0.29' as='int((1 + 2)/2) * {WID} * 0.29'
+ pd='2*int((1 + 1)/2) * ({WID} + 0.29)' ps='2*int((1 + 2)/2) * ({WID} + 0.29)' nrd='0.29 / {WID} / 1 ' nrs='0.29 / {WID} / 1 ' sa=0
+ sb=0 sd=0 mult=1 m=1
s
@Colin Weltin-Wu the
*1
is the number of fingers,
nf
. Whenever possible xschem replaces the numeric value of parameters. the
*_nf.sym
symbols take the 'W' parameter as the '1-finger width'. The total width of the transistor is
W * nf
. If you set nf=2 you will see a '*2' in the netlist. This is different from standard fet symbols (no
_nf
suffix)where the 'W' parameter is the total width, and if nf > 1 is specified the transistor will be drawn as 'nf' parallel branches, each of width W/nf
Ah, so commenting out the skywaterpdk makes ngspice MORE tolerant? Usually the PDK is the one that does a lot of parametrization 🙂
The skywaterpdk option was added to speed up the time to parse the spice models. This comes at some price, doing some assumptions about parameters and number of pins of components. On my ngspice installation the time to read in the spice models does not change significantly with or without this option.