summaryrefslogtreecommitdiff
path: root/Windows/spice/share/ngspice/scripts/spectrum
diff options
context:
space:
mode:
Diffstat (limited to 'Windows/spice/share/ngspice/scripts/spectrum')
-rw-r--r--Windows/spice/share/ngspice/scripts/spectrum165
1 files changed, 165 insertions, 0 deletions
diff --git a/Windows/spice/share/ngspice/scripts/spectrum b/Windows/spice/share/ngspice/scripts/spectrum
new file mode 100644
index 00000000..3e394432
--- /dev/null
+++ b/Windows/spice/share/ngspice/scripts/spectrum
@@ -0,0 +1,165 @@
+* Fourier Series Function for SPICE
+* This script is offered here for learning purposes, even if it is outdated
+* and superseeded by the spec function and especially by the much faster fft function.
+* You may use this script in conjunction with e.g. a ringoscillator output (see
+* the ngspice manual, chapter 17).
+
+.control
+ begin
+
+* Variable argc delivers the number of command line parameters given by the user
+* after the 'spectrum' command
+ if ($argc lt 4)
+ echo Error: Too few arguments.
+ echo ' 'Spectrum produces a plot containing a fourier series transformation of
+ echo ' 'the specified vectors
+ echo usage: spectrum startfreq stop step vec [[vec] ...]
+ goto bottom
+ end
+
+* Check if vectors 'time' and any input vector(s) are available
+* argv[n] delivers the command line entries after the 'spectrum' command,
+* starting with argv[1]. $argv[4-len] delivers the value of all tokens,
+* starting with postion 4 till the end of the command line
+ if ( time eq time )
+ foreach vec $argv[4-len]
+ if ( $vec eq $vec )
+ else
+ goto bottom
+ end
+ end
+ else
+ echo ' 'Spectrum can not work without a time vector from a transient analysis.
+ goto bottom
+ end
+
+ * generate a new plot entitled 'scratch', which will hold intermediate
+ * results and will be discarded after their evaluation.
+ set dt=$curplot
+ set title=$curplottitle
+ set curplot=new
+ set scratch=$curplot
+
+ * A vector 'span' is created in the 'scratch' plot to hold the time difference
+ * of the transient simulation. {$dt}.time allows to access the 'time' vector
+ * from the dt plot (which is normally named 'tranx' with x a consecutoive
+ * integer number, depending on the amount of transient simulations already run
+ * in the present job.
+ let span={$dt}.time[length({$dt}.time)-1]-{$dt}.time[0]
+
+* Calculate the number of steps in all of the spectra to be evaluated below
+ if ($argv[3] gt 0.999/span)
+ let fpoints= ( $argv[2] - $argv[1] ) / $argv[3] +1
+ if (fpoints < 2)
+ echo frequency start stop or step not correctly specified
+ goto reset
+ end
+ else
+ echo Error: time span is not long enough for a step frequency of $argv[3] Hz
+ goto reset
+ end
+ let lent = length({$dt}.time)
+ set lent = "$&lent"
+ let nyquist = {$lent}/2/span
+ if ($argv[2] gt nyquist)
+ echo Error: The nyquist limit is exceeded, try a frequency less than "$&nyquist" Hz
+ goto reset
+ end
+ set fpoints="$&fpoints"
+
+ * generate a new plot to hold the spectra
+ set curplot=new
+ set spec=$curplot
+ set curplottitle=$title
+ set curplotname='Spectrum Analysis'
+
+* argv[3] is the third agrgument from the input line
+* spectrum 1 1000MEG 10MEG v(out25)
+* that is the delta frequency
+* The fcn vector(n) creates a vector of length n, its elements have
+* the values 0, 1, 2, 3, ..., n-2, n-1. Each element then is multiplied
+* with the frequency step value.
+ let frequency=vector( $fpoints )*$argv[3]
+
+* Add an frequency offset to each element of vector 'frequency'
+* to suppress the (typically) large dc component.
+ dowhile frequency[1] < ( $argv[1] + 1e-9 )
+ let frequency = frequency + $argv[3]
+ end
+
+* For each input vector given on the command line,
+* create a new vector for complex numbers
+ foreach vec $argv[4-len]
+ let $vec = vector( $fpoints ) + j(vector( $fpoints ))
+ reshape $vec [{$fpoints}]
+ end
+
+* $scratch is a plot for intermediate results, will be destroyed during cleanup
+* $dt is the plot with the original data
+* $spec is a plot for storing the spectrum
+ set curplot=$scratch
+
+ * some test
+ let npers=1
+ let test = span-2/$argv[3] + 1e-9
+ while test > 0
+ let npers = npers + 1
+ let test = test-1/$argv[3]
+ end
+
+ * Do the spectrum calculations
+ let ircle = 2*pi*max(-1,({$dt}.time-{$dt}.time[{$lent}-1])*{$argv[3]}/npers)
+ let win = 1 - cos(ircle)
+ let ircle = npers*ircle
+ let circle = ircle * ({$spec}.frequency[0]/$argv[3] - 1)
+ let k=vector( $fpoints )
+ foreach k $&k
+ let circle = circle + ircle
+ foreach vec $argv[4-len]
+ let tmp = win*{$dt}.{$vec}
+ let {$spec}.{$vec}[{$k}] = 2*(mean(cos(circle)*tmp),mean(sin(circle)*tmp))
+ end
+ end
+
+* plot (and write) the generated spectrum
+ set curplot = $spec
+ settype frequency frequency
+ foreach vec $argv[4-len]
+ let spectrum = mag({$vec})
+ plot spectrum
+ write specout.out spectrum
+ end
+
+* If you have an oscillator, fimd its frequency
+* as maximum of vector spectrum or goto end (uncomment next line)
+* goto cleanup
+ set curplot=$scratch
+ let counter = 0
+ let contents = 0
+ let freqmax = 0
+ let spectrum = {$spec}.spectrum
+
+ foreach spectrum $&spectrum
+ if counter > 4
+ if ( contents < $spectrum )
+ let contents = $spectrum
+ set count = "$&counter"
+ let freqmax = {$spec}.frequency[{$count}]
+ end
+ end
+ let counter = counter + 1
+ end
+
+ echo
+ echo Osc. frequency at "$&freqmax" Hz
+ echo
+ goto cleanup
+
+ label reset
+ set curplot=$dt
+ label cleanup
+ destroy $scratch
+ unset fpoints dt scratch spec vec k title lent
+ label bottom
+
+ end