Yosys hierarchy -check 报错:Module is not part of the design 排查
更新时间:2026-10-29。报错排查速查页,属于 EDA 报错排查系列。
hierarchy -check是 Yosys 里主动核对设计层级的工序,报错Module ... is not part of the design的意思是:某个例化单元指向的模块定义,在当前设计库里找不到。注意它和 yosys 子模块未声明排查 是同一族问题的两个入口——那篇是synth流程顺带跑 hierarchy 时炸出来,本篇讲的是你主动跑hierarchy -check(比如自建 Tcl 脚本、CI 里先做层级体检再综合)时怎么定位和修。
首屏答案:hierarchy -check -top top 报 Module \fifo' referenced in module `top' in cell `u_fifo' is not part of the design,九成的根因是定义 fifo的那份.v文件没进read_verilog 清单——Yosys 的视野只有已读入的模块,不会自己去磁盘搜文件。修复就是把缺失文件补进读入列表再复跑:yosys -p 'read_verilog fifo.v top.v; hierarchy -check -top top'`。剩下的一成是模块名拼写/大小写不一致,或参数化例化在 derive 阶段失败。
本文要回答的问题
hierarchy -check这条命令到底在检查什么,-check加不加有什么区别?- 报错串里
fifo、top、u_fifo三个名字各是什么角色? - 缺失模块、拼写不一致、参数化例化三类触发怎么逐条收敛?
- 修复后怎么确认层级真的闭合了?
一、报错原文与现象
最小复现工程:顶层 top.v 例化了一个参数化的同步 FIFO——fifo #(.WIDTH(8), .DEPTH(16)) u_fifo (...),而 fifo.v 故意不读入。主动跑一次层级检查:
yosys -p 'read_verilog top.v; hierarchy -check -top top'真实报错实录(Yosys 0.33):
读这段输出抓三个要点。第一,Verilog 前端对 top.v 是 Successfully finished 的——语法解析没有抱怨,也就是说报错不来自 RTL 写错。第二,2. Executing HIERARCHY pass 的 Analyzing design hierarchy 阶段先确认了 Top module: \top,随后才报错——说明顶层指定没问题,挂在「顶层引用的子模块」上。第三,报错串的三个名字分工明确:fifo 是缺失的模块定义名,top 是引用它的父模块,u_fifo 是例化单元的实例名。整条排查都围绕一件事:名为 fifo 的模块定义此刻在不在设计库里。
二、根因:hierarchy -check 在检查什么
hierarchy 工序把已读入的所有模块定义建成层级表,从 -top 指定的顶层出发,顺藤摸瓜核对每一个例化单元:被例化的模块名必须在表里;遇到参数化例化(fifo #(.WIDTH(8)) 这种),还要以 derive 模式把参数代入重新推导出一个具体模块——日志里那个 $paramod$e9ce...\fifo 就是参数代入后生成的「实例化版本」模块名。
-check 开关的含义是:查完发现缺失就 ERROR 中止,而不是降级成警告继续往下走。所以 hierarchy -check 常被放在自建综合脚本的最前面当前置体检——层级不闭合的设计,后面的 proc、opt、techmap 跑了也是浪费,不如第一步就炸。这也是为什么 CI 里建议显式写一步 hierarchy -check,而不是等 synth 顺带检查:报错位置更早、信息更聚焦。
这里有一个容易混淆的点值得单独说清:synth 流程内部第一步也会自动跑一遍 hierarchy(不带显式 -check 时行为等价),所以同一份缺文件的设计,直接 synth 也会在同一处报出同样的 ERROR。两者的差别不在「会不会报」,而在报的时机和上下文:主动跑 hierarchy -check 时输出只有层级分析几行,报错紧跟 Analyzing design hierarchy,一眼能定位;混在 synth 几十行日志里时,得往回翻才能看清是哪个工序炸的。把层级体检从综合里拆出来单独一步,本质是把排查成本前移。
三类真实成因按下表逐条对照:
| 成因 | 典型现场 | 快速确认 | 处置 |
|---|---|---|---|
| 子模块文件没读入 | 命令行/脚本只列了顶层 | 看 read_verilog 清单里有没有 fifo.v | 把缺失文件补进读入列表 |
| 模块名拼写/大小写不一致 | RTL 例化写 Fifo,定义是 fifo | grep -rn "^module" *.v 比对真实拼写 | 统一拼写,建议模块名全小写 |
| 参数化例化 derive 失败 | 参数类型/宽度不被支持 | 去掉 -check 跑一次看 derive 阶段警告 | 修正参数声明或例化写法 |
三、排查漏斗
拿到这条 ERROR 后的标准收敛路径,按命中率从高到低排成漏斗——先查最常见的漏读文件,再查拼写,最后才轮到参数化例化这种少见形态:
这张漏斗卡的读法是从上往下逐层排除:绝大多数情况在第二层(读入清单)就能闭环,不用往下走;只有当清单确实完整、拼写也对,才去怀疑参数化例化——那通常在 derive 阶段还会附带别的警告,不会只有这一条 ERROR。
补一个工程里高频的变体:很多人不是不写 fifo.v,而是写了但读入动作在另一个脚本分支里——比如 filelist 由构建脚本生成,新增文件忘了登记;或者仿真 Makefile 里文件齐全、综合脚本里是另一份手维护的清单,两边渐渐漂移。判断方法很机械:把仿真用的文件清单和 read_verilog 的清单 diff 一下,差集里找缺失模块名,命中即结案。防漂移的正道是让综合和仿真共用同一份自动生成的 filelist,而不是两份手维护的列表靠人盯。
四、修复与复跑验证
本例属于第一层成因:fifo.v 没进读入清单。修复就是把它补上,再复跑同一条检查命令:
yosys -p 'read_verilog fifo.v top.v; hierarchy -check -top top; stat'复跑实录的关键段落:
这段输出里藏着参数化例化的完整生命周期:Analyzing design hierarchy 先确认 Top module: \top、Used module: \fifo 并列出参数 WIDTH = 8 / DEPTH = 16;随后 Executing AST frontend in derive mode 把参数代入,生成 $paramod$e9ce...1fb8c\fifo 这个具体模块;Removing unused module \fifo'表示未绑定参数的「模板」定义被清理,层级里只剩参数化实例。最后stat打印的 design hierarchy 树里top下面挂着$paramod...\fifo` 各一个实例——看到这棵树,才算层级真正闭合。确认闭环的标准不是「没报 ERROR」,而是层级树里每个例化单元都有具体模块定义兜底。
还要注意一个细节:补读文件后日志里出现两条 Warning: Replacing memory \mem with list of registers,这是 Yosys 前端把 reg [WIDTH-1:0] mem [...] 展开成寄存器组的常规提示,与层级检查无关,不影响本例结论——但它提醒了一个经验:复跑时只对比层级相关的行,其他工序的既有警告不要误当成新问题去追。
顺带强调一点:不要用删掉 -check 的方式「绕过」报错——那样层级缺口只是被降级成警告带进后续工序,综合出来的网表里那个位置是个黑盒空壳,问题会在更晚、更贵的环节爆发。修结构,而不是调工具的嗓门。
五、预防清单
- 读入清单宁多勿漏:脚本里列全所有
.v文件,或用read_verilog -lib/ filelist 统一管理,新增模块文件必须登记。 - 模块名全小写:Verilog 大小写敏感,团队约定模块定义与例化名一律小写,从根上消灭拼写类触发。
- CI 前置 hierarchy -check:综合脚本第一步显式跑层级体检,报错早暴露、信息更聚焦。
- 参数化例化写全参数:
#(.WIDTH(8), .DEPTH(16))显式具名传参,比依赖默认值更不容易在 derive 阶段翻车。
实验环境
- 机器/系统:docker 容器(镜像 geek-eda:0.2)
- 工具版本:Yosys 0.33 (git sha1 2584903a060)
- 日期:2026-10-29
- 完整命令:
yosys -p 'read_verilog top.v; hierarchy -check -top top'(报错复现);yosys -p 'read_verilog fifo.v top.v; hierarchy -check -top top; stat'(修复后复验)
代码获取
复现用源码(top.v 顶层、fifo.v 参数化 FIFO 子模块)在公开仓 https://github.com/derekzhuo/geek-doc.cn/tree/main/experiments/yosys-hierarchy-check-fail。装好 Yosys 后先跑 yosys -p 'read_verilog top.v; hierarchy -check -top top' 复现报错,再把 fifo.v 补进读入清单跑同一命令验证修复。
这一篇在知识体系里的位置
本篇是开源 EDA 报错排查系列中 Yosys 层级检查专题:同一族问题的 synth 入口见 yosys 子模块未声明排查;顶层名字本身指错看 yosys ERROR no top module;模块找不到的泛化速查见 Yosys 模块单元找不到;整个系列的目录在 EDA 报错排查系列。
总结
hierarchy -check 报 Module ... is not part of the design,就是顶层引用的某个模块定义没在设计库里——绝大多数是子模块文件没进 read_verilog 清单,少数是模块名拼写不一致或参数化例化 derive 失败。排查按「读报错三个名字 → 查读入清单 → 查拼写 → 查参数化」的漏斗逐层收敛;修复后复跑要看 stat 打印的层级树确认每个例化单元都有定义兜底(参数化模块会显示为 $paramod$... 形式),而不是只看没有 ERROR。永远不要用去掉 -check 的方式消音,层级缺口带到综合后只会更贵。