Virtuoso中使用leafValue提取Sweep结果

在 Virtuoso ADE Assembler 中,当同一个 Test 对设计变量进行参数扫描时,可以使用 leafValue() 从 Sweep 结果族中提取指定扫描点的数据。

典型应用包括:

例如,设计变量 N 扫描:

N = 1 16

同时温度由 Corner 设置:

temp = -40:10:120

希望在每个温度 Corner 下分别计算:

DeltaV1(temp) = Vdio1(N=16, temp) - Vdio1(N=1, temp)

此时可以使用 leafValue() 配合:

EvalType = sweeps

leafValue基本语法

基本形式为:

leafValue(
    expression
    "sweepVariable"
    sweepValue
)

各参数含义如下:

参数 含义
expression Sweep 产生的波形族或输出结果
"sweepVariable" Sweep 变量名称
sweepValue 需要提取的变量值

例如,从 N Sweep 中提取 N=16 的结果:

leafValue(Vdio1 "N" 16)

提取 N=1 的结果:

leafValue(Vdio1 "N" 1)

Cadence Calculator 中可以使用 leafValue() 从参数扫描结果中选择指定的 Sweep 点;选择两个不同点后,可以直接进行加减、比值等运算。(Cadence Community)

计算两个Sweep点的差值

假设基础输出名称为:

Vdio1

N 的扫描值为:

1 16

则差值表达式为:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

对应关系为:

DeltaV1 = Vdio1(N=16) - Vdio1(N=1)

这个计算发生在同一个 Test 的同一组 Sweep 结果中,不需要使用 calcVal()。

ADE输出配置

建议建立两个输出。

基础输出Vdio1

输出名称:

Vdio1

表达式为原始测量公式。例如,在瞬态仿真中读取 10 us 时的节点电压:

value(VT("/vdio1") 10u)

其 EvalType 设置为:

point

point 表示表达式在每个仿真点上独立计算。因此,每个温度和每个 N 都会得到一个 Vdio1 结果。

结果结构类似:

temp=-40, N=1   → Vdio1
temp=-40, N=16  → Vdio1

temp=-30, N=1   → Vdio1
temp=-30, N=16  → Vdio1

...

temp=120, N=1   → Vdio1
temp=120, N=16  → Vdio1

差值输出DeltaV1

输出名称:

DeltaV1

表达式:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

其 EvalType 设置为:

sweeps

EvalType=sweeps 使表达式在相关 Sweep 点完成之后,基于整个 Sweep 数据族进行计算,而不是在每个单独仿真点立即计算。(Cadence Community)

最终配置为:

输出名称 表达式 EvalType
Vdio1 原始测量表达式 point
DeltaV1 leafValue(Vdio1 "N" 16)-leafValue(Vdio1 "N" 1) sweeps

与Corner配合使用

当前仿真结构为:

每个温度 Corner
└── Sweep N = 1、16

由于 N 是 Sweep 维度,而温度是 Corner 维度,因此:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

会在每个温度 Corner 内分别计算。

结果关系为:

temp=-40:
    Vdio1(N=16, temp=-40)
    -
    Vdio1(N=1, temp=-40)

temp=-30:
    Vdio1(N=16, temp=-30)
    -
    Vdio1(N=1, temp=-30)

...

temp=120:
    Vdio1(N=16, temp=120)
    -
    Vdio1(N=1, temp=120)

当计算目标是“跨 Sweep 运算,但每个 Corner 保留一个独立结果”时,应选择 EvalType=sweeps,而不是 EvalType=all。Cadence 对该行为的说明是:sweeps 跨 Sweep 数据计算,并保留每个 Corner 的独立结果。(Cadence Community)

EvalType的区别

EvalType 表达式可访问的数据范围 典型用途
point 当前单个仿真点 普通电压、电流、延迟等测量
sweeps 当前 Corner 下的 Sweep 结果族 比较不同 Sweep 参数值
corners 对应 Sweep 点下的多个 Corner 求所有 Corner 的最大值或最小值
all Sweep 和 Corner 的全部结果 对所有结果统一统计

对于本例:

温度 = Corner
N = Sweep

因此使用:

DeltaV1 EvalType = sweeps

这样不会把不同温度的数据混合在一起。

EvalType=all 会让表达式看到 Sweep 和 Corner 两个维度的全部结果,通常不适合“每个温度单独计算一次差值”的需求。(Cadence Community)

标量输出和波形输出

leafValue() 返回的数据类型取决于第一个参数。

提取标量

如果 Vdio1 已经是标量:

value(VT("/vdio1") 10u)

则:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

返回标量差值。

这种方式适合:

提取波形

如果直接使用:

VT("/vdio1")

则:

leafValue(VT("/vdio1") "N" 16)
-
leafValue(VT("/vdio1") "N" 1)

返回两条瞬态波形之差。

对应关系为:

DeltaV1(t)
=
Vdio1(t, N=16)
-
Vdio1(t, N=1)

leafValue() 既可以用于波形族,也可以用于由各 Sweep 点标量结果构成的数据族。(Cadence Community)

常用运算

两个扫描点的绝对差值

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

平均到每个单位N的变化量

(
    leafValue(Vdio1 "N" 16)
    -
    leafValue(Vdio1 "N" 1)
) / (16 - 1)

相对变化率

(
    leafValue(Vdio1 "N" 16)
    -
    leafValue(Vdio1 "N" 1)
)
/
leafValue(Vdio1 "N" 1)

百分比变化率

100 *
(
    leafValue(Vdio1 "N" 16)
    -
    leafValue(Vdio1 "N" 1)
)
/
leafValue(Vdio1 "N" 1)

两个扫描点的平均值

(
    leafValue(Vdio1 "N" 16)
    +
    leafValue(Vdio1 "N" 1)
) / 2

两个扫描点的比值

leafValue(Vdio1 "N" 16)
/
leafValue(Vdio1 "N" 1)

使用除法时,需要检查分母是否可能为零。

直接对原始表达式使用leafValue

除了引用已有输出 Vdio1,也可以直接对原始波形表达式使用 leafValue()。

例如:

leafValue(VT("/vdio1") "N" 16)
-
leafValue(VT("/vdio1") "N" 1)

读取两条波形在 10 us 时的差值:

value(
    leafValue(VT("/vdio1") "N" 16)
    10u
)
-
value(
    leafValue(VT("/vdio1") "N" 1)
    10u
)

不过在 ADE Assembler 中,通常更推荐先建立基础输出:

Vdio1

再建立二次运算输出:

DeltaV1

这样能够清楚区分原始测量和跨 Sweep 运算,也便于定位 eval err。

多个Sweep变量

leafValue() 可以依次指定多个 Sweep 变量:

leafValue(
    expression
    "variable1" value1
    "variable2" value2
)

例如同时扫描:

N   = 1 16
VDD = 1.6 1.8 2.0

提取 N=16、VDD=1.8 的结果:

leafValue(
    Vdio1
    "N" 16
    "VDD" 1.8
)

leafValue() 支持通过多个“变量名称—变量值”参数对,从多维 Sweep 数据族中定位具体叶节点。(Cadence Community)

如果只指定:

leafValue(Vdio1 "N" 16)

那么 N 维度会被固定为 16,未指定的 VDD 维度仍会保留,返回结果可能仍然是一个 Family,而不是单个标量。

leafValue和calcVal的区别

leafValue

leafValue() 用于从一个 Sweep 数据族中提取指定参数点:

leafValue(Vdio1 "N" 16)

适合:

calcVal

calcVal() 主要用于建立 ADE 输出之间或不同 Test 之间的结果依赖,例如:

calcVal(
    "Vdio1"
    "reference_test"
)

不应在当前 Test 中使用下面的方式选择当前 Test 自己的另一个 Sweep 点:

calcVal(
    "Vdio1"
    "current_test"
    ?matchParams list(list("N" "16"))
    ?ignoreParams "rest"
)

这种写法会触发类似错误:

?matchParams cannot be used to retrieve output values
from the same test as where the expression is defined

对于同一个 Test 内的 N=1 和 N=16 比较,应改用:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

常见错误

EvalType仍为point

错误配置:

DeltaV1 EvalType = point

此时表达式只能看到当前单个仿真点,无法同时访问 N=1 和 N=16。

正确配置:

DeltaV1 EvalType = sweeps

Sweep变量名称不一致

表达式中的变量名称必须与 ADE 中完全一致:

leafValue(Vdio1 "N" 16)

如果实际变量名为 N,不要写成:

leafValue(Vdio1 "n" 16)

Sweep值不存在

如果实际 Sweep 为:

N = 1 8

则下面的表达式无法找到对应数据:

leafValue(Vdio1 "N" 16)

将数值写成字符串

对于数值型设计变量,通常使用:

leafValue(Vdio1 "N" 16)

而不是:

leafValue(Vdio1 "N" "16")

扫描值的数据类型应与结果族中的 Sweep 参数类型一致。

基础输出没有生成完整结果

Vdio1 应在每个 Sweep 点上正常求值:

Vdio1 EvalType = point

如果某个 N 或某个温度下基础输出为:

eval err
nil

那么后续的 leafValue() 差值表达式也无法得到有效结果。

使用了all导致Corner混合

对于:

温度 = Corner
N = Sweep

应使用:

EvalType = sweeps

如果使用:

EvalType = all

表达式可能同时跨越温度 Corner 和 N Sweep 进行运算,结果维度会与预期不同。

本例最终设置

基础输出:

Name:     Vdio1
EvalType: point
Expr:     原始Vdio1测量表达式

差值输出:

Name:     DeltaV1
EvalType: sweeps
Expr:
leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

仿真结构:

Corner:
    temp = -40:10:120

Sweep:
    N = 1 16

最终效果:

对于每个温度Corner:

DeltaV1(temp)
=
Vdio1(N=16, temp)
-
Vdio1(N=1, temp)

总结

当需要在同一个 Test 内比较不同参数扫描点时,使用:

leafValue(output "sweepVariable" sweepValue)

本例的核心表达式为:

leafValue(Vdio1 "N" 16)
-
leafValue(Vdio1 "N" 1)

输出设置为:

Vdio1   → EvalType = point
DeltaV1 → EvalType = sweeps

这样可以在每个温度 Corner 内,分别取得 N=1 和 N=16 的结果并完成差值运算。