在 IC 设计部门承接新 fab 工艺节点时,往往需要从零搭建 Virtuoso 设计环境。本文梳理配置流程中涉及的关键文件与操作步骤。


一、PDK 是什么

PDK(Process Design Kit) 是 fab 交付给设计团队的工艺库包,通常包含:

内容 说明
Technology Library(技术库) 层定义、via 规则、连接规则等工艺参数
器件 SPICE/Spectre 模型文件 用于仿真 NMOS/PMOS 及 IP 器件特性
原语符号库 / 布局库 Virtuoso 中可直接调用的 cell
DRC / LVS 规则文件 供 Pegasus / Calibre 等工具使用
display.drf 每一层的颜色与填充样式
cds.lib / libInit.il 库定义与初始化脚本(PDK 标准交付件)

Cadence 另提供通用 PDK(如 gpdk045ADVGPDK)供学习与开发使用,可在 Process Design Kits (PDK) Downloads 页面获取。


二、Cadence 的文件搜索机制(CSF)

Virtuoso 启动时通过 CSF(Cadence Setup Search File)机制 依序搜索所有配置文件,入口是 setup.loc

setup.loc 的默认搜索顺序(从高到低优先级):

1
2
3
4
5
6
7
8
.                      # 当前工作目录
@LIBRARY               # cds.lib 中定义的各库目录
$CDS_WORKAREA          # 工作区(若已定义)
$CDS_SEARCHDIR         # 工具启动时设置
$HOME                  # 用户主目录
$CDS_PROJECT           # 项目目录(若已定义)
$CDS_SITE              # 站点公共目录(默认 install_dir/share/local)
$TOOL_INST_ROOT/share  # Cadence 安装目录

对于每一个路径,CSF 会依次在 <path>/.cadence/<path>/<path>/cdssetup/ 三个子目录下查找目标文件,找到即停止

可用以下命令调试搜索结果:

1
cdswhich -debug setup.loc

配置建议:公司/fab 级公共配置放 $CDS_SITE;项目级配置放 $CDS_PROJECT;个人偏好放 $HOME;当前工程放工作目录。不要修改 Cadence 安装目录下的默认 setup.loc,应新建自己的副本。


三、关键配置文件

3.1 cds.lib — 库定义文件

cds.lib 是 Library Manager 的核心,定义 Virtuoso 可访问的所有库路径。

1
2
3
4
5
6
7
8
# 包含 Cadence 内建 analogLib
INCLUDE $CDS_INST_DIR/tools/dfII/etc/cdslib/artist/cds.lib

# 包含 fab PDK 提供的库定义(PDK 通常自带 cds.lib)
INCLUDE $PDK_HOME/cds.lib

# 直接定义用户设计库
DEFINE  myProject  /home/user/designs/myProject

启动 Virtuoso 时可通过 -cdslib 参数指定非默认路径的 cds.lib

1
virtuoso -cdslib /path/to/project/cds.lib

注意:-cdslib 是启动时的一次性读取。后续在 Library Manager 中新增或删除库,仍会写入当前工作目录下的 cds.lib


3.2 .cdsinit — 启动初始化脚本

.cdsinit 是 SKILL 脚本,Virtuoso 启动时自动执行一次。

默认搜索顺序

  1. $CDS_INST_DIR/tools/dfII/local/
  2. 当前工作目录 ./
  3. $HOME/

也可通过 csfLookupConfig 文件将其纳入 CSF 搜索路径。

典型内容示例(lab 或公共 $CDS_SITE 级别):

; 加载 fab PDK 的初始化脚本(PDK 通常提供此文件)
load("/pdk/myFabPDK/cdssetup/cdsinit.il")

; 自动打开 Library Manager
ddsOpenLibManager()

3.3 .cdsenv — 环境变量设置文件

.cdsenv 控制各工具窗口的默认行为,格式为:

1
tool[.section]  setting  type  value

其搜索顺序受环境变量 CDS_LOAD_ENV 控制,常用值:

行为
CSF(推荐) setup.loc 搜索所有 .cdsenv
CWDElseHome 先找当前目录,再找 $HOME
addCWD 先加载 $HOME/.cdsenv,再叠加当前目录

3.4 display.drf — 层显示资源

fab PDK 通常提供专属的 display.drf,定义每一工艺层的颜色与填充样式。可通过 .cdsinit 加载:

hiLoadColorMap("/pdk/display/display.drf")

四、工艺库(Technology Library)的挂载

每个用户设计库需要 attach 到 fab 提供的 Technology Library,否则无法获取层定义和设计规则。

界面操作:Library Manager → 右键设计库 → Technology File for Library

SKILL 操作(可写入 libInit.il):

techBindTechFile(ddGetObj("myDesignLib") "/pdk/tech/fabTech.tf")

Technology Library 包含:层次定义(layer purpose pairs)、via / contact 规则、工艺参数等,是 DRC、LVS 以及参数提取的基础。


五、器件模型(Device Model)的接入

PDK 中的器件模型通常是 Spectre 格式(.scs 文件,内部按工艺角(corner)分成多个 section:

1
2
3
4
5
6
7
8
9
10
11
// 典型模型文件结构
simulator lang=spectre

section tt
  model nmos_lvt nmos ...
  model pmos_lvt pmos ...
endsection tt

section ff
  ...
endsection ff

5.1 推荐方式:libInit.il(PDK 级,对所有用户透明)

libInit.il 放在 PDK 库目录中,Virtuoso 打开该 PDK 库时自动执行,是 Cadence 官方推荐的模型注册位置。

; 文件:/pdk/myFabPDK/libInit.il
; 使用 ADE 会话回调,确保在 ADE 完全初始化后再添加模型

ddRegPostOpenLib("myFabPDKLib"
  lambda(nil
    asiSetEnvOptionVal(asiGetTool('spectre) "modelFiles"
      list(
        list("/pdk/models/spectre/tt_27c.scs"  "tt")
        list("/pdk/models/spectre/ff_27c.scs"  "ff")
        list("/pdk/models/spectre/ss_27c.scs"  "ss")
        list("/pdk/models/spectre/sf_27c.scs"  "sf")
        list("/pdk/models/spectre/fs_27c.scs"  "fs")
      )
    )
  )
)

5.2 .cdsenv 方式(项目/用户级)

多个模型文件用空格分隔,section 跟在文件路径后以分号连接:

1
spectre.envOpts  modelFiles  string  "/pdk/models/tt.scs;tt /pdk/models/res.scs"

5.3 .cdsinit SKILL 方式(用户级,不推荐用于 PDK 模型)

; 单文件单 section
asiSetEnvOptionVal(asiGetTool('spectre) "modelFiles"
  '(("/pdk/models/models.scs" "tt")))

; 多文件多 section
asiSetEnvOptionVal(asiGetTool('spectre) "modelFiles"
  list(
    list("/pdk/models/models.scs" "tt_bip")
    list("/pdk/models/models.scs" "tt_mos")
  ))

; "#" 开头表示该条目为未勾选状态(inactive)
asiSetEnvOptionVal(asiGetTool('spectre) "modelFiles"
  '(("#" "/pdk/models/ff.scs" "ff")
    ("/pdk/models/tt.scs"    "tt")))

不推荐在 .cdsinit 中配置 PDK 模型,而是推荐 libInit.il。原因:.cdsinit 是用户专属文件,不可移植;PDK 升级后容易残留旧路径,导致 ADE 仍引用旧版本模型(参见 ADE still refers to old PDK model files)。此外,如果 PDK 不更新而模型需要更新,此时需要单独处理初始化脚本里的模型文件路径。

5.4 ADE 界面操作(手动,适合临时测试)

1
2
3
4
ADE Explorer / Assembler → Setup → Model Library Setup
  → Add File → 选择 .scs 文件
  → 在 Section 列填写 corner 名称(如 tt)
  → 勾选需要激活的 corner

设置会随 maestro view 保存到设计库中持久化。


六、推荐工程目录结构

1
2
3
4
5
6
project/
├── cds.lib          # 项目库定义(INCLUDE PDK + DEFINE 用户库)
├── .cdsinit         # 项目级初始化(仅 load fab 提供的 cdsinit.il)
├── .cdsenv          # 项目级工具默认值
├── setup.loc        # 自定义 CSF 搜索路径(可选)
└── myDesignLib/     # 用户设计库(attach 到 fab Technology Library)

fab PDK 解压后通常包含以下目录,不需要用户单独维护

1
2
3
4
5
6
7
/pdk/myFabPDK/
├── cds.lib          # PDK 库路径定义,项目 cds.lib 中 INCLUDE 此文件
├── libInit.il       # 模型注册、工具初始化(打开 PDK 库时自动执行)
├── tech/            # Technology File / Technology Library
├── models/          # Spectre 器件模型文件(含各工艺角)
├── display/         # display.drf 层颜色定义
└── cdssetup/        # cdsinit.il、.cdsenv 模板(供项目引用)

七、各配置层级汇总

配置文件 推荐放置层级 作用
cds.lib 项目工作目录 声明所有可见库(INCLUDE PDK + DEFINE 用户库)
setup.loc $CDS_SITE 或项目目录 自定义 CSF 搜索路径
libInit.il PDK 库目录(PDK 提供) 库打开时自动注册模型、加载工具
.cdsinit $CDS_SITE / 项目目录 Virtuoso 启动时执行,load PDK 的 cdsinit.il
.cdsenv $CDS_SITE / $HOME 工具默认参数,不用于模型路径配置
display.drf PDK 提供,.cdsinit 中 load 层颜色与填充

附录:libInit.il 的自动加载机制详解

参考:Cadence ASK 官方文档 loading sequenceSKILL to reload libInit.il

一、自动加载机制

不需要.cdsinit 中手动 load("libInit.il")。只要库在 cds.lib / lib.defs 中被 DEFINE,DFII 框架在首次访问该库时会自动加载其 libInit.il

触发”首次访问”的典型场景:

  • Library Manager 启动时扫描到该库
  • 打开该库下的任意 cell(layout、schematic 等任意视图)
  • 在 CIW 的 File → recent history 中涉及该库的 cell view

二、多库时的加载顺序

当打开一个设计库中的 cell,该 cell 引用了工艺库和标准单元库时,三个库的 libInit.il 按以下顺序依次加载:

  1. Design Library(用户设计库)的 libInit.il
  2. Standard Library(标准单元库)的 libInit.il
  3. Technology Library(工艺库 / PDK 库)的 libInit.il

即 PDK 工艺库的 libInit.il 最后加载。各库之间的加载由”首次访问”时序决定。

三、重要限制

每个库的 libInit.il 在一个 Virtuoso session 中只加载一次。此后:

  • 在 Library Manager 执行 View → Refresh不会重新触发 libInit.il 的加载;
  • libInit.il 文件内容有更新,只能通过手动 loadi()重启 Virtuoso 使其生效。

如果需要在 Refresh 时自动重新加载,可在 .cdsinit 中注册如下 trigger:

procedure(abRefreshLibInit()
  let((fileName)
    foreach(libId ddGetLibList()
      foreach(fileName '("libInit.il" "libInit.ils")
        fileId = ddGetObj(libId~>name nil nil fileName)
        when(fileId && (fileName = ddGetObjReadPath(fileId)) &&
             isReadable(fileName)
          loadi(fileName)
        )
      )
    )
    t
  )
)

procedure(abRegRefreshLibInit()
  ddRegTrigger("PostUpdateLibList" 'abRefreshLibInit)
)
abRegRefreshLibInit()

四、小结

问题 结论
是否需要在 .cdsinit 中手动 load PDK 的 libInit.il 不需要,DEFINE 库后 DFII 自动处理
attach 到工艺库是 libInit.il 被加载的前提吗? 不是,任何 DEFINE 的库首次访问即触发
每次打开 Virtuoso 都会重新加载 libInit.il 吗? 是,但每次 session 内只加载一次
Refresh 能重新加载 libInit.il 吗? 不能,需手动 loadi() 或重启

参考资料

本文内容均参考自以下 Cadence ASK 官方文档(需登录访问):