在 Virtuoso 里用 ADE / CDL Out / NC Verilog 网表化 schematic 时,只要原理图里有 schematic pcell,netlister 就会在它的 subckt 名字后面挂一个 _pcell_0_pcell_1 … 这种 cyclic 后缀。单份网表用没问题;问题在于 —— 同一个 pcell 在不同 cell 里被取了不同参数实例化时,网表合并后会出现”名字相同但内容不同”的 subckt,引发仿真失败 / LVS 不匹配。本文基于 Cadence Support 文章 《How to add a unique suffix to a schematic pcell subckt name during netlisting》 整理新的 .cdsenv 控制方法。


1. 默认行为与隐患

假设原理图里有一个 schematic pcell abc_cell,被实例化后,netlist 出来类似:

block A 里

1
2
3
4
5
.subckt abc_cell_pcell_0 D G S B
XM1 D G S B xyz_nmos          // nmos 版本
.ends abc_cell_pcell_0

XI1 D1 G1 S1 B1 abc_cell_pcell_0

block B 里(同一份 pcell,但参数不同,最终展开成 pmos 版本)

1
2
3
4
5
.subckt abc_cell_pcell_0 D G S B
XM7 D G S B xyz_pmos          // pmos 版本
.ends abc_cell_pcell_0

XI5 D1 G1 S1 B1 abc_cell_pcell_0

两份网表分别看都没问题。但只要把它们 合并到同一份顶层网表(多 block / 分块仿真 / IP 集成 / LVS 时常见),就会出现两个 abc_cell_pcell_0 同名 subckt —— 一个 nmos、一个 pmos,仿真器要么报重定义,要么按”后定义覆盖前定义”得到错误结果,LVS 也会因为器件类型对不上而 mismatch。

早期方案:用 nlSetPcellName SKILL 函数(详见相关 KB 11253836)写自定义命名。可行,但需要写代码、覆盖面也有限,”想得不够全”就还是会撞名。

社区一直希望 Virtuoso 提供 原生、可由 .cdsenv 控制 的 pcell subckt 命名机制。从 IC6.1.8 ISR10 / ICADVM18.1 ISR10 开始,这一能力终于内建了。


2. 适用版本

新增的环境变量可用于以下版本及之后:

  • IC6.1.8.500.10(IC6.1.8 ISR10)
  • ICADVM18.1.500.10(ICADVM18.1 ISR10)

3. 两个新环境变量

控制 schematic pcell subckt 命名的核心变量都挂在 asimenv.netlist 下:

变量 类型 取值 作用
pcellNameGenerationStyle cyclic Default / UniqueKey / CustomFormat 选择整体命名策略
pcellNameCustomFormat string 形如 "l:%NAME-%VALUE,m:%NAME-%VALUE" 仅在 CustomFormat 下生效,定义后缀模板

下面分别看三种 style。


4. style = Default:保持原有行为

1
2
.cdsenv:
spectre.opts pcellNameGenerationStyle cyclic "Default"

准确路径写法(也可以放在 .cdsinit):

1
envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "Default")

行为与历史版本完全一致:每个 schematic pcell 实例按出现顺序拿到 _pcell_0_pcell_1 … —— 也就是上文那个会撞名的版本。等价于不设置这个变量


5. style = UniqueKey:长 UUID 后缀,彻底消除撞名

1
envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "UniqueKey")

或在 .cdsenv 里:

1
asimenv.netlist pcellNameGenerationStyle cyclic "UniqueKey"

效果:

1
subckt abc_cell_pcell_6830957405889745413 D G S B

后缀是一个长整型 UUID。同一份 pcell 在不同 cell / 不同参数下实例化,UUID 各不相同,合并网表时绝不撞名。

适用场景:

  • 不关心可读性、只想”一次性把撞名问题铲掉” 的批量流程(脚本化 IP 集成、自动化 LVS)。
  • ADE 在不同 cell 之间产生重复 subckt 时的兜底方案。

代价是名字非常长,对人 review 不友好。


6. style = CustomFormat:按参数拼有意义的后缀

1
2
envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "CustomFormat")
envSetVal("asimenv.netlist" "pcellNameCustomFormat" 'string "l:%NAME-%VALUE,m:%NAME-%VALUE,f:%NAME,w:%VALUE")

格式约定:

  • 多个参数用英文逗号 , 分隔。
  • 每段写法是 paramName:<格式>,其中 paramName 必须是该 pcell 的形参名(不是形参的会被忽略)。
  • %NAME 表示打印参数名(可选)。
  • %VALUE 表示打印参数值(可选)。
  • 同时给 %NAME%VALUE 时,用连字符 - 分隔

下面这个是文档里的标准例子:

模板片段 说明 实际后缀
l:%NAME-%VALUE l = 6n l6n
m:%NAME-%VALUE m = 3 m3
f:%NAME 只打印名字 f
w:%VALUE w = 2.5n 2_5n

最终生成的 subckt 名:

1
subckt abc_cell_pcell_l6n_m3_f_2_5n_6830957405889745413 D G S B

注意:即便用了 CustomFormat,netlister 仍会再补一个 UUID 兜底,确保唯一。

6.1 注意事项

  1. 小数点会被替换为下划线 _。例如 w = 2.5n → 后缀里写作 2_5n(SPICE / spectre 标识符不能含 .)。
  2. 不在 pcell 形参列表里的名字写了也没用,会被静默忽略。可以借此特性写一份”通吃”的模板,部分参数对某些 pcell 不存在也不报错。
  3. pcellNameCustomFormat 默认值是空串 ""。在 CustomFormat 模式下若未给模板,实际行为退化为 UniqueKey(只有 UUID 后缀)。

6.2 实例:analogLib 的 multibit pcell

analogLib/multibit 是个典型的 schematic pcell,常见参数:numbitspattern

设置:

1
2
envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "CustomFormat")
envSetVal("asimenv.netlist" "pcellNameCustomFormat" 'string "numbits:%NAME-%VALUE,pattern:%VALUE")

原理图里两个实例:一个 numbits=3, pattern=000,一个 numbits=5, pattern=11111

Spectre 网表:

1
2
3
4
5
6
7
8
// Library name: analogLib
// Cell name: multibit
// View name: schematic
//_expand:Yes_numbits:5_pattern:11111
subckt multibit_pcell_numbits5_11111_3915811363807132152 ref ref ref ref \
        ref ref
........
subckt multibit_pcell_numbits3_000_8405243096460152274 ref ref ref ref

auCdl 网表:

1
2
3
.SUBCKT multibit_pcell_numbits5_11111_3915811363807132152 a0 a1 a2 a3 a4 ref

.SUBCKT multibit_pcell_numbits3_000_8405243096460152274 a0 a1 a2 ref

可以看到:参数差异直接体现在 subckt 名字里,肉眼一眼就能区分两份 multibit;同时尾部仍有 UUID 兜底。


7. auCdl 用 GUI 出网表时的小坑

如果是用命令行 si ... 出 auCdl 网表,把上述 envSetVal(...) 写在 .simrc 即可。

但用 Virtuoso GUI: File > Export > CDL 时,需要二选一:

  • envSetVal 写在 .simrc,或
  • 在 Export 对话框里把 “Run in Background” 关掉(OFF)。

两个条件至少满足一个,CDL 出网表才会把 pcellNameGenerationStyle / pcellNameCustomFormat 真正吃进去。后台模式跑出来不带这些设置是常见踩坑。


8. 三种 style 对比

Style 后缀形式 可读性 是否绝对去重 适用场景
Default _pcell_0/1/2… 保证,跨 block 合并易撞 兼容旧流程;单独 block 仿真无合并需求
UniqueKey _<UUID> 自动化 / 批量 LVS / IP 集成时的兜底
CustomFormat _<参数>_<UUID> 中-高 是(UUID 兜底) Review 友好,又要保证唯一;推荐默认

9. 实战建议

  • 新流程默认开 CustomFormat,把核心区分参数(如 lwmnumbitspattern 等)放到模板里。这样 review 网表时一眼能看出哪个 subckt 对应什么参数,撞名也不可能发生。
  • 遗留项目如果不想动每个 cell 的 .cdsenv,可以在用户级 .cdsinit 里统一加 envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "UniqueKey"),作为 farm 级兜底。
  • 调到 UniqueKeyCustomFormat 后,老的 DSPF/SPEF 反标和老的 LVS rules 文件可能跟不上新名字。第一次切换之前,先在小项目上跑一次完整 netlist → DSPF → 反仿 → LVS 链路,确认上下游都能匹配新命名。
  • _schematic 后缀问题 区分开:_schematic 是因为 (lib, cell, view) 三元组重复触发的命名消歧,靠 Recreate Netlist 解;_pcell_X 是 schematic pcell 自身的命名规则,靠本文这两个变量解。

10. 小结

  • 默认的 _pcell_X 后缀只在单份网表内自洽,跨 block 合并时容易撞名 → 仿真错误 / LVS mismatch。
  • IC6.1.8.500.10 / ICADVM18.1.500.10 起,asimenv.netlist 下新增 pcellNameGenerationStylepcellNameCustomFormat,可以纯靠 .cdsenv / .cdsinit 控制 pcell subckt 命名。
  • UniqueKey 一劳永逸但难读;CustomFormat 兼顾可读性与唯一性,是推荐选项。
  • 用 GUI 出 auCdl 时记得 .simrc 或关闭 “Run in Background”,否则设置不生效。

参考