Yosys 回归结果丢失速查:批量回归跑完部分设计/任务结果不见了怎么办
更新时间:2026-10-23。FAQ 速查页,属于 FPGA 工具报错排错系列。多设计、多参数扫描的批量回归(或 sby formal 多任务)跑了一夜,早上打开汇总脚本输出:几十条里有两三条没有
.json网表、没有综合统计,sby 的status一栏空白——是这几条没跑、跑了没写盘,还是写了又被覆盖/清掉?本篇把「Yosys 回归结果丢失」的六类真实病因排成速查表。如果单条综合本身就返回非零退出码,先走 Yosys 命令返回非零速查;如果结果都在但两次回归对不上,那是 Yosys 偶发不确定速查 的地盘;同主题的 Quartus 版本见 Quartus 回归结果缺失速查。
本文要回答的问题
- 汇总输出里某几条没有结果行,回归脚本到底跑没跑它们?
set -e的回归脚本中途退出后,后面的任务是「缺结果」还是「根本没跑」?- 并行回归(
xargs -P/make -j)里多条任务共用 build 目录,结果会不会互相覆盖? - sby 任务跑完了但
status没回写、汇总脚本读不到,是哪种情况? - 相对路径的结果文件,换个目录执行怎么就「丢」了?
一、现象与报错原文
回归丢结果的现场有三层痕迹,从汇总层往任务层逐层看:
1. 回归汇总:缺行或产物路径不存在。
design top status cells wires
uart_rx uart_rx PASS 412 1033
uart_tx uart_tx PASS 388 971
spi_master spi_master MISSING - -
i2c_slave i2c_slave PASS 265 640
summary: expected 24 results, found 21 (missing: spi_master, pwm, can_ctrl)MISSING 多数是汇总脚本「在预期路径没找到结果文件」的兜底措辞,不代表 Yosys 说过这句话。
2. 回归脚本中途被 set -e 打断:日志停在某条任务,后面一行都没有。
=== [12/24] synth spi_master ===
yosys -p 'read_verilog spi_master.v; synth -top spi_master; stat' > logs/spi_master.log 2>&1
make: *** [regress] Error 1Error 1 之后第 13–24 条任务从未启动——它们不是「丢了」,是没跑。
3. sby 任务目录:engine 日志在,但 status 行没写。
$ tail -3 formal/led_blink/logfile.txt
SBY 21:12:44 [led_blink] engine_0: smtbmc: checking proof in step 12..
SBY 21:12:47 [led_blink] engine_0: smtbmc: Status: passed!
SBY 21:12:47 [led_blink] summary: engine_0 (smtbmc) returned pass有的任务目录里连这行 summary 都没有,status 文件缺失,汇总脚本自然读不到结果。
二、现象 → 区分点 → 处置速查表
| 现象 | 区分点 / 最常见原因 | 处置 |
|---|---|---|
汇总缺行,脚本日志在中途 Error 1 停住 | 某条综合失败触发 set -e,后续任务全部未执行 | 逐条复跑并记录退出码(` |
| 并行回归里两条任务结果只剩一份 | 多任务共用同名 build 目录(如都用 build/),后跑覆盖先跑 | 每任务独立目录 build/<design>_<seed>/;查目录时间戳是否被改写 |
| 日志成功但结果文件不存在 | 结果路径是相对路径,任务 cd 到别的目录后写在了别处 | 结果路径改绝对路径;find . -name "*.json" -newer regress.start 定位写丢的文件 |
| sby 任务目录 engine 日志在、无 status | 任务被 kill(超时/内存)或 sby 进程本身异常退出,status 没回写 | sby -f <task>.sby 复跑该任务;查系统 OOM 记录 |
| CI 上结果生成过、流水线结束找不到 | 工作空间清理策略(checkout 前 clean / 容器销毁)把产物删了 | 产物显式归档为 artifacts 并设留存期;回归输出放受归档路径下 |
| 汇总脚本数到的条数比预期少,且无任何日志 | 遍历清单与实际设计文件不同步,该条从未进队列 | 清单动态生成(ls designs/*.v),禁止手写硬编码 |
| 单条手动复跑成功,回归里就缺 | 资源竞争:只在高并发时触发 OOM 或临时盘写满 | 带同并发数复现;降并行或加内存后补跑 |
三、排查决策树
分诊只问三个问题:这条任务有没有真的被执行?执行了是自然结束还是被中断/被覆盖?结果文件是从来没写过、写过找不到、还是写了又被清?三个答案把现场切成四条通道:
读这张图抓住一条主线:先确定「没跑」「跑了被中断/覆盖」「写了找不到」「写了被清掉」四选一,再进对应通道——脚本日志中途停是 set -e 连坐(后面任务根本没执行),目录时间戳被改写是并行互踩(红色病态态),日志成功但预期路径无文件是相对路径写别处,CI 场景产物消失是清理策略。蓝色是排查动作,绿色表示「原因通道已锁定」,橙色是补跑修复,紫色是收口防复发。最忌讳的是不查脚本日志直接整批重跑:脚本还是 set -e,缺的还是那几条。
四、逐条排查展开
set -e 连坐:一条失败,后面全部没跑,是最常见的「丢失」。 回归脚本开头一行 set -e,第 12 条 yosys 返回非零,shell 直接退出,13–24 条从未启动,汇总脚本却按预期清单找结果,自然全部标 MISSING。确认只要看脚本日志最后一行停在哪条任务。处置不是把失败条「修好再整批重跑」就完事——回归脚本本身要改成逐条容错:
for d in designs/*.v; do
name=$(basename "$d" .v)
if yosys -p "read_verilog $d; synth -top $name; stat" > "logs/$name.log" 2>&1; then
echo "$name PASS"
else
echo "$name FAIL"
fi
done失败条目的分诊路径与 Yosys 命令返回非零速查 完全一致。
并行任务共用 build 目录:互相覆盖,只剩最后一份。 xargs -P 4 起 4 个任务,每条都用默认 build/ 或同名中间文件,先跑完的结果马上被后跑的覆盖,汇总时若干条「共享」同一份结果、其余的消失。特征是结果文件时间戳集中在回归收尾时刻。根治是每任务独立工作目录:
run_one() {
local d=$1; local name; name=$(basename "$d" .v)
mkdir -p "build/$name" && cd "build/$name" || return 1
yosys -p "read_verilog ../../$d; synth -top $name; write_json netlist.json" > synth.log 2>&1
}
export -f run_one
ls designs/*.v | xargs -P 4 -I{} bash -c 'run_one "$@"' _ {}相对路径结果文件:任务 cd 之后写在了别处。 任务脚本里 cd build/$name 之后又写 yosys -p "...; stat" > ../../results/$name.stat,层级数错一级,结果就写到了别的目录。特征是 Yosys 日志明明成功,汇总路径却空。用时间戳定位真实落点:
find . -name "*.stat" -newer regress.start 2>/dev/null找到后把结果路径统一改成绝对路径(RESULT_DIR=$(pwd)/results 在脚本开头展开一次),杜绝层级口算。
sby 任务无 status:任务被外力终止,status 没回写。 sby 正常结束(pass/fail/timeout)都会在任务目录回写 status;engine 日志在、status 缺席,说明 sby 主进程被 SIGKILL——典型是内存被 smtbmc/btor 求解器吃爆触发 OOM。石锤:
dmesg -T | grep -i -A2 "out of memory"看到 Killed process ... (smtbmc) 或 (python3) 就结案:降并行、给单任务内存上限(ulimit -v 或 cgroup),缺失任务 sby -f formal/<task>.sby 单独补跑。
CI 清理策略:结果生成过,流水线收尾被删。 两类高发形态:一是流水线下次执行 git clean -fdx 或 checkout 前清空工作空间,产物没归档就消失;二是回归输出写在容器临时层,容器销毁即蒸发。处置一句话:产物路径显式声明为 artifacts 并设留存期(GitLab 的 artifacts:paths + expire_in、GitHub Actions 的 upload-artifact),回归脚本只往受归档目录写结果。
遍历清单漂移:该条从未进队列。 脚本里写死 designs="uart_rx uart_tx spi_master",仓库里 spi_master.v 上周改名成了 spi_master_v2.v,遍历取不到文件,该条安静缺席——连「失败日志」都没有。清单动态生成(ls designs/*.v 或 find designs -name "*.v"),让文件系统当唯一事实源。
「单跑好的、回归里就缺」一律先怀疑资源竞争。 手动单跑成功只证明设计没问题;回归环境特有的变量是并发——内存竞争触发 OOM、临时盘被并行任务写满。复现要带上同等并发数,否则永远「无法重现」。结果忽有忽无、但每条单独都成立时,也要和结果漂移类问题区分开,后者见 Yosys 偶发不确定速查。
五、预防与纪律
- 回归脚本禁裸
set -e:逐条容错、逐条记退出码,失败不连坐;结尾按退出码汇总给非零总退出码,CI 仍能拦住。 - 每任务独立目录 + 日志落盘:
build/<design>_<seed>/下综合输出> synth.log 2>&1,缺结果时第一动作是翻这个文件。 - 结果路径一律绝对路径:脚本开头展开
RESULT_DIR=$(pwd)/results,不在 cd 之后算相对层级。 - 汇总前校验:汇总脚本先数「预期条数 vs 实际结果数」,不等就报警并打印缺失清单,不静默标 MISSING 了事。
- CI 产物显式归档:回归结果目录进 artifacts 配置并设留存期;不依赖工作空间存活。
- sby 任务跑完查 status 回写:汇总脚本对「无 status 文件」的任务单独报警(= 被 kill),与 FAIL 区分开。
这一篇在知识体系里的位置
本篇是 FPGA 排错速查簇中「Yosys 批量回归丢结果」节点的 FAQ 页:缺的那条如果综合本身就是非零退出,分诊展开见 Yosys 命令返回非零速查;如果结果都在但两次回归对不上,属于结果漂移问题,见 Yosys 偶发不确定速查;Quartus 侧的同类问题见 Quartus 回归结果缺失速查。几篇合起来覆盖回归健康的三个维度:有没有跑成、失败为什么、跑成了稳不稳。
一句话总结
Yosys 回归结果丢失的分诊起点是把汇总表的 MISSING 还原成该条任务的真实现场:脚本日志中途停住是 set -e 连坐、后续任务根本没执行,改逐条容错继续;结果时间戳被改写是并行任务共用 build 目录互踩,改每任务独立目录;日志成功但路径无文件是相对路径写别处,统一绝对路径;sby 无 status 是任务被 OOM 杀掉,降并行补跑;CI 上产物消失是清理策略没归档,产物进 artifacts。根治靠逐条记退出码、独立工作目录、日志全量落盘、汇总前条数校验,让每一次回归缺结果都自带可回溯的现场。