在做电路迁移或库整理时,经常会遇到需要把一个库下所有 cell 的指定引脚从 output 批量改为 input(或其他方向)的需求。逐个 cell 手动改既费时又容易遗漏,用 SKILL 脚本在 CIW 中批量处理是最高效的方式。

本文整理自 Cadence ASK,给出三种场景的完整脚本。


背景

Virtuoso 中引脚有两个层面的”方向”概念:

属性 说明
term~>direction 逻辑方向属性(input / output / inputOutput
pin~>fig~>master 引脚符号(basic/ipinbasic/opinbasic/iopin

两者相互独立。若只改逻辑属性,LVS/ERC 规则可以感知,但原理图上的三角方向箭头不会变;若还需要同步更换符号,则要同时替换 master。


方案一:只改 direction 属性,遍历整库指定引脚

适合只需修正电气属性、不追求符号外观一致的场合。

procedure(CCSchgPinDir(sourceLibName viewName pinList pinDir)
let((cv cellId pin_id)
   foreach(sourceCellName ddGetObj(sourceLibName)~>cells~>name
         cellId = ddGetObj(sourceLibName sourceCellName)
                foreach(view cellId~>views~>name
                        if(view == viewName
                        then
                        cv = dbOpenCellViewByType(sourceLibName sourceCellName view "" "a")
                        foreach(pin pinList
                                pin_id = dbFindTermByName(cv pin)
                                if(pin_id
                                then
                                printf("found pin %L in cell %L \n" pin sourceCellName)
                                pin_id~>direction = pinDir
                                else
                                printf("pin %L does not exist in cell %L \n" pin sourceCellName)
                                ) ;if
                                ) ;foreach pin
                        dbSave(cv)
                        dbClose(cv)
                        ) ;if
                        ) ;foreach view
        ) ;foreach cell
  ) ;let
) ;procedure

将上面代码保存为 CCSchgPinDir.il,在 CIW 执行:

1
2
3
4
5
6
7
load "CCSchgPinDir.il"

; 将 mylib 所有 schematic 视图中名为 A、Z、ZX 的引脚改为 input
CCSchgPinDir("mylib" "schematic" list("A" "Z" "ZX") "input")

; 同步更新 symbol 视图
CCSchgPinDir("mylib" "symbol" list("A" "Z" "ZX") "input")

pinDir 的合法值只有三个:"input""output""inputOutput"(驼峰,注意大小写)。


方案二:同时替换 pin master,针对单个 cell

若要把 opin 符号换成 ipin(三角箭头方向随之改变),需要用 CCSchgPinDirMaster。官方脚本以单个 cell 为粒度:

procedure(CCSchgPinDirMaster(sourceLibName sourceCellName pinList newDirection)
let((cv cv_sym pin_id pin_cell)
case(newDirection
    ("input"       pin_cell="ipin")
    ("output"      pin_cell="opin")
    ("inputOutput" pin_cell="iopin")
    (t error("Invalid direction %L, valid: input, output, inputOutput\n" newDirection))
    )
cv_sym = dbOpenCellViewByType("basic" pin_cell "symbol" "schematicSymbol" "r")
cv     = dbOpenCellViewByType(sourceLibName sourceCellName "schematic" "schematic" "a")
foreach(pin pinList
        pin_id = dbFindTermByName(cv pin)
        if(pin_id
            then
            printf("found %L pin %L in cell %L \n" pin_id~>direction pin sourceCellName)
            pin_id~>direction = newDirection
            foreach(pin1 pin_id~>pins
                pin1~>fig~>master = cv_sym
                )
            else
            printf("pin %L does not exist in cell %L \n" pin sourceCellName)
           )
           )
dbSave(cv)
dbClose(cv)
) ;let
) ;procedure

在 CIW 调用:

1
CCSchgPinDirMaster("mylib" "mycell" list("A" "Z" "ZX") "input")

方案三(推荐):遍历整库所有 cell 所有引脚,direction + master 一次性全改

官方脚本不直接提供”遍历所有引脚”的版本,将上面两个思路合并即可:

procedure(CCSchangeAllPinDir(libName viewName newDirection)
let((cv cv_sym pin_cell)
  case(newDirection
    ("input"       pin_cell="ipin")
    ("output"      pin_cell="opin")
    ("inputOutput" pin_cell="iopin")
    (t error("Invalid direction: %L\n" newDirection))
  )
  cv_sym = dbOpenCellViewByType("basic" pin_cell "symbol" "schematicSymbol" "r")
  foreach(cellName ddGetObj(libName)~>cells~>name
    foreach(view ddGetObj(libName cellName)~>views~>name
      if(view == viewName then
        cv = dbOpenCellViewByType(libName cellName view "" "a")
        foreach(term cv~>terminals
          term~>direction = newDirection
          foreach(pin term~>pins
            pin~>fig~>master = cv_sym
          )
          printf("Set %L/%L pin %L -> %L\n" libName cellName term~>name newDirection)
        )
        dbSave(cv)
        dbClose(cv)
      )
    )
  )
)
)

在 CIW 调用:

1
2
3
4
5
6
7
load "CCSchangeAllPinDir.il"

; 将 mylib 的所有 schematic 视图中每个引脚都改为 input
CCSchangeAllPinDir("mylib" "schematic" "input")

; 将 symbol 视图引脚改为 output
CCSchangeAllPinDir("mylib" "symbol" "output")

关键 SKILL API 速查

API 作用
ddGetObj(lib)~>cells~>name 获取库下所有 cell 名称列表
ddGetObj(lib cell)~>views~>name 获取某 cell 的所有视图名
dbOpenCellViewByType(lib cell view type "a") 以 append 模式打开视图(可写)
cv~>terminals 视图中所有逻辑引脚(term)
dbFindTermByName(cv pinName) 按名称查找单个 term
term~>direction = "input" 修改方向属性
pin~>fig~>master = cv_sym 替换引脚 master 符号
dbSave(cv) / dbClose(cv) 保存并关闭 cellview

注意事项

  • 脚本以 append("a")模式打开 cellview,会直接写磁盘,操作前建议先备份库目录。
  • CCSchgPinDir(方案一)不改 pin master,原理图上三角箭头外观不变;若 LVS 规则依赖 master 类型,需用方案二/三。
  • 方案三遍历 cv~>terminals,会覆盖该视图中所有引脚,请确认不需要保留部分引脚的原方向。
  • 对于 symbol 视图,只有 pin instance 存在于 symbol 中才需要同步修改;部分纯连线 symbol 可能没有 pin instance,不需要单独处理。