skill实现不打开窗口checkandsave 库中所有schematic和symbol
在整理设计库时,逐个打开 schematic 和 symbol,再执行检查与保存,会产生大量重复操作。本教程以给定的 SKILL 过程为例,通过遍历库中的 cell、取得 cellView 数据库对象并执行检查与保存,减少手动打开编辑窗口的步骤。
一、目标与操作范围
- 输入一个库名,例如 my_design_lib。
- 遍历该库中的全部 cell。
- 仅处理名称为 schematic 和 symbol 的两个 view。
- 对能够打开的 cellView 执行 schCheck 和 dbSave。
- 保存成功后调用 dbReopen,再通过 dbClose 释放本次打开的引用。
这里的“不打开窗口”指代码没有调用打开图形编辑窗口的函数,而是直接使用 dbOpenCellViewByType 取得数据库对象。它不等于“不修改数据库”:代码使用可写打开方式并执行保存,会影响库里的设计数据。
二、完整代码
procedure(check(source_lib)
let((libObj libCells cv)
libObj = ddGetObj(source_lib)
if(libObj then
libCells = libObj~>cells
foreach(cell libCells
foreach(viewName '("schematic" "symbol")
when(ddGetObj(source_lib cell~>name viewName)
printf("Check and save: %s/%s/%s\n"
source_lib cell~>name viewName)
cv = dbOpenCellViewByType(
source_lib
cell~>name
viewName
viewName
"a"
)
when(cv
schCheck(cv)
if(dbSave(cv) then
dbReopen(cv "r") ; 保存成功后切换为只读
else
printf("Save failed: %s/%s/%s\n"
source_lib cell~>name viewName)
)
dbClose(cv) ; 释放本次打开的引用
)
)
)
)
else
printf("Library not found: %s\n" source_lib)
)
)
)三、逐段理解执行逻辑
1. 获取库对象,处理库不存在的情况
libObj = ddGetObj(source_lib)代码将查询结果放入 libObj,然后通过 if 判断是否取得对象。没有取得库对象时,只打印 Library not found,不进入后续遍历。输入的库名应与当前会话中能够访问的库名一致。
2. 遍历 cell 与目标 view
libCells = libObj~>cells
foreach(cell libCells
foreach(viewName '("schematic" "symbol")
...
)
)外层循环遍历 libCells,内层循环分别处理 schematic 和 symbol。cell~>name 取得当前 cell 的名称。固定 view 列表意味着本代码不会处理 schematic_test、layout 等其他名称的 view。
3. 先判断 view 是否存在,再打开
when(ddGetObj(source_lib cell~>name viewName)
...
)只有查询返回对象时才执行 when 内的代码。一个 cell 只有 symbol、没有 schematic 时,不存在的 view 会被跳过。存在性检查与后面的可写打开是两回事:代码仍需要检查 cv 是否取得。
4. 获取数据库对象,不主动创建编辑窗口
cv = dbOpenCellViewByType(
source_lib
cell~>name
viewName
viewName
"a"
)该调用传入库名、cell 名、view 名,以及与 view 名相同的类型字符串。末尾使用 "a",表达本过程打开后要检查并保存的意图。返回结果进入 cv,后续通过 when(cv ...) 避免对空对象继续执行检查和保存。
注意:代码假定 view 名与传入的类型字符串一致。对于自定义 view 或不同库组织方式,不能仅通过修改名称列表就认定类型也正确。
5. 检查、保存与关闭
schCheck(cv)
if(dbSave(cv) then
dbReopen(cv "r")
else
printf("Save failed: %s/%s/%s\n"
source_lib cell~>name viewName)
)
dbClose(cv)代码先执行 schCheck,再判断 dbSave 的返回值。保存分支成功时调用 dbReopen(cv "r");失败时输出 Save failed。若前面的调用均正常返回,最后会执行 dbClose(cv)。
这里必须区分“运行过检查”“检查结果满足要求”和“保存成功”。原代码没有对 schCheck 的检查结果进行分级处理,也没有收集检查告警;因此不能把保存成功解读为电路已经通过所有规则验证。
四、如何调用
将完整过程保存为 check_library.il,在 Virtuoso 的 CIW 中加载该文件,再传入目标库名调用。下面的库名与文件位置仅为示例。
load("check_library.il")
check("my_design_lib")当文件不在当前可解析的位置时,load 中应填写实际文件路径。执行前先选择一个可写的测试库副本,包含少量 schematic 和 symbol,用于核对打开、检查、保存和关闭的行为。
五、如何读日志
Check and save: my_design_lib/inverter/schematic
Check and save: my_design_lib/inverter/symbol以上是日志格式示例,不是实际测试结果。原代码在打开 cellView 之前就打印 Check and save,所以看到这一行,只能说明目标 view 进入处理流程,不能证明打开或保存成功。
- Library not found:没有取得输入库的对象。
- Save failed:dbSave 返回值未进入成功分支。
- 没有输出某个 view:先核对该 view 是否存在及名称是否匹配。
- 只有 Check and save:原代码没有单独打印打开失败或保存成功日志,需要进一步检查实际结果。
六、正式工程脚本的改进方向
- 添加打开失败、检查结果、保存成功及失败的独立日志。
- 统计已处理、跳过与失败的 cellView 数量。
- 为检查失败定义策略:停止、继续,或仅记录而不保存。
- 为异常退出增加资源清理,避免错误中断后遗留引用。
- 提供 cell 白名单或小批量模式,先验证再扩展到整库。
- 保留运行前后可对比的数据库状态与检查报告。
总结
这段 SKILL 的核心路径是:获取库 → 遍历 cell → 筛选 schematic/symbol → 打开数据库对象 → 检查 → 保存 → 关闭引用。它将重复的手动操作转成批处理流程,但仍需要用测试库验证 view 类型、检查行为和异常处理。本教程基于用户提供的代码进行解析,未宣称已完成实际运行或环境兼容性测试。