Quartus 编译卡死速查:quartus_fit/quartus_map 跑几小时不出结果怎么办
更新时间:2026-10-23。FAQ 速查页,属于 FPGA 工具报错排错系列。Quartus 最折磨人的故障不是报错退出,而是「不报错也不出结果」:
quartus_fit停在某个百分比几个小时不动,GUI 进度条冻结,CI 里编译任务跑到超时被系统杀掉。本篇分诊 Quartus 编译期的卡死与超时。进程直接闪退、报段错误的那类问题见 Quartus 崩溃/段错误速查,Vivado 侧同类问题的对照片见 Vivado 运行卡死/超时速查。
本文要回答的问题
quartus_fit停在某一行几小时,怎么分清是 Fitter 在难解布局上正常迭代,还是真的挂死?- 进度条停在某个百分比(比如 Analysis & Synthesis 的 90%)不动,各自指向哪类根因?
top里看到 CPU 100%、CPU 0%、内存在涨 swap 在抖,分别说明什么?- 增量编译数据库(db 目录)损坏、license 心跳断开、seed 运气差,分别怎么确认和处理?
- CI 里编译任务固定跑满时长被杀,除了加大超时还能做什么?
一、现象与报错原文
Quartus 编译卡死时,现场通常只剩三样东西:编译日志(quartus_sh --flow compile 的 stdout 或 GUI 的 Processing 面板)的尾行、进程状态、CPU 与内存占用。以下四类形态最典型,工程名与路径均占位。
1. 日志停在 Fitter 某一步不再推进,GUI 进度条冻结在某个百分比:
Info (170129): Fitter routing operations beginning
Info (170130): Fitter routing operations ending: elapsed time is 00:12:47
Info (170186): Fitter placement operations beginning
<- 几小时没有下一行,也没有报错这不一定是故障:资源接近打满、扇出极高的设计,Fitter 布局布线本身就可能跑数小时并反复迭代。判断标准是「日志时间戳是否推进」加「CPU 是否在跑」,不是「我觉得它该跑完了」。
2. Analysis & Synthesis(quartus_map)卡在高百分比,日志停在某个大模块的展开处,CPU 单核 100% 但长时间零推进——常见于超宽 case、巨形 generate 循环、或某 IP 的黑盒推断走进了病态路径。
3. CI 编译任务固定时长后被杀,日志最后一行停在任意正常阶段,没有任何 Quartus 报错——任务是被外部超时机制终止的,与工具自身崩溃是两回事。
4. 内存持续上涨、系统开始 swap,机器整体变卡、磁盘灯常亮,quartus_fit 的 RSS 逼近物理内存上限——此时它在「抖」,不是在算。
二、现象 → 区分点 → 处置速查表
| 现象 | 区分点 / 最常见原因 | 处置 |
|---|---|---|
| CPU 高、日志时间戳缓慢推进 | Fitter 在难解布局上正常迭代(扇出高/资源接近打满) | 看 Fitter 报告的峰值利用率;降扇出、放松布局区域约束或换 seed 重扫 |
| CPU 高、RSS 逼近内存上限、swap 在涨 | 内存不足导致 swap 抖动,越跑越慢像卡死 | 加内存或降 Quartus 并行处理器数;关闭同机其他大进程;分区编译降低单次峰值 |
| CPU 0%、日志尾行与 license 有关 | license 心跳断开,进程悬挂等服务器响应 | 确认 license 服务可达;按本版本 Licensing 指南设心跳/重连超时,让失败快速暴露 |
| 换台机器或删 db 后能跑过 | 增量编译数据库(db/incremental_db)损坏 | 停掉进程后删 db 与 incremental_db 目录全量重编;工程迁移后养成清 db 习惯 |
| 同一设计有时几小时有时几十分钟 | seed(布局种子)运气差,初值落在难解区 | 用 seed sweep 扫 5-10 个种子取最优;不要在失败 seed 上死等 |
| 约束只有引脚没有时钟/时序 | 优化目标发散,Fitter 无边界地试 | 补齐 .sdc 时钟与 false path/multicycle 约束后再编 |
| quartus_map 停在大模块、单核 100% 零推进 | 病态 RTL(超宽 case/巨 generate)或 IP 推断异常 | 对半注释定位模块;改用显式原语或重写该段结构 |
| Windows 上时快时慢、磁盘常亮 | 杀毒实时扫描大中间文件 | 工程目录加入杀毒排除列表 |
三、排查决策树
分诊只问两个问题:日志尾行的时间戳还在不在推进,CPU 与内存到底处于什么状态。答案把现场切成「在算」和「在等/在抖」两条通道:
读这张图抓住三条分叉:CPU 高且日志在推进,走绿色通道,Fitter 在算,杀掉只会浪费已跑完的时间;CPU 为 0,走等待通道,头号嫌疑是 license 心跳;内存逼近上限、swap 在涨,那是抖动通道,它在换页而不是在算。 红色是入口现象与三类病态状态,蓝色是排查动作,绿色表示「其实在干活」,橙色是修复,紫色是收口防复发。不要一卡就杀进程:正在做第 40 次布局迭代的 Fitter 和心跳断掉空等的进程,处置完全相反。
四、逐条排查展开
先取证,再动手。 Linux 下一条命令看清线程级 CPU 与内存:
ps -o pid,stat,%cpu,rss,etime,cmd -p <pid>
top -H -p <pid> # 有线程 100% = 在算;全 0 = 在等;RSS 逼近物理内存 = 在抖Windows 下开任务管理器的「详细信息」页,看 quartus_fit.exe 的 CPU 列与工作集内存列,磁盘列持续 100% 且 CPU 很低时,要么在换页要么在慢盘上读写中间文件。
Fitter 迭代:先判断值不值得等。 打开上一次成功编译的 Fitter 报告,看逻辑利用率与布线资源峰值:超过 85% 的设计,Fitter 在布局合法化上反复拉扯是常态,几小时不稀奇。应对有三条路:削高扇出网络(复制寄存器、加流水线)、用 Logic Lock 区域把关键模块钉住减小搜索空间、或者直接换 seed——同一设计不同种子的编译时间可以差 3-5 倍,用 quartus_sh --flow compile -c <revision> 配合 Tcl 的 set_global_assignment -name SEED <n> 扫 5-10 个种子,取时序与耗时都好的那个固定下来。
约束缺失会让优化目标发散。 只有引脚分配、没有 .sdc 时钟约束的工程,Fitter 不知道哪条路要紧,会在所有路径上无差别地试,表现为时间越跑越长且时序结果随机。检查 .sdc 是否真的被工程引用(set_global_assignment -name SDC_FILE),补上 create_clock 与必要的 set_false_path 后再编,很多「卡死」会自己消失。
增量编译数据库损坏:删 db 是最便宜的试金石。 工程跨版本打开、编译中途被杀、工程目录被同步工具(网盘)写过,都可能让 db 与 incremental_db 目录内部状态不一致,表现为重新编译后卡在奇怪的阶段。确认没有活着的 Quartus 进程后删掉这两个目录全量重编,能跑通即石锤。
license 心跳断开是静默悬挂。 网络抖一下,编译进程可能停在等 license 服务器响应的调用上,CPU 0%、日志停在与 license 相关的尾行附近。先确认 license 服务可达、席位没被僵尸会话占住;再按你本机版本 Quartus Licensing 指南设置心跳与重连超时,让断连表现为快速失败而不是无限悬挂——变量名以官方文档为准,不要凭印象设。
内存不足换页:加内存前先降峰值。 quartus_fit 的峰值内存随设计规模线性涨,物理内存不够时整个系统跟着抖。处置顺序:关掉同机其他大进程、把 Quartus 并行处理器数(NUM_PARALLEL_PROCESSORS)降到 1-2、用设计分区(Design Partition)把编译拆小;都不够再加内存。
CI 侧把「卡死」改造成「带现场的超时失败」。 给 map/fit/asm 各阶段分级超时(fit 的额度按本工程历史耗时给足),提交命令显式重定向 stdin 避免任何交互等待:
cd /proj/demo && timeout 6h quartus_sh --flow compile demo \
</dev/null > compile.out 2>&1真正挂起时先保留编译日志与进程状态快照再杀进程;反复在同一阶段卡死且有具体报错指向的,转 Quartus 崩溃/段错误速查 对号。
五、预防与纪律
- 约束先行:每个工程从第一天就配齐
.sdc时钟约束,别等 Fitter 跑飞再补。 - db 卫生:跨版本打开、异常中断、工程迁移后,先删
db与incremental_db再重编。 - seed 制度化:时序吃紧的设计,把 seed sweep 做成 CI 例行步骤,不要死磕单个种子。
- 内存留裕量:编译机内存按设计峰值留 30% 以上;并行度按核心数与内存折算,不要默认拉满。
- license 超时化:心跳与排队都设上限,断连快速失败。
- CI 分级超时 + 阶段时间戳:map/fit/asm 分开限时,日志带时间戳,哪一段超时看尾行即知。
这一篇在知识体系里的位置
本篇是 FPGA 排错速查簇中「Quartus 编译期卡死」节点的 FAQ 页:进程闪退、段错误见 Quartus 崩溃/段错误速查;Vivado 侧同一类「跑几小时不出结果」的分诊口径见 Vivado 运行卡死/超时速查,两篇的分诊框架一致(时间戳 + CPU/内存三态),但根因轴不同——Quartus 侧独有 seed、增量编译 db 与 Logic Lock 这一套手段。
一句话总结
Quartus 编译卡死的分诊起点是编译日志尾行时间戳加 CPU/内存状态:CPU 高且日志在推进就是 Fitter 正常迭代,按资源利用率决定继续等还是降扇出、补约束、换 seed;CPU 0% 查 license 心跳与 db 损坏;内存将满 swap 在抖就降并行度、分区编译或加内存。根治靠约束先行、db 卫生、seed sweep 制度化,CI 侧用分级超时配阶段时间戳日志,把无期限卡死改造成带现场的快速失败。