跳转至

原理与机制

读者:会用工具、但想知道"为什么这样设计"的人。 前置:跑通过一次前仿(见 tutorial-first-sim.md)。 读完能做什么:理解白名单、层次网名、srun 崩溃、存储分层这四件事背后的道理。 环境锚点:Virtuoso IC617 + Spectre 15.10 + Slurm;核实日期 2026-10-13。

三十秒版

这篇回答四个"为什么":为什么要配白名单、为什么子层次节点选不了、 为什么加了 srun 就崩、为什么结果要分三层存。每个都按"解决什么问题 → 怎么运作 → 为什么 → 何时失效"讲。

一、为什么要配保存白名单

它解决什么问题

不配的话,仿真器默认把电路里每个节点的波形都存下来,盘会满。 本项目未裁剪时 200 个点 × 60 µs 估计约 780 GB——整个集群都装不下。

怎么运作

你在 Outputs Setup 表勾 Save  ──►  网表写出 save VCTL REF VCOCK FB  ──►  Spectre 只写这四路
        (名单)                        (规矩:save=selected)              (其余不写盘)

体积的算式:

体积 = 保存信号数 × 采样点数(时长 ÷ strobeperiod) × 每点字节

三个因子就是三个旋钮:少存信号、少存时间点、换更省的格式。

为什么这么设计

波形是"时间 × 节点 × 精度"的三维数据。其中节点数最容易失控, 所以工具给了"只存点名的"这一层闸门(selected),而不是让你事后删。

实测(本项目,2026-10-12)

配置 单点 psf 6 点目录
无白名单,1 µs 8.5 MB 55 MB
4 路白名单,1 µs 0.27 MB 5.5 MB
4 路白名单,10 µs 4.4 MB 32 MB

白名单把单点压约 31×;目录总量只降约 10×,因为 netlist、日志等固定开销不随白名单变。

什么情况下失效

  • 名单为空时 selected 退化成"全存所有节点"——这是最坑的一点,配了等于没配。
  • strobeperiod 抽稀(采样间隔调大)只能用于慢节点/包络,不能用于 VCO 高频波形,会严重欠采样。
  • compression=yes 在本环境实测反而变大(×1.73),别开。

二、为什么子层次里的节点选不了

它解决什么问题

你想存"div8 的输出",但在信号列表里,div8 内部节点是灰的,选不了。

怎么运作

仿真器按顶层网表保存,顶层网表里只有顶层 net 有名字:

XDIV (VCOCK GND FB VDD) div8
      └──── 括号里是 div8 的四个顶层连接,第 3 个 FB 就是 div8 的输出

所以"某模块的输出"要认顶层连接的网名,这里就是 FB。

为什么这么设计

子层次内部节点的名字在顶层不唯一(两个模块里都可以有一个 out), 没法直接指名保存,所以工具只让你选顶层 net。

什么情况下失效

  • 子 cell 的端口名大小写与子 schematic 必须逐字一致,否则层次连接为空,FB 这种顶层名也就不存在了。
  • 顶层 net 名带前导 /(如 /VCTL);不带 / 的多半不是顶层 net。

三、为什么加了 srun,Spectre 就崩

它解决什么问题

ADE-XL 把每个仿真点丢给 Slurm 集群跑,但作业一启动就报错、跑不起来。

怎么运作

ADE-XL ──► Job Policy = Command ──► srun -N1 -n1 -c1 -p long --mpi=none ./runICRP
                                          │
                                    srun 默认会往进程里塞 MPI 环境变量(PMI_*)
                                          │
                                    Spectre 看到 PMI_* 以为要跑 MPI,初始化失败 → 崩

报错长这样:[cli_0]: Unable to write to PMI_fd 或 Fatal error in MPI_Init。 加 --mpi=none 告诉 srun"别塞这些变量",就好了。

为什么这么设计 / 为什么会踩

本集群的 Slurm 配置里 MpiDefault = pmi2(上游出厂默认是 none), 所以这道坎是本集群特有的——换一套默认 none 的集群就不会遇到。

什么情况下失效

  • 必须用 srun(前台阻塞),不能用 sbatch:ADE-XL 靠本地代理进程推断作业状态、发 SIGTERM。
  • 失败会留 SE/JobHeldUser 残骸,累积到一定量后 ADE-XL 会停止派发(清掉即恢复)。
  • 派发粒度是一点一核(-N1 -n1 -c1);单点用多核(+mt=4)对小电路几乎没有收益。

四、为什么结果和日志要分开存

它解决什么问题

波形大、寿命短;日志小、寿命长;设计源要永久留。放一起会互相拖累盘。

怎么运作

层 路径 性质 放什么
Tier1 /projects/... NFS,持久、可备份 设计源、netlist、日志、配置、裁剪后的结果
Tier0 /mnt/lustre/scratch/users/<你>/... Lustre,共享临时,30 天老化 仿真波形、大中间产物、作业 workdir
本地 $TMPDIR(节点本地盘,不共享) 不共享 作业级临时(脚本别放这里)

为什么这么设计

三类东西的容量与生命周期完全不同:波形会撑爆盘但几天后就没用, 日志很小但要长期查,设计源必须永久留。用一块盘扛三种需求,必然有一头被牺牲。

什么情况下失效

  • Lustre 30 天老化:要长期保留的结果必须 stage-out 回 /projects。
  • EDA 编译产物默认落在当前目录,作业脚本要显式 cd "$TMPDIR" 或指定路径。
  • 判"能不能写"别用 test -w(曾误报),要真实写一个文件验证。

五、为什么作业数上不去(三道闸门)

它解决什么问题

明明机器闲着,作业却排着队;改了参数并发数变了,却不知道为什么。

怎么运作

能同时跑几个作业,由三道闸门里最紧的那道决定:

第一道 配额(逻辑)   QOS 的 MaxJobsPerUser      ← 管理员设
第二道 内存(申请)   节点内存 ÷ 每个作业 --mem
第三道 核数(物理)   节点核数 × 节点数
并发 = 三者取最小

在本机实测(2026-10-13,198 点批跑)

配置 第一道 第二道 第三道 实际并发
-p long、--mem=2G 10 21 24 10
-p regression、--mem=2G 200 21 24 21
-p regression、--mem=1G 200 42 24 24

读法:先换分区解开配额,再降 --mem 解开内存,最后才碰到物理核数这堵真墙。

怎么知道现在撞的是哪道

squeue 的 REASON 列直接说了:

REASON 撞哪道 对策
QOSMaxJobsPerUserLimit 配额 换 QOS 更宽的分区(本机 regression 是 200)
Resources 内存或核 降 --mem;已到核数上限就无解
Priority 排队优先级 等

为什么这么设计

集群多人共用:配额防一个人吃独食,内存防一个作业撑爆节点,核数就是机器的物理容量。 三件事各管一段,所以分三道闸门。

什么情况下失效

  • 配额放大到几百,物理核数不会跟着涨——超过核数的配额是虚的。
  • --mem 申请的是上限不是预占:--mem=1G 时作业实际只用 93 MB,剩下仍被记账占位, 所以降它能提并发,但降太狠会 OOM。
  • 四个分区(long/regression/compile/interactive)共用同一批节点, 换分区只换配额与时限,不换机器。

相关


来源:/home/rain/Documents/eda_tools_ins/design/docs/kb/concept.md | 最后更新:2026-10-13 01:53(由 build/sync.py 同步,请勿在站点侧修改)