summaryrefslogtreecommitdiff
path: root/Windows/spice/examples/Monte_Carlo
diff options
context:
space:
mode:
authorrahulp132020-03-03 05:31:58 +0530
committerrahulp132020-03-03 05:31:58 +0530
commitdfc268e0863c913a1b8726cd54eea3b40caf7c67 (patch)
tree1cd82634684da5ae86b558d44756189e080545d4 /Windows/spice/examples/Monte_Carlo
parentfd62c52150c7d1f81da8060b2f5db6b94d174ccf (diff)
downloadeSim-dfc268e0863c913a1b8726cd54eea3b40caf7c67.tar.gz
eSim-dfc268e0863c913a1b8726cd54eea3b40caf7c67.tar.bz2
eSim-dfc268e0863c913a1b8726cd54eea3b40caf7c67.zip
upgrade ngspice to v31
Diffstat (limited to 'Windows/spice/examples/Monte_Carlo')
-rw-r--r--Windows/spice/examples/Monte_Carlo/MC_2_control.sp22
-rw-r--r--Windows/spice/examples/Monte_Carlo/MC_ring.sp129
-rw-r--r--Windows/spice/examples/Monte_Carlo/MC_ring_ts.sp180
-rw-r--r--Windows/spice/examples/Monte_Carlo/MonteCarlo.sp16
-rw-r--r--Windows/spice/examples/Monte_Carlo/OpWien.sp8
-rw-r--r--Windows/spice/examples/Monte_Carlo/mc_ring_circ.net56
-rw-r--r--Windows/spice/examples/Monte_Carlo/mc_ring_lib_complete_actual.cir212
-rw-r--r--Windows/spice/examples/Monte_Carlo/rand_numb_test.cir40
8 files changed, 595 insertions, 68 deletions
diff --git a/Windows/spice/examples/Monte_Carlo/MC_2_control.sp b/Windows/spice/examples/Monte_Carlo/MC_2_control.sp
index 9b9f3606..d155c877 100644
--- a/Windows/spice/examples/Monte_Carlo/MC_2_control.sp
+++ b/Windows/spice/examples/Monte_Carlo/MC_2_control.sp
@@ -1,16 +1,16 @@
+*ng_script
* Perform Monte Carlo simulation in ngspice
* script for use with 25 stage Ring-Osc. BSIM3
* circuit is in MC_2_circ.sp
-* edit 'set sourcepath' for your path to circuit file
+* edit 'setcs sourcepath' for your path to circuit file
* start script by 'ngspice -o MC_2_control.log MC_2_control.sp'
*
.control
- save buf $ we just need output vector buf, save memory by more than 10x
- let mc_runs = 100 $ number of runs for monte carlo
- let run = 1 $ number of the actual run
+ let mc_runs = 10 $ number of runs for monte carlo
+ let run = 1 $ number of the actual run
* Where to find the circuit netlist file MC_2_circ.sp
- set sourcepath = ( D:\Spice_general\ngspice\examples\Monte_Carlo )
+ setcs sourcepath = ( D:\Spice_general\ngspice\examples\Monte_Carlo )
* create file for frequency information
echo Monte Carlo, frequency of R.O. > MC_frequ.log
@@ -19,10 +19,14 @@
dowhile run <= mc_runs
* without the reset switch there is some strange drift
* towards lower and lower frequencies
- reset
- set run ="$&run" $ create a variable from the vector
- set rndseed = $run $ set the rnd seed value to the loop index
- source MC_2_circ.sp $ load the circuit, including model data
+ set run = $&run $ create a variable from the vector
+ setseed $run $ set the rnd seed value to the loop index
+ if run = 1
+ source MC_2_circ.sp $ load the circuit once from file, including model data
+ else
+ mc_source $ re-load the circuit from internal storage
+ end
+ save buf $ we just need output vector buf, save memory by more than 10x
tran 15p 200n 0
write mc_ring{$run}.out buf $ write each sim output to its own rawfile
linearize buf $ lienarize buf to allow fft
diff --git a/Windows/spice/examples/Monte_Carlo/MC_ring.sp b/Windows/spice/examples/Monte_Carlo/MC_ring.sp
index 58e5c141..3ffab2a3 100644
--- a/Windows/spice/examples/Monte_Carlo/MC_ring.sp
+++ b/Windows/spice/examples/Monte_Carlo/MC_ring.sp
@@ -1,5 +1,9 @@
Perform Monte Carlo simulation in ngspice
-* 25 stage Ring-Osc. BSIM3
+* 25 stage Ring-Osc. BSIM3 with statistical variation of various model parameters
+* cd into ngspice/examples/Monte_Carlo
+* start in interactive mode 'ngspice MC_ring.sp' with several plots for output
+* or start in batch mode, controlled by .control section (Control mode)
+* with 'ngspice -b -r MC_ring.raw -o MC_ring.log MC_ring.sp'.
vin in out dc 0.5 pulse 0.5 0 0.1n 5n 1 1 1
vdd dd 0 dc 3.3
@@ -31,7 +35,7 @@ cout buf ss 0.2pF
.options noacct
.control
save buf $ we just need buf, save memory by more than 10x
- let mc_runs = 10 $ number of runs for monte carlo
+ let mc_runs = 30 $ number of runs for monte carlo
let run = 0 $ number of actual run
set curplot = new $ create a new plot
set curplottitle = "Transient outputs"
@@ -60,52 +64,64 @@ cout buf ss 0.2pF
* of the BSIM3 model for the NMOS and PMOS transistors.
* We may obtain the nominal values (nom) by manually extracting them from
* the parameter set. Here we get them automatically and store them into
-* variables. This has the advantage that you may change the parameter set
+* vectors. This has the advantage that you may change the parameter set
* without having to look up the values again.
- set n1vth0=@n1[vth0]
- set n1u0=@n1[u0]
- set n1tox=@n1[tox]
- set n1lint=@n1[lint]
- set n1wint=@n1[wint]
- set p1vth0=@p1[vth0]
- set p1u0=@p1[u0]
- set p1tox=@p1[tox]
- set p1lint=@p1[lint]
- set p1wint=@p1[wint]
+ let n1vth0=@n1[vth0]
+ let n1u0=@n1[u0]
+ let n1tox=@n1[tox]
+ let n1lint=@n1[lint]
+ let n1wint=@n1[wint]
+ let p1vth0=@p1[vth0]
+ let p1u0=@p1[u0]
+ let p1tox=@p1[tox]
+ let p1lint=@p1[lint]
+ let p1wint=@p1[wint]
+
*
* run the simulation loop
dowhile run <= mc_runs
- * without the reset switch there is some strange drift
- * towards lower and lower frequencies
- reset
* run=0 simulates with nominal parameters
if run > 0
- altermod @n1[vth0]=gauss($n1vth0, 0.1, 3)
- altermod @n1[u0]=gauss($n1u0, 0.05, 3)
- altermod @n1[tox]=gauss($n1tox, 0.1, 3)
- altermod @n1[lint]=gauss($n1lint, 0.1, 3)
- altermod @n1[wint]=gauss($n1wint, 0.1, 3)
- altermod @p1[vth0]=gauss($p1vth0, 0.1, 3)
- altermod @p1[u0]=gauss($p1u0, 0.1, 3)
- altermod @p1[tox]=gauss($p1tox, 0.1, 3)
- altermod @p1[lint]=gauss($p1lint, 0.1, 3)
- altermod @p1[wint]=gauss($p1wint, 0.1, 3)
+ setplot $max_fft
+ altermod @n1[vth0] = gauss(n1vth0, 0.1, 3)
+ altermod @n1[u0] = gauss(n1u0, 0.05, 3)
+ altermod @n1[tox] = gauss(n1tox, 0.1, 3)
+ altermod @n1[lint] = gauss(n1lint, 0.1, 3)
+ altermod @n1[wint] = gauss(n1wint, 0.1, 3)
+ altermod @p1[vth0] = gauss(p1vth0, 0.1, 3)
+ altermod @p1[u0] = gauss(p1u0, 0.1, 3)
+ altermod @p1[tox] = gauss(p1tox, 0.1, 3 )
+ altermod @p1[lint] = gauss(p1lint, 0.1, 3)
+ altermod @p1[wint] = gauss(p1wint, 0.1, 3)
end
- tran 15p 50n 0
-* select stop and step so that number of data points after linearization is not too
+ tran 15p 100n 0
+* select stop and step so that number of data points after linearization is not too
* close to 8192, which would yield varying number of line length and thus scale for fft.
*
* We have to figure out what to do if a single simulation will not converge.
-* Is there a variable which may be set if there is no convergence?
-* Then we might skip this run and continue with a new run. It does not exist for now.
-* So we have to rely on the robustness of the following steps not leading
-* to a seg fault if the tran data are missing.
+* There is the variable 'sim_status' which is set to 1 if the simulation
+* fails with ’xx simulation(s) aborted’, e.g. because of non-convergence.
+* Then we might skip this run and continue with a new run.
*
+ echo Simulation status $sim_status
+ let simstat = $sim_status
+ if simstat = 1
+ if run = mc_runs
+ echo go to end
+ else
+ echo go to next run
+ end
+ destroy $curplot
+ goto next
+ end
+
set run ="$&run" $ create a variable from the vector
set mc_runs ="$&mc_runs" $ create a variable from the vector
echo simulation run no. $run of $mc_runs
+ set dt = $curplot
* save the linearized data for having equal time scales for all runs
linearize buf $ linearize only buf, no other vectors needed
+ destroy $dt $ delete the tran i plot
set dt = $curplot $ store the current plot to dt (tran i+1)
setplot $plot_out $ make 'plt_out' the active plot
* firstly save the time scale once to become the default scale
@@ -115,11 +131,14 @@ cout buf ss 0.2pF
let vout{$run}={$dt}.buf $ store the output vector to plot 'plot_out'
setplot $dt $ go back to the previous plot (tran i+1)
fft buf $ run fft on vector buf
+ destroy $dt $ delete the tran i+1 plot
let buf2=db(mag(buf))
* find the frequency where buf has its maximum of the fft signal
meas sp fft_max MAX_AT buf2 from=0.1G to=0.7G
* find the frequency where buf is -40dB at rising fft signal
- meas sp fft_40 WHEN buf2=-40 RISE=1 from=0.1G to=0.7G
+ meas sp fft_40 WHEN buf2=-40 RISE=1 from=0.1G to=0.7G
+ echo
+ echo
* store the fft vector
set dt = $curplot $ store the current plot to dt (spec i)
setplot $plot_fft $ make 'plot_fft' the active plot
@@ -130,19 +149,26 @@ cout buf ss 0.2pF
* store the measured value
setplot $max_fft $ make 'max_fft' the active plot
let maxffts[{$run}]={$dt}.fft_max
- let halfffts[{$run}]={$dt}.fft_40
-* setplot $plot_out
-* The following command does not work here. Why not? Probably not a real copy.
-* destroy $dt $ save memory, we don't need this plot (spec) any more
- setplot $dt $ go back to the previous plot
+ let halfffts[{$run}]={$dt}.fft_40
let run = run + 1
+ label next
+ reset
end
***** plotting **********************************************************
-* plot {$plot_out}.allv
- plot {$plot_out}.vout0 $ just plot the tran output with nominal parameters
-* setplot $plot_fft
-* plot db(mag(ally)) xlimit .1G 1G ylimit -80 10
- plot db(mag({$plot_fft}.ally)) xlimit .1G 1G ylimit -80 10
+if $?batchmode
+ echo
+ echo Plotting not available in batch mode
+ echo Write linearized vout0 to vout{$mc_runs} to rawfile $rawfile
+ echo
+ write $rawfile {$plot_out}.allv
+ rusage
+ quit
+else
+ setplot $plot_out
+ plot vout0 ylabel 'RO output, original parameters' $ just plot the tran output with nominal parameters
+ setplot $plot_fft
+ settype decibel ally
+ plot db(mag(ally)) xlimit .1G 1G ylimit -80 10 ylabel 'fft output'
*
* create a histogram from vector maxffts
setplot $max_fft $ make 'max_fft' the active plot
@@ -158,7 +184,7 @@ cout buf ss 0.2pF
* put data into the correct bins
let run = 0
dowhile run < mc_runs
- set run = "$&run" $ create a variable from the vector
+ set run = $&run $ create a variable from the vector
let val = maxffts[{$run}]
let part = 0
* Check if val fits into a bin. If yes, raise bin by 1
@@ -171,13 +197,22 @@ cout buf ss 0.2pF
end
let run = run + 1
end
+
* plot the histogram
set plotstyle=combplot
- plot yvec-1 vs xvec $ subtract 1 because with started with unitvec containing ones
+ plot yvec-1 vs xvec xlabel 'oscillation frequency' ylabel 'bin count' $ subtract 1 because we started with unitvec containing ones
+
+ * plot simulation series
+ set plotstyle=linplot
+ let xx = vector(mc_runsp)
+ settype frequency maxffts
+ plot maxffts vs xx xlabel 'iteration no.' ylabel 'RO frequency'
+
* calculate jitter
let diff40 = (vecmax(halfffts) - vecmin(halfffts))*1e-6
echo
echo Max. jitter is "$&diff40" MHz
+end
rusage
.endc
********************************************************************************
@@ -193,11 +228,11 @@ cout buf ss 0.2pF
+k3b=2.233
+vsat=86301.58 ua=6.47e-9 ub=4.23e-18 uc=-4.706281e-11
+rdsw=650 u0=388.3203 wr=1
-+a0=.3496967 ags=.1 b0=0.546 b1=1
++a0=.3496967 ags=.1 b0=0.546 b1=1
+dwg=-6.0e-09 dwb=-3.56e-09 prwb=-.213
+keta=-3.605872e-02 a1=2.778747e-02 a2=.9
+voff=-6.735529e-02 nfactor=1.139926 cit=1.622527e-04
-+cdsc=-2.147181e-05
++cdsc=-2.147181e-05
+cdscb=0 dvt0w=0 dvt1w=0 dvt2w=0
+cdscd=0 prwg=0
+eta0=1.0281729e-02 etab=-5.042203e-03
diff --git a/Windows/spice/examples/Monte_Carlo/MC_ring_ts.sp b/Windows/spice/examples/Monte_Carlo/MC_ring_ts.sp
new file mode 100644
index 00000000..ee88c329
--- /dev/null
+++ b/Windows/spice/examples/Monte_Carlo/MC_ring_ts.sp
@@ -0,0 +1,180 @@
+*ng_script
+* Example script for Monte Carlo with commercial HSPICE-compatible libraries
+* The circuit in mc_ring_circ.net is a 25-stage inverter ring oscillator.
+* Add your library to mc_ring_circ.net and choose transistors accordingly.
+* Add the source file and the library path.
+* A simple BSIM3 inverter R.O. serves as an MC example wtihout need for a library.
+.control
+begin
+ let mc_runs = 30 $ number of runs for monte carlo
+ let run = 0 $ number of actual run
+ set curplot = new $ create a new plot
+ set curplottitle = "Transient outputs"
+ set plot_out = $curplot $ store its name to 'plot_out'
+ set curplot = new $ create a new plot
+ set curplottitle = "FFT outputs"
+ set plot_fft = $curplot $ store its name to 'plot_fft'
+ set curplot = new $ create a new plot
+ set curplottitle = "Oscillation frequency"
+ set max_fft = $curplot $ store its name to 'max_fft'
+ let mc_runsp = mc_runs + 1
+ let maxffts = unitvec(mc_runsp) $ vector for storing max measure results
+ let halfffts = unitvec(mc_runsp)$ vector for storing measure results at -40dB rising
+ unlet mc_runsp
+
+ set mc_runs = $&mc_runs $ create a variable from the vector
+ let seeds = mc_runs + 2
+ setseed $&seeds
+ unlet seeds
+
+ echo source the input file
+* Path of your circuit file and library file here
+* Will be added to the already existing sourcepath
+ setcs sourcepath = ( $inputdir $sourcepath ./ngspice/examples/Monte_Carlo )
+* source with file name of your circuit file
+ source mc_ring_circ.net
+
+ save buf $ we just need buf, save memory by more than 10x
+
+* Output path (directory has already to be there)
+* set outputpath = 'D:\Spice_general\ngspice\examples\Monte_Carlo\out'
+* If your current directory is the 'ngspice' directory
+* set outputpath = './examples/Monte_Carlo/out' $ LINUX alternative
+* run the simulation loop
+
+* We have to figure out what to do if a single simulation will not converge.
+* There is now the variable sim_status, that is 0 if simulation ended regularly,
+* and 1 if the simulation has been aborted with error message '...simulation(s) aborted'.
+* Then we skip the rest of the run and continue with a new run.
+
+ dowhile run <= mc_runs
+
+ set run = $&run $ create a variable from the vector
+
+ * run=0 simulates with nominal parameters
+ if run > 0
+ echo
+ echo * * * * * *
+ echo Source the circuit again internally for run no. $run
+ echo * * * * * *
+ setseed $run
+ mc_source $ re-source the input file
+ else
+ echo run no. $run
+ end
+ echo simulation run no. $run of $mc_runs
+ tran 100p 1000n 0
+ echo Simulation status $sim_status
+ let simstat = $sim_status
+ if simstat = 1
+ if run = mc_runs
+ echo go to end
+ else
+ echo go to next run
+ end
+ destroy $curplot
+ goto next
+ end
+
+* select stop and step so that number of data points after linearization is not too
+* close to 8192, which would yield varying number of line length and thus scale for fft.
+*
+ set dt0 = $curplot
+ * save the linearized data for having equal time scales for all runs
+ linearize buf $ linearize only buf, no other vectors needed
+ set dt1 = $curplot $ store the current plot to dt (tran i+1)
+ setplot $plot_out $ make 'plt_out' the active plot
+ * firstly save the time scale once to become the default scale
+ if run=0
+ let time={$dt1}.time
+ end
+ let vout{$run}={$dt1}.buf $ store the output vector to plot 'plot_out'
+ setplot $dt1 $ go back to the previous plot (tran i+1)
+ fft buf $ run fft on vector buf
+ let buf2=db(mag(buf))
+ * find the frequency where buf has its maximum of the fft signal
+ meas sp fft_max MAX_AT buf2 from=0.05G to=0.7G
+ * find the frequency where buf is -40dB at rising fft signal
+ meas sp fft_40 WHEN buf2=-40 RISE=1 from=0.05G to=0.7G
+ * store the fft vector
+ set dt2 = $curplot $ store the current plot to dt (spec i)
+ setplot $plot_fft $ make 'plot_fft' the active plot
+ if run=0
+ let frequency={$dt2}.frequency
+ end
+ let fft{$run}={$dt2}.buf $ store the output vector to plot 'plot_fft'
+ settype decibel fft{$run}
+ * store the measured value
+ setplot $max_fft $ make 'max_fft' the active plot
+ let maxffts[{$run}]={$dt2}.fft_max
+ let halfffts[{$run}]={$dt2}.fft_40
+ destroy $dt0 $dt1 $dt2 $ save memory, we don't need this plot (spec) any more
+
+ label next
+ remcirc
+ let run = run + 1
+ end
+***** plotting **********************************************************
+if $?batchmode
+ echo
+ echo Plotting not available in batch mode
+ echo Write linearized vout0 to vout{$mc_runs} to rawfile $rawfile
+ echo
+ write $rawfile {$plot_out}.allv
+ rusage
+ quit
+else
+ if $?sharedmode or $?win_console
+ gnuplot xnp_pl1 {$plot_out}.vout0 $ just plot the tran output with nominal parameters
+ else
+ plot {$plot_out}.vout0 $ just plot the tran output with nominal parameters
+ end
+ setplot $plot_fft
+ if $?sharedmode or $?win_console
+ gnuplot xnp_pl2 db(mag(ally)) xlimit 0 1G ylimit -80 10
+ else
+ plot db(mag(ally)) xlimit 0 1G ylimit -80 10
+ end
+*
+* create a histogram from vector maxffts
+ setplot $max_fft $ make 'max_fft' the active plot
+ set startfreq=50MEG
+ set bin_size=1MEG
+ set bin_count=100
+ compose osc_frequ start=$startfreq step=$bin_size lin=$bin_count $ requires variables as parameters
+ settype frequency osc_frequ
+ let bin_count=$bin_count $ create a vector from the variable
+ let yvec=unitvec(bin_count) $ requires vector as parameter
+ let startfreq=$startfreq
+ let bin_size=$bin_size
+ * put data into the correct bins
+ let run = 0
+ dowhile run < mc_runs
+ set run = $&run $ create a variable from the vector
+ let val = maxffts[{$run}]
+ let part = 0
+ * Check if val fits into a bin. If yes, raise bin by 1
+ dowhile part < bin_count
+ if ((val < (startfreq + (part+1)*bin_size)) & (val >= (startfreq + part*bin_size)))
+ let yvec[part] = yvec[part] + 1
+ break
+ end
+ let part = part + 1
+ end
+ let run = run + 1
+ end
+ * plot the histogram
+ let count = yvec - 1 $ subtract 1 because we started with unitvec containing ones
+ if $?sharedmode or $?win_console
+ gnuplot np_pl3 count vs osc_frequ combplot
+ else
+ plot count vs osc_frequ combplot
+ end
+* calculate jitter
+ let diff40 = (vecmax(halfffts) - vecmin(halfffts))*1e-6
+ echo
+ echo Max. jitter is "$&diff40" MHz
+end
+ rusage
+* quit
+end
diff --git a/Windows/spice/examples/Monte_Carlo/MonteCarlo.sp b/Windows/spice/examples/Monte_Carlo/MonteCarlo.sp
index 608dc4cf..e079893f 100644
--- a/Windows/spice/examples/Monte_Carlo/MonteCarlo.sp
+++ b/Windows/spice/examples/Monte_Carlo/MonteCarlo.sp
@@ -15,9 +15,9 @@ R2 0 OUT 141
let run = 0
set curplot=new $ create a new plot
set scratch=$curplot $ store its name to 'scratch'
- setplot $scratch $ make 'scratch' the active plot
+ setplot $scratch $ make 'scratch' the active plot
let bwh=unitvec(mc_runs) $ create a vector in plot 'scratch' to store bandwidth data
-
+
* define distributions for random numbers:
* unif: uniform distribution, deviation relativ to nominal value
* aunif: uniform distribution, deviation absolut
@@ -47,19 +47,19 @@ R2 0 OUT 141
alter c3 = limit(250e-12, 25e-12)
*
ac oct 100 250K 10Meg
-*
+*
* measure bandwidth at -10 dB
meas ac bw trig vdb(out) val=-10 rise=1 targ vdb(out) val=-10 fall=1
-*
- set run ="$&run" $ create a variable from the vector
+*
+ set run = $&run $ create a variable from the vector
set dt = $curplot $ store the current plot to dt
setplot $scratch $ make 'scratch' the active plot
let vout{$run}={$dt}.v(out) $ store the output vector to plot 'scratch'
- let bwh[run]={$dt}.bw $ store bw to vector bwh in plot 'scratch'
+ let bwh[run]={$dt}.bw $ store bw to vector bwh in plot 'scratch'
setplot $dt $ go back to the previous plot
- let run = run + 1
+ let run = run + 1
end $ loop ends here
-*
+*
plot db({$scratch}.allv)
echo
print {$scratch}.bwh
diff --git a/Windows/spice/examples/Monte_Carlo/OpWien.sp b/Windows/spice/examples/Monte_Carlo/OpWien.sp
index 91b45d08..b6ada544 100644
--- a/Windows/spice/examples/Monte_Carlo/OpWien.sp
+++ b/Windows/spice/examples/Monte_Carlo/OpWien.sp
@@ -17,18 +17,18 @@ OPWIEN.CIR - OPAMP WIEN-BRIDGE OSCILLATOR
IS 0 3 dc 0 PWL(0US 0MA 10US 0.1MA 40US 0.1MA 50US 0MA 10MS 0MA)
*
* RC TUNING
-VR2 r2 0 dc 0 trrandom (2 'ttime10' 0 1) $ Gauss controlling voltage
+VR2 r2 0 dc 0 trrandom (2 'ttime10' 0 1) ; Gauss controlling voltage
*
-*VR2 r2 0 dc 0 trrandom (1 'ttime10' 0 3) $ Uniform within -3 3
+*VR2 r2 0 dc 0 trrandom (1 'ttime10' 0 3) ; Uniform within -3 3
*
* If Gauss, factor 0.033 is 10% equivalent to 3 sigma
* if uniform, uniform between +/- 10%
-R2 4 6 R = 'res + 0.033 * res*V(r2)' $ behavioral resistor
+R2 4 6 R = 'res + 0.033 * res*V(r2)' ; behavioral resistor
*R2 4 6 'res' $ constant R
VC2 c2 0 dc 0 trrandom (2 'ttime10' 0 1)
*C2 6 3'cn' $ constant C
-C2 6 3 C = 'cn + 0.033 * cn*V(c2)' $ behavioral capacitor
+C2 6 3 C = 'cn + 0.033 * cn*V(c2)' ; behavioral capacitor
VR1 r1 0 dc 0 trrandom (2 'ttime10' 0 1)
*VR1 r1 0 dc 0 trrandom (1 'ttime10' 0 3)
diff --git a/Windows/spice/examples/Monte_Carlo/mc_ring_circ.net b/Windows/spice/examples/Monte_Carlo/mc_ring_circ.net
new file mode 100644
index 00000000..cd058a5e
--- /dev/null
+++ b/Windows/spice/examples/Monte_Carlo/mc_ring_circ.net
@@ -0,0 +1,56 @@
+Perform Monte Carlo simulation in ngspice
+* 25 stage Ring-Osc. BSIM3 or 4 with statistical variation of model parameters
+* Model parameters are varied according to the PDK selection.
+* Tested with 3 different commercial HSPICE libraries from 2 vendors.
+* To be started with script MC_ring_ts.sp
+
+.options noacct seedinfo
+
+vin in out dc 0.5 pulse 0.5 0 0.1n 5n 1 1 1
+vdd dd 0 dc 3.3
+vss ss 0 dc 0
+ve sub 0 dc 0
+vpe well 0 dc 3.3
+
+* transistors to be selected according to the library (here: p33ll and n33ll or pch_5_mac and nch_5_mac
+* or pe3 and ne3 or p1 and n1 (these models see below))
+.subckt inv1 dd ss sub well in out
+*XMP1 out in dd well p33ll w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+*XMN1 out in ss sub n33ll w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+*XMP1 out in dd well pch_5_mac w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+*XMN1 out in ss sub nch_5_mac w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+*XMP1 out in dd well pe3 w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+*XMN1 out in ss sub ne3 w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+MP1 out in dd well p1 w=5u l=800n m=3 ad=1.35p as=1.35p pd=9.6u ps=9.6u
+MN1 out in ss sub n1 w=5u l=800n m=1 ad=0.9p as=0.9p pd=6.6u ps=6.6u
+.ends inv1
+
+.subckt inv5 dd ss sub well in out
+xinv1 dd ss sub well in 1 inv1
+xinv2 dd ss sub well 1 2 inv1
+xinv3 dd ss sub well 2 3 inv1
+xinv4 dd ss sub well 3 4 inv1
+xinv5 dd ss sub well 4 out inv1
+.ends inv5
+
+xinv1 dd ss sub well in out5 inv5
+xinv2 dd ss sub well out5 out10 inv5
+xinv3 dd ss sub well out10 out15 inv5
+xinv4 dd ss sub well out15 out20 inv5
+xinv5 dd ss sub well out20 out inv5
+xinv11 dd 0 sub well out buf inv1
+cout buf ss 0.2pF
+
+ *** Model library files.
+* Add your library here
+* Chose the transistors for XMP1 and XMN1 accordingly
+*.lib "jc_usage.l" MC_LIB
+*.lib "my_ts_usage.l" MC_LIB
+*.lib "x_usage.l" MC_LIB
+
+* or use the BSIM3 model with internal parameters except Vth0
+* that varies the threshold voltage +-3 sigma around a mean of +-0.6V
+.model p1 PMOS version=3.3.0 Level=8 Vth0=agauss(-0.6, 0.1, 3)
+.model n1 NMOS version=3.3.0 Level=8 Vth0=agauss(0.6, 0.1, 3)
+
+.end
diff --git a/Windows/spice/examples/Monte_Carlo/mc_ring_lib_complete_actual.cir b/Windows/spice/examples/Monte_Carlo/mc_ring_lib_complete_actual.cir
new file mode 100644
index 00000000..9fd239e4
--- /dev/null
+++ b/Windows/spice/examples/Monte_Carlo/mc_ring_lib_complete_actual.cir
@@ -0,0 +1,212 @@
+Perform Monte Carlo simulation in ngspice
+* 25 stage Ring-Osc. BSIM3 or 4 with statistical variation of model parameters
+* Model parameters are varied according to the PDK selection.
+* Tested with 3 different commercial HSPICE libraries from 2 vendors.
+* Add your library to mc_ring_circ.net and choose transistors accordingly.
+* Add the library path to the .LIB statement.
+* A simple BSIM3 inverter R.O. serves as an MC example.
+
+.options noacct
+
+vin in out dc 0.5 pulse 0.5 0 0.1n 5n 1 1 1
+vdd dd 0 dc 3.3
+vss ss 0 dc 0
+ve sub 0 dc 0
+vpe well 0 dc 3.3
+
+* transistors to be selected according to the library (here: p33ll and n33ll or pch_5_mac and nch_5_mac
+* or pe3 and ne3 or p1 and n1 (these models see below))
+.subckt inv1 dd ss sub well in out
+*XMP1 out in dd well p33ll w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+*XMN1 out in ss sub n33ll w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+XMP1 out in dd well pch_5_mac w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+XMN1 out in ss sub nch_5_mac w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+*XMP1 out in dd well pe3 w=5u l=800n m=3 nf=1 ad=1.35p as=1.35p pd=9.6u ps=9.6u mosmis_mod=1
+*XMN1 out in ss sub ne3 w=5u l=800n m=1 nf=3 ad=0.9p as=0.9p pd=6.6u ps=6.6u mosmis_mod=1
+*MP1 out in dd well p1 w=5u l=800n m=3 ad=1.35p as=1.35p pd=9.6u ps=9.6u
+*MN1 out in ss sub n1 w=5u l=800n m=1 ad=0.9p as=0.9p pd=6.6u ps=6.6u
+.ends inv1
+
+.subckt inv5 dd ss sub well in out
+xinv1 dd ss sub well in 1 inv1
+xinv2 dd ss sub well 1 2 inv1
+xinv3 dd ss sub well 2 3 inv1
+xinv4 dd ss sub well 3 4 inv1
+xinv5 dd ss sub well 4 out inv1
+.ends inv5
+
+xinv1 dd ss sub well in out5 inv5
+xinv2 dd ss sub well out5 out10 inv5
+xinv3 dd ss sub well out10 out15 inv5
+xinv4 dd ss sub well out15 out20 inv5
+xinv5 dd ss sub well out20 out inv5
+xinv11 dd 0 sub well out buf inv1
+cout buf ss 0.2pF
+
+ *** Model library files.
+* Add your library here (full path required, or path relative to path
+* of ngspice executable (interactive mode), or relative to path of
+* input file (batch mode))
+* Chose the transistors for XMP1 and XMN1 according to the library
+*.lib "jc_usage.l" MC_LIB
+*.lib "../../../various/lib-test/my_usage.l" MC_LIB
+.lib "D:\Spice_general\tests\lib-test\ts14\my_ts_usage.l" MC_LIB
+*.lib "x_usage.l" MC_LIB
+
+* or use the BSIM3 model with internal parameters except Vth0
+* that varies the threshold voltage +-3 sigma around a mean of +-0.6V
+*.model p1 PMOS version=3.3.0 Level=8 Vth0=agauss(-0.6, 0.1, 3)
+*.model n1 NMOS version=3.3.0 Level=8 Vth0=agauss(0.6, 0.1, 3)
+
+.control
+ let mc_runs = 10 $ number of runs for monte carlo
+ let run = 0 $ number of actual run
+ set curplot = new $ create a new plot
+ set curplottitle = "Transient outputs"
+ set plot_out = $curplot $ store its name to 'plot_out'
+ set curplot = new $ create a new plot
+ set curplottitle = "FFT outputs"
+ set plot_fft = $curplot $ store its name to 'plot_fft'
+ set curplot = new $ create a new plot
+ set curplottitle = "Oscillation frequency"
+ set max_fft = $curplot $ store its name to 'max_fft'
+ let mc_runsp = mc_runs + 1
+ let maxffts = unitvec(mc_runsp) $ vector for storing max measure results
+ let halfffts = unitvec(mc_runsp)$ vector for storing measure results at -40dB rising
+ unlet mc_runsp
+
+ set mc_runs = $&mc_runs $ create a variable from the vector
+ let seeds = mc_runs + 2
+ setseed $&seeds
+ unlet seeds
+
+ save buf $ we just need buf, save memory by more than 10x
+
+* run the simulation loop
+
+* We have to figure out what to do if a single simulation will not converge.
+* There is now the variable sim_status, that is 0 if simulation ended regularly,
+* and 1 if the simulation has been aborted with error message '...simulation(s) aborted'.
+* Then we skip the rest of the run and continue with a new run.
+
+ dowhile run <= mc_runs
+
+ set run = $&run $ create a variable from the vector
+
+ * run=0 simulates with nominal parameters
+ if run > 0
+ echo
+ echo * * * * * *
+ echo Source the circuit again internally for run no. $run
+ echo * * * * * *
+ setseed $run
+ mc_source $ re-source the input file
+ else
+ echo run no. $run
+ end
+ echo simulation run no. $run of $mc_runs
+ tran 100p 1000n 0
+ echo Simulation status $sim_status
+ let simstat = $sim_status
+ if simstat = 1
+ if run = mc_runs
+ echo go to end
+ else
+ echo go to next run
+ end
+ destroy $curplot
+ goto next
+ end
+
+* select stop and step so that number of data points after linearization is not too
+* close to 8192, which would yield varying number of line length and thus scale for fft.
+*
+ set dt0 = $curplot
+ * save the linearized data for having equal time scales for all runs
+ linearize buf $ linearize only buf, no other vectors needed
+ set dt1 = $curplot $ store the current plot to dt (tran i+1)
+ setplot $plot_out $ make 'plt_out' the active plot
+ * firstly save the time scale once to become the default scale
+ if run=0
+ let time={$dt1}.time
+ end
+ let vout{$run}={$dt1}.buf $ store the output vector to plot 'plot_out'
+ setplot $dt1 $ go back to the previous plot (tran i+1)
+ fft buf $ run fft on vector buf
+ let buf2=db(mag(buf))
+ * find the frequency where buf has its maximum of the fft signal
+ meas sp fft_max MAX_AT buf2 from=0.05G to=0.7G
+ * find the frequency where buf is -40dB at rising fft signal
+ meas sp fft_40 WHEN buf2=-40 RISE=1 from=0.05G to=0.7G
+ * store the fft vector
+ set dt2 = $curplot $ store the current plot to dt (spec i)
+ setplot $plot_fft $ make 'plot_fft' the active plot
+ if run=0
+ let frequency={$dt2}.frequency
+ end
+ let fft{$run}={$dt2}.buf $ store the output vector to plot 'plot_fft'
+ * store the measured value
+ setplot $max_fft $ make 'max_fft' the active plot
+ let maxffts[{$run}]={$dt2}.fft_max
+ let halfffts[{$run}]={$dt2}.fft_40
+ destroy $dt0 $dt1 $dt2 $ save memory, we don't need this plot (spec) any more
+
+ label next
+ remcirc
+ let run = run + 1
+ end
+***** plotting **********************************************************
+if $?batchmode
+ echo
+ echo Plotting not available in batch mode
+ echo Write linearized vout0 to vout{$mc_runs} to rawfile $rawfile
+ echo
+ write $rawfile {$plot_out}.allv
+ rusage
+ quit
+else
+ plot {$plot_out}.vout0 $ just plot the tran output with run 0 parameters
+ setplot $plot_fft
+ plot db(mag(ally)) xlimit 0 1G ylimit -80 10
+*
+* create a histogram from vector maxffts
+ setplot $max_fft $ make 'max_fft' the active plot
+ set startfreq=50MEG
+ set bin_size=1MEG
+ set bin_count=100
+ compose osc_frequ start=$startfreq step=$bin_size lin=$bin_count $ requires variables as parameters
+ settype frequency osc_frequ
+ let bin_count=$bin_count $ create a vector from the variable
+ let yvec=unitvec(bin_count) $ requires vector as parameter
+ let startfreq=$startfreq
+ let bin_size=$bin_size
+ * put data into the correct bins
+ let run = 0
+ dowhile run < mc_runs
+ set run = $&run $ create a variable from the vector
+ let val = maxffts[{$run}]
+ let part = 0
+ * Check if val fits into a bin. If yes, raise bin by 1
+ dowhile part < bin_count
+ if ((val < (startfreq + (part+1)*bin_size)) & (val > (startfreq + part*bin_size)))
+ let yvec[part] = yvec[part] + 1
+ break
+ end
+ let part = part + 1
+ end
+ let run = run + 1
+ end
+ * plot the histogram
+ set plotstyle=combplot
+ let counts = yvec - 1 $ subtract 1 because we started with unitvec containing ones
+ plot counts vs osc_frequ
+* calculate jitter
+ let diff40 = (vecmax(halfffts) - vecmin(halfffts))*1e-6
+ echo
+ echo Max. jitter is "$&diff40" MHz
+end
+ rusage
+* quit
+.endc
+
+.end
diff --git a/Windows/spice/examples/Monte_Carlo/rand_numb_test.cir b/Windows/spice/examples/Monte_Carlo/rand_numb_test.cir
new file mode 100644
index 00000000..dac4b5b6
--- /dev/null
+++ b/Windows/spice/examples/Monte_Carlo/rand_numb_test.cir
@@ -0,0 +1,40 @@
+*** random number test for scope-inpcom-8
+
+*** Start value of seed for random number generator: variable 'rndseed' is set to 1
+*** and random number generator is seeded with this value.
+*** You may override this value by adding 'setseed 5' or similar to file .spiceinit.
+
+*** print a message when the random number generator gets a new seed
+.option seedinfo
+
+*** like HSPICE: set rndseed to (number of seconds since 1.1.1970 - 1470000000)
+*** and seed the random number generator with rndseed
+*.option seed = random
+
+*** like HSPICE: set rndseed to 55
+*** and seed the random number generator with rndseed (here 55)
+.option seed = 55
+
+*** the 'circuit'
+.param myval = agauss(0, 1, 1)
+v1 1 0 'myval'
+
+*** the .control script
+.control
+
+*** set variable rndseed to value 11
+*set rndseed = 11
+*** seed the random number generator with value from variable rndseed
+*setseed
+
+*** seed the random number generator with value 12 and set rndseed to 12
+setseed 12
+
+*** reload circuit and re-evaluate all random functions (agauss etc.)
+mc_source
+*** simulate and print result
+op
+print v(1)
+.endc
+
+.end