|
本帖最后由 彭加木 于 2023-11-6 17:00 编辑
如果你是一名模拟IC设计者,如果你曾经或者将要换工艺,那么你一定寻找过原理图迁移工艺的方法,下面介绍的就是可以实现这个功能的脚本。
脚本内容
首先感谢网友的无私奉献,该脚本来源于Cadence在线技术支持网站:support.cadence.com,需要注册用户才有权限进入,具体脚本(文件名:CCSdelInstCreate.il)如下。
以上脚本实现的思路大概分成以下几步:
第一步:用户通过传递参数确定不同工艺之间器件名称、参数之间的对应关系。
第二步:打开原始电路,并将原始电路中的参数值和坐标信息保存在变量中。
第三步:删除原始电路中需要替换的cell,并从参考库中调进新的cell,将上一步保存的参数值填入相应位置,并按照原始电路中cell的坐标放置新的cell,保存电路。
第四步:遍历目标Library中所有原理图,重复上面三个步骤,完成所有替换。
使用上面的脚本可以完成器件替换,但是很可能替换完成之后仿真中依然存在错误,原因是在替换过程中器件的参数虽然填入,但是未触发相应的CDF callbacks函数,所以还需要用下文提供的函数重新触发CDF callbacks.
推荐大家在完成替换流程之后重新触发该Library下所有的CDF callbacks,需要加载两个脚本。
第一个脚本实现触发CDF callbacks函数,脚本内容比较复杂,具体内容没有认真看过,内容如下(文件名:CCSinvokeCdfCallbacks.il):
- /* CCSinvokeCdfCallbacks.il
-
- Date Jul 11, 1 9
- Modified Dec 3, 2 13
-
- Invoke all the CDF callbacks for instances
-
- The main entry point is (CCSinvokeCdfCallbacks cellView)
- 9which invokes all the CDF callbacks for every instance in
- a cellView. This has some keyword arguments which allow debug
- messages to be displayed, to invoke the formInitProc if needed,
- and to invoke using the instance CDF directly, rather than try
- to create something that looks more like the effective CDF that
- is found when the callbacks are normally invoked from the forms.
-
- You can use the variable CCScallbackPatternsToIgnore so
- that some callbacks can be omitted.
-
- 9Extended in version 1.1 to allow ?filterFunc to be passed.
- This is a function that gets the cdf, the param name (nil
- for the initProc) and callback string.
- The function should return t if the callback should be called,
- and nil otherwise. For example:
-
- procedure(MYfilterFunc(cdf paramName callback)
- destructuringBind(
- (lib @optional cell) CCSgetLibCellFromCDF(cdf)
- ; t if any other parameter than w for gpdk090/nmos1v
- !(lib=="gpdk090" && cell=="nmos1v" && param=="w")
- )
- )
-
- CCSinvokeCdfCallbacks(geGetEditCellView() ?filterFunc 'MYfilterFunc)
-
- ***************************************************
-
- SCCS Info: @(#) CCSinvokeCdfCallbacks.il 12/23/13.12:50:52 1.16
-
- */
-
- /*******************************************************************************
- * DISCLAIMER: The following code is provided for Cadence customers to use at *
- * their own risk. The code may require modification to satisfy the *
- * requirements of any user. The code and any modifications to the code may *
- * not be compatible with current or future versions of Cadence products. *
- * THE CODE IS PROVIDED "AS IS" AND WITH NO WARRANTIES, INCLUDING WITHOUT *
- * LIMITATION ANY EXPRESS WARRANTIES OR IMPLIED WARRANTIES OF MERCHANTABILITY *
- * OR FITNESS FOR A PARTICULAR USE. *
- *******************************************************************************/
- /***************************************************************
- * *
- * The variable CCScallbackPatternsToIgnore is set to be *
- * a list of patterns against which the callbacks are *
- * checked. If any of these patterns are matched then *
- * the callback is not invoked. *
- * *
- ***************************************************************/
-
- (unless (boundp 'CCScallbackPatternsToIgnore)
- (setq CCScallbackPatternsToIgnore
- '("^MYPDKNot_Allowed.*")))
-
- /***************************************************************
- * *
- * (CCSshouldCallbackBeExecuted callback filterFunc cdf param) *
- * *
- * This checks the callback against all the patterns defined *
- * in the list CCScallbackPatternsToIgnore to determine *
- * whether the callback should be executed or not. *
- * If filterFunc is passed, call with cdf, param name and *
- * callback - this should return t or nil *
- * *
- ***************************************************************/
-
- (procedure (CCSshouldCallbackBeExecuted callback filterFunc cdf param)
- (and
- (forall pattern CCScallbackPatternsToIgnore
- (null (rexMatchp pattern callback)))
- (if filterFunc
- (funcall filterFunc cdf param callback)
- t
- )
- )
- )
-
- /***************************************************************
- * *
- * (CCSgetLibCellFromCDF cdf) *
- * *
- * Utility function to retrieve a list of lib and cell name *
- * from the CDF, regardless of whether it is an inst, cell or *
- * lib CDF. For lib CDF it only returns a list of the lib name *
- * *
- ***************************************************************/
-
- (procedure (CCSgetLibCellFromCDF cdf)
- (let (id)
- (setq id (getq cdf id))
- (case (type id)
- (dbobject
- (list (getq id libName) (getq id cellName))
- )
- (ddCellType
- (list (getq (getq id lib) name) (getq id name))
- )
- (ddLibType
- (list (getq id name))
- )
- )
- )
- )
-
- /*********************************************************************
- * *
- * (CCScreateEffectiveCDFLookalike cdf [lookalikeParams] *
- * [resetLookalikeParams]) *
- * *
- * Create a structure which looks (sort of) like an effective *
- * CDF. The reason for creating this is to allow the "id" parameter *
- * to be correctly set to the cell, rather than the instance, which *
- * is what happens if we use the cdfGetInstCDF() function to simulate *
- * cdfgData. The lookalikeParams optional parameter allows creation *
- * of the parameters to be "lookalike" as well, so that callbacks can *
- * be called even if there is no actual instance. By default, the *
- * parameters will be reset with using lookalikeParams, unless you *
- * pass nil as the third argument. *
- * *
- *********************************************************************/
-
- (procedure (CCScreateEffectiveCDFLookalike cdf @optional lookalikeParams
- (resetLookalikeParams t))
- (let (new cdfFields newParam)
- (unless (getd 'make_CCSeffCDF)
- ;---------------------------------------------------------
- ; Because some slots appear twice in cdf->? have
- ; to make the list unique
- ;---------------------------------------------------------
- (setq cdfFields (makeTable 'cdfFields))
- (foreach field (getq cdf ?)
- (setarray cdfFields field t)
- )
- (eval `(defstruct CCSeffCDF ,@(getq cdfFields ?))))
- (setq new (make_CCSeffCDF))
- (when (and lookalikeParams (null (getd 'make_CCSeffCDFparam)))
- (setq cdfFields (makeTable 'cdfFields))
- (foreach field (getq (car (getq cdf parameters)) ?)
- (setarray cdfFields field t))
- (eval `(defstruct CCSeffCDFparam ,@(getq cdfFields ?))))
- ;-----------------------------------------------------------------
- ; populate the effective cdf with the top level cdf attributes
- ;-----------------------------------------------------------------
- (foreach param (getq cdf ?)
- (putprop new (get cdf param) param))
- ;-----------------------------------------------------------------
- ; Set the id and type attributes appropriately
- ;-----------------------------------------------------------------
- (when (equal (getq new type) "instData")
- (putpropq new (dbGetq (dbGetq (getq cdf id) master) cell) id)
- (putpropq new "cellData" type)
- )
- ;-----------------------------------------------------------------
- ; If we want the parameters to be lookalike too, create those
- ;-----------------------------------------------------------------
- (when lookalikeParams
- (putpropq new
- (foreach mapcar param (getq cdf parameters)
- (setq newParam (make_CCSeffCDFparam))
- (foreach slot (getq param ?)
- (putprop newParam (get param slot) slot))
- (when resetLookalikeParams
- ; reset the value to defValue for safety
- (putpropq newParam (getq newParam defValue) value)
- )
- newParam
- )
- parameters)
- ) ; when
- ;-----------------------------------------------------------------
- ; Add the parameters as properties in the effective cdf
- ;-----------------------------------------------------------------
- (foreach param (getq new parameters)
- (putprop new param (getq param name))
- )
- new
- )
- )
-
- /*******************************************************************
- * *
- * (CCSaddFormFieldsToEffectiveCDFLookalike cdf inst) *
- * *
- * Populate four extra fields - libraryName, cellName, viewName and *
- * instanceName to emulate the forms on the forms - i.e. so that *
- * cdfgForm gets these slots. This is for callbacks which (badly) *
- * use cdfgForm to find out libraryName, cellName and viewName. *
- * *
- *******************************************************************/
-
- (procedure (CCSaddFormFieldsToEffectiveCDFLookalike cdf inst)
- (let (fieldData value)
- (unless (getd 'make_CCSeffCDFFormFields)
- (defstruct CCSeffCDFFormFields value defValue lastValue
- editable enabled invisible)
- )
- (foreach (field attr) '(libraryName cellName viewName instanceName)
- '(libName cellName viewName name)
- (setq value (dbGet inst attr))
- (setq fieldData
- (make_CCSeffCDFFormFields
- ?value value
- ?defValue value
- ?lastValue value
- ?editable t
- ?enabled t
- ?invisible nil
- ))
- (putprop cdf fieldData field)
- )
- cdf
- )
- )
-
- /********************************************************************
- * *
- * (CCSinvokeObjCdfCallbacks cdf @key (debug nil) order *
- * (callInitProc nil) (setCdfgForm t) (filterFunc nil)) *
- * *
- * Underlying function which does all the real work. This *
- * is separated from the original function CCSinvokeInstCdfCallbacks *
- * so that this can be called with a completely virtual CDF. *
- * See CCSinvokeInstCdfCallbacks for a description of the *
- * arguments - note that there is the ability to control whether *
- * cdfgForm is set or not. *
- * Return nil if any callback failed with a SKILL error, t otherwise*
- * *
- ********************************************************************/
-
- (procedure (CCSinvokeObjCdfCallbacks cdf @key (debug nil) order
- (callInitProc nil) (setCdfgForm t)
- filterFunc)
- ;----------------------------------------------------------------------
- ; Make cdfgData and cdfgForm dynamically scoped, to avoid
- ; interfering with any global usage of these variables
- ;----------------------------------------------------------------------
- (let (callback parameters cdfgData cdfgForm (success t))
- ;-----------------------------------------------------------------
- ; Set the cdfgData to be the instance CDF
- ;-----------------------------------------------------------------
- (setq cdfgData cdf)
- (setq cdfgForm nil)
- (when setCdfgForm
- ;---------------------------------------------------------------
- ; some callbacks use cdfgForm instead
- ;---------------------------------------------------------------
- (setq cdfgForm cdfgData)
- )
- ;-----------------------------------------------------------------
- ; Call the formInitProc if there is one.
- ;-----------------------------------------------------------------
- (when callInitProc
- (setq callback (getq cdfgData formInitProc))
- (when (and callback
- (nequal callback "")
- (CCSshouldCallbackBeExecuted callback filterFunc
- cdfgData nil))
- (when debug
- (printf " Invoking formInitProc: '%s'\n" callback))
- ;-----------------------------------------------------
- ; Evaluate the callback
- ;-----------------------------------------------------
- (unless
- (errset (evalstring
- (strcat callback "(cdfgData)")) t)
- (setq success nil)
- )
- )
- )
- ;-----------------------------------------------------------------
- ; Control order of parameter evaluation. If order specified,
- ; just do those, otherwise do all in arbitrary order
- ;-----------------------------------------------------------------
- (if order
- (setq parameters (foreach mapcar param order
- (get cdfgData param)))
- (setq parameters (getq cdfgData parameters))
- )
- ;-----------------------------------------------------------------
- ; loop through all parameters
- ;-----------------------------------------------------------------
- (foreach param parameters
- (setq callback (getq param callback))
- (when (and callback
- (nequal callback "")
- (CCSshouldCallbackBeExecuted callback filterFunc
- cdfgData
- (getq param name)))
- (when debug
- (printf " Invoking callback for '%s': '%s'\n"
- (getq param name) callback))
- ;--------------------------------------------------
- ; evaluate the callback
- ;--------------------------------------------------
- (unless (errset (evalstring callback) t)
- (setq success nil)
- )
- ))
- success))
-
- /*****************************************************************
- * *
- * (CCSinvokeInstCdfCallbacks instance [?debug debug] *
- * [?order order] [?callInitProc callInitProc] [?useInstCDF nil] *
- * [?addFormFields nil] [?filterFunc nil] *
- * *
- * Invoke all the parameter callbacks in the CDF for an instance. *
- * This won't do anything if it doesn't have any CDF. *
- * debug is a flag to turn on debug messages. order allows just *
- * selected parameters to be called, in the specified order. *
- * callInitProc allows the formInitProc to be called. useInstCDF *
- * tells the formInitProc to be called with the instCDF rather *
- * than the effective lookalike CDF. addFormFields tells it to *
- * add the libraryName/cellName/viewName slots to emulate the *
- * fields on the cdfgForm, which are used by some bad callback *
- * code - note this is only done if useInstCDF is nil *
- * *
- *****************************************************************/
-
- (procedure (CCSinvokeInstCdfCallbacks instance @key (debug nil) order
- (callInitProc nil) (useInstCDF nil)
- (addFormFields nil) (filterFunc nil))
- ;----------------------------------------------------------------------
- ; Make cdfgData and cdfgForm dynamically scoped, to avoid
- ; interfering with any global usage of these variables
- ;----------------------------------------------------------------------
- (let (cdf)
- (when debug
- (printf " Invoking callbacks for instance '%s'\n"
- (dbGetq instance name)))
- ;-----------------------------------------------------------------
- ; Set the cdf to be the instance CDF
- ;-----------------------------------------------------------------
- (setq cdf (cdfGetInstCDF instance))
- (unless useInstCDF
- (setq cdf (CCScreateEffectiveCDFLookalike cdf))
- (when addFormFields
- (CCSaddFormFieldsToEffectiveCDFLookalike cdf instance)
- )
- )
- ;-----------------------------------------------------------------
- ; Return value will be nil if any callbacks had errors
- ;-----------------------------------------------------------------
- (CCSinvokeObjCdfCallbacks
- cdf
- ?debug debug ?order order ?callInitProc callInitProc
- ?setCdfgForm (null useInstCDF) ?filterFunc filterFunc
- )
- ))
-
- /***************************************************************
- * *
- * (CCSconvertCdfToPcellParams cdf) *
- * *
- * Take modified parameters in the CDF, and return this as the *
- * list of parameter names, types, and values that is *
- * needed to create a pcell with dbCreateParamInst. *
- * *
- ***************************************************************/
-
- (procedure (CCSconvertCdfToPcellParams cdf)
- (foreach mapcar param
- (setof par (getq cdf parameters)
- (nequal (getq par value) (getq par defValue)))
- (list
- (getq param name)
- ; need to map this to pcell parameter types...
- (case (getq param paramType)
- (("int" "boolean" "float" "string") (getq param paramType))
- (t "string")
- )
- (getq param value)
- )
- )
- )
-
- /***************************************************************
- * *
- * (CCSinvokeCdfCallbacks cellView @key (debug nil) *
- * (callInitProc nil) (useInstCDF nil) (addFormFields nil)) *
- * (filterFunc nil) *
- * *
- * Invoke the CDF callbacks for all instances in the cellView. *
- * Returns nil if any callback had a SKILL error, otherwise t *
- * *
- ***************************************************************/
-
- (procedure (CCSinvokeCdfCallbacks cellView @key (debug nil)
- (order nil)
- (callInitProc nil) (useInstCDF nil)
- (addFormFields nil) (filterFunc nil))
- (let ((success t))
- (when debug
- (printf "Invoking callbacks for all instances in cell '%s'\n"
- (dbGetq cellView cellName)))
- (foreach instance (dbGetq cellView instances)
- (unless
- (CCSinvokeInstCdfCallbacks instance
- ?debug debug
- ?order order
- ?callInitProc callInitProc
- ?useInstCDF useInstCDF
- ?addFormFields addFormFields
- ?filterFunc filterFunc
- )
- (setq success nil)
- )
- ) ; foreach
- success
- )
- ) ; procedure
复制代码
第二个脚本遍历指定Library下所有原理图,并依次触发该原理图中cell的CDF callbacks函数,内容如下(文件名:CCSCdfCallbackEntireLib.il)。
- /*
- This SKILL code is not sufficient on its own. You need to also
- download CCSinvokeCdfCallbacks.il file before running this code.
-
- load "CCSinvokeCdfCallbacks.il"
- load "CCSCdfCallbackEntireLib.il"
-
- CCSCdfCallbackEntireLib("MYLIB")
-
- Where "MYLIB" is the design library.
-
- */
-
-
-
- /***************************************************************
- * *
- * (CCSCdfCallbackEntireLib libName *
- * *
- * Invoke the CDF callbacks for all schematics of given library *
- * *
- ***************************************************************/
-
- procedure(CCSCdfCallbackEntireLib(library)
- let((libName)
- unless(libName=ddGetObj(library) error("Library %s does not exists\n" library))
- foreach(cell libName~>cells
- if(exists(x cell~>views~>name (x=="schematic"))
- then
- printf("Processing cell %s\n" cell~>name)
- ;Open schematic
- cv = dbOpenCellViewByType(library cell~>name "schematic" "schematic" "a")
-
- /* Run CDF Callback.
-
- Modify the below line if you want to run it with callInitProc and userInstCDF:
- CCSinvokeCdfCallbacks(cv ?callInitProc t ?useInstCDF t)
-
- Modify the below line if want to run callback of certain parameters only and in a particular order:
- CCSinvokeCdfCallbacks(cv ?order list("l" "w"))
-
- */
-
- CCSinvokeCdfCallbacks(cv)
- ;Run schematic heck and Save
- schCheck(cv)
- dbSave(cv)
- ) ;if
- );foreach
- ) ;let
- ) ; procedure
复制代码
以上是原理图迁移工艺脚本需要使用的代码,至于代码中更具体的内容,欢迎感兴趣的同学在评论中积极讨论,当然对于大部分同学来说只需要了解如何使用脚本即可。
脚本使用介绍
下面介绍一下脚本的使用方法,在使用脚本前需要仔细阅读脚本最前面的注释内容,对每个脚本的使用方法都有详细介绍。
使用CCSdelInstCreate.il函数时,首先需要修改脚本第46行中deviceMapList和第48行中propMapList对应的内容,其中:
deviceMapList:指定器件的对应关系,格式为:("old_cell name" ("lib_name" "new_cell name")).
propMapList:指定器件参数的对应关系,比如,不同工艺中有可能对MOS的栅长、栅宽等参数叫法不一致,所以需要用户提供正确的对应关系,否则可能出现替换之后属性错误的情况。
注意:propMapList中的属性是指器件CDF中对应的Name一项,并非指器件Q出的属性名称,有几种方法可以查看propMapList中需要使用的属性名称。
最简单的方法是查看CDF中属性名称,在CIW界面:Tools->CDF->Edit,然后按照下图中标注选择Library Name、Cell Name等,即可在Component Parameter一项查看到器件参数名称。
还有一种方法可以查看对应参数在CDF中的名称,在Q出器件属性之后,每个参数后面有个是否显示器件属性名称和对应值的选择框,选择both一项可以同时查看器件属性名称和其对应值。
按照上述方法查看CDF中器件属性名称,并按照对应关系修改脚本中propMapList的值。
修改完脚本即可在CIW界面内load脚本,脚本load成功之后,使用函数
CCSdelInstCreate("library_name"),即可完成器件替换。
需要注意的是,由于每个工艺中器件种类较多,而不同种类器件属性不一样,所以为了避免出错,大家务必每次使用脚本只替换具有相同属性的器件。
对于一个原理图中包含不同属性的不同器件时,使用脚本替换数量较多的器件,或者选择重复多次上述替换步骤,分别替换不同类型器件的方法,进行整个设计的原理图替换。
实例:smic18mmrf工艺向tsmc18rf迁移的操作,CCSdelInstCreate.il脚本第46~48行内容修改如下:
- ( deviceMapList '(("n33" ("tsmc18rf" "nmos3v")) ("p33" ("tsmc18rf" "pmos3v"))))
- ;; Modify propMapList as per the properties you want to copy
- (propMapList '(("m" "m") ("l" "l") ("fw" "w") ("fingers" "fingers")) )
复制代码
在CIW窗口load脚本,并运行函数:
查看原理图,可以看到器件及相应属性已经按照预期替换成新工艺下的属性,但是部分器件的CDF callbacks没有触发,这时候电路抽出的网表极有可能是不正确的。
脚本使用第二步,替换完器件之后,使用以下脚本重新触发器件的CDF callbacks函数。
在CIW界面,依次load脚本CCSinvokeCdfCallbacks.il和CCSCdfCallbackEntireLib.il,然后按照格式:CCSCdfCallbackEntireLib("lib_name")调用函数。
重新触发CDF callbacks函数之后,使用脚本替换的器件与手工调用器件参数完全一致,仿真中生成的网表内容也一致,到此完成整个替换过程。
已知问题
脚本极有可能只完成用户80%的原理图迁移工作,为大家带来一部分效率提升,剩下的已知或者未知问题只能手动修改。
如果在脚本使用中发现:脚本运行报error,并且无法实现替换功能,请尽量保证每次脚本只替换一种器件类型,并且器件名称和参数对应正确。
在触发CDF callbacks函数时偶尔会出现CIW报错但是并不影响功能,无需在意,关于CDF callbacks函数的触发脚本还有多种其它用法,请参考脚本前的注释内容。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
EDA1024论坛免责声明
请勿上传侵权资料及软件!
如果发现资料侵权请及时联系,联系邮件: fenxin@fenchip.com QQ: 2322712906. 我们将在最短时间内删除。
|