• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC Design
  3. spectre: subcktprobelvl and the reliability of Monte-Carlo...

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 125
  • Views 14439
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

spectre: subcktprobelvl and the reliability of Monte-Carlo results

miwe
miwe over 7 years ago

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

  • Cancel
Parents
  • miwe
    miwe over 7 years ago

    Andrew,

    thank you for this explanation. Knowing that subcktprobelvl internally does affect the netlist, changes in the results now totally make sense.

    I repeated the simulation using 2000 iterations, and observed for my test circuit that

    • the means of the OCEAN results are always close to each other, the worst case deviation of approx. 1.4% occurs for delay_fallingoutput.
    • at first sight, the variances are sometimes bad (crossvoltage_fallingoutput: different by a factor of 21.2) and sometimes good (different by a factor of 0.86).

    The "bad" variance is not as bad as it sounds in a second thought: here, the standard deviation (computed as sqrt of variance) is several orders of magnitude smaller than the mean, so I would call it negligible in any case.

    Thank you again, I really feel now as if I have learned something. :-)

    - Michael

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • miwe
    miwe over 7 years ago

    Andrew,

    thank you for this explanation. Knowing that subcktprobelvl internally does affect the netlist, changes in the results now totally make sense.

    I repeated the simulation using 2000 iterations, and observed for my test circuit that

    • the means of the OCEAN results are always close to each other, the worst case deviation of approx. 1.4% occurs for delay_fallingoutput.
    • at first sight, the variances are sometimes bad (crossvoltage_fallingoutput: different by a factor of 21.2) and sometimes good (different by a factor of 0.86).

    The "bad" variance is not as bad as it sounds in a second thought: here, the standard deviation (computed as sqrt of variance) is several orders of magnitude smaller than the mean, so I would call it negligible in any case.

    Thank you again, I really feel now as if I have learned something. :-)

    - Michael

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information