• 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 Design
  3. Manipulate and export data from ViVa

Stats

  • Locked Locked
  • Replies 12
  • Subscribers 125
  • Views 17519
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Manipulate and export data from ViVa

BaaB
BaaB over 9 years ago

I have two signals as in the picture below.

I would like to measure some information and export them to a table or a file something like this:

Pulse width     fall time

614n                738n

696n                686n

581n                660n

660n                672n

  ...                     ...

I am wondering if there is a way to do that. It would be a great help. Otherwise, I have to do it manually with hundreds points.

Thank you.

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 9 years ago

    To use the code, you can use the load() function to load it. Put it in a file (abGetCyclePeaks.il) and then in the CIW:

    load("abGetCyclePeaks.il")

    You can put this line in your .cdsinit too (put the full path to the file if necessary).

    The code is written in SKILL - which is a LISP variant. In fact all your calculator expressions are SKILL too - so to actually use the function, you'd need to type the function call (as shown the comments) into the calculator buffer. It's possible to add it as a custom function in IC617 easily through the UI - I'll post how to do that a little later.

    I tend to write my code using LISP syntax. To make it a bit easier to understand for those less familiar with SKILL, I've reformatted it into C-style below. This is equivalent, so there's no performance benefit in using either format - it's just the parser allows these alternative approaches to writing the code, because more engineers are probably familiar with a C-style than a LISP-style.

    Regards,

    Andrew.

    /* abGetCyclePeaks.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Mar 23, 2016 
    Modified   
    By         
    
    Function to calculate the peak values (or times of peak values)
    within each period. Has some tolerances built in so that it should
    detects when it first reaches the peak and filters out numerical
    noise.
    
    Example - measure fall time (peak to peak) in each period:
    
    abGetCyclePeaks(v("ramp" ?result 'tran) "rising" "max" ?yValues "x")-
        abGetCyclePeaks(v("ramp" ?result 'tran) "rising" "min" ?yValues "x")
    
    ***************************************************
    
    SCCS Info: @(#) abGetCyclePeaks.il 03/23/16.22:27:05 1.1
    
    */
    
    /*******************************************************************
    *                                                                  *
    *      (abGetCyclePeaks wave crossType minMax [?mode "auto"]       *
    *         [?threshold 0.0] [?yValues "y"] [?xName "cycle"]         *
    *                  [?reltol 1e-3] [?abstol 1e-6])                  *
    *                                                                  *
    *     For each cycle - identified by the rising or falling (or     *
    *     either, but that's not so likely to be used) crossing of     *
    *     the threshold (which is controlled by the ?mode argument     *
    *  "auto" means automatic, "user" means as specified) - find the   *
    * "min" or "max" value of the signal within the cycle. In order to *
    * filter out numerical noise on the signal influencing the precise *
    *     position of the peak, only look at changes bigger than a     *
    *   reltol+abstol type delta from the previously found peak. The   *
    *   resulting waveform can be plotted versus "cycle" or "time",    *
    *    and the yValues can be either the y or x values at the peak.  *
    *                                                                  *
    *******************************************************************/
    
    procedure(abGetCyclePeaks(wave crossType minMax @key (mode "auto") 
        (threshold 0.0) (yValues "y") (xName "cycle") 
        (reltol 1e-3) (abstol 1e-6) "gSSSfSSff")
      cond(
        (drIsWaveform(wave)
          let((xVec yVec len outX outY newXVec newYVec newWave cycleNum lastY 
              thisY localPeakX localPeakY direction func absdelta tolerance)
            ;----------------------------------------------------------------
            ; Validate the arguments to ensure they are valid strings
            ;----------------------------------------------------------------
            foreach(validInfo
              `(
                (crossType ,(crossType=get_string(crossType))
                ("rising" "falling" "either"))
                (minMax ,(minMax=get_string(minMax)) ("min" "max"))
                (?mode ,(mode=get_string(mode)) ("auto" "user"))
                (?xName ,(xName=get_string(xName)) ("cycle" "time"))
                (?yValues ,(yValues=get_string(yValues)) ("y" "x"))
              )
              unless(member(cadr(validInfo) caddr(validInfo))
                error("abGetCyclePeaks: %s argument must be one of \"%s\": %L\n"
                  car(validInfo)
                  buildString(caddr(validInfo) "\",\"")
                  cadr(validInfo))
                )
            )
            when(mode=="auto"
              threshold=average(wave)
            )
            func=if(minMax=="max" 'greaterp 'lessp)
            xVec=drGetWaveformXVec(wave)
            yVec=drGetWaveformYVec(wave)
            len=drVectorLength(xVec)
            cycleNum=0
            lastY=drGetElem(yVec 0)
            localPeakY=lastY
            localPeakX=drGetElem(xVec 0)
            ;----------------------------------------------------------------
            ; Iterate through all the points
            ;----------------------------------------------------------------
            for(i 1 sub1(len)
              thisY=drGetElem(yVec i)
              ;--------------------------------------------------------------
              ; Determine if this is a transition, and if so, which direction
              ;--------------------------------------------------------------
              direction=
                cond( 
                  (lastY<threshold && thisY>=threshold "rising")
                  (lastY>=threshold && thisY<threshold "falling")
                  (t nil)
                )
              ;--------------------------------------------------------------
              ; Assuming it's a crossing in the right direction, record
              ; the peak in that cycle (doesn't do it before the first
              ; transition though)
              ;--------------------------------------------------------------
              if(crossType==direction || crossType=="either" && direction then
                when(cycleNum>0
                  outX=tconc(outX if(xName=="cycle" cycleNum localPeakX))
                  outY=tconc(outY if(yValues=="y" localPeakY localPeakX))
                )
                localPeakX=drGetElem(xVec i)
                localPeakY=thisY
                cycleNum++
              else
                ;------------------------------------------------------------
                ; Otherwise see if the peak has been exceeded
                ;------------------------------------------------------------
                when(funcall(func thisY localPeakY)
                  absdelta=abs(thisY-lastY)
                  tolerance=max(abs(thisY) abs(lastY))*reltol+abstol 
                  when(absdelta>tolerance
                    localPeakX=drGetElem(xVec i)
                    localPeakY=thisY
                  )
                )
              )
              lastY=thisY
            ) ; for
            ;----------------------------------------------------------------
            ; Construct output vectors and waveforms with the right
            ; attributes
            ;----------------------------------------------------------------
            newXVec=drCreateVec(if(xName=="cycle" 'intlong 'double) car(outX))
            newYVec=drCreateVec('double car(outY))
            newXVec->units=if(xName=="cycle" "" xVec->units)
            newXVec->name=if(xName=="cycle" "cycle" xVec->name)
            newYVec->units=if(yValues=="y" yVec->units xVec->units)
            newYVec->name=if(yValues=="y" yVec->name xVec->name)
            newWave=drCreateWaveform(newXVec newYVec)
            famSetExpr(newWave 
              `abGetCyclePeaks(,famGetExpr(wave) crossType minMax 
                 ?mode ,mode ?threshold ,threshold 
                 ?yValues yValues ?xName ,xName 
                 ?reltol ,reltol ?abstol ,abstol)
            )
            newWave
          )
        )
        (famIsFamily(wave)
          famMap('abGetCyclePeaks minMax ?mode mode ?threshold threshold 
            ?yValues yValues ?xName xName ?reltol reltol ?abstol abstol
          )
        )
        (t
          error("abGetCyclePeaks: Cannot handle %L\n" wave)
        )
      )
    )
    

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 9 years ago

    To use the code, you can use the load() function to load it. Put it in a file (abGetCyclePeaks.il) and then in the CIW:

    load("abGetCyclePeaks.il")

    You can put this line in your .cdsinit too (put the full path to the file if necessary).

    The code is written in SKILL - which is a LISP variant. In fact all your calculator expressions are SKILL too - so to actually use the function, you'd need to type the function call (as shown the comments) into the calculator buffer. It's possible to add it as a custom function in IC617 easily through the UI - I'll post how to do that a little later.

    I tend to write my code using LISP syntax. To make it a bit easier to understand for those less familiar with SKILL, I've reformatted it into C-style below. This is equivalent, so there's no performance benefit in using either format - it's just the parser allows these alternative approaches to writing the code, because more engineers are probably familiar with a C-style than a LISP-style.

    Regards,

    Andrew.

    /* abGetCyclePeaks.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Mar 23, 2016 
    Modified   
    By         
    
    Function to calculate the peak values (or times of peak values)
    within each period. Has some tolerances built in so that it should
    detects when it first reaches the peak and filters out numerical
    noise.
    
    Example - measure fall time (peak to peak) in each period:
    
    abGetCyclePeaks(v("ramp" ?result 'tran) "rising" "max" ?yValues "x")-
        abGetCyclePeaks(v("ramp" ?result 'tran) "rising" "min" ?yValues "x")
    
    ***************************************************
    
    SCCS Info: @(#) abGetCyclePeaks.il 03/23/16.22:27:05 1.1
    
    */
    
    /*******************************************************************
    *                                                                  *
    *      (abGetCyclePeaks wave crossType minMax [?mode "auto"]       *
    *         [?threshold 0.0] [?yValues "y"] [?xName "cycle"]         *
    *                  [?reltol 1e-3] [?abstol 1e-6])                  *
    *                                                                  *
    *     For each cycle - identified by the rising or falling (or     *
    *     either, but that's not so likely to be used) crossing of     *
    *     the threshold (which is controlled by the ?mode argument     *
    *  "auto" means automatic, "user" means as specified) - find the   *
    * "min" or "max" value of the signal within the cycle. In order to *
    * filter out numerical noise on the signal influencing the precise *
    *     position of the peak, only look at changes bigger than a     *
    *   reltol+abstol type delta from the previously found peak. The   *
    *   resulting waveform can be plotted versus "cycle" or "time",    *
    *    and the yValues can be either the y or x values at the peak.  *
    *                                                                  *
    *******************************************************************/
    
    procedure(abGetCyclePeaks(wave crossType minMax @key (mode "auto") 
        (threshold 0.0) (yValues "y") (xName "cycle") 
        (reltol 1e-3) (abstol 1e-6) "gSSSfSSff")
      cond(
        (drIsWaveform(wave)
          let((xVec yVec len outX outY newXVec newYVec newWave cycleNum lastY 
              thisY localPeakX localPeakY direction func absdelta tolerance)
            ;----------------------------------------------------------------
            ; Validate the arguments to ensure they are valid strings
            ;----------------------------------------------------------------
            foreach(validInfo
              `(
                (crossType ,(crossType=get_string(crossType))
                ("rising" "falling" "either"))
                (minMax ,(minMax=get_string(minMax)) ("min" "max"))
                (?mode ,(mode=get_string(mode)) ("auto" "user"))
                (?xName ,(xName=get_string(xName)) ("cycle" "time"))
                (?yValues ,(yValues=get_string(yValues)) ("y" "x"))
              )
              unless(member(cadr(validInfo) caddr(validInfo))
                error("abGetCyclePeaks: %s argument must be one of \"%s\": %L\n"
                  car(validInfo)
                  buildString(caddr(validInfo) "\",\"")
                  cadr(validInfo))
                )
            )
            when(mode=="auto"
              threshold=average(wave)
            )
            func=if(minMax=="max" 'greaterp 'lessp)
            xVec=drGetWaveformXVec(wave)
            yVec=drGetWaveformYVec(wave)
            len=drVectorLength(xVec)
            cycleNum=0
            lastY=drGetElem(yVec 0)
            localPeakY=lastY
            localPeakX=drGetElem(xVec 0)
            ;----------------------------------------------------------------
            ; Iterate through all the points
            ;----------------------------------------------------------------
            for(i 1 sub1(len)
              thisY=drGetElem(yVec i)
              ;--------------------------------------------------------------
              ; Determine if this is a transition, and if so, which direction
              ;--------------------------------------------------------------
              direction=
                cond( 
                  (lastY<threshold && thisY>=threshold "rising")
                  (lastY>=threshold && thisY<threshold "falling")
                  (t nil)
                )
              ;--------------------------------------------------------------
              ; Assuming it's a crossing in the right direction, record
              ; the peak in that cycle (doesn't do it before the first
              ; transition though)
              ;--------------------------------------------------------------
              if(crossType==direction || crossType=="either" && direction then
                when(cycleNum>0
                  outX=tconc(outX if(xName=="cycle" cycleNum localPeakX))
                  outY=tconc(outY if(yValues=="y" localPeakY localPeakX))
                )
                localPeakX=drGetElem(xVec i)
                localPeakY=thisY
                cycleNum++
              else
                ;------------------------------------------------------------
                ; Otherwise see if the peak has been exceeded
                ;------------------------------------------------------------
                when(funcall(func thisY localPeakY)
                  absdelta=abs(thisY-lastY)
                  tolerance=max(abs(thisY) abs(lastY))*reltol+abstol 
                  when(absdelta>tolerance
                    localPeakX=drGetElem(xVec i)
                    localPeakY=thisY
                  )
                )
              )
              lastY=thisY
            ) ; for
            ;----------------------------------------------------------------
            ; Construct output vectors and waveforms with the right
            ; attributes
            ;----------------------------------------------------------------
            newXVec=drCreateVec(if(xName=="cycle" 'intlong 'double) car(outX))
            newYVec=drCreateVec('double car(outY))
            newXVec->units=if(xName=="cycle" "" xVec->units)
            newXVec->name=if(xName=="cycle" "cycle" xVec->name)
            newYVec->units=if(yValues=="y" yVec->units xVec->units)
            newYVec->name=if(yValues=="y" yVec->name xVec->name)
            newWave=drCreateWaveform(newXVec newYVec)
            famSetExpr(newWave 
              `abGetCyclePeaks(,famGetExpr(wave) crossType minMax 
                 ?mode ,mode ?threshold ,threshold 
                 ?yValues yValues ?xName ,xName 
                 ?reltol ,reltol ?abstol ,abstol)
            )
            newWave
          )
        )
        (famIsFamily(wave)
          famMap('abGetCyclePeaks minMax ?mode mode ?threshold threshold 
            ?yValues yValues ?xName xName ?reltol reltol ?abstol abstol
          )
        )
        (t
          error("abGetCyclePeaks: Cannot handle %L\n" wave)
        )
      )
    )
    

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

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