Quantcast
Channel: Cadence Custom IC Design Forum
Viewing all articles
Browse latest Browse all 4897

spectre: subcktprobelvl and the reliability of Monte-Carlo results

$
0
0

Dear Cadence forum,

while experimenting with my netlists with respect to the performance of spectre simulations, I found this forum post saying that reducing the parameter value of subcktprobelvl can avoid saving unnecessary terminal currents of hierarchical subcircuits.

I experimented with this and noticed that the numerical results of the Monte-Carlo simulations I made changed (the resulting numbers are different) when I changed subcktprobelvl=2 to subcktprobelvl=0. As I understand, this parameter affects the amount of data that is stored on disk, but does not modify the simulation parameters (like other parameters do, such as method or gmin). This leaves me confused: Why does a parameter that is supposed to configure result storage have an effect on the numbers that come out?

I am using spectre on the command line (without Virtuoso):

$ spectre -W
sub-version  11.1.0.509.isr14

I created a distilled "sample" netlist that reproduces the problem. The file "corners.scs" included in the netlist references a STMicroelectronics 65nm technology.

simulator lang=spectre
global 0 vdds! gnds! vdd!
include "corners.scs"

subckt inv A Z inh_gnd inh_gnds inh_vdd inh_vdds
parameters nmos_aspect_ratio pmos_scale_factor=2.2
M0 (Z A inh_vdd inh_vdds) psvtlp w=pmos_scale_factor*nmos_aspect_ratio*0.06 l=0.06 nfing=1 mult=1 srcefirst=1 ngcon=1 mismatch=1 lpe=0 dnoise_mdev=0 dmu_mdev=0 dvt_mdev=0
M1 (Z A inh_gnd inh_gnds) nsvtlp w=nmos_aspect_ratio*0.06                   l=0.06 nfing=1 mult=1 srcefirst=1 ngcon=1 mismatch=1 lpe=0 dnoise_mdev=0 dmu_mdev=0 dvt_mdev=0
ends inv

parameters g_nmos_aspect_ratio=10.0
parameters g_pmos_scale_factor=2.2
parameters g_cload=100f
parameters g_risefall=10p
parameters g_dcvoltage=1.200000

// supply
V0 (vdd!      0) vsource dc=g_dcvoltage type=dc
V1 (vdds! gnds!) vsource dc=g_dcvoltage type=dc
R0 (gnds! 0) resistor r=1m isnoisy=no

// test signal
//
// t/ns    0  100 200
//         | . | . | 
//            ___    
// in_s    __/   \__
// 
Vin (in_s 0) vsource dc=0 type=pulse val0=0 val1=g_dcvoltage period=200n delay=50n rise=g_risefall fall=g_risefall width=100n
I0 (in_s out_s 0 gnds! vdd! vdds!)   inv nmos_aspect_ratio=g_nmos_aspect_ratio pmos_scale_factor=g_pmos_scale_factor
Cload (out_s 0) capacitor c=g_cload

simulatorOptions options reltol=1e-3 vabstol=1e-6 iabstol=1e-12 temp=27.000000 \
    tnom=27 scalem=1.0 scale=1.0 gmin=1e-13 rforce=1 maxnotes=5 maxwarns=5 \
    digits=5 cols=80 pivrel=1e-3 sensfile="./psf/sens.output" \
    checklimitdest=psf
mc1 montecarlo numruns=10 seed=12345 variations=mismatch sampling=standard \
    donominal=no scalarfile="../monteCarlo/mcdata" \
    paramfile="../monteCarlo/mcparam" saveprocessparams=yes \
    savemismatchparams=yes mismatchparamfile="../monteCarlo/mismatchParam" mismatchscalarfile="../monteCarlo/mismatchData" \
    processparamfile="../monteCarlo/processParam" \
    processscalarfile="../monteCarlo/processData" savefamilyplots=no {
tran tran stop=200n write="./psf/spectre.ic" writefinal="./psf/spectre.fc" \
    annotate=status maxiters=5 method=trap

export falltime=oceanEval("delay(\
    ?wf1 getData(\"out_s\" ?result \"tran\") ?value1 0.9*1.200000 ?edge1 'falling ?nth1 1 ?td1 50n \
    ?wf2 getData(\"out_s\" ?result \"tran\") ?value2 0.1*1.200000 ?edge2 'falling ?nth2 1 ?td2r0 50n \
    ?stop nil ?multiple nil)")
export risetime=oceanEval("delay(\
    ?wf1 getData(\"out_s\" ?result \"tran\") ?value1 0.1*1.200000 ?edge1 'rising ?nth1 1 ?td1 150n \
    ?wf2 getData(\"out_s\" ?result \"tran\") ?value2 0.9*1.200000 ?edge2 'rising ?nth2 1 ?td2r0 150n \
    ?stop nil ?multiple nil)")

export delay_fallingoputput=oceanEval("delay(\
    ?wf1 getData(\"in_s\" ?result \"tran\") ?value1 0.5*1.200000 ?edge1 'rising ?nth1 1 ?td1 50n \
    ?wf2 getData(\"out_s\" ?result \"tran\") ?value2 0.5*1.200000 ?edge2 'falling ?nth2 1 ?td2r0 50n \
    ?stop nil ?multiple nil)")
export delay_risingoutput=oceanEval("delay(\
    ?wf1 getData(\"in_s\" ?result \"tran\") ?value1 0.5*1.200000 ?edge1 'falling ?nth1 1 ?td1 150n \
    ?wf2 getData(\"out_s\" ?result \"tran\") ?value2 0.5*1.200000 ?edge2 'rising ?nth2 1 ?td2r0 150n \
    ?stop nil ?multiple nil)")

export crossvoltage_fallingoutput=oceanEval("value(intersect(getData(\"in_s\" ?result \"tran\") getData(\"out_s\" ?result \"tran\")) 0)")
export crossvoltage_risingoutput=oceanEval("value(intersect(getData(\"in_s\" ?result \"tran\") getData(\"out_s\" ?result \"tran\")) 1)")
}
saveOptions options save=allpub subcktprobelvl=2

I created the same netlist with the only difference being the subcktprobelvl parameter:

$ diff level_0/input.scs level_2/input.scs 
67c67< saveOptions options save=allpub subcktprobelvl=0
---> saveOptions options save=allpub subcktprobelvl=2

The results from the OCEAN expressions, as stored in the files named mcdata, are different:

$ diff level_0/monteCarlo/mcparam level_2/monteCarlo/mcparam 
$ diff level_0/monteCarlo/mcdata level_2/monteCarlo/mcdata  
1,10c1,10< 3.75671e-10 3.85534e-10 1.91515e-10 1.8117e-10 1.19625 0.00450162 < 3.70535e-10 3.77426e-10 1.88768e-10 1.77268e-10 1.19583 0.00508238 < 3.9898e-10 3.79619e-10 2.00802e-10 1.78006e-10 1.19758 0.00514946 < 3.75885e-10 3.81322e-10 1.91951e-10 1.79069e-10 1.19653 0.00486543 < 3.78338e-10 3.89232e-10 1.92815e-10 1.82674e-10 1.19638 0.00438965 < 3.75745e-10 3.78624e-10 1.91937e-10 1.77619e-10 1.19659 0.00515173 < 3.78653e-10 3.69747e-10 1.93295e-10 1.73545e-10 1.1967 0.00571527 < 4.02996e-10 3.81731e-10 2.01757e-10 1.79157e-10 1.19745 0.00490435 < 3.91684e-10 3.83e-10 1.97172e-10 1.80602e-10 1.197 0.00435559 < 3.7777e-10 3.74312e-10 1.92494e-10 1.75773e-10 1.19636 0.00532838 
---> 3.8052e-10 3.85254e-10 1.92651e-10 1.8159e-10 1.1999 0.000852351 > 3.74567e-10 3.77439e-10 1.89568e-10 1.77275e-10 1.19966 0.00121274 > 3.98463e-10 3.8045e-10 2.04844e-10 1.7814e-10 1.2 0.00125012 > 3.80442e-10 3.81592e-10 1.93164e-10 1.79424e-10 1.2 0.00108245 > 3.83699e-10 3.90274e-10 1.9411e-10 1.83726e-10 1.2 0.000768679 > 3.80214e-10 3.79212e-10 1.93152e-10 1.77677e-10 1.2 0.00125574 > 3.83735e-10 3.69479e-10 1.94674e-10 1.72791e-10 1.2 0.00161701 > 4.00954e-10 3.82288e-10 2.05985e-10 1.79522e-10 1.2 0.0010966 > 3.91888e-10 3.80556e-10 2.00957e-10 1.80933e-10 1.2 0.000795901 > 3.83069e-10 3.74182e-10 1.93744e-10 1.75474e-10 1.19999 0.00136871 

Note that the two means are quite close to each other while the variances are off by a factor of roughly 1.7:

>>> from numpy import mean, var>>> mean([3.75671e-10, 3.70535e-10, 3.9898e-10, 3.75885e-10, 3.78338e-10, 3.75745e-10, 3.78653e-10, 4.02996e-10, 3.91684e-10, 3.7777e-10])
3.8262569999999997e-10>>> mean([3.8052e-10, 3.74567e-10, 3.98463e-10, 3.80442e-10, 3.83699e-10, 3.80214e-10, 3.83735e-10, 4.00954e-10, 3.91888e-10, 3.83069e-10])
3.8575509999999996e-10>>> var([3.75671e-10, 3.70535e-10, 3.9898e-10, 3.75885e-10, 3.78338e-10, 3.75745e-10, 3.78653e-10, 4.02996e-10, 3.91684e-10, 3.7777e-10])
1.1095435361000017e-22>>> var([3.8052e-10, 3.74567e-10, 3.98463e-10, 3.80442e-10, 3.83699e-10, 3.80214e-10, 3.83735e-10, 4.00954e-10, 3.91888e-10, 3.83069e-10])
6.5714590489999961e-23>>> 1.1095435361000017e-22/6.5714590489999961e-23
1.6884279850588815

My first (and only) idea was that subcktprobelvl could affect the random number generation; I had used the option savemismatchparams=yes to save the random parameters of all transistors, and compared them. They are equal.

$ diff level_0/monteCarlo/mismatchParam level_2/monteCarlo/mismatchParam
$ diff level_0/monteCarlo/mismatchData level_2/monteCarlo/mismatchData

At this point, I have no clue what is happening. Did I do anything wrong or miss any detail in how the netlist is set up? And (in general) how much can I trust the results?

Thank you very much in advance for your help!
Best regards,
Michael Weiner


Viewing all articles
Browse latest Browse all 4897

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>