4. 自动化流程设计原则与模式
把 Calibre 后端流程从“手工点工具”推进到“可重复执行的自动化系统”,核心不在于把命令写进脚本,而在于用一套稳定的设计原则约束任务的组织方式。Calibre 的 DRC、LVS、PEX、ERC、DFM 等步骤天然具有“输入文件多、运行时间长、结果文件大、失败原因分散”的特点,如果只是顺序调用 runset,很快就会遇到重复计算、依赖错乱、失败后无法续跑、重跑污染结果等问题。本节围绕批处理、并行执行、依赖管理、错误处理与幂等性五个原则,说明如何把 Calibre 步骤抽象为可复用任务。
一、批处理:把“一次调用”变成“一批任务”
Calibre 单次运行通常只处理一个 cell 或一个 corner。批处理的价值在于把同一类操作按输入维度展开成任务集合,例如按 block、按电压角、按金属堆叠方案分别生成 DRC 任务。批处理的关键是任务描述与执行分离:任务描述只记录“做什么”,执行器负责“怎么跑”。一个可复用的任务描述至少应包含任务 ID、工具类型、runset 路径、输入版图/GDS、规则文件、工作目录、期望输出与超时时间。
例如,对三个 block(cpu_core、ddr_phy、pmu)分别跑 DRC,可以抽象为同一任务模板加不同参数:
task_id: drc_cpu_core
tool: calibre
runset: /proj/rules/drc/calibre_drc.rs
layout: /proj/gds/cpu_core.gds
top_cell: cpu_core
workdir: /proj/run/drc/cpu_core
outputs: [drc.results, drc.summary]
timeout: 7200
批处理不是简单 for 循环,而是把任务集合交给调度器统一管理,这样才能在后续引入并行、重试和依赖。
二、并行执行:按资源与依赖切分并发度
Calibre 的多数步骤可以并行,但并行度受 license 数量、CPU 核数、磁盘 I/O 和内存限制。盲目开满并发会导致 license 争抢、临时目录爆满、结果互相覆盖。合理的做法是:先按依赖关系分层,同一层内无依赖的任务并行,层与层之间串行。例如 DRC 与 LVS 可并行,但 PEX 必须等 LVS 通过后才能启动。
并行执行还需要为每个任务分配独立工作目录,避免 Calibre 生成的临时文件、日志和结果文件冲突。常见做法是 workdir 按 task_id 命名,并在任务结束后保留日志、清理中间文件。
三、依赖管理:用 DAG 表达步骤先后
Calibre 流程的依赖关系不是简单线性,而是有向无环图(DAG)。例如:
- DRC 依赖 GDS 与 DRC 规则;
- LVS 依赖 GDS、网表与 LVS 规则;
- PEX 依赖 LVS 通过后的提取网表与 PEX 规则;
- ERC 依赖 PEX 结果或独立网表。
依赖管理要明确“前置任务成功”才触发后继任务,而不是“前置任务启动”就触发。对于 Calibre,LVS 的“通过”不能只看进程退出码,还要检查 LVS 报告中的 compare 结果。因此依赖条件应支持“退出码 + 结果文件关键字”双重判断。
四、错误处理:区分“可重试”与“需人工介入”
Calibre 任务失败的原因大致分三类:资源类(license 不足、磁盘满、超时)、输入类(GDS 缺失、规则文件语法错误)、结果类(DRC 违例、LVS 不匹配)。资源类通常可重试,输入类需要立即停止并报错,结果类则属于“任务成功但结果不合格”,不应重试,而应进入结果审查。
错误处理策略应写入任务模板:设置最大重试次数(如 2 次)、重试间隔(如 60 秒)、超时时间,并区分退出码。Calibre 的退出码 0 表示运行完成,非 0 表示工具异常;但 DRC 有违例时退出码仍可能为 0,因此必须解析结果文件。建议在任务后置钩子中检查 drc.summary 或 lvs.report 的关键字段,把“运行失败”和“结果不合格”分开记录。
五、幂等性设计:同一任务重复执行结果一致
幂等性指同一任务无论执行一次还是多次,最终输出一致、不产生副作用。Calibre 任务要做到幂等,需要满足:工作目录固定且可清理、输出文件覆盖而非追加、临时文件按 task_id 隔离、任务开始前检查是否已有成功标记。常见实现是“成功标记文件”机制:任务成功后写入 .done 文件,调度器发现标记存在则跳过,除非显式指定 --force。
幂等性还要求任务不依赖上一次运行的残留状态。例如 PEX 任务如果复用上次的提取网表,必须校验输入 GDS 与规则的哈希值是否变化。建议在任务描述中记录输入文件的 checksum,作为缓存键的一部分。
六、把 Calibre 步骤抽象为可复用任务
抽象的关键是提取“变化点”与“不变点”。不变点包括:Calibre 调用方式、日志规范、退出码判断、结果文件解析、成功标记写入。变化点包括:工具类型、runset、输入文件、top cell、工作目录、超时与重试策略。把这些变化点参数化,就能用同一套执行器跑 DRC、LVS、PEX、ERC。
一个可复用的任务模板可以这样定义:
task:
id: "{{block}}_{{step}}"
tool: calibre
step: "{{step}}"
runset: "/proj/rules/{{step}}/calibre_{{step}}.rs"
layout: "/proj/gds/{{block}}.gds"
top_cell: "{{block}}"
workdir: "/proj/run/{{step}}/{{block}}"
outputs:
- "{{step}}.results"
- "{{step}}.summary"
retry: 2
timeout: 7200
idempotent: true
depends_on: "{{deps}}"
执行器读取该模板后,按 DAG 拓扑排序,先并行执行无依赖任务,再逐层推进。每个任务在独立目录中运行,成功后写 .done,失败则按策略重试或标记为需人工介入。这样,新增一个 block 或新增一个 corner,只需增加参数组合,而不需要修改执行逻辑。
总结来看,批处理解决“任务集合化”,并行执行解决“资源利用率”,依赖管理解决“顺序正确”,错误处理解决“失败可控”,幂等性解决“重复安全”。五者共同构成 Calibre 后端自动化流程的设计底座,也是后续接入 CI 系统时能够稳定触发、稳定复现的前提。