ngspice no such vector 报错:.meas 引用不存在的节点与退出码 0 的测量级失败
更新时间:2026-11-11。长尾排查篇,属于 EDA 报错排查系列,汇总入口见 开源 EDA 报错排查导航。一个 RC 充放电网表,瞬态仿真跑得好好的,结尾却冒出
Error: measure tcross when(WHEN) : no such vector as 'v(outx)',而脚本打印的退出码竟然是 0。本文用一份只错一个字母的网表,把这条测量级报错的完整演进、vector 命名空间机制和 CI 判据讲透。
首屏答案:meas_bad.cir 的测量语句 .meas tran tcross when v(outx)=0.5 cross=1 引用了节点 outx,但网表里真实存在的节点只有 in 和 out。ngspice 先在解析期打 Warning: can't parse 'outx': ignored,瞬态分析本身正常完成并产出 213 行数据,到测量阶段才在 vector 命名空间里找不到 v(outx),报 no such vector 与 .meas ... failed!。关键反差是:测量失败不影响分析成功,进程退出码仍是 0,只判断 $? 的 CI 会漏掉这类失败。把引用改回真实节点 v(out) 后,测量成功打印 tcross = 7.43572e-06。
这张对比卡对应全文主线:左右两栏的网表只差一个字母,仿真分析层都成功,差别只在测量层有没有拿到向量;第三栏给出工程上的收口方式。记住卡片底部这句判词,后面所有现象都围绕它展开。
本文要回答的问题
- 引用不存在节点的
.meas语句,ngspice-47 的完整报错原文是什么,警告和错误分别出现在什么阶段? - 瞬态分析已经跑完并产出数据,为什么测量还会报
no such vector? - 测量失败后进程退出码为什么是 0,它与退出码 1 的硬错误有什么本质区别?
- CI 或自动化脚本怎样才能可靠地抓住这类测量级失败?
- 正确的修复改哪一行,复跑输出如何确认闭环?
一、完整报错原文
出问题的 meas_bad.cir 是一个 PWL 电压源驱动的 RC 充放电电路,节点只有 in 和 out,但测量语句把 out 拼成了 outx:
Measure references a non-existent vector name
V1 in 0 PWL(0 0 1u 1)
R1 in out 1k
C1 out 0 10n
.tran 0.1u 20u
.meas tran tcross when v(outx)=0.5 cross=1
.print tran v(in) v(out)
.end执行 ngspice -b meas_bad.cir,日志原样摘录如下,未作润色:
$ ngspice -b meas_bad.cir
Warning: can't parse 'outx': ignored
Error: measure tcross when(WHEN) : no such vector as 'v(outx)'
.meas tran tcross when v(outx)=0.5 cross=1 failed!读这段输出要抓住两个时间点。第一行 Warning: can't parse 'outx': ignored 出现在网表解析期,ngspice 读到 .meas 里的 v(outx) 时无法把 outx 识别为任何已知对象,先警告并忽略这一片段,但整条语句被保留下来延后处理。随后 Doing analysis、Initial Transient Solution、213 行数据表依次正常产出,说明瞬态分析完全没有受影响。直到分析结束后的测量阶段,.meas 重新求值 when 表达式时才正式报错:no such vector as 'v(outx)',并紧跟一行 .meas ... failed! 宣告这条测量没有结果。
失败段的完整终端实录如下,注意警告、数据表与错误在同一次运行里的先后顺序:
二、工具与版本
本次实验在 macOS 本机以 ngspice 批处理模式完成,版本与日志头部一致:
- ngspice-47,KLU 稀疏矩阵求解器,可执行文件位于
/usr/local/bin/ngspice - 批处理入口
ngspice -b <netlist>,不进入交互界面 - 运行日期 2026-11-11,默认温度 TEMP/TNOM 均为 27 摄氏度
先固定版本,是因为 no such vector 的文案与 .meas 的解析容错行为随版本演进过。本文的警告措辞、错误格式和退出码只对 ngspice-47 负责;换大版本时应保留当次完整输出对照,不要凭文案反推行为。
三、根本原因:vector 命名空间里没有 v(outx)
3.1 ngspice 的向量是分析产物,不是网表文本
ngspice 在一次分析跑完后,会把结果组织成一组 vector(向量):每个实际节点对应一个节点电压向量,如 v(in)、v(out);每个电压源对应一个支路电流向量,如 v1#branch。这些名字构成当前 plot 的向量命名空间,.meas 的 when 表达式、let、print 引用的任何对象都必须在这个命名空间里能查到。SPICE 求解器如何从网表装配矩阵、产出节点电压序列,SPICE 仿真器:在数值上解一张非线性动态电路 有系统讲解。
下图画出从网表解析到测量求值的解析链路,红色是失败节点,蓝色是 ngspice 的正常动作:
读图抓住一条主线:解析期的警告不会中止任何东西,真正的硬失败发生在最右端的测量求值。命名空间里有什么,取决于网表实际声明了哪些节点和元件,而不是 .meas 里写了什么——文本里多写一个 outx 不会凭空创建节点。
3.2 同一套命名空间约束的三种触发场景
no such vector 不止拼写错误一种来源,常见触发有三类:
- 节点名拼错或大小写写错:本例的
outx,以及把Vout写成vout这类大小写不一致。 - plot 切换后引用旧向量:ngspice 交互模式下每次分析生成一个 plot,
setplot切到新 plot 后,旧 plot 的向量名在当前命名空间不可见,直接引用即报此错。 - 分析运行之前就引用其产物:在
.tran执行前的let或.meas里引用瞬态向量,向量尚未生成,同样查无此名。
三种场景机理相同:引用名在当前命名空间没有绑定对象。排查时先核对节点拼写,再确认当前 plot 与分析时序。
四、排查清单与退出码 0 的测量级失败
4.1 反直觉的真机表现:失败了,退出码却是 0
本次运行的失败段结尾,脚本明确打印 exit code: 0。原因在于 ngspice 把「分析」和「测量」分成两层判定:瞬态分析成功收敛、数据行完整产出,分析层就是成功的;.meas 只是分析之后的后处理语句,它失败只让该测量变量没有值,不回滚分析结果,也不改变进程退出码。
这与网表本身无法求解的硬错误形成鲜明对照。本班次的 ngspice subckt not found 报错 与 timestep too small 报错 都属于分析层失败,进程以退出码 1 中止、不产生结果数据。两类失败的差异和 CI 判据如下:
| 对比维度 | 测量级失败(本篇) | 分析层硬错误(subckt/model/timestep) |
|---|---|---|
| 典型报错 | no such vector、.meas ... failed! | could not find subckt、singular matrix、timestep too small |
| 分析数据 | 正常产出,本例 213 行 | 无结果或中止前的残缺数据 |
| 进程退出码 | 0 | 1 |
只判断 $? | 漏报 | 能抓住 |
| 可靠判据 | grep Error/failed!,或核对目标变量有无数值 | 退出码非零即失败,日志 grep 双保险 |
工程上的收口做法是让 CI 同时检查两层:先判退出码,再对日志做 grep -E 'Error|failed!',要求零命中;更严格的做法是直接核对目标测量变量是否真的打印出数值,例如断言日志里出现 tcross 后跟一个浮点数。解析期的 Warning: can't parse 也应纳入告警,它往往是测量失败的前置信号。
下图把两层判定的分流画出来,绿色是通过路径,红色是测量层失败但退出码仍为 0 的陷阱路径:
图中橙色节点就是本篇的陷阱:它挂在分析层成功的分支下面,靠退出码无法与全绿路径区分,只有日志内容或变量数值能把两者分开。
4.2 四步排查清单
- 核对节点拼写:打开网表,把
.meas、let、.print里每个v(...)与元件行的节点名逐一对照,注意大小写和多字母后缀,本例的outx与out只差一个字母。 - 顺着警告回查:看到
can't parse 'xxx': ignored就把xxx当成首要嫌疑,警告里的名字通常就是失败向量的前缀。 - 确认当前 plot 与分析时序:交互模式下用
display列出当前 plot 的全部向量,确认引用对象在列表里;批处理多分析场景确认.meas挂在对应.tran/.ac之后。 - 检查 CI 判据:确认流水线不是只看
$?,补上Error/failed!关键字检查和目标变量数值断言。
五、修复代码与复跑确认
修复只动一行:把 .meas 里的向量改成真实节点 v(out),其余网表不变:
Measure references the real node name
V1 in 0 PWL(0 0 1u 1)
R1 in out 1k
C1 out 0 10n
.tran 0.1u 20u
.meas tran tcross when v(out)=0.5 cross=1
.print tran v(in) v(out)
.endcross=1 表示取输出波形第一次上升越过 0.5V 的时刻。修复段的复跑实录如下,测量变量正常给出数值:
日志打印 tcross = 7.43572e-06,即约 7.44 µs。这个数量级与手工估算吻合:RC 时间常数 τ = R1·C1 = 1kΩ × 10nF = 10 µs,输入在 1 µs 内升到 1V,输出从零开始充电,越过 0.5V 的时刻落在 7 µs 量级合理。数值与物理对上,才算闭环,而不是仅仅看到退出码 0 就收工。
实验环境
- 机器/系统:macOS 本机,ngspice 批处理模式(
ngspice -b) - 工具版本:ngspice-47(KLU),可执行文件
/usr/local/bin/ngspice - 日期:2026-11-11
- 完整命令:在实验目录执行
bash run.sh;脚本依次运行ngspice -b meas_bad.cir(坏网表,测量失败但退出码 0)与ngspice -b meas_fixed.cir(修复网表,打印tcross = 7.43572e-06,退出码 0),并分别打印退出码。
代码获取
完整网表与复现脚本位于公开仓:https://github.com/derekzhuo/geek-doc.cn/tree/main/experiments/ts-ngspice-vector-undefined-plot,含 meas_bad.cir、meas_fixed.cir 与 run.sh。本地安装 ngspice 后,在该目录执行以下命令即可原样复现两段运行:
bash run.sh这一篇在知识体系里的位置
本篇属于 开源 EDA 报错排查导航 的开源仿真器分支,回答「测量语句引用不存在的向量会怎样、为什么退出码仍然是 0」。同班的 ngspice timestep too small 报错 与 ngspice subckt not found 报错 是分析层硬错误、退出码 1 的代表,与本篇的测量级失败构成完整对照;向量命名空间背后的节点方程与瞬态求解原理,见 SPICE 仿真器:在数值上解一张非线性动态电路。
总结
ngspice no such vector 在这份 RC 网表里根因极简:.meas tran tcross when v(outx)=0.5 cross=1 引用了不存在的节点 outx,真实节点是 out。ngspice 解析期先打 Warning: can't parse 'outx': ignored,瞬态分析照常跑完 213 行数据,测量阶段在 vector 命名空间查无 v(outx),报 no such vector 与 .meas ... failed!。必须记住的真机纠偏是:测量属于分析后的后处理层,它失败不改变进程退出码,失败段退出码仍是 0,只判断 $? 的 CI 必然漏报,可靠做法是 grep 日志的 Error/failed! 并断言目标变量打印出数值。把引用改回 v(out) 后复跑得到 tcross = 7.43572e-06(约 7.44 µs),与 τ = 10 µs 的手工估算同量级,修复闭环。