Create abConcatWaveforms.il file:
/* abConcatWaveforms.ilwrite also DrawNyquistPlot function
Author A.D.Beckett
Group Custom IC (UK), Cadence Design Systems Ltd.
Language SKILL
Date Jan 08, 2009
Modified Jan 12, 2009
By A.D.Beckett
Function to concatenate waveforms.
For example:
new=abConcatWaveforms(flip(sig) sig)
will produce a new waveform made out of a flipped version of
the input signal, glued to the original input signal.
Copies units and name attributes from the first x and y vector it can find
them on. Other attributes (e.g. expression) are ignored, because they're
unlikely to be valid for the concatenated waveform. Also copies plotStyle,
xScale and barBase waveform attributes.
Can also register as a special function:
abRegConcatWaveformsSpecialFunction()
This will add abConcatWaveforms as a calculator special function.
***************************************************
SCCS Info: @(#) abConcatWaveforms.il 01/12/09.10:29:05 1.2
*/
/*****************************************************************
* *
* (abConcatWaveforms (wave1 [waves...])) *
* *
* Function to concatenate a number of waveforms. The function *
* takes an arbitrary number of waveforms (assumed to all be *
* waveforms or families of the same number of dimensions), and *
* concatenates the axes together. Note that care should be taken *
* if the x-axes overlap, because this merely concatenates the *
* vectors without any checking at all. *
* *
*****************************************************************/
(defun abConcatWaveforms (wave1 @rest waves)
(let (xVec yVec newX newY newLen len xName xUnits yName yUnits
newWave (attribs (makeTable 'attribs nil)))
(cond
((drIsWaveform wave1)
(setq newLen (drVectorLength (drGetWaveformXVec wave1)))
(foreach wave waves
(setq newLen (plus newLen
(drVectorLength (drGetWaveformXVec wave))))
)
(setq newX (drCreateVec (drGetWaveformXType wave1) newLen))
(setq newY (drCreateVec (drGetWaveformYType wave1) newLen))
(foreach wave (cons wave1 waves)
(setq xVec (drGetWaveformXVec wave))
(setq yVec (drGetWaveformYVec wave))
(setq len (drVectorLength xVec))
(for pos 0 (sub1 len)
(drAddElem newX (drGetElem xVec pos))
(drAddElem newY (drGetElem yVec pos))
)
;--------------------------------------------------------
; Record attributes
;--------------------------------------------------------
(unless xName (setq xName (getq xVec name)))
(unless xUnits (setq xUnits (getq xVec units)))
(unless yName (setq yName (getq yVec name)))
(unless yUnits (setq yUnits (getq yVec units)))
(foreach attrib '(plotStyle xScale barBase)
(unless (and
(arrayref attribs attrib)
(get wave attrib))
(setarray attribs attrib (get wave attrib))
))
)
;-----------------------------------------------------------------
; Store found attributes
;-----------------------------------------------------------------
(when xName (putpropq newX xName name))
(when xUnits (putpropq newX xUnits units))
(when yName (putpropq newY yName name))
(when yUnits (putpropq newY yUnits units))
;-----------------------------------------------------------------
; Finally create the new waveform
;-----------------------------------------------------------------
(setq newWave (drCreateWaveform newX newY))
(foreach attrib attribs
(putprop newWave (arrayref attribs attrib) attrib)
)
newWave
) ; is waveform
((famIsFamily wave1)
(apply 'famMap (constar 'abConcatWaveforms wave1 waves))
) ; is family
(t
(error "abConcatWaveforms - can't handle %L\n" wave1)
)
) ; cond
) ; let
) ; defun
/******************************************************************
* *
* (abConcatWaveformsSpecialFunctionCB) *
* *
* Callback function for the abConcatWaveforms special function *
* Just takes the buffer and one stack item and concatenates them. *
* *
******************************************************************/
(defun abConcatWaveformsSpecialFunctionCB ()
(calSpecialFunctionInput 'abConcatWaveforms '(STACK))
)
/*******************************************************************
* *
* (abRegConcatWaveformsSpecialFunction) *
* *
* Register abConcatWaveforms as a special function. Note that this *
* only uses abConcatWaveforms with two arguments - otherwise would *
* need a form to indicate how many values to concatenate - so this *
* keeps it simple! *
* *
*******************************************************************/
(defun abRegConcatWaveformsSpecialFunction ()
(calRegisterSpecialFunction
(list "abConcatWaveforms" 'abConcatWaveformsSpecialFunctionCB))
t
)
(procedure (DrawNyquistPlot)
(let (lg lg2 stb_x stb_margin)
lg = -getData("loopGain" ?result "stb")
lg2 = abConcatWaveforms(flip(conjugate(lg)) lg)
ocnYvsYplot(?wavex real(lg2) ?wavey imag(lg2))
stb_x = xmin(abs(lg2-complex(-1.0,0.0))**2)
stb_margin = value(lg2, stb_x)
addTitle(sprintf(nil "stb_margin = %f dB" -dB20(stb_margin)))
xLimit( list(-1.6 0.2) )
yLimit( list(-0.5 0.5) )
)
)
then, simulate the circuit using stb analysis (spectre), and execute the command in CIW:
DrawNyquistPlot
No comments:
Post a Comment