• 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. variable scopes within cdf files

Stats

  • Locked Locked
  • Replies 4
  • Subscribers 142
  • Views 14454
  • 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

variable scopes within cdf files

CADcasualty
CADcasualty over 7 years ago

I have a myCell.cdf file that is being used to create the cdf. A stripped down version of the file is:

LIBRARY = "myLib"
CELL = "myCell"
let( ( libId cellId cdfId )
unless( cellId = ddGetObj( LIBRARY CELL ) error( "Can't find cell: %s." CELL ) )
when( cdfId = cdfGetBaseCellCDF( cellId ) cdfDeleteCDF( cdfId ) )
cdfId = cdfCreateBaseCellCDF( cellId )

cdfCreateParam( cdfId
?name "X"
?prompt "X"
?defValue "0"
?type "string"
?storeDefault "yes"
?callback "letseq( a bunch of code goes here )"
)

cdfCreateParam( cdfId
?name "Y"
?prompt "Y"
?defValue "0"
?type "string"
?storeDefault "yes"
?callback "letseq( a bunch of code goes here )"
)
)


All of the cdf parameter callbacks share a few common constants that are expensive to figure out (especially on a per-callback basis). If I declare those common constants at the top (above all the cdfCreateParam functions) will the callbacks always have access to them and is the scope of those constants limited only to the cdf in which they are declared?

I'm pretty sure the answer is yes but just wanted some assurance before doing a lot of work.

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago

    The callbacks are evaluated in the global scope. Because of this it doesn't matter where you define those constants, provided they are defined by the time the callback gets first executed. You should however ensure that any constants you define have a sufficiently unique name - we suggest using a prefix starting with an uppercase letter (since Cadence doesn't do that for its functions) for any global variables to avoid clashing with any other code.

    Alternatively, you could take advantage of SKILL++'s lexical scoping by creating all your callback functions in a file with the .ils suffix:

    let((const1 const2 const3)

      procedure(factorial(n "x")
        if(n>1 then
          n*factorial(n-1)
        else
          1
        )
      )
      const1=3.14159265358979323
      const2=1.6180339887
      const3=factorial(15)

      globalProc(MyCallback1()
        const1*const3
      )
      globalProc(MyCallback2()
        const1*const2
      )
    )

    In the above, the three variables const1, const2, const3 are only visible within the scope of the block of text containing the let (hence the term lexical scoping). That means that they are visible in the locally defined functions too. The function factorial is truly local - can't be called from outside, whereas MyCallback1 and MyCallback2 are visible outside the let, but when they run, they can see any variables (or functions) within their lexical scope.

    This only works in SKILL++ mode (with the .ils suffix) because SKILL needs to know that this is defined with the different scoping rules (SKILL's normal scoping rule is dynamic scoping).

    Possibly more than you wanted to know, but it may help somebody!

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • CADcasualty
    CADcasualty over 7 years ago in reply to Andrew Beckett

    Thanks for your great reply, Andrew! It does spawn an iteration of my question though. Just to clarify things further, say the myCell.cdf file actually contained the following (and sorry in advance because all the indentation is apparently lost when I paste it into the box where I ask my question):

    LIBRARY = "myLib"
    CELL = "myCell"
    let( ( libId cellId cdfId )
    unless( cellId = ddGetObj( LIBRARY CELL ) error( "Can't find cell: %s." CELL ) )
    when( cdfId = cdfGetBaseCellCDF( cellId ) cdfDeleteCDF( cdfId ) )
    cdfId = cdfCreateBaseCellCDF( cellId )

    a = 3.14159 <---- a constant whose name is likely to clash with a lot of stuff
    b = 1.41421 <---- a constant hopefully accessible by all of this final cdf's callbacks

    cdfCreateParam( cdfId
    ?name "X"
    ?prompt "X"
    ?defValue "0"
    ?type "string"
    ?storeDefault "yes"
    ?callback "letseq( a bunch of code that hopefully uses a and b from above goes here )" <------
    )

    cdfCreateParam( cdfId
    ?name "Y"
    ?prompt "Y"
    ?defValue "0"
    ?type "string"
    ?storeDefault "yes"
    ?callback "letseq( a bunch of code that hopefully uses a and b from above goes here )" <------
    )
    )


    I'm under the impression myCell.cdf file is an intermediate file that is used to create the actual cdf for myCell in the library myLib. The code in the callback is just a really long string that is presumably *blindly* written out to the real cdf and the references to the callback's a and b variables in the new location might not actually have anything to do with the declared a and b variables at the top of the myCell.cdf file. If that's the case, then declaring the a and b variables in myCell.cdf is irrelevant, and the poor choice of names for the variables a and b are now highly open to being stomped on in the global space. That's the essential part of my question.

    Finally, the code above is in a file called e.g. myCell.cdf - not a *.ils file. Is this an issue?

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to CADcasualty

    First of all, the suffix ".cdf" doesn't mean anything special - it's just SKILL code. The file essentially looks the same structure as you'd get from using the "CDF Dump" button in the Tools->CDF->Edit CDF form - i.e. what the SKILL function cdfDump() would write out. That code is intended to be loaded once by the CDF creator to create the CDF. It is not intended to be loaded per-session, because otherwise it would recreate the CDF each time and would require the person who loads the code to have write permission to the cell property bag (the data.dm at the cell level) which is where the cell CDF gets stored. 

    That cell CDF stored in the cell property bag contains all the info about the CDF, including the callback string.

    So, since the file is unlikely to be loaded per-session, when the callback gets loaded, it won't know about the variables a, b etc (and they're not named with good prefixes either, but that's by the by). As you noticed, the scoping is not file-based (so they're not private per file, as in some other languages) - the a and b end up being global - hence the high likelihood of a clash with other variables a and b (although this is somewhat irrelevant if you are not even going to load the file per-session anyway).

    Therefore you need to define those variables (your constants) in a file that will be loaded each session. A good place to put that would be in a file within the library containing the cell with these CDFs - either the libInit.il or libInit.ils (if you want SKILL++ semantics). This file gets automagically loaded the first time the library is referenced in a virtuoso session. This file could either directly contain the variable definitions, and any functions  you need, or it could simply load the actual file with those definitions.

    The benefit of doing it this way is that you then don't need to have the definitions loaded in your .cdsinit - it becomes part of the library that needs them. Most PDKs do some initialisation this way within their technology libraries - they load functions and data needed by that PDK so that it's self-contained as part of the library.

    Hope that helps clarify things!

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • CADcasualty
    CADcasualty over 7 years ago in reply to Andrew Beckett

    Perfect! I really appreciate the time and thoughtfulness you put into your responses :-).

    • Cancel
    • Vote Up 0 Vote Down
    • 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