Quartus 找不到模块(Module not found / Top-level entity undefined)报错速查
更新时间:2026-10-23。速查页,面向刚用 Quartus 搭工程、把 RTL、仿真模型和 IP 混在一起编译的同学。症状很典型:点 Analysis & Synthesis 没跑几秒就红掉,日志甩出
Error (12007): Top-level design entity "xxx" is undefined,或者Can't find design file,而你明明记得这个.v就在工程目录里躺着。
报错原文与一句话根因
典型报错长这样:
Error (12007): Top-level design entity "top_uart" is undefined
Error (10028): Can't resolve multiple constant drivers for net "tx" at top_uart.v(42)
Error: Quartus Prime Analysis & Synthesis was unsuccessful. 1 error, 3 warnings
Error (12006): Node instance "u_fifo" instantiates undefined entity "fifo_256x8"
Error (10170): Verilog HDL syntax error at top_uart.v(10) near text: ...其中 12007 与 12006 才是「找不到模块」这一对兄弟:Top-level design entity is undefined 是顶层实体找不到,Node instance ... instantiates undefined entity 是顶层里某个例化找不到。
一句话根因:Quartus 在 Analysis 阶段按「工程文件清单」去解析每个实体/模块名,清单里没有这份定义,或定义的名字和你引用的名字对不上。它不是文件真丢了,而是工程配置(.qsf)没把文件喂给编译器,或者喂进去的那份定义名字不对。看到这类错,先去查「文件在不在工程里」和「名字对不对得上」,不要去查语法。
六大病因速查表
| 报错形态 | 最可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| 12007 顶层 undefined | Settings 里顶层实体名与 module 名不一致 | Assignments → Settings → General 看 Top-level entity | 改成与 RTL module 名逐字符一致 |
| 12007 顶层 undefined | 顶层文件根本没加进工程 | Project Navigator → Files 页找该文件 | Add/Remove Files in Project 加入 |
| 12006 例化 undefined | 子模块 .v 没加入工程,或加进了但被排除 | 看 .qsf 里有无对应 VERILOG_FILE 行 | 补 set_global_assignment -name VERILOG_FILE |
| Can't find design file | .qsf 里路径是相对旧目录写的,工程被移动过 | 用文本编辑器打开 .qsf 搜文件名 | 修正相对路径或重新 Add |
例化 altsyncram 等宏模块 | 器件库/宏模块库没参与编译 | 报错模块名是否 altera_mf 系列 | 确认器件库已安装,仿真时加 altera_mf.v |
| Linux 上才炸、Windows 正常 | 文件名大小写敏感 | 对比文件实际名与 .qsf 里写的名 | 统一大小写,文件名与 module 名同规则 |
| IP 核(PLL/FIFO)例化找不到 | 只例化了 IP 实例,.v 变体文件没纳入工程 | IP 输出目录下有无 <ip名>.v | 把 IP 生成的 .v / .qip 加进工程 |
排查决策流程
照这张图自上而下短路排查,第一个答「否」的节点就是根因。图中红色是入口现象,蓝色是排查动作,绿色是判定通过,橙色是修复动作,紫色是防复发收尾:
读法:先看顶层(最高频),再查文件清单,再查路径与大小写,最后才轮到库和 IP。绝大多数案例倒在「文件没加进工程」和「顶层名不一致」这两格。
逐条排查步骤
第一步,确认顶层实体名。 Assignments → Settings → General,看 Top-level entity 一栏。Quartus 要求这里的字符串与 RTL 里 module top_uart (...) 的名字逐字符一致,包括大小写。GUI 里写 Top_Uart 而代码里是 top_uart,Windows 下有时能蒙混,Linux 下直接 12007。改完不用重开工程,直接重跑 Analysis。
第二步,确认文件真的在工程里。 Project Navigator 切到 Files 页,挨个找你怀疑丢了的源文件。找不到就 Project → Add/Remove Files in Project 加进来。注意 Quartus 不会自动扫描工程目录——把 .v 拷进目录和把它加进工程是两回事,这是新手踩得最多的一格。
第三步,直接看 .qsf。 工程根目录下的 <工程名>.qsf 是文本文件,文件清单长这样:
set_global_assignment -name VERILOG_FILE rtl/top_uart.v
set_global_assignment -name VERILOG_FILE rtl/uart_rx.v
set_global_assignment -name VHDL_FILE tb/fifo_model.vhd没有对应行 = 文件没进工程;有行但路径是相对旧目录写的(工程被整体移动过)= Can't find design file。手工修路径后重新打开工程即可。也可以用 Tcl 控制台批量核对:
project_open top_uart
foreach f [get_all_assignments -name VERILOG_FILE] { puts $f }第四步,查名字与大小写。 12006 报错里给了例化名,全局搜这个名字的定义。Verilog 大小写敏感,Fifo_256x8 和 fifo_256x8 是两个模块。Linux 上连文件名都敏感:Fifo.v 里定义 fifo,Windows 能过,Linux 编译器按例化名找文件时找不到。
这里要解释一下 Quartus 的解析模型,理解了它后面每一步为什么是查这些就顺了:Analysis 阶段 Quartus 把 .qsf 清单里列出的所有源文件逐份编译成「设计单元」,放进一个以工程名为默认库(work)的符号表里,然后从顶层实体开始向下做层次化展开,每遇到一个例化就到符号表里按名字找定义。任何一环——文件没进清单、编译失败没进符号表、名字对不上——在展开阶段就表现为 undefined。所以这类报错的排查本质是「符号表里为什么缺这一项」,而不是「代码写得对不对」。
第五步,库与 IP。 例化 altsyncram、altpll 这类 Altera(现 Intel)宏模块时,综合阶段 Quartus 自带器件库通常没问题;仿真阶段要手动把 altera_mf.v(在 <Quartus安装目录>/eda/sim_lib/ 下)加进仿真工程。自研 IP 核(Platform Designer / 旧 MegaWizard 生成)要注意:只例化实例不够,必须把 IP 生成的 .v 变体文件或 .qip 也 Add 进工程,否则综合时一样 undefined。
第六步,VHDL 工程的特例。 报 entity "xxx" is undefined 的 VHDL 工程,先查 library work; use work.xxx_pkg.all; 是否齐全,再查 entity 名与 set_global_assignment -name VHDL_FILE 指向文件里的定义是否一致——VHDL 要求实体名而非文件名匹配,文件名随意但实体名必须对得上例化。
修复后验证
- 重跑 Processing → Start → Start Analysis & Synthesis,确认 12007/12006 消失,而不是仅仅「错误数变少」。
- 看 Compilation Report → Analysis & Synthesis → Summary,确认顶层实体名是你预期的那个,且没有黑盒警告(
Warning (13024): Output pins are stuck at GND类常伴生黑盒)。 - RTL Viewer 里展开顶层,确认每个子模块实例下面都有内容,不是一个空框。
第七步,多文件同名定义的遮蔽。 还有一种隐蔽情况:工程里两份文件定义了同名模块(比如 rtl 目录一份旧版 uart_rx.v,第三方目录又一份新版),Quartus 不会报 undefined,而是挑其中一份用,行为和你预期完全不同。症状是「编译能过但功能不对」。用文本搜索在整个工程目录搜 module uart_rx,命中两处以上就要清理,只保留一份进 .qsf。
常见坑
- 拷目录不等于加进工程:把别人给的
.v拷进工程目录就以为完事,Quartus 只认.qsf里的清单。 - 顶层名靠下拉框选:Settings 里顶层实体用下拉框选比手敲靠谱,手敲容易大小写错位。
- Linux CI 上才炸:本地 Windows 全绿、服务器上 12007,九成是大小写。命名一开始统一全小写。
- IP 改了名忘改例化:MegaWizard 里改了 IP 输出文件名,旧例化还指着老实体名。
.qsf被 GUI 静默改写:Add/Remove 文件后直接关工程可能丢修改,养成改完立刻看 git diff 的习惯,.qsf必须入库。
防复发清单
.qsf与 RTL 同提交,禁止「工程配置只存在某台机器上」。- 命名全小写,文件名跟随 module/entity 名,一条规则管到底。
- IP 生成后第一件事:把
.qip或变体.vAdd 进工程,写进团队 checklist。 - 仿真工程单独维护一份文件清单,
altera_mf.v/220model.v这类库文件固定在前。 - CI 里把 Analysis & Synthesis 当最小检查:
quartus_map <工程名>几十秒就能把 undefined 类错误拦在提交前,不用等全编译。
这一篇在知识体系里的位置
同族报错:Quartus license 取不出来速查、Quartus 未定义符号速查(实例化对象找不到的另一张面孔);跨工具对照可看 Vivado 模块/单元找不到速查,病因轴相通、工程文件从 .qsf 换成 .xpr。
一句话总结
Quartus 找不到模块的本质是编译器按 .qsf 文件清单解析实体名时没找到匹配定义:按「顶层名 → 文件在不在工程 → 路径与大小写 → 库与 IP」四格短路排查,GUI 操作配合直接读 .qsf 里的 set_global_assignment 行,VHDL 特例查 library/use 与实体名,修完用 quartus_map 与 RTL Viewer 做闭环验证,再把 .qsf 入库与全小写命名固化成团队纪律,这类报错十分钟内必收敛。