• 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. Changing schematic properties and callbacks

Stats

  • Locked Locked
  • Replies 8
  • Subscribers 144
  • Views 14034
  • 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

Changing schematic properties and callbacks

AncisMichele
AncisMichele over 3 years ago

Hi,

I am in the process of evaluating a new PDK and I would like to run some sweeps for different geometries and device types.

The issue with sweeping "the standard way" is that this substitution process does not update those parameters of the model which rely on callbacks.

These days, things like perimeter/area and total width of transistors are caclulated via callbacks.

In trying to overcome this issue, I thought of automating the creation of an array of devices, each with its own properties.

Changing the properties of an instance created in a schematic view looks easy enough (I just learned about it today),

I gathered most of the info I now have, from this post on the Forum, and about the "callback plague" a bit here and there.

This thread in Ggroups has a full-fledged "callback caller" but I am still hoping (since I cannot understand the code) to get away with something simpler

like what I've found here (again Ggroups).

My first steps are - of course - interactive, so I have:

A symbol cellview on a schematic canvas, which I can select and then type on the CIW:

inst = car(selectedSet())

gives me a handle to the instance. I can either inspect the CDF from within the GUI (Tools->CDF->Edit)  or do a cdfGetInstCDF(inst) to get a handle to the db object.

The cell has a property called "fingers", which is as you guessed, the number of fingers of the device. If I do, from the CIW:

inst->fingers="2"

then I can see from the form of the cell instance, which I can of course inspect as I have the schematic canvas open, that the number of fingers is now - correctly - set to two.

But not only! (And this is where it starts to puzzle me)

Also other elements have changed in the form, the very same way one would expect when changing the n. of fingers manually, in the form.

The total witdth, areas and perimeters have changed as well (perimeters and areas are not editable, btw).

The joy does not last long, however. A call to ADE and successive netlisting brings up a device which has only the n. of fingers I've set. All other parameters are the "old" ones!!

Now as a side question, I would like to ask: how is it possible that I have a schematic showing me devices with property XYZ which, once netlisted, have different ones? This of course

opens an abyss of questions... But back to the main point.

Although I don't understand the above, i.e. how can it be that the schematic is showing me something that is not netlisted in that precise way, I thought that maybe I can solve this incongruency

by using callbacks. I used the snippet found in the 'simple version'  thread (2nd link). 

This means that if you change a database property on an instance,
you'll need to call any CDF callbacks yourself for that instance
property. One way of doing that is:


; set the global variable used to communicate with callbacks
cdfgData=cdfGetInstCDF(inst)
; assuming W is the parameter that was modified
paramName='W;
callback=get(cdfgData paramName)->callback
when(callback && callback!=""
; catch any errors during the evaluation
errset(evalstring(callback) t)
)

If I understand the gist of it, to invoke a callback is just performing an evalstring() on its name.

This name, a string, is what's returned by get(cdfgData paramName)->callback.

I've tried to do this, to no avail. The netlisted device has only the property I directly changed and none of the derived ones recalculated in any way.

I'm thinking I don't really know how to invoke the callback function, because how is the tool supposed to know on which instance to perform the operation?

Just to name one.

Any pointers highly appreciated, keeping in mind that what I'm really looking to implement is a very basic thing: just an array of automatically generated devices with a series of values for their main properties (length, width, n. of fingers...) so in my simple world (tell me if it's not so simple), the whole thing should go like:

for (X in instance_list):

  create instance X

  for parameter in par_list:

     X --> parameter = "myval"

     callback_for_parameter_1

so, nothing too complicated. Of course I'm missing something, hopefully not too much!

Thanks for your help,

Michele

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

    Michele,

    I'd suggest you either:

    1. Use the parameters capability in ADE Explorer/Assembler (or even XL) which allows you to sweep the parameters of a device and the callbacks do get fired in the background (rather than putting a variable on it, you use the parameterisation flow in ADE). This is the simplest because the tool does all the work for you
    2. Use my callback calling code (not an ancient version on the comp.cad.cadence forum, but something more recent which is indented and maybe easier to read). This also handles the pain for you. How to call CDF callbacks procedurally from SKILL to update CDF parameters?

    Trying to get the right CDF and then doing evalstring() yourself is possible, but sometimes you might need to take care of calling the init proc, or making sure it's the right kind of CDF - it's a can of worms. You can write it succinctly for a specific case, but depending on the PDK there might need to be a chain of callbacks invoked, not just the one you changed.

    I'd personally go for option 1 above if you can.

    Andrew

    • Cancel
    • Vote Up +2 Vote Down
    • Cancel
  • AncisMichele
    AncisMichele over 3 years ago in reply to Andrew Beckett

    Hi Andrew,

    thanks. I am not too enthusiastic about using Explorer/Assembler or XL - I would like to have a tighter control on what the simulator is doing.

    For instance - but I don't know whether this behaviour can be changed - I can't see the actual simulated netlists if I go for the "parametrisation flow" as you suggest. At least, I wasn't able to find them.

    EDIT: I was just looking in the "standard" places (.../spectre/schematic kind of thing) but actually when running Explorer the data is stored under the Maestro folder. I was able to find the netlists but

    they are not as transparent as I would like them to be, meaning that the transistor now has the swept parameter (# of fingers) put equal to a variable, but the other parameters of the cell view are NOT changing!

    Also, I've swept the # of fingers from 1 to 4 but I can't find a netlist with values for the variable assigned to the parameter different from 1.

    I'm starting to think, however, that there might be an underlying PDK maturity issue too.

    ----

    Also, I'm now totally in love with my idea of creating a sort of matrix of devices as a single schematic view, and this works best if done programmatically.

    Thank you for the link to a newer version of your code - you might remember that in my capacity as Consultant I'll have to go through a couple of hoops to get my hands on the content of the link.
    I've started the procedure, anyhow.

    I've tried to use your old - Ggroups - code, and I'm not sure whether I'm doing something wrong or the code is obsolete in the new Virtuoso versions or what not.

    I do something like this:

    load("abMagicCode.il")

    cvId = dbOpenCellViewByType("my_lib" "my_cell" "schematic")

    abInvokeCdfCallbacks( cvId)

    unfortunately, I get a bunch of error messages as a result:

    abEffCDF@0x269d2218

    *Error* PasCdfGetDpt: argument #1 should be any user-defined (other) type (type template = "o") - 

    In general, I got curious and now would like to try and understand the underlying mechanisms a little better.

    I can spend time and decypher what your code is doing, I've got a barrier in that Lisp syntax does not come natural to me, I just haven't spent enough time working with it, but it's just a matter of putting more effort into it.

    However, what I am missing is some sort of "picture" of the interplay, at this level, of CDFs, callbacks and PDKs, I suppose.

    I have the whole Cadence Documentation available: can you suggest me a few pointers for a study path?

    Thanks!

    Michele

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • AncisMichele
    AncisMichele over 3 years ago in reply to Andrew Beckett

    Hi Andrew,

    thanks. I am not too enthusiastic about using Explorer/Assembler or XL - I would like to have a tighter control on what the simulator is doing.

    For instance - but I don't know whether this behaviour can be changed - I can't see the actual simulated netlists if I go for the "parametrisation flow" as you suggest. At least, I wasn't able to find them.

    EDIT: I was just looking in the "standard" places (.../spectre/schematic kind of thing) but actually when running Explorer the data is stored under the Maestro folder. I was able to find the netlists but

    they are not as transparent as I would like them to be, meaning that the transistor now has the swept parameter (# of fingers) put equal to a variable, but the other parameters of the cell view are NOT changing!

    Also, I've swept the # of fingers from 1 to 4 but I can't find a netlist with values for the variable assigned to the parameter different from 1.

    I'm starting to think, however, that there might be an underlying PDK maturity issue too.

    ----

    Also, I'm now totally in love with my idea of creating a sort of matrix of devices as a single schematic view, and this works best if done programmatically.

    Thank you for the link to a newer version of your code - you might remember that in my capacity as Consultant I'll have to go through a couple of hoops to get my hands on the content of the link.
    I've started the procedure, anyhow.

    I've tried to use your old - Ggroups - code, and I'm not sure whether I'm doing something wrong or the code is obsolete in the new Virtuoso versions or what not.

    I do something like this:

    load("abMagicCode.il")

    cvId = dbOpenCellViewByType("my_lib" "my_cell" "schematic")

    abInvokeCdfCallbacks( cvId)

    unfortunately, I get a bunch of error messages as a result:

    abEffCDF@0x269d2218

    *Error* PasCdfGetDpt: argument #1 should be any user-defined (other) type (type template = "o") - 

    In general, I got curious and now would like to try and understand the underlying mechanisms a little better.

    I can spend time and decypher what your code is doing, I've got a barrier in that Lisp syntax does not come natural to me, I just haven't spent enough time working with it, but it's just a matter of putting more effort into it.

    However, what I am missing is some sort of "picture" of the interplay, at this level, of CDFs, callbacks and PDKs, I suppose.

    I have the whole Cadence Documentation available: can you suggest me a few pointers for a study path?

    Thanks!

    Michele

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to AncisMichele

    For your first question, you can go over each simulation point in the output pane and do right mouse->View Netlist and then see the netlist for that point.

    The comments at the top of the code (probably rather hard to see from that old version with messed up formatting) answer your other questions. In fact you could quite safely use the version in this post (I made a recent small change which would have no impact as it was for an internal team that needed a special feature). That has all the formatting and comments preserved and is recent enough (1.17 is the latest version), and that code has the "ab" prefix rather than "CCS" from the support article. Ah, just realised the article talks more about the special cases than the comments in the code.

    Some PDKs check the type of the arguments (those done using PAS) and so you'll need to pass ?useInstCDF t to abInvokeCdfCallbacks. You may also need ?callInitProc t too:

    abInvokeCdfCallbacks(cvId ?useInstCDF t ?callInitProc t)

    There is some documentation on CDF in general, but you may also find this of interest: The Dangers of CDF Callbacks

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • AncisMichele
    AncisMichele over 3 years ago in reply to Andrew Beckett

    Thanks Andrew!  

    About the netlist thing, that's also what I thought. Unfortunately, I don't seem to have that luxury:

    (please just click the link, I've tried to add image as link but it does not work)

    https://ibb.co/4ZT1N89

    when I go "the hard route", looking for the actual input.scs files, I can't make much sense of them, as I wrote.

    I've now used your suggested form for the procedure and "it works", in the sense that it returns true.

    However, when I change the # of fingers and then call the procedure, this number goes back to 1 and instead the total width/finger width is increased!!

    Probably something to do with the order of evaluation of parameters? If I try the more "internal"  procedure abInvokeInstCdfCallbacks() and specify that I want only the

    "# of fingers"  parameter callback to be fired, it works as intended.

    Needless to say, I can't access "The Dangers of CDF Callbacks"  with my limited powers :-(

    ---

    I would have many questions but probably a good study session is inorder, before I flood the Forum with redundant sentences :-D 

    But one thing puzzles me and I would like to ask:

    by creating a reference to the particular instance ( inst = car(selectedSet()))  I was able to change one of its parameters, and this was reflected at the schematic canvas level because the properties in the form were  actually  changing, and were stored somewhere because they survived, once saved, a close/reopen cycle. So, from the properties form available in the Schematic Editor, you would say your transistor is just fine.

    However, the  netlist  produced by that very same schematic, was  not  showing the "correct"  properties for the netlisted device... This leaves me with the sensation I am really missing something big here.

    How is that possible that I open a schematic and see "drain area = xxx"  and when I netlist that very schematic, the parameter ad = yyy?

    Thanks!

    Michele

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to AncisMichele
    AncisMichele said:

    About the netlist thing, that's also what I thought. Unfortunately, I don't seem to have that luxury:

    (please just click the link, I've tried to add image as link but it does not work)

    You're doing the Right Mouse button over the wrong column. You need to do it over the Nominal or the specific corner if corners are used. Each row in the detailed output can have multiple simulations, so you need to be looking at the specific corner because each will have a different netlist. If you do it over the output name, there's no run associated with that column.

    AncisMichele said:

    when I go "the hard route", looking for the actual input.scs files, I can't make much sense of them, as I wrote.

    Similarly you can look at the netlist for each simulation point.

    AncisMichele said:
    Probably something to do with the order of evaluation of parameters?

    Yes. This is one of the challenges with CDF callbacks - if they are written in a way that there is ambiguity in the results, then calling them procedurally can be a challenge. Though the UI the order is always defined, because it's simply the order you change the parameters on the form. If calling callbacks for a set of parameters, you really don't know which is edited first. I normally determine for a particular application which I want to win, and then specify the ?order to be the list of parameters I want to call in the right order. For many PDKs you don't need to call all the callbacks anyway because there is often (not always) some level of policing - but at the very least you only really need to call the callbacks for the parameters you're changing.

    You could call abInvokeCdfCallbacks with a ?order which works for all the types of device you've got, or you can call abInvokeInstCdfCallbacks for each instance - it doesn't really matter (it won't save you anything particularly on the efficiency - it's just a common requirement to re-call all the callbacks to ensure everything is consistent and it avoids having to think about it so much to call all the callbacks for all the instances).

    AncisMichele said:

    However, the  netlist  produced by that very same schematic, was  not  showing the "correct"  properties for the netlisted device... This leaves me with the sensation I am really missing something big here.

    How is that possible that I open a schematic and see "drain area = xxx"  and when I netlist that very schematic, the parameter ad = yyy?

    The chances are that the PDK has some derived (and maybe hidden) parameter that is used for netlisting. An approach I find particularly horrible because it's a recipe for things going wrong. You can tell by looking in the simulation information in the CDF for a particular simulator (netlister) for the component which parameters are output (note they may be mapped via the propMapping) and you need to ensure that you're calling the right callbacks to ensure that any dependency is followed. It's very hard to be specific without the details of what you're doing and the specific PDK, but it's going to be a matter of a callback not being called, I'm sure. Your ?order may not be enough.

    Note that when the callbacks are fired (either interactively, or using this function), modified values are stored on the instance itself in the instance user-defined properties. You can check values on the instance itself by doing:

    foreach(mapcar prop car(geGetSelSet())~>prop list(prop~>name prop~>value))

    which will show you a list of name-value pairs for properties on the instance. Note that other CDF parameters will pick up the default value from the CDF instead. Put simply, the instance CDF is the Cell CDF with the instance properties overlaid on top to override the value on a per-instance basis.

    Regards,

    Andrew

    • 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