skill把当前打开的schematic中所有的方括号[]改为尖括号<>

当原理图中的总线名称使用方括号,而项目命名要求使用尖括号时,可以通过 SKILL 批量转换。本教程基于提供的两个过程,讲解字符串替换、当前编辑视图获取、terminal 名称和 label 文本修改,以及检查与保存流程。

一、先明确修改范围

题目中的“所有”需要结合代码的实际范围理解:脚本处理当前编辑 schematic 的 terminal 名称,以及 shapes 中 objType 为 label 的文本。它不是整个数据库的全文替换,不遍历子层级,也不修改 symbol、实例属性或所有 net 对象的名称。

二、完整代码

convert_schematic_brackets.il
; 把字符串中的 [ 和 ] 分别替换为 < 和 >
procedure(bracketToAngle(name)
  let((result ch)
    result = ""
    for(i 1 strlen(name)
      ch = substring(name i 1)
      cond(
        (ch == "[" result = strcat(result "<"))
        (ch == "]" result = strcat(result ">"))
        (t         result = strcat(result ch))
      )
    )
    result
  )
)

; 修改当前正在编辑的 schematic
procedure(convertSchematicBrackets()
  let((cv oldName newName pinCount labelCount)
    cv = geGetEditCellView()
    unless(cv
      error("请先打开要修改的 schematic。\n")
    )
    unless(cv~>viewName == "schematic"
      error("当前编辑视图不是 schematic。\n")
    )

    pinCount = 0
    labelCount = 0

    ; Pin 名:修改 terminal
    foreach(term cv~>terminals
      oldName = term~>name
      newName = bracketToAngle(oldName)
      unless(oldName == newName
        printf("PIN: %s -> %s\n" oldName newName)
        term~>name = newName
        pinCount = pinCount + 1
      )
    )

    ; Wire 名:修改 schematic 中的 net label
    foreach(fig cv~>shapes
      when(fig~>objType == "label"
        oldName = fig~>theLabel
        when(stringp(oldName)
          newName = bracketToAngle(oldName)
          unless(oldName == newName
            printf("LABEL: %s -> %s\n" oldName newName)
            fig~>theLabel = newName
            labelCount = labelCount + 1
          )
        )
      )
    )

    schCheck(cv)
    dbSave(cv)
    printf("完成:修改 %d 个 pin 名、%d 个 label。请检查 CIW 的 schCheck 告警。\n"
           pinCount labelCount)
  )
)

三、字符串转换:bracketToAngle

辅助过程从空字符串 result 开始,以 substring(name i 1) 每次读取一个字符。cond 的前两个分支分别处理左右方括号,最后的 t 分支保留其他字符。循环结束后,最后一个表达式 result 作为过程结果。

; 预期结果示例,并非实际环境运行记录
bracketToAngle("DATA[7:0]")  ; "DATA<7:0>"
bracketToAngle("CLK[0]")    ; "CLK<0>"
bracketToAngle("VDD")       ; "VDD"
bracketToAngle("A[3][1]")   ; "A<3><1>"
bracketToAngle("A[3")       ; "A<3"

最后一项说明:这个函数是字符转换器,不是总线名称校验器。输入中不配对的括号不会被补齐;原有尖括号也不会被改动。调用者还应保证输入为字符串,辅助过程没有独立的类型保护。

四、获取当前编辑的 schematic

cv = geGetEditCellView()
unless(cv
  error("请先打开要修改的 schematic。\n")
)
unless(cv~>viewName == "schematic"
  error("当前编辑视图不是 schematic。\n")
)

脚本不接收库名或 cell 名,而是使用当前编辑上下文。未取得 cv 时终止;viewName 不等于 schematic 时也终止。该名称检查不会接受 schematic_test 等自定义 view 名。

运行前核对当前活动窗口的库名、cell 名和 view 名,尤其是在同时打开多个原理图时。原代码没有检查可写状态,也没有自动将只读视图切换为可编辑状态。

五、修改 pin:遍历 terminals

foreach(term cv~>terminals
  oldName = term~>name
  newName = bracketToAngle(oldName)
  unless(oldName == newName
    term~>name = newName
    pinCount = pinCount + 1
  )
)

这一段修改的是 terminal 对象的 name。只有转换前后不同的对象才会被赋值和计数。因此 pinCount 是发生修改的 terminal 数量,不是替换的括号字符数,也不是 pin 图形数量。

代码没有单独遍历 pin 图形、symbol terminal 或关联 net 来同步赋值。名称修改后应检查原理图连接性及接口一致性,不能仅凭 terminal 赋值成功就认定所有关联对象都已同步。

六、修改 label:遍历 shapes

foreach(fig cv~>shapes
  when(fig~>objType == "label"
    oldName = fig~>theLabel
    when(stringp(oldName)
      newName = bracketToAngle(oldName)
      unless(oldName == newName
        fig~>theLabel = newName
        labelCount = labelCount + 1
      )
    )
  )
)

先筛选 label 对象,再确认 theLabel 为字符串,随后转换并赋值。这里并没有进一步判断 label 是否真正附着在 wire 上:只要满足对象类型和文本条件,就会处理。因此包含方括号的普通说明文字也在此代码的处理范围内。

labelCount 统计发生变化的 label 对象数量。它不是线段数量,也不直接代表更名的独立 net 数量。需要仅修改网络标注时,应先识别目标标签关系,再实现更严格的筛选。

七、在 CIW 中加载与运行

  1. 先复制或备份目标 cellView,使用可编辑的测试原理图。
  2. 将完整代码保存为 convert_schematic_brackets.il。
  3. 打开需要处理的 schematic,并核对当前编辑上下文。
  4. 在 CIW 中加载脚本,再调用 convertSchematicBrackets()。
  5. 检查 PIN、LABEL 日志,核对显示名称与连接性,并查看检查告警和保存结果。
CIW
load("convert_schematic_brackets.il")
convertSchematicBrackets()

load 的文件位置仅为示例;使用时填写实际可访问的文件位置。辅助过程与主过程需一起加载。

八、日志与保存结果不能混为一谈

; 格式示例,不是实际测试结果
PIN: DATA[7:0] -> DATA<7:0>
LABEL: CLK[0] -> CLK<0>
完成:修改 1 个 pin 名、1 个 label。请检查 CIW 的 schCheck 告警。

原代码依次调用 schCheck(cv)、dbSave(cv),然后打印完成信息,但没有判断 dbSave 的返回值,也没有根据 schCheck 的结果决定是否保存。因此“完成”日志只表示执行到了该输出语句,不是保存成功或检查无告警的证明。

它还会保存当前 cellView 内已有的其他未保存修改,而不仅是本次括号转换。执行前应明确原理图当前的修改状态。

九、使用前重点核对

十、工程化改进方向

正式使用时,可在修改前生成 oldName/newName 对照清单,检查重名并让操作者审核;为 label 增加网络关系筛选;记录修改对象、检查结果及保存状态;在小测试集通过后再处理真实设计。以上是改进方向,本教程没有把未实现的保护措施描述成原脚本已具备的能力。

总结

这段 SKILL 将字符串转换与数据库遍历分开:bracketToAngle 负责逐字符转换,convertSchematicBrackets 负责修改当前 schematic 的 terminal 名称和 label 文本,再执行检查与保存。示例代码按原逻辑保留,本文未在实际 Virtuoso 环境中运行,不代表已完成兼容性或连接性验证。