<@U03EF6JH61F> attached the working spice netlist....
# xschem
s
@Nelson Rodriguez attached the working spice netlist. (set the .lib path to your installation). the syntax for mos parameters is more complicated because the mos devics are encapsulated into subcircuits. Also a
.option savecurrents
is added to save all device internal currents. To quickly see the syntax of mos internal parameters, add a
.option savecurrents
, then in the
.control
section do a
save all
and a
op
command, then at ngspice prompt, after simulation issue a
display
command, you see the name of all device currents.
Copy code
ngspice 17 -> display
Here are the vectors currently active:

Title: MOS Characteristic
Name: op5 (Operating Point)
Date: Fri Nov 25 00:32:13  2022

    @m.xm0.msky130_fd_pr__nfet_01v8[ib]: current, real, 0 long
    @m.xm0.msky130_fd_pr__nfet_01v8[id]: current, real, 1 long
    @m.xm0.msky130_fd_pr__nfet_01v8[ig]: current, real, 0 long
    @m.xm0.msky130_fd_pr__nfet_01v8[is]: current, real, 0 long
    drain               : voltage, real, 1 long
    gate                : voltage, real, 1 long [default scale]
    m.xm0.msky130_fd_pr__nfet_01v8#body: voltage, real, 1 long
    m.xm0.msky130_fd_pr__nfet_01v8#dbody: voltage, real, 1 long
    m.xm0.msky130_fd_pr__nfet_01v8#sbody: voltage, real, 1 long
    vd#branch           : current, real, 1 long
    vg#branch           : current, real, 1 long
n
Oh ok, so when accesing into mos parameters I always have to start with
m.instance_name.m_device_name
? Another question about the line 37, why are you doing
$&w_test
I was reading the manual and there says that it's used to convert a numerical value to a string, so why to use it here, I don't understand (fig 1)
s
For the $& syntax you may try to remove, in this specific case it is not needed. However if you assign a variable to the alterparam it will not work until you convert to a string with $&. I don't have a clear understanding why in some cases $& is needed and in some other cases not, I just do trial and error until it works. A good tutorial on the ngspice control language is here
n
Ok I see, thanks Stefan. Another two questions: 1. I was checking the output of simulation and I was wondering about these errors. It's like there wasn't consistency, because for example, the blue line indicate that there is no model available for W=1u, L=0.15u, but then below it, in the blue box, there are both the W_test=1u and the drain current of the device. So why are these errors if at the end I'm getting numerical values? (so, those models do exist) 2. I was looking for the minimum width for the nfet_01v8 and find this post here in the Slack, from February, where in conclusion, there was possible to use 0.36u as Wmin for standard cells (I'm interested into designing some), and my question is, if the Wmin is 0.36, why am I getting simulation values for W less than 0.36u?
s
For the 1st question I really don't know, looks like it is a ngspice glitch. If you notice the W value is reported as is (1, 2, 3, 4, 5) while the l value is reported after scaling by 1e-6 ( l= 1.5000000e-07), The sizing is correct since values are given in um units, the sky130 models have a global scale=1e-6.
If you look in file
.../share/pdk/sky130A/libs.ref/sky130_fd_pr/spice/sky130_fd_pr__nfet_01v8__tt.pm3.spice
the minimum w is 0.36:
Copy code
...
+ lmin = 1.5e-07 lmax = 1.8e-07 wmin = 3.6e-07 wmax = 3.9e-7
...
There are various model bins, used for different W/L combinations. May be the minimum W is used in special structures (SRAM cells) but not allowed for generic circuitry.
n
Let me see if I understood last part of your message: So there are model bins with W less than 0.36u and that explains why I'm still getting numerical values when
w_test
is 1u, 2u, 3u?
s
No, there are no model bins with W less than 0.36. 0.36 is the absolute minimum regardless of L. That said DRC and DFM rules require W>=0.42 in circuitry and -maybe- (not 100% sure) 0.36 in selected circuit blocks (RAM / ROM arrays and similar).
n
Ok I see thanks Stefan, but excuse me, you didn't answer my question: why if 0.36u is the minimum width, I'm still getting simulation values when
w_test
takes 1u, 2u, 3u? Another question, I was cheking the minimum sizes in the file you mentioned (fig 1) and I saw that those models are sorted in a descendent order of W value, but why are there so many models? And just to check, the Wmin for the pmos would be 0.42u isn't it? (fig 2)
Stefan is it possible to save different transient outputs for the same circuit while varying some device parameters? I'm trying to do a series of simulations varying the widths wp, wn of an inverter, but it doesn't give me any result.
Copy code
.title Maximum and Minimum Rise and Fall Times

*************************************
* Model Import
*************************************
.lib /home/nelson/cad/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice tt


*************************************
* Circuit Netlist
*************************************
v1 vin 0 PULSE(0 1.8 0 1n 1n 5n 10n) 
v2 vdd 0 DC 1.8
xp vdd vin vout vdd sky130_fd_pr__pfet_01v8 l=0.15 w=0.42 $ w=wp_min
xn vout vin 0 0 sky130_fd_pr__nfet_01v8 l=0.15 w=0.36 $ w=wn_min

*************************************
* Control Section
*************************************
.control
let wp_start = 1 $ wp maximum possible for 12T and DRC
let wp_stop = 0.42 $ wp minimum possible according to pdk
let wn_start = 0.36 $ wn minimum possible according to pdk
let wn_stop = 0.94 $ wn maximum possible for 12T and DRC
let delta_w = 0.1

* initialize loop variable
let wp = wp_start $ wp starts in 1

* loop
while wp le wp_stop $ stops when wp is less or equal to 0.42
        alter @m.xp.msky130_fd_pr__nfet_01v8[w] = $&wn
        alter @m.xn.msky130_fd_pr__pfet_01v8[w] = $&wp
        tran 0.1n 20n
        let wn = wn_start + delta_w
        let wp = wp_start - delta_w
        print wp wn vout
end
.endc


*************************************
* End of file
*************************************
.end
s
Sorry i don't understand your question, if 0.36 is the minimum, 1, 2, 3 are greater than the minimum, so these are allowed values. There are multiple models for various geometrical ranges (lmin...lmax, wmin...wmax) of W and L, this is done to better fit the various MOS sizes. this is a decision made by the TCAD engineers, and there are lot of objections to this choice, mostly because there are often discontinuities when 'crossing' one W/L bin to another W/L bin The loop above does not execute since you start with wp=1 and want to execute the loop if wp < 0.42. you need to reverse the comparison:
while wp ge wp_stop
There are various other errors in the code, this one works:
🍺 1
n
Don't worry Stefan, I had a mental lapse with those numbers🤦🏼‍♂️. God yes, I had lot of errors, I didn't see them, because I still don't feel confortable with ngspice, I was focusing more on the syntax than in the logic. Thanks a lot for your time. PS: When you say "_W/L bin"_ what does bin mean?
s
Model 'bin-ning' is the practice of developing multiple mos models, each model is valid for a limited range of W and L values. For a different W and L combination another model 'bin' is used. The end result is that a single mos has many different models called xxxx.1, xxxx.2, xxxx.3, ... . The simulator uses the right model depending on the geometrical dimensions. The advantage is that within the given W and L limits fitting of measured silicon data is easier. The disadvantages are 1) the model file is huge, each transistor has 30+ models. 2) there are often discontinuities when sweeping a W or L value and 'crossing bins'.
n
Oh I understand, thank you! @Stefan Schippers one question about the latter code and pic you send me: how did you plot all the outputs in the same graph, I was trying to do it but I only get one, and also, how did you do that zoom? did you use the right-click several times over the plot (fig 1)?
s
usually all signals are saved with a prefix, if doing multiple transient simulation first signal will be
tr1.vout
, then
tr2.vout
and so on. You can plot individual signals, like
plot tr1.vout tr3.vout
, and the reserved word
all
means plot all:
plot all.vout
.