SpyGlass 缓存陈旧:改了 RTL 违例结果不变速查
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列,总入口见 开源 EDA 报错排错中心。SpyGlass(Synopsys 的 SpyGlass Lint/CDC/RDC)是 goal-based 的增量流程:工程目录下的
spyglass_work/、work/、<top>/<goal>/等工作目录里,缓存了各文件的 analyze 中间产物与 goal 结果,工具按时间戳和依赖关系决定哪些文件要重跑。这套机制平时省时,改了输入却复现旧结果时极其浪费时间——它通常不报错,只是安静地给你上一轮的答案。工程根本起不来的配置类问题见 SpyGlass 配置解析失败速查,规则体系与 waiver 治理见 RTL 静态检查(Lint):SpyGlass 规则体系与基线门禁。
本文要回答的问题
- 明明改了 RTL,重跑后违例条数、违例行号为什么纹丝不动?
- filelist 里加的新文件、更新过的
.awlwaiver,为什么像没被读到? - GUI 里看到的结果和命令行回归不一致,切了 git 分支后结果发怪,问题出在哪?
spyglass_work/、work/、<top>/<goal>/这些目录分别装了什么,能不能直接删?- CI 上怎样保证每次跑的都是全新分析,而不是复用脏工作目录?
一、现象与日志
缓存陈旧最大的特征是没有 error:流程正常退出、报告正常产出,只是结果和源码对不上。以下三组是最高频的典型形态(目录名为占位,各版本日志措辞有差异,以本单位安装版本为准):
1. 改了代码还报老行号(违例指向的代码行已经不存在或内容已变):
# 已把 rtl/fifo.v 的位宽问题修掉,重跑后同一规则仍报旧位置
Rule Severity File Line Message
W164a Error rtl/fifo.v 97 Width mismatch ... # 第 97 行现已不存在
Goal lint/lint_rtl completed: 13 errors, 42 warnings # 与上一轮完全相同2. 新文件没被 analyze、waiver 像没生效(日志里没有新输入的读取记录):
Analyzing file rtl/uart.v ...
Analyzing file rtl/fifo.v ...
# filelist 里新增的 rtl/new_block.v 在整段日志中没有任何 Analyzing 记录
Reusing cached results for goal lint/lint_rtl3. 权限导致缓存写不回(共享目录、CI 挂载目录常见,有时只给一条 warning):
Warning: Cannot write to work directory './spyglass_work': Permission denied
Warning: failed to update incremental database for goal lint/lint_rtl第三种要特别警惕:写不回缓存时,不同版本的行为不一致——有的当轮静默重算(结果对但下次照样慢),有的沿用上一轮能读到的旧结果(结果直接不可信)。无论哪种,看到 work 目录写权限告警就不要相信这次报告。
二、原因速查表
| 现象 | 可能原因 | 处置 |
|---|---|---|
| 改 RTL 后违例数不变 | 增量判定认为文件未变,命中旧 analyze 结果 | 清工作目录或用 clean 方式重跑 |
| 报已删除的旧行号 | goal 结果库未随源码更新 | 删 <top>/<goal>/ 缓存后重跑 |
| 新文件没被读 | filelist 改了但工程依赖未刷新 | 确认 filelist 被重新读入,必要时重建工程 |
| 改 waiver 仍报违例 | .awl 时间戳/路径问题或 waiver 未重新加载 | 核对日志 waiver 加载条数,清缓存重跑 |
| GUI 与命令行结果不同 | 两者工作目录不同,缓存新旧不一 | 统一 work 目录约定,都做干净重跑比对 |
| 切分支后结果发怪 | 增量库里混着两个分支的中间产物 | 切分支即清缓存,分支用独立输出目录 |
| CI 结果与本地不一致 | 复用器上残留的脏 work 目录 | CI 固定全新检出,结束即清工作目录 |
| 权限 warning 后结果可疑 | 缓存写不回,静默重算或沿用旧结果 | 修目录属主/权限后干净重跑 |
| 拷贝文件后不重算 | 拷贝保留/回拨了 mtime,骗过时间戳判定 | 不以拷贝代替更新,重跑前清缓存 |
三、逐条排查展开
第一步:先判定结果是不是陈旧的——拿报告对源码,不要拿感觉对报告。 陈旧的判据只有一个:报告内容与当前源码对不上。三个三十秒可做的核对:① 挑一条违例,打开报告行号对应的当前源码,看该行问题是否还在(行已删除或已修复却仍报,直接坐实陈旧);② 在新加入的文件里临时写一个必然触发的违例,重跑看它出不出现;③ ls -l 对比输入文件(RTL、filelist、.awl)与工作目录产物的修改时间,产物早于输入却没有重新 analyze 的记录,就是旧结果。三招中任意一招对不上,不必再怀疑规则本身,进入清缓存流程。
颜色按语义分角色:红色是问题入口与坐实的陈旧判定,蓝色是排查动作,橙色是修复手段,紫色是防复发。读这张图抓住一条主线:先用「报告对源码」证实陈旧,再删缓存干净重跑,最后必须在日志里核对重新 analyze 的文件数——没做这步核对,清缓存只算心理安慰。
第二步:认清缓存长在哪,再动手删。 SpyGlass 的工作产物通常分布在工程目录下几处:spyglass_work/(工程级工作区与内部数据库)、work/(部分版本流程模板使用的工作目录)、<top>/<goal>/(按顶层名和 goal 名分格的增量产物,如 top/lint/lint_rtl/ 一类层级),报告则落在 spyglass_reports/<goal>/。具体目录名与层级随版本和 set_option wdir/projectdir 设置而变,以本单位版本实际生成的目录为准。删之前先 du -sh 与 ls 确认范围,删的原则是只删可再生的工作/产物目录,绝不删源码、filelist、.prj、waiver 与脚本;拿不准时先把目录改名备份,确认重跑无影响后再彻底删除。
第三步:干净重跑,并在日志里核对「重新 analyze 的文件数」。 两种做法:一是退出工具后手工清空上述工作目录再启动原命令;二是使用流程提供的 clean 选项——部分版本的启动命令或 run_setup/common_run_template 模板支持 clean 类开关(如命令行 clean 选项或模板内对应 set_option),名称与行为各版本不一,以本单位版本手册和流程模板为准,不要凭记忆跨版本套用。重跑后别只看违例总数,翻日志确认两件事:本轮 Analyzing 的文件数与 filelist 行数一致、新增/修改过的文件逐个出现在 analyze 列表里;加载了 waiver 的,确认 waiver 加载记录条数非零且无 skipped 警告。
第四步:分支切换、GUI 与命令行、CI 复用,是团队场景的三大高发坑。 切 git 分支后,增量数据库里可能混着两个分支的文件状态,时间戳相近时工具无从分辨——纪律是切分支即清工作目录,或让每个分支使用独立输出目录。GUI 与命令行结果不一致,九成是两者启动目录不同、各自写了一份新旧不一的缓存;统一 work 目录约定后,两边都做一次干净重跑再比对。CI 侧最彻底:每次任务全新检出代码、工作目录放在任务专属临时目录、任务结束随容器一并销毁,从根上消除「复用器上脏目录」的可能;同时确保 CI 用户对工作目录有写权限,权限告警出现即判本次结果无效。
第五步:规范输出目录,让缓存可整目录丢弃。 在 .prj/run_setup 里把工作目录与报告目录显式固定到工程根下的统一位置(命名带顶层名与 goal 名),不要让产物散落在启动目录。这样「清缓存」就是一条确定的 rm -rf <工作目录>,可以安全脚本化;配套要求团队不以手工拷贝文件的方式「更新」输入——拷贝可能保留或回拨 mtime,恰好骗过增量判定的时间戳比较,更新代码只走版本库或正常编辑。
四、预防与纪律
- 结果先对源码再讨论规则:违例行号对不上当前代码,一律先按缓存陈旧处理,不与规则语义纠缠。
- 改了输入就干净重跑:RTL、filelist、waiver、
.prj任一变更后,清工作目录或以 clean 方式重跑,并在日志核对重新 analyze 的文件数与 waiver 加载条数。 - 切分支即清缓存:分支用独立输出目录;GUI 与命令行统一 work 目录约定。
- CI 固定全新检出:任务专属临时工作目录、结束即销毁;目录写权限告警直接判结果无效。
- 工作目录显式固定、可整目录丢弃:清缓存脚本常备,让「不信就干净重跑」成为零成本动作;选项名称一律以本单位版本手册为准。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇中「确定性与复现」节点的 FAQ 页,总入口见 开源 EDA 报错排错中心;工程连启动都失败的配置/Goal/Tcl 加载问题走 SpyGlass 配置解析失败速查,waiver 加载与签收纪律见 Lint waiver 签收与基线门禁,规则体系、违例治理与 lint 在流程中的门禁位置见 RTL 静态检查(Lint):SpyGlass 规则体系与基线门禁。
一句话总结
SpyGlass 缓存陈旧不报错、只给旧答案,判据是报告与当前源码对不上(旧行号、违例数不变、新文件无 analyze 记录);定位 spyglass_work/、work/、<top>/<goal>/ 等工作目录后清空或以 clean 方式重跑(选项以本单位版本手册为准),并在日志核对重新 analyze 的文件数与 waiver 加载条数;长期靠「切分支即清、CI 全新检出、输出目录显式固定、权限告警即判无效」四条纪律,把结果可信度从运气变成可核对的事实。