在 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。
早期方案:用
nlSetPcellNameSKILL 函数(详见相关 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):
1envSetVal("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 注意事项
- 小数点会被替换为下划线
_。例如w = 2.5n→ 后缀里写作2_5n(SPICE / spectre 标识符不能含.)。 - 不在 pcell 形参列表里的名字写了也没用,会被静默忽略。可以借此特性写一份”通吃”的模板,部分参数对某些 pcell 不存在也不报错。
pcellNameCustomFormat默认值是空串""。在CustomFormat模式下若未给模板,实际行为退化为UniqueKey(只有 UUID 后缀)。
6.2 实例:analogLib 的 multibit pcell
analogLib/multibit 是个典型的 schematic pcell,常见参数:numbits、pattern。
设置:
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,把核心区分参数(如l、w、m、numbits、pattern等)放到模板里。这样 review 网表时一眼能看出哪个 subckt 对应什么参数,撞名也不可能发生。 - 遗留项目如果不想动每个 cell 的 .cdsenv,可以在用户级
.cdsinit里统一加envSetVal("asimenv.netlist" "pcellNameGenerationStyle" 'cyclic "UniqueKey"),作为 farm 级兜底。 - 调到
UniqueKey或CustomFormat后,老的 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下新增pcellNameGenerationStyle与pcellNameCustomFormat,可以纯靠.cdsenv/.cdsinit控制 pcell subckt 命名。 UniqueKey一劳永逸但难读;CustomFormat兼顾可读性与唯一性,是推荐选项。- 用 GUI 出 auCdl 时记得
.simrc或关闭 “Run in Background”,否则设置不生效。
参考
- Cadence Support: How to add a unique suffix to a schematic pcell subckt name during netlisting using ADE for Spectre and Virtuoso CDL Out for auCdl and verilog; How to have extension other than _pcell(Article ID
a1O3w000009xyhQEAQ,内部 CCR# 2183719) - Cadence Support: How to prefix pcell subckt instances uniquely in ADE(KB 11253836,
nlSetPcellNameSKILL 自定义方案) - Cadence ADE User Guide:Generating Customized Cellnames
- 同站相关:Spectre netlister 为什么给 subckt 名字加 _schematic 后缀?