diff options
Diffstat (limited to 'Windows/spice/share/ngspice/scripts/spectrum')
-rw-r--r-- | Windows/spice/share/ngspice/scripts/spectrum | 165 |
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 |