SpyGlass 配置解析失败:.prj/Goal/Tcl 加载不起来速查
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列,总入口见 开源 EDA 报错排错中心。SpyGlass(Synopsys 的 SpyGlass Lint/CDC/RDC)是 goal-based 流程:
spyglass -project xxx.prj -goals lint/lint_rtl启动后,先加载.prj工程文件,再 sourcerun_setup、common_run_template一类 Tcl 脚本,最后按 policy/goals 目录拼装 goal——这条配置加载链断在任何一环,工具连 RTL 都不会开始读。本篇只处理工程配置、Goal、Tcl 脚本加载失败;RTL 源码本身读不下去(syntax error near那类)属于姊妹篇 SpyGlass 语法解析报错速查,文件或模块按名字找不到见 SpyGlass 模块/单元找不到速查。规则体系与工程纪律见 RTL 静态检查(Lint):SpyGlass 规则体系与基线门禁。
本文要回答的问题
- 一长串报错刷屏,怎么找到真正的第一条配置错误?日志在哪个目录下?
set_option search/projectdir/wdir拼错参数、set_goal_option写错命令名,报错文案长什么样?- Goal/policy 名(
lint/lint_rtl、lint_turbo、clock_reset、CDC 路径)写错时怎么判? .awlwaiver、rule 集文件换了目录后相对路径失效,与SPYGLASS_HOME未设置各是什么现象?- 老版本工程迁到新版本,option 被移除、模板加载失败,如何用 GUI 保存再 diff 定位?
一、报错原文与现象
配置类报错在工程加载阶段就抛出,通常连 GUI 主界面都进不去。以下三组文案最高频,工程名与路径已占位:
1. 文件打不开(模板、policy、waiver 引用断链):
**ERROR: Cannot open file '../../../scripts/common_run_template.tcl'
Error: couldn't read "policy/goals/lint/lint_rtl/lint_rtl.tcl": no such file or directory
Warning: Cannot find waiver file 'waivers/2024q1/common.awl' -- waivers skipped2. Tcl 语法或 option 参数错(命令名拼错、参数不属于该命令、参数个数不对):
Error: invalid command name "set_goal_opt"
Error (TCL-01): bad option "projectdir": must be one of search, wdir, top, ...
Error: wrong # args: should be "set_option option value" while executing "set_option search"3. Goal/policy 名与环境变量问题:
**ERROR: Failed to read project file 'run.spyglass.prj'
Error: Goal 'lint/lint_turbo' not found in installed policy
Error: can't read "env(SPYGLASS_HOME)": no such element in array先记住一个分界:第一组断在「按路径找文件」,第二组断在「Tcl 解释器认不认这条命令」,第三组断在「goal 解析与环境」。三组的修法完全不同,凭报错关键词对号入座即可,不要混着改。
二、原因速查表
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| Cannot open file 模板/policy | 模板相对路径基准随启动目录变化 | 从工程根启动;模板路径改绝对路径或工程变量 |
| invalid command name | Tcl 命令拼错(如 set_goal_opt)或脚本未 source | 对版本手册核对命令全名,查 source 顺序 |
| bad option "xxx" | set_option 参数名拼错或该版本不支持 | 按报错给出的合法值清单改正 |
| Goal not found in policy | goal 名/层级写错,或方法学库未安装 | 对安装目录 policy/goals 核对真实层级名 |
| waiver skipped / .awl 找不到 | .awl 相对路径随工程搬迁失效 | 以工程根为基准重写相对路径并 test -r 验证 |
| env(SPYGLASS_HOME) 读不到 | 非交互 shell 未 source 环境脚本 | 启动脚本显式设变量,不依赖登录环境 |
| Windows 路径报一片错 | 反斜杠被当转义符、路径含空格 | 全部改正斜杠,含空格路径用花括号包裹 |
| 老工程升级后起不来 | 旧 option/goal 在新版本被移除改名 | 最小化二分 + GUI 另存后 diff 配置 |
| flist 后报莫名 Tcl 错 | filelist 内嵌注释带非 UTF-8/全角字符 | 注释单独成行、转 UTF-8 无 BOM |
| 改了配置仍报旧错 | goal 目录增量产物掩盖 | 删 spyglass_reports/<goal>/ 干净重跑 |
三、逐条排查展开
第一步:到 goal 目录的日志里找第一条配置报错。 SpyGlass 每次 run 的完整日志在工程下的 spyglass_reports/<goal>/(如 spyglass_reports/lint/lint_rtl/)里,工程根另有一份 spyglass.log。配置加载是顺序执行的,第一条 Error 之后的十几条往往都是连锁反应。打开日志从前往后搜 Error/ERROR,只认第一条:它点名的那个文件或那条 Tcl 命令,就是加载链断掉的确切位置。GUI 起不来时这条日志同样存在,不必执着于在界面里复现。
第二步:用最小 .prj 二分收敛。 配置文件与模板层层 source、动辄几百行时,最快的办法是裁出最小工程:复制一份 .prj,只留 read_file 一个最小 RTL、set_option top 和出问题的 goal,把 run_setup、common_run_template 等 source 行先整体注释,确认空骨架能起来;再逐段放回,每放一段重跑一次,哪一段放回去就报错,根因就在那段脚本引用的内容里。这比逐行读模板快得多,也能立刻区分「工程配置坏了」还是「RTL 坏了」。
读这张图抓住「先取首错、再按文案分流」:红色入口是现象,两个蓝色节点是排查动作,三个橙色节点分别对应速查表的三组根因,最后汇到紫色的干净重跑。不要一上来就改 .prj——首错没定位就动手,极容易把真正断链的那行模板埋得更深。
第三步:option 与 goal 名按版本手册核对,别按记忆。 set_option 的合法参数是版本相关的闭集,报错时文案会直接列出全部合法值(must be one of search, wdir, top, ...),照着改即可,高频错字集中在 search、projectdir、wdir 这几个路径类参数上。Goal 名则是安装目录下 policy/goals/ 的真实层级:lint 类常见 lint/lint_rtl,快速 lint 与 clock_reset、CDC 各 goal 在不同版本的方法学库里路径并不相同,手写 lint/lint_turbo 这类想当然的名字必然报 Goal not found。判据是去安装目录把目录层级 ls 出来照抄,或在新建工程的 GUI 里从 goal 列表点选,再与命令行字符串对一遍。
第四步:路径、变量与启动目录一次查清。 .prj 与被 source 脚本里的相对路径,按启动 spyglass 时的工作目录解析,不是按 .prj 所在目录——模板用 ../../../scripts/ 这种写法时,换个启动目录立刻 Cannot open file。同时核对三件事:回归/nohup 环境是否 source 了设置 SPYGLASS_HOME 的环境脚本(非交互 shell 不读登录配置,报 can't read "env(SPYGLASS_HOME)" 全是这个原因);Windows 编辑过的路径反斜杠要全部改正斜杠(反斜杠在 Tcl 里是转义符),含空格的路径用花括号整体包裹;filelist 内嵌的行尾注释若混入全角字符或非 UTF-8 编码,会在配置解析期抛出与 RTL 无关的 Tcl 错,注释单独成行、统一 UTF-8 无 BOM 即可。
第五步:waiver 与 rule 集引用单独验。 .awl waiver 文件和自定义 rule 集多通过相对路径或工程变量引用,工程目录搬迁、季度基线换目录后最容易断。注意它有时只给一条 Warning: Cannot find waiver file ... -- waivers skipped 就继续跑——这意味着违例在没有豁免基线的情况下裸跑,报告里的违例数会虚高或误判签收。处置是以工程根为基准重写相对路径,引用后在 shell 里 test -r <文件> 确认可读,再重跑确认日志中 waiver 加载条数非零。waiver 签收纪律见 Lint waiver 签收与基线门禁。
第六步:版本迁移问题用「GUI 另存再 diff」对照。 老版本工程(连同 common_run_template、run_setup)搬到新版本后,部分 option 被移除或改名、policy 目录重组,报错可能在模板深处。最省事的对照法:在新版本 GUI 里新建一个只含相同 top 与 goal 的空工程,Save Project 生成一份新的 .prj,与老工程逐行 diff——差异行里 option 写法、goal 全名、source 路径的不同之处,就是迁移要改的全部内容。不要凭老脚本经验猜新选项名,以新版本 GUI 实际生成的文本为准。
四、预防与纪律
- 启动脚本固定工作目录与环境:先
cd工程根、显式 exportSPYGLASS_HOME等变量再启动,杜绝「交互能过、回归不过」。 - 路径三规矩:模板与 waiver 一律正斜杠、以工程根为基准、含空格用花括号;跨平台共享的 filelist 与脚本纳入编码检查(UTF-8 无 BOM、LF)。
- 改一处、删
spyglass_reports/<goal>/重跑一次、只认第一条报错,不让增量产物掩盖配置问题。 - 版本升级做工程配置回归:用新版本 GUI 另存空工程做基准 diff,废弃 option 一次性迁移,不把老模板原样带进新版本。
- waiver 加载条数纳入开跑自检:日志里 waiver skipped 即视为配置失败,不允许带空基线产出报告。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇的一员,总入口见 开源 EDA 报错排错中心;配置加载通过之后,RTL 源码解析问题见 SpyGlass 语法解析报错速查,按名字找不到模块见 SpyGlass 模块/单元找不到速查,规则体系与 waiver 治理的上游方法学见 RTL 静态检查(Lint):SpyGlass 规则体系与基线门禁 与 Lint waiver 签收与基线门禁。
一句话总结
SpyGlass 配置解析失败先到 spyglass_reports/<goal>/ 日志里只认第一条配置 Error:文件打不开查相对路径基准、SPYGLASS_HOME、反斜杠与空格,Tcl/option/goal 报错用最小 .prj 二分并对版本手册与 policy/goals 实目录校名字,.awl 引用断了必须确认 waiver 真正加载(skipped 等于裸跑),老版本迁移用 GUI 另存再 diff;修完删 goal 目录干净重跑,0 配置 Error 之后才有资格进入 RTL 解析阶段。