• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. how to parse custom header using string variable with abDumpWaveformsToVCSV...

Stats

  • Replies 0
  • Subscribers 143
  • Views 1239
  • Members are here 0

how to parse custom header using string variable with abDumpWaveformsToVCSV.il

Ali Bastami
Ali Bastami 5 months ago

Hi, 

I am new to skill and would need support with one of the skill code I have been using for while with great success.

The skill code I am using is originally shared by A.D.Beckett.

when using this script like below:

abDumpWaveformsToVCSV(outm outp ?expr '("OUTM" "OUTP") ?file "./dump.vcsv")

it successfully dumps a file with "OUTM" and "OUTP"  as header for the outm and outp plots.

but if I have a variable called:

mynetp="OUTP"

mynetm="OUTM"

and calling the script as this:

abDumpWaveformsToVCSV(outm outp ?expr '(mynetm mynetp) ?file "./dump.vcsv")

the script dumps a file with "mynetp" and "mynetm"  as header for the outp and outm curves.

the reason I would like to parse the custom header is to be able to use abDumpWaveformsToVCSV function in a loop. 

does anyone know how to modify this script to be able to parse a string variable as plot header?

Here is a copy of abDumpWaveformsToVCSV.il script shared by A.D.Beckett:

/* abDumpWaveformsToVCSV.il

Author A.D.Beckett
Group Custom IC (UK), Cadence Design Systems Ltd.
Language SKILL
Date Dec 11, 2012
Modified
By

Function to write waveform objects out to VCSV.
Examples:

outm=v("/OUTM" ?result 'tran)
outp=v("/OUTP" ?result 'tran)

abDumpWaveformsToVCSV(outm outp ?expr '("OUTM" "OUTP") ?file "./dump.vcsv")

abDumpWaveformsToVCSV(outm outp ?expr '("OUTM" "OUTP") ?file "./dump.vcsv"
?from 1u ?to 3u ?by 0.1u)

The code should handle families, complex waveforms, sets of waveforms
where the number of points in each waveform is different. It is
unlikely to handle waveforms where the data contains strings (no testing
performed). Also you should be careful about interpolating too few points
- it uses the sample function which will return a number if there is
only one sample point.

Doesn't really have enough error checking in this yet...

Uses a couple of Cadence private functions: drWaveformGetDimension,
famGetExpr

***************************************************

SCCS Info: @(#) abDumpWaveformsToVCSV.il 03/26/13.13:42:03 1.2

*/

;------------------------------------------------------------------------
; Container structure to keep the cleaned signal name,
; length, whether it's complex etc
;------------------------------------------------------------------------
(defstruct abFamilySignal wave name len isComplex)

/*****************************************************************
* *
* (abUnwrapFamily fam @optional topName top (level 0) (name "")) *
* *
* Convert a family or waveform into a flat list of single *
* waveforms, wrapped by an abFamilySignal container structure *
* *
*****************************************************************/

(defun abUnwrapFamily (fam @optional topName top (level 0) (name ""))
(let (dim sweepName)
(unless top (setq top fam))
(setq dim (if (or (famIsFamily top) (drIsWaveform top))
(drWaveformGetDimension top)
0))
(cond
((and (famIsFamily top) (lessp level (sub1 dim)))
(setq sweepName (famGetSweepName top level))
(foreach mapcan sweepValue (famGetSweepValues fam)
(abUnwrapFamily
(famValue fam sweepValue) topName top (add1 level)
(sprintf nil "%s (%s=%Y)" name sweepName sweepValue))
)
)
(t (list (make_abFamilySignal
?wave fam
; the messing with strcat in format is to stop SCCS doing
; keyword substitution!
?name (sprintf nil (strcat "%Y" "%s")
(or topName (famGetExpr top)) name))))
)
)
)


/****************************************************************************
* *
* (abDumpWaveformsToVCSV ?file outFileOrPort [?from xVal] [?to xVal] *
* [?type "linear"] [?by interpStep] *
* [?expr listOfNames] [?digits 14] *
* wave1 [wave2 ...]) *
* *
* Dump the waveforms passed in to a VCSV (ViVA Comma Separated Value) *
* file. Normally the raw data is dumped, but if ?from or ?to are passed, *
* the data is clipped, and if ?by is passed, it is interpolated with that *
* step. Normally ?digits would be left alone. The ?expr argument allows for *
* cleaner names to be written into the file. *
* *
****************************************************************************/

(defun abDumpWaveformsToVCSV (@key file from to (type "linear")
by expr (digits 14) @rest waves)
(let (flattened xVec last port lastRow units name first)
(cond
((stringp file)
(unless (setq port (outfile file))
(error "Could not write to file %s\n" file))
)
((outportp file)
(setq port file)
)
(t
(error
"?file argument must be a fileName or an open output port - %L\n"
file)
)
)
;--------------------------------------------------------------------
; Convert expr into a list with the same length as waves
;--------------------------------------------------------------------
(setq expr
(foreach mapcar wave waves
; pointless statement to keep lint happy
(null wave)
; this is what I really wanted to do...
(prog1 (car expr) (setq expr (cdr expr)))))
(setq flattened
(foreach mapcan (wave exp) waves expr
(abUnwrapFamily wave exp))
)
(unless flattened
(error "No waveforms to dump")
)
;--------------------------------------------------------------------
; Sample or clip the individual waveforms if the from, to, by
; arguments have been given
;--------------------------------------------------------------------
(cond
(by
(foreach flat flattened
(setq xVec (drGetWaveformXVec (getq flat wave)))
(setq last (sub1 (drVectorLength xVec)))
(putpropq flat
(sample (getq flat wave)
(or from (drGetElem xVec 0))
(or to (drGetElem xVec last))
type
by
)
wave)
)
)
((or from to)
(foreach flat flattened
(setq xVec (drGetWaveformXVec (getq flat wave)))
(setq last (sub1 (drVectorLength xVec)))
(putpropq flat
(clip (getq flat wave)
(or from (drGetElem xVec 0))
(or to (drGetElem xVec last))
)
wave)
)
)
)
;--------------------------------------------------------------------
; Record the length of each waveform for ease of use and
; whether it is complex or not
;--------------------------------------------------------------------
(foreach flat flattened
(putpropq flat
(if (drIsWaveform (getq flat wave))
(drVectorLength
(drGetWaveformXVec (getq flat wave)))
0)
len)
(putpropq flat
(and (drIsWaveform (getq flat wave))
(eq (drGetWaveformYType (getq flat wave))
'doublecomplex))
isComplex)
)
;--------------------------------------------------------------------
; Output header info
;--------------------------------------------------------------------
(fprintf port ";Version, 1, 0\n")
(foreach flat flattened
(fprintf port ";%s" (getq flat name)))
(fprintf port "\n")
(foreach flat flattened
(fprintf port (if (getq flat isComplex) ";X, Y, Y" ";X, Y")))
(fprintf port "\n")
(foreach flat flattened
(fprintf port (if (getq flat isComplex)
";Re, ComplexRe, ComplexIm" ";Re, Re")))
(fprintf port "\n")
;--------------------------------------------------------------------
; Includes some messing around to ensure that there's an X and Y name
; because otherwise ViVA will abort when reading the file
;--------------------------------------------------------------------
(foreach flat flattened
(fprintf port ";%s,%s"
(or (and
(setq name (getq (drGetWaveformXVec
(getq flat wave)) name))
(null (blankstrp name))
name)
"X")
(or (and
(setq name (getq (drGetWaveformYVec
(getq flat wave)) name))
(null (blankstrp name))
name)
"Y")
))
(fprintf port "\n")
;--------------------------------------------------------------------
; Similar messing around to ensure there's an X and Y unit
;--------------------------------------------------------------------
(foreach flat flattened
(fprintf port ";%s,%s"
(or (and
(setq units (getq (drGetWaveformXVec
(getq flat wave)) units))
(null (blankstrp units))
units)
"xunit")
(or (and
(setq units (getq (drGetWaveformYVec
(getq flat wave)) units))
(null (blankstrp units))
units)
"yunit")
))
(fprintf port "\n")
;--------------------------------------------------------------------
; Figure out the maximum length of any of the waveforms
;--------------------------------------------------------------------
(setq lastRow
(sub1
(apply 'max (foreach mapcar flat flattened (getq flat len)))))
;--------------------------------------------------------------------
; Output all the data
;--------------------------------------------------------------------
(for row 0 lastRow
(setq first "")
(foreach flat flattened
(if (lessp row (getq flat len))
(if (getq flat isComplex)
(fprintf port "%s%s,%s,%s" first
(aelEngNotation
(drGetElem
(drGetWaveformXVec
(getq flat wave)) row) digits)
(aelEngNotation
(real (drGetElem
(drGetWaveformYVec
(getq flat wave)) row)) digits)
(aelEngNotation
(imag (drGetElem
(drGetWaveformYVec
(getq flat wave)) row)) digits)
)
(fprintf port "%s%s,%s" first
(aelEngNotation
(drGetElem
(drGetWaveformXVec
(getq flat wave)) row) digits)
(aelEngNotation
(drGetElem
(drGetWaveformYVec
(getq flat wave)) row) digits)
)
)
;----------------------------------------------------
; Seems to require spaces between commas
;----------------------------------------------------
(if (getq flat isComplex)
(fprintf port "%s , , " first)
(fprintf port "%s , " first)
)
)
(setq first ",")
)
(fprintf port "\n")
)
;--------------------------------------------------------------------
; Close the file if it was passed as a string
;--------------------------------------------------------------------
(when (stringp file) (close port))
)
)

  • Sign in to reply
  • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information