Featured image of post Calibre+TVF输出NET(电源和地)的GDS

Calibre+TVF输出NET(电源和地)的GDS

说是脚 本,其实还是一个 tvf , 上期《用TVF输出只有label的LAYER简化GDS》反响不错, 其实稍加更改可以输出指定名称的 net 的GDS, 每个名称输出一个GDS, 尤其适用于 powerground 的提取。用 calibre -drc 跑一遍这个 tvf 就可以了

对比

与《用TVF输出只有label的LAYER简化GDS》相比以有下变化

  • 前者是抓取 所有text , 当前是 抓取 指定TEXT
  • 前者用了 net area ratio, 当前直接用 net
  • 前者输出所有结果到 同一GDS , 当前输出到 不同GDS

预览

  • 输入 input
  • out1 out3
  • bit out out4

相同部分

第一到第六步不变, 同 《用TVF输出只有label的LAYER简化GDS》

第七步:提取指定列表NET-GDS

这是整个流程的核心步骤,目的是从超大版图中筛选出指定label的金属层网络,结果将GDS分割成以 label名为名称的NET的网络的多个GDS, 方便查看每个NET或抽取RCX

分两步处理:先用NET 命令抓取所指定 layer , 再用 DFM 命令将结果按 layer Number 写成新的 GDS

# 定义需要单独导出GDS的NET名称
set outNetList [list vss vdd net<4>]

# 外层循环:遍历NET, 并为每个NET导出GDS
for {set i 0} {$i<[llength $outNetList]} {incr i } {
  # 提取当前遍历到的原始网络名(如vss、net<4>)
  set NET [lindex $outNetList $i]
  
  # 处理网络名中的特殊字符:尖括号< >在Calibre/文件命名中是非法字符,会导致层名/文件名报错
  # 判断当前网络名是否包含右尖括号>,若包含则进入字符替换逻辑
  if {[string last ">" ${NET}] != -1} {
    # 将网络名中的<和>统一替换为#,生成合法的网络别名(如net<4> → net#4#)
    set NET_ [string map {"<" "#" ">" "#"} ${NET} ]
  } else {
    # 无特殊字符的网络名(如vss/vdd),直接使用原名称作为合法别名
    set NET_ ${NET}
  }

  # 内层循环:遍历所有版图层列表ALLLAYER(金属/过孔层,如M6/V56/M5),为当前网络提取各层的版图区域
  for {set j 0} {$j<[llength $ALLLAYER]} {incr j 1 } {
    # 提取当前遍历到的版图层名(如M6、V56、M5)
    set MX [lindex $ALLLAYER $j]
    # 核心TVF命令:创建专属层,层名为「合法网络别名_版图层名」,层内容为「当前版图层中属于目标网络的区域」
    # 例:vss_M6 → M6层中所有属于vss网络的版图区域
    SETLAYER ${NET_}_${MX} = ${MX} NET \"${NET}\"
    # 保留新建的专属层,COPY关键字表示将该层结果存入Calibre结果集,为后续导出GDS做准备
    RULECHECK ${NET_}_${MX}  {
      COPY ${NET_}_${MX}
    }
  }

  # 核心导出命令:为当前目标网络导出专属GDS文件,仅包含该网络在各层的版图区域
  # 解决超大版图整层导出冗余的问题,实现「单网络精准导出GDS」(如仅导出vss网络的所有层GDS)
  RULECHECK  ${NET_}_${MX}_GDS {
    # 导出GDS文件,文件名为「合法网络别名_最后一个版图层名.gds」,存储该网络的所有层版图
    DFM RDB GDS ${NET_}_${MX}.gds \
    ${NET_}_M6 38 \  # 映射:网络专属层vss_M6 → 物理层号38(原M6A层,与前文层映射一致)
    ${NET_}_V56 39 \ # 映射:网络专属层vss_V56 → 物理层号39(原V56层)
    ${NET_}_M5 33 \  # 映射:网络专属层vss_M5 → 物理层号33(原M5A层)
    ${NET_}_V45 32 \ # 映射:网络专属层vss_V45 → 物理层号32(原V45层)
    ${NET_}_M4 31 \  # 映射:网络专属层vss_M4 → 物理层号31(原M4A层)
    ${NET_}_V34 29 \ # 映射:网络专属层vss_V34 → 物理层号29(原V34层)
    ${NET_}_M3 28    # 映射:网络专属层vss_M3 → 物理层号28(原M3A层)
  }
}

核心代码知识点解析

这部分代码融合了TCL 基础语法Calibre TVF 专属命令,是实现「指定网络精准导出」的关键,这里拆解几个核心点,方便大家理解和修改:

  1. TCL 列表遍历llength $outNetList获取网络列表长度,lindex $outNetList $i按索引提取单个网络,是 TCL 遍历列表的标准写法,适配任意长度的网络列表;
  2. 特殊字符处理string last ">" ${NET}判断是否包含尖括号,string map实现字符批量替换,解决 Calibre层名 / 文件名非法字符问题(Calibre 不支持< > / \ :等特殊字符);
  3. TVF 层创建SETLAYER A = B NET "C"是 TVF 筛选网络的核心语法,表示从 B 层中提取属于 C 网络的区域,创建为新层 A,精准过滤非目标网络的版图;
  4. GDS 导出映射DFM RDB GDS 文件名.gds 新层名 物理层号实现 Calibre 结果层到 GDS 物理层的映射,层号需与原始版图的 GDS 层号一致,否则后续工具无法识别。

实操关键注意事项

实际跑脚本时,这几个点直接决定脚本能否正常运行,也是新手最容易踩坑的地方,务必注意:

1. 提前定义ALLLAYER列表

脚本中用到的ALLLAYER所有需要提取的金属 / 过孔层列表,需在该段代码前提前定义,格式如下(根据自己的工艺层调整):

# 定义需要提取的金属层+过孔层,按从上到下/从下到上顺序均可
set ALLLAYER [list M6 V56 M5 V45 M4 V34 M3]

2. 支持任意数量的目标网络

outNetList列表可按需增删,比如只需提取电源地则写[list vss vdd],需要提取多个信号网络则写[list vss vdd net<0> net<1> core_vdd],脚本会自动遍历并逐个导出 GDS;

# 定义需要单独导出GDS的NET名称
set outNetList [list vss vdd net<4>]

3. 特殊字符处理可拓展

若你的网络名包含其他非法字符(如/*),可在string map中补充替换规则,示例:

# 拓展处理/和*,替换为_
set NET_ [string map {"<" "#" ">" "#" "/" "_" "*" "_"} ${NET} ]

4. 层号映射必须与工艺一致

DFM RDB GDS后的数字层号是 GDS 的物理层号,不是工艺层名,需与你的工艺 GDSII 层表完全匹配,若层号错误,导出的 GDS 会出现层丢失 / 层识别错误

运行TVF

脚本编写完成后,将其保存为extract_net_gds.tvf(命名随意)

启动 calibre DRC GUI, rule部分填入 extract_net_gds.tvf, 推荐顺手 Load 一下。 正常 run DRC

运行结果

  • 脚本运行完成后,在当前目录下会生成多个 GDS 文件,文件名格式为网络名_最后一层名.gds(如vss_M3.gdsnet#4#_M3.gds),每个文件对应一个指定网络的所有层版图。
-rwxr-xr-x 1 root root 1.5K mmm dd hh:mm net#4#_M3.gds
-rwxr-xr-x 1 root root 1.5K mmm dd hh:mm vdd_M3.gds
-rwxr-xr-x 1 root root 1.5K mmm dd hh:mm vss_M3.gds
  • DRC report 可以手动点亮 out1

总结

本文在上一期 TVF 提取 label 层的基础上,通过指定网络筛选循环遍历导出特殊字符处理,实现了单个网络精准导出 GDS的功能,尤其适合电源(vdd)、地(vss)网络的提取,是超大规模版图设计中提升后端处理效率的实用小技巧。

该方法的核心是Calibre TVF 的SETLAYER ... NET语法TCL 的循环遍历,代码简洁、易修改、可拓展,只需根据自己的工艺层和目标网络做简单调整,即可快速落地使用。

后续会继续分享 Calibre TVF/SVRF 的实用技巧,比如如何批量提取版图中的接触孔、如何自动生成版图报告等,感兴趣的小伙伴可以持续关注~

如果在使用过程中遇到问题,欢迎在评论区留言交流,一起探讨解决!

完整代码

#!tvf
#####################################
# release `by chiplayout.net`
# calibre version: 2016
# var: MAPLIST, ALLLAYER, outNetList
####################################

namespace import tvf::*
VERBATIM {
PRECISION 1000
RESOLUTION 1
DRC KEEP EMPTY NO
TEXT DEPTH PRIMARY
DRC CELL TEXT NO
DRC MAP TEXT YES
DRC MAP TEXT DEPTH PRIMARY
DRC MAXIMUM RESULTS ALL
}

set MAPLIST [list \
 "45 0 M6T TEXTTYPE" \
 "44 0 M5T TEXTTYPE" \
 "43 0 M4T TEXTTYPE" \
 "42 0 M3T TEXTTYPE" \
 "38 0 M6A DATATYPE" \
 "39 0 V56 DATATYPE" \
 "33 0 M5A DATATYPE" \
 "32 0 V45 DATATYPE" \
 "31 0 M4A DATATYPE" \
 "29 0 V34 DATATYPE" \
 "28 0 M3A DATATYPE" \
 "38 1 M6R DATATYPE" \
 "33 1 M5R DATATYPE" \
 "31 1 M4R DATATYPE" \
 "28 1 M3R DATATYPE" \
]

foreach LAY1 $MAPLIST {
  set LAY1_NU [lindex $LAY1 0]
  set LAY1_DT [lindex $LAY1 1]
  set LAY1_NA [lindex $LAY1 2]
  set LAY1_TY [lindex $LAY1 3]
  set LAY1_MP [expr $LAY1_NU*100+$LAY1_DT]
  LAYER MAP $LAY1_NU $LAY1_TY $LAY1_DT $LAY1_MP
  LAYER $LAY1_NA $LAY1_MP
}

set ALLLAYER [list M6 V56 M5 V45 M4 V34 M3]

for {set i 0} {$i<[llength $ALLLAYER]} {incr i 2 } {
  set MX [lindex $ALLLAYER $i]
  setlayer $MX = ${MX}A NOT (OR ${MX}R)
  TEXT LAYER ${MX}T
  ATTACH ${MX}T ${MX}
}

for {set i 0} {$i<[llength $ALLLAYER]-2} {incr i 2 } {
  set MU [lindex $ALLLAYER $i]
  set VA [lindex $ALLLAYER [expr $i+1]]
  set MD [lindex $ALLLAYER [expr $i+2]]
  CONNECT $MU $MD BY $VA
}



set outNetList [list vss vdd net<4>]
for {set i 0} {$i<[llength $outNetList]} {incr i } {
  set NET [lindex $outNetList $i]
  if {[string last ">" ${NET}] != -1} {
    set NET_ [string map {"<" "#" ">" "#"} ${NET} ]
  } else {
    set NET_ ${NET}
  }
  for {set j 0} {$j<[llength $ALLLAYER]} {incr j 1 } {
    set MX [lindex $ALLLAYER $j]
    SETLAYER ${NET_}_${MX} = ${MX} NET \"${NET}\"
    RULECHECK ${NET_}_${MX}  {
      COPY ${NET_}_${MX}
    }
  }
  RULECHECK  ${NET_}_${MX}_GDS {
    DFM RDB GDS ${NET_}_${MX}.gds \
    ${NET_}_M6 38 \
    ${NET_}_V56 39 \
    ${NET_}_M5 33 \
    ${NET_}_V45 32 \
    ${NET_}_M4 31 \
    ${NET_}_V34 29 \
    ${NET_}_M3 28 
  }
}
陕ICP备20000710号
本站已运行15年5月22天
发表了400篇文章 · 总计14万2千字
最后更新:2026-02-07
Umami
Built with Hugo
Theme Stack designed by Jimmy