P
PolyPusher
Guest
Hi,
I am trying to find the proper way(if there is one) to change some
properties without the Edit Instance Property form.
I can run this code I wrote that changes the SD connect and poly head
to top..
procedure(InstWack()
cv=geGetEditCellView()
foreach(inst cv~>instances
if(inst~>master then
unless(leIsContact(inst)
foreach(prop inst~>prop
if(prop~>name=="connectGates"
then println("connectGates found")
prop~>value="Top"
)
if(prop~>name=="connectSD"
then println("connectSD found")
prop~>value="unconnected"
)
)
)
)
)
)
This seems to work, but I worry about the unknown unknowns that I
don't know! I did notice that when I change one of the instances and
then click on the instance and start Edit Instance Properties the
Connect Gates and Connect SD are still the former property(say
connectGates is set to "bottom" in the Form and in layout it is top).
I did find the below post by Andrew, but I am still confused.
So, will the above cause any "real" problems, if so any fixes? Is
there a better way/ BTW, I have hundreds of devices that need to be
changed, that is the reasoning for using the code rather than the
form.
Thank you in advance for your help,
Eric
Previous post by Andrew.....
Changing properties using dbReplaceProp() is perfectly OK, and
will behave in a similar manner to changing the property another
way.
In fact Grant's suggested code isn't quite right - it should be:
;; selectedSet() is an old Edge compatibility func
;; use geGetSelSet() instead
inst=car(geGetSelSet())
;; don't use ~>value
inst~>W=2
Either using dbReplaceProp() or the above will _NOT_ trigger the
CDF callbacks. There's a good reason for this. CDF callbacks are
_form_ field callbacks, and not _database_ property callbacks.
This means they're only invoked when the property is changed from
a form (for example, the create instance or edit properties forms in
the schematic or layout editor).
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)
)
Now, using the instance CDF is not strictly correct, because when CDF
callbacks get invoked, they're actually presented with cdfgData set
to
an effective cell CDF, but populated with the instance's values.
There
is no easy way to do this (something similar can be done, but it's
more work than I really want to describe here). Most CDF callbacks
work fine if called as above - the only issue will be if the callback
looks at cdfgData->id (e.g. cdfgData->id->name) to do different
things. With instance CDF ->id points to the instance object; with
cell CDF it points to the cell object (so ->id->name gives the
instance name instead of the cell name, hence the trouble).
Personally I always try to avoid using CDF callbacks at any point.
They nearly always lead to trouble, because:
a) There are ways of changing properties which can cause the
callbacks to not get evaluated
b) They prevent hierarchical inheritance of properties;
for example, you can't use pPar() any more
This is really only true if you're using CDF callbacks to calculate
the values of other parameters; if using them to validate
field values, then that's OK.
What I always suggest to people to do is to use a "pull" model
instead of the callback-based "push" model. This means that you
do any computation at the point you need it. So, if you
were having a CDF callback to compute a value for a pcell;
put the computation in the pcell code. If it was for a spectre
model, put it in an inline-subckt (or failing that, in a custom
netlisting procedure).
CDF callbacks are an attractive concept, but there are so many
pitfalls that they're really best avoided except for simple
user interface checks and manipulations.
(gets off soapbox).
Regards,
Andrew.
I am trying to find the proper way(if there is one) to change some
properties without the Edit Instance Property form.
I can run this code I wrote that changes the SD connect and poly head
to top..
procedure(InstWack()
cv=geGetEditCellView()
foreach(inst cv~>instances
if(inst~>master then
unless(leIsContact(inst)
foreach(prop inst~>prop
if(prop~>name=="connectGates"
then println("connectGates found")
prop~>value="Top"
)
if(prop~>name=="connectSD"
then println("connectSD found")
prop~>value="unconnected"
)
)
)
)
)
)
This seems to work, but I worry about the unknown unknowns that I
don't know! I did notice that when I change one of the instances and
then click on the instance and start Edit Instance Properties the
Connect Gates and Connect SD are still the former property(say
connectGates is set to "bottom" in the Form and in layout it is top).
I did find the below post by Andrew, but I am still confused.
So, will the above cause any "real" problems, if so any fixes? Is
there a better way/ BTW, I have hundreds of devices that need to be
changed, that is the reasoning for using the code rather than the
form.
Thank you in advance for your help,
Eric
Previous post by Andrew.....
Changing properties using dbReplaceProp() is perfectly OK, and
will behave in a similar manner to changing the property another
way.
In fact Grant's suggested code isn't quite right - it should be:
;; selectedSet() is an old Edge compatibility func
;; use geGetSelSet() instead
inst=car(geGetSelSet())
;; don't use ~>value
inst~>W=2
Either using dbReplaceProp() or the above will _NOT_ trigger the
CDF callbacks. There's a good reason for this. CDF callbacks are
_form_ field callbacks, and not _database_ property callbacks.
This means they're only invoked when the property is changed from
a form (for example, the create instance or edit properties forms in
the schematic or layout editor).
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)
)
Now, using the instance CDF is not strictly correct, because when CDF
callbacks get invoked, they're actually presented with cdfgData set
to
an effective cell CDF, but populated with the instance's values.
There
is no easy way to do this (something similar can be done, but it's
more work than I really want to describe here). Most CDF callbacks
work fine if called as above - the only issue will be if the callback
looks at cdfgData->id (e.g. cdfgData->id->name) to do different
things. With instance CDF ->id points to the instance object; with
cell CDF it points to the cell object (so ->id->name gives the
instance name instead of the cell name, hence the trouble).
Personally I always try to avoid using CDF callbacks at any point.
They nearly always lead to trouble, because:
a) There are ways of changing properties which can cause the
callbacks to not get evaluated
b) They prevent hierarchical inheritance of properties;
for example, you can't use pPar() any more
This is really only true if you're using CDF callbacks to calculate
the values of other parameters; if using them to validate
field values, then that's OK.
What I always suggest to people to do is to use a "pull" model
instead of the callback-based "push" model. This means that you
do any computation at the point you need it. So, if you
were having a CDF callback to compute a value for a pcell;
put the computation in the pcell code. If it was for a spectre
model, put it in an inline-subckt (or failing that, in a custom
netlisting procedure).
CDF callbacks are an attractive concept, but there are so many
pitfalls that they're really best avoided except for simple
user interface checks and manipulations.
(gets off soapbox).
Regards,
Andrew.