Yosys 命令返回非零速查:CI 里 make 报 Error 但滚屏看不出原因怎么办
更新时间:2026-10-23。FAQ 速查页,属于 FPGA 工具报错排错系列。Yosys 在脚本/CI 里最典型的失败形态是:
make打出一行Error 1,往上翻只有 yosys 的一大串 pass 输出,真正的ERROR:行沉在几百行之前——到底是哪条 pass 挂了、还是 yosys 根本没挂只是外壳脚本误判?本篇把「Yosys 命令返回非零」的六类真实病因排成速查表。进程不是非零退出而是直接段错误崩掉的那类见 Yosys 崩溃段错误速查,读入 HDL 就报语法错的那类见 Yosys 语法解析错误速查。
本文要回答的问题
- make 只报
Error 1,yosys 的ERROR:行藏在哪里、怎么一行捞出来? .ys脚本里哪条 pass 报的 ERROR 才是「第一处」,后面一堆报错是不是连锁反应?- yosys 只有 Warning,为什么脚本/CI 还是判失败?
yosys -p "cmd1; cmd2; cmd3"一长串里某条失败,为什么后面还在跑?- 退出码 137、139 是谁杀了 yosys 或它的子进程?
- 报
No such command: 'synth_xlinx'这种 typo,yosys 的退出码是什么行为?
一、现象与报错原文
现场通常有两层输出,原因往往在上层滚屏的中段:
1. make / CI 封装层看到的,只有一个转述的退出码:
yosys -s synth.ys
make: *** [Makefile:15: synth] Error 1
ERROR: Job failed: exit code 1Error 1 是 make 转述的子进程退出码,不含任何 Yosys 语义。真正的信息在 yosys 自己打印的输出里。
2. yosys 输出的中段,ERROR 行前后带着具体 pass 名:
2.47. Executing CHECK pass (checking for obvious problems).
checking module top..
ERROR: multiple conflicting drivers for top.led:
process $proc$top.v:23$1
process $proc$top.v:31$2
make: *** [Makefile:15: synth] Error 1yosys 的报错格式高度规整:ERROR: 前缀 + 一句话原因,前一行通常就是出事的 pass 名与编号小节(如 2.47. Executing CHECK pass)。定位手法永远是 grep,不是肉眼翻屏。
3. 另一种形态:yosys 全程没有 ERROR,但 make 还是 Error 1。 这时失败判据不在 yosys,而在外壳——Makefile 的 shell 选项、warning 计数断言、或管道最后一环的退出码。
二、现象 → 区分点 → 处置速查表
| 现象 | 区分点 / 最常见原因 | 处置 |
|---|---|---|
输出里有 ERROR: 行 | 某条 pass 真失败(check、read_verilog、techmap…) | grep -n "ERROR" run.log 拿第一处,按 pass 名与原因修设计或脚本 |
| 多条 ERROR 连发 | 第一条是真因,后面是设计状态已被破坏的连锁反应 | 只修第一处 ERROR,其余重跑后大多自然消失 |
| 屏幕只有 Warning 但退出码非零 | CI/脚本有 -Werror 类升级开关或 warning 计数断言 | 翻脚本里对 stderr/warning 的判据;确认后修 warning 或放宽判据 |
| yosys 成功但 make 报 Error 1 | Makefile 里 set -e/管道把无害非零转成了失败 | 命令落盘日志后 echo $? 单独复跑,拿 yosys 裸退出码核对 |
-p "a; b; c" 跑到一半失败后面还在执行 | -p 串按顺序执行,某条失败后继续跑完最后才统一非零退出 | 看输出里第一条 ERROR:;改用 .ys 脚本分段跑逐步定位 |
报 No such command: 'xxx' | 脚本命令名 typo(如 synth_xlinx)或引用了未加载插件命令 | 对照 yosys -h 或 help 输出核对命令名;typo 修正即可 |
| 退出码 137 | abc 等子进程被 OOM killer 杀掉(137 = 128+9 SIGKILL) | dmesg 查 OOM 记录;降 abc 并发或加内存 |
| 退出码 139 | yosys 自己段错误(128+11 SIGSEGV) | 属崩溃不是普通报错,走 Yosys 崩溃段错误速查 分诊 |
三、排查决策流程图
分诊只问两个问题:输出里有没有真 ERROR: 行;退出码是不是落在外部信号区间。两个答案把现场切成「yosys 自己拒绝」「外壳脚本误判」「进程被外力终止」三条通道:
读这张图抓住两条主线:yosys 自己拒绝的路径——grep 总能捞出 ERROR: 行,第一处就是真因,后面连发的 ERROR 多半是设计状态已被破坏的连锁反应,修第一处重跑即可;外力与外壳的路径——退出码 137/139 不是 yosys 的意见而是信号(OOM 或段错误),屏幕干净只有 Warning 时是 Makefile/CI 的判据在误伤,排错方向要换成脚本本身。 红色是入口现象与「进程被杀」这一病态态,蓝色是排查动作,绿色表示「真错已到手」,橙色是修复,紫色是收口防复发。
四、逐条排查展开
先把第一处 ERROR 捞出来。 yosys 失败任务的输出里定位全部 ERROR 只要一行:
yosys -s synth.ys -l run.log
grep -n "ERROR" run.log | head -5注意关键词是「第一处」:check pass 发现多重驱动之后,后续 techmap、opt 可能继续在同一坨坏设计上连发 ERROR,只修第一条,其余大概率跟着消失。-l run.log 让输出落盘,是后面一切分析的前提。
-p 串的失败点会被后续输出淹没。 yosys -p "read_verilog top.v; synth; write_json out.json" 里 read 就 ERROR 了,synth 与 write 仍会依次尝试执行,滚屏尾部看到的是最后一条的输出而非失败点。排错期把它拆成 .ys 脚本,每段后肉眼确认或分步执行;定位到出错 pass 后再合回去。
.ys 脚本里出错行号要会看。 yosys 执行脚本时会在输出里打印当前执行到哪条命令(Executing Verilog-2005 frontend 这类小节头之前常有脚本命令回显),对照 grep -n 拿到的 ERROR 位置往回找最近的一条 pass 小节头,就能锁定 .ys 里的出错行;这比逐行注释脚本二分法快得多。多人共用脚本时,把每个阶段的输出用 tee 拆开落盘,分工排查互不干扰。
No such command 就是拼写事故。 报 No such command: 'synth_xlinx'(少了个 i)这类,yosys 会提示并中止脚本执行返回非零。对照官方命令清单核对拼写;如果命令确实存在但报这个错,多半是该命令由插件提供而插件没加载。
只有 Warning 却非零,查外壳判据。 yosys 默认 warning 不置退出码;CI 里「0 ERROR 仍失败」九成是脚本里 grep 了 warning 计数、或 Makefile 用 set -e 把管道里某个无害的非零(比如 grep 没匹配到返回 1)转成了 make 失败。单独复跑拿裸退出码核对:
yosys -s synth.ys > run.log 2>&1
echo "exit=$?"退出码 ≥128 按信号死亡处理。 137 = 128+9(SIGKILL),综合大设计时最常见的是 abc 子进程内存暴涨被 OOM killer 收掉,dmesg | grep -i oom 能石锤;修复对象是内存配额与 abc 的并发/策略,不是 yosys 工程本身。139 = 128+11(SIGSEGV),那是 yosys 自己崩了,属于崩溃类问题,按 Yosys 崩溃段错误速查 拿 core 与最小复现,别在本篇的「普通报错」框架里打转。读入阶段的语法类 ERROR(syntax error, unexpected TOK_ID)则走 Yosys 语法解析错误速查。
五、防复发与纪律
- 日志先行:所有 CI 调用固定加
-l run.log或> run.log 2>&1,失败任务第一动作是 grep 不是重跑。 - 脚本化优于 -p 长串:排错期与正式 CI 都用
.ys脚本,命令逐条可读、失败点不沉底。 - 只修第一处 ERROR:连锁报错不逐条追,重跑验证。
- 命令名入版本控制评审:
.ys脚本和代码一样过 review,typo 在提交前拦住。 - 内存留裕量 + 分级超时:大设计给 abc 留内存余量;CI 超时杀进程前保留日志现场,区分「真失败」与「被超时杀」。
这一篇在知识体系里的位置
本篇是 FPGA 排错速查簇中「Yosys 退出码」节点的 FAQ 页:进程直接段错误崩掉、来不及打 ERROR 的形态见 Yosys 崩溃段错误速查;失败点固定在 read_verilog 读入阶段、ERROR 带行号的语法类问题见 Yosys 语法解析错误速查。三篇合起来覆盖 yosys 失败的三种终态:有 ERROR 的失败、无声的失败(外壳误判)、被外力终止的失败。
一句话总结
Yosys 命令返回非零的分诊起点是把「make 转述的 Error 1」还原成「yosys 自己的输出」:-l run.log 落盘后 grep 第一处 ERROR: 按 pass 语义修,连发 ERROR 只追第一条;屏幕只有 Warning 就查外壳脚本的判据与 set -e,单独复跑 echo $? 拿裸退出码;报 No such command 是命令名 typo;退出码 137/139 一律按外部信号(OOM killer、段错误)处理。根治靠日志落盘、用 .ys 脚本替代 -p 长串、内存留裕量与分级超时,让每次失败都自带可回溯现场。