Search code examples
simulationmontecarlodigital-design

NGSpice Monte Marlo analysis, how to pass the parameters to the sub-circuit?


Question:

How to pass the modified device model parameters (such as W, L, Tox) to the sub-circuit during Monte Carlo iterations loop?

Tool version:

[boris@E7440 inverter]$ ngspice -v
ngspice compiled from ngspice revision 23
Written originally by Berkeley University
Currently maintained by the NGSpice Project

Copyright (C) 1985-1996,  The Regents of the University of California
Copyright (C) 1999-2008,  The NGSpice Project
[boris@E7440 inverter]$ uname -a
Linux E7440.DELL 4.4.13-200.fc22.x86_64 #1 SMP Wed Jun 8 15:59:40 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
[boris@E7440 inverter]$ 

Test-case:

Here is a small standalone test-case that demonstrates the problem; performing Monte Carlo analysis on a simple inverter gate by varying the width and length of the transistor channel.

SPICE3 file

.GLOBAL VDD VBP
V0DD VDD 0 1.1
V0BP VBP 0 1.1
.GLOBAL VSS VBN
V0SS VSS 0 0.0
V0BN VBN 0 0.0

X1 VDD VSS VBP VBN X A INV1

V1 A 0 DC 0 PWL( 2501.80p 1.10 2503.02p 1.10 2504.24p 1.10 2505.46p 1.10 2506.68p 1.10 2507.90p 1.09 2509.12p 1.09 2510.34p 1.09 2511.56p 1.09 2512.78p 1.08 2514.00p 1.07 2515.22p 1.06 2516.44p 1.05 2517.66p 1.03 2518.88p 1.01 2520.10p 0.98 2521.32p 0.94 2522.54p 0.88 2523.76p 0.79 2524.98p 0.67 2526.20p 0.55 2527.42p 0.43 2528.64p 0.31 2529.86p 0.22 2531.08p 0.16 2532.30p 0.12 2533.52p 0.09 2534.74p 0.07 2535.96p 0.05 2537.18p 0.04 2538.40p 0.03 2539.62p 0.02 2540.84p 0.01 2542.06p 0.01 2543.28p 0.01 2544.50p 0.01 2545.72p 0.00 2546.94p 0.00 2548.16p 0.00 2549.38p 0.00 2550.60p 0.00 )
C1 X 0 12.3f

.OPTIONS NOACCT

.control
    save A X
    let mc_runs = 25
    let run = 0
    set curplot = new
    set plot_out = $curplot

    define unif(nom, var) (nom + (nom*var) * sunif(0))
    define aunif(nom, avar) (nom + avar * sunif(0))
    define gauss(nom, var, sig) (nom + (nom*var)/sig * sgauss(0))
    define agauss(nom, avar, sig) (nom + avar/sig * sgauss(0))

    dowhile run <= mc_runs
        alter @M1[W] = gauss(0.72u, 0.1, 3)
        alter @M1[L] = gauss(0.18u, 0.1, 3)
        alter @M2[W] = gauss(0.36u, 0.1, 3)
        alter @M2[L] = gauss(0.18u, 0.1, 3)

        tran 3p 3n 2n

        set run ="$&run"
        print run

        linearize A X
        set plot_tmp = $curplot
        setplot $plot_out
        if run=0
            let time={$plot_tmp}.time
            let vin={$plot_tmp}.A
        end
        let vout{$run}={$plot_tmp}.X
        setplot $plot_tmp
        let run = run + 1
    end
    plot {$plot_out}.allv
.endc

.END

.MODEL NFET NMOS(LEVEL=14 VERSION=4.6.5)
.MODEL PFET PMOS(LEVEL=14 VERSION=4.6.5)

.SUBCKT INV1 VDD VSS VBP VBN X A
M1 X A VDD VBP pfet W=0.72u L=0.18u AD=3.6p PD=2.34p AS=3.6p PS=2.34p
M2 X A VSS VBN nfet W=0.36u L=0.18u AD=1.8p PD=1.62p AS=1.8p PS=1.62p
.ENDS

The SPICE output is following:

[boris@E7440 inverter]$ ngspice simulate_mc2.sp
******
** ngspice-23 : Circuit level simulation program
** The U. C. Berkeley CAD Group
** Copyright 1985-1994, Regents of the University of California.
** Please get your ngspice manual from http://ngspice.sourceforge.net/docs.html
** Please file your bug-reports at http://ngspice.sourceforge.net/bugrep.html
** Creation Date: Tue Jul  8 03:06:23 UTC 2014
******

Circuit: simulation file

Error: no such device or model name m1
Error: no such device or model name m1
Error: no such device or model name m2
Error: no such device or model name m2
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 0.000000e+00
Error: no such device or model name m1
Error: no such device or model name m1
Error: no such device or model name m2
Error: no such device or model name m2
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 1.000000e+00
Error: no such device or model name m1
Error: no such device or model name m1
Error: no such device or model name m2
Error: no such device or model name m2
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 2.000000e+00
Error: no such device or model name m1
Error: no such device or model name m1
Error: no such device or model name m2
Error: no such device or model name m2
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00nce value :  2.55551e-09

No. of Data Rows : 501
run = 3.000000e+00

Obviously something goes wrong with passing the parameters to the sub-circuit. I have also tried the following syntax variations:

alter X1.@M1[W] = gauss(0.72u, 0.1, 3)
alter X1:@M1[W] = gauss(0.72u, 0.1, 3)
alter X1/@M1[W] = gauss(0.72u, 0.1, 3)
alter @X1.M1[W] = gauss(0.72u, 0.1, 3)
alter @X1:M1[W] = gauss(0.72u, 0.1, 3)
alter @X1/M1[W] = gauss(0.72u, 0.1, 3)
alter @X1.@M1[W] = gauss(0.72u, 0.1, 3)
alter @X1:@M1[W] = gauss(0.72u, 0.1, 3)
alter @X1/@M1[W] = gauss(0.72u, 0.1, 3)
alter @X1[M1[W]] = gauss(0.72u, 0.1, 3)
alter @X1(M1[W]) = gauss(0.72u, 0.1, 3)
alter @X1{M1[W]} = gauss(0.72u, 0.1, 3)

Nothing works...


By the way, when I move the sub-circuit content within the main netlist, simulation works fine...

Example:

SPICE3 file

.GLOBAL VDD VBP
V0DD VDD 0 1.1
V0BP VBP 0 1.1
.GLOBAL VSS VBN
V0SS VSS 0 0.0
V0BN VBN 0 0.0

M1 X A VDD VBP pfet W=0.72u L=0.18u AD=3.6p PD=2.34p AS=3.6p PS=2.34p
M2 X A VSS VBN nfet W=0.36u L=0.18u AD=1.8p PD=1.62p AS=1.8p PS=1.62p

V1 A 0 DC 0 PWL( 2501.80p 1.10 2503.02p 1.10 2504.24p 1.10 2505.46p 1.10 2506.68p 1.10 2507.90p 1.09 2509.12p 1.09 2510.34p 1.09 2511.56p 1.09 2512.78p 1.08 2514.00p 1.07 2515.22p 1.06 2516.44p 1.05 2517.66p 1.03 2518.88p 1.01 2520.10p 0.98 2521.32p 0.94 2522.54p 0.88 2523.76p 0.79 2524.98p 0.67 2526.20p 0.55 2527.42p 0.43 2528.64p 0.31 2529.86p 0.22 2531.08p 0.16 2532.30p 0.12 2533.52p 0.09 2534.74p 0.07 2535.96p 0.05 2537.18p 0.04 2538.40p 0.03 2539.62p 0.02 2540.84p 0.01 2542.06p 0.01 2543.28p 0.01 2544.50p 0.01 2545.72p 0.00 2546.94p 0.00 2548.16p 0.00 2549.38p 0.00 2550.60p 0.00 )
C1 X 0 12.3f

.OPTIONS NOACCT

.control
    save A X
    let mc_runs = 5
    let run = 0
    set curplot = new
    set plot_out = $curplot

    define unif(nom, var) (nom + (nom*var) * sunif(0))
    define aunif(nom, avar) (nom + avar * sunif(0))
    define gauss(nom, var, sig) (nom + (nom*var)/sig * sgauss(0))
    define agauss(nom, avar, sig) (nom + avar/sig * sgauss(0))

    dowhile run <= mc_runs
        alter @M1[W] = gauss(0.72u, 0.1, 3)
        alter @M1[L] = gauss(0.18u, 0.1, 3)
        alter @M2[W] = gauss(0.36u, 0.1, 3)
        alter @M2[L] = gauss(0.18u, 0.1, 3)

        tran 3p 3n 2n

        set run ="$&run"
        print run

        linearize A X
        set plot_tmp = $curplot
        setplot $plot_out
        if run=0
            let time={$plot_tmp}.time
            let vin={$plot_tmp}.A
        end
        let vout{$run}={$plot_tmp}.X
        setplot $plot_tmp
        let run = run + 1
    end
    plot {$plot_out}.allv
.endc

.END

.MODEL NFET NMOS(LEVEL=14 VERSION=4.6.5)
.MODEL PFET PMOS(LEVEL=14 VERSION=4.6.5)

Result:

[boris@E7440 inverter]$ ngspice simulate_mc1.sp
******
** ngspice-23 : Circuit level simulation program
** The U. C. Berkeley CAD Group
** Copyright 1985-1994, Regents of the University of California.
** Please get your ngspice manual from http://ngspice.sourceforge.net/docs.html
** Please file your bug-reports at http://ngspice.sourceforge.net/bugrep.html
** Creation Date: Tue Jul  8 03:06:23 UTC 2014
******

Circuit: simulation file

Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 0.000000e+00
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 1.000000e+00
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00

No. of Data Rows : 501
run = 2.000000e+00
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

OpenMP: 2 threads are requested in BSIM4
%100.00nce value :  2.52249e-09

No. of Data Rows : 501
run = 3.000000e+00

However, this is not a practical solution. I would like to simulate other cells too, but copy pasting the contents of different sub-circuits into the main netlist is cumbersome and error prone.


Solution

  • May I recommend the ngspice discussion forums for posting such question? A much faster answer would have been available, not just by chance as has happened here.

    After running your input file interactively, give the command 'listing expand', and you will see what the circuit structure looks like after subcircuit expansion.

    m1 has becom m.x1.m1, m2 has become m.x1.m2. The alter command acts on the expanded circuit. Therefore, by replacing m1 by m.x1.m1 and m2 by m.x1.m2 in the alter statements you will get a suitable result.

    Holger