FPGA 入门 11:Quartus 工程上手——Intel FPGA 流程
更新时间:2026-09-12。本文是
fpga/入门层第 13 篇。Xilinx 平台流程见 Vivado 上手,厂商家族见 厂商与器件家族,软核概念见专家层《软核处理器》(后续)。
本文要回答的问题
- 没用过 Intel/Altera 平台,能不能用 Vivado 的经验直接上手 Quartus?两家的步骤、报告、文件格式怎么一一对应?
- New Project Wizard 里器件系列(Cyclone/Arria/Stratix/MAX)那么多,入门该选哪个?
- Analysis & Synthesis、Fitter、Assembler、Programmer 每一步在干什么、产物是什么、卡在哪一步看什么?
.sof和.pof区别是什么?为什么下载完掉电程序就没了,怎样固化?- TimeQuest/Timing Analyzer 报告里的 Fmax、slack 怎么看,和 Vivado 的 WNS/WHS 是什么关系?
- 管脚分配用 Pin Planner 还是写 QSF?SDC 约束和 XDC 差多少?
- Platform Designer(Qsys)什么时候才需要碰,纯 Verilog 工程能不能完全不用它?
- 第一次装 Quartus、第一次用 USB-Blaster,最容易卡住的环境问题有哪些?
读完本文,你应当能在一块 Cyclone 开发板上,从零建工程、写/加 Verilog、分配管脚、加时钟约束、跑到 Fitter 时序无红、最终用 Programmer 把 LED 例程下载并固化——并且能把这里的每一步映射回你已经熟悉的 Vivado 流程。
一、流程对照
| 步骤 | Vivado(Xilinx) | Quartus(Intel) |
|---|---|---|
| 建工程选器件 | New Project | New Project Wizard |
| 综合 | Synthesis | Analysis & Synthesis |
| 布局布线 | Implementation | Fitter (Place & Route) |
| 时序报告 | WNS/WHS | Timing Analyzer / Fmax |
| 生成比特流 | Generate Bitstream(.bit) | Assembler(.sof/.pof) |
| 下载 | Hardware Manager | Programmer + USB-Blaster |
| 图形系统 | Block Design (IPI) | Platform Designer(Qsys) |
| 约束 | XDC(Tcl) | SDC/QSF(Tcl) |
二、下载与固化

三、新手要点
- 入门选 Cyclone 系列板(资料最多、便宜),对应 Artix-7 定位;
- 顶层模块名设为工程 top(Settings 里指定);
- 管脚分配:Pin Planner 图形化或 QSF 中
set_location_assignment; - SDC 写
create_clock,Fitter 后看 Timing Analyzer 无红; - 软核/多 IP 系统用 Platform Designer 图形互联(对应 Block Design)。
四、从零走一遍:New Project Wizard 到下载
下面用「LED 闪烁」把整条链路串起来(完整代码见 第一个工程 LED 计数器,逻辑与平台无关,换 Quartus 工程即可)。
- 新建工程:File → New Project Wizard。第一页选空目录、工程名与顶层模块名三者一致(Quartus 对工程名/top 名较敏感,建议同名,如
led_blink)。第二页选 Empty Project(不要用模板)。第三页把写好的.v加进来,也可先空着后加。 - 选器件:在 Family 里选 Cyclone(入门板多为 Cyclone IV E / Cyclone V / Cyclone 10 LP),然后在器件列表里按板子丝印精确选到具体型号与封装、速度等级(如
EP4CE6E22C8:EP4C=Cyclone IV、E6 规模、E22=EQFP144 封装、C8=速度档)。型号选错会直接导致管脚号对不上、下载失败。也可以用 Board 标签按开发板筛选。 - EDA 工具设置页:入门全留空(仿真可以用 ModelSim 单独跑,见 Testbench 与仿真),Finish。
- 加/写 RTL:Project Navigator 里 Files 右键 Add/Remove,把全部
.v(含子模块)加进来;在 Settings → General 里确认 Top-level entity 是你的顶层模块名(区分大小写要和 module 名一致)。 - 管脚分配:Assignments → Pin Planner,在底部表格把每个端口拖到对应管脚号、设 I/O Standard(多为
3.3-V LVTTL);保存后这些信息写进.qsf。也可以直接在.qsf里写set_location_assignment PIN_xx -to clk和set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk。管脚号一律以具体板子原理图/master QSF 为准,只看 FPGA 型号推不出管脚。 - 时钟约束:新建
.sdc加入工程,写一行create_clock -name clk -period 20 [get_ports clk](50MHz 板周期 20ns)。晶振频率、RTL 计数参数、SDC 周期三处必须一致,否则 Fmax/slack 结论不可信。 - 综合:Processing → Start → Start Analysis & Synthesis(工具栏紫色三角形)。成功后看 Compilation Report 的 Analysis & Synthesis 资源(LE/ALM、寄存器、管脚),有 inferred latch 等警告要清。
- 布局布线:Start Fitter(或直接点全编译 Start Compilation 一次跑完综合+Fitter+Assembler)。Fitter 完成后看 TimeQuest/Timing Analyzer 的 Fmax 与 slack。
- 生成配置文件:Start Assembler 产出
.sof(默认);要固化再生成.pof(Assignments → Device → Device and Pin Options → Configuration 里选对配置芯片 EPCS/EPCQ,并勾选生成对应文件,或用 File → Convert Programming Files)。 - 下载:Tools → Programmer → Hardware Setup 选 USB-Blaster → Mode 选 JTAG → Add File 选
output_files/led_blink.sof→ 勾 Program/Configure → Start。进度条 100%(Successful),板子上 LED 开始闪。整个过程遇到任何一步卡住,按「语法/elaboration→管脚/资源→时序→下载链」的顺序回看报告,比反复点 Start 有效得多。
一条很实用的心智:Quartus 的 Start Compilation(全编译)= Vivado 一键综合+实现+写比特流;调试阶段也可以分步单跑,省时间。
综合 / Fitter / Assembler 各在做什么
- Analysis & Synthesis(分析与综合):读 RTL、做语法/elaboration(展开参数、例化)、把行为代码翻译成 LE(Logic Element,Cyclone IV)或 ALM(Adaptive Logic Module,Cyclone V 以后)+ 寄存器组成的网表。对应 Vivado 的
synth_design。这一步能抓语法错、模块找不到、位宽/多驱动/推断锁存器等问题。 - Fitter(适配器 / Place & Route):把网表里每个 LE/FF/RAM/PLL 摆放到芯片具体位置(plan),再用布线资源连起来(route),同时按 SDC 做时序驱动布局布线。对应 Vivado 的
place_design+route_design。管脚冲突、资源超容、时序违例都在这一步暴露。 - Assembler(汇编器):把 Fitter 结果转成配置数据——
.sof(SRAM Object File,下 FPGA)和.pof(Programmer Object File,烧配置芯片)。对应 Vivado 的write_bitstream。 - TimeQuest / Timing Analyzer:不是独立的「步骤」,而是贯穿 Fitter 的静态时序分析器(Cyclone IV 时代叫 TimeQuest,新版统一为 Timing Analyzer),读 SDC、算每条寄存器到寄存器路径的 slack 和每个时钟能跑到的 Fmax。
五、看懂 Fitter 后的时序报告
Quartus 的时序表达和 Vivado 略有不同,但内核完全是同一套 STA(系统讲解见进阶 静态时序分析):
- Fmax(最高频率):某个时钟域在不违例前提下能跑的最高频率。报告给要求频率与实际能达到的频率;你的时钟频率低于它即满足。等价说法:Vivado 给周期裕量 WNS,Quartus 爱直接报 Fmax,两者换算
slack = 数据要求时间 - 数据到达时间。 - Slack:setup 的
Slack = Data Required Time - Data Arrival Time。绿色/正数=满足,红色/负数=违例,和 Vivado 的 WNS/WHS 同号同义;建立 slack 负→频率上不去(逻辑级数太深、扇出太大),保持 slack 负→通常工具会自动插延迟,也要查时钟偏斜。 - Setup / Hold / Recovery / Removal:分别对应建立、保持、复位恢复/移除检查,都要为正。
- Unconstrained Paths / Clocks:先确认 SDC 的时钟被识别、没有未约束时钟;时钟不对,后面全绿也没意义。这和 Vivado「先看 Clock Summary」是同一个纪律。
- 最差路径展开:在 Timing Analyzer 里用
report_timing或图形界面列出 worst path,能看到源寄存器、目的寄存器、逻辑级数、布线延迟——负 slack 的定位方法两家一模一样。
入门 LED 工程时序极宽松,Fmax 会远高于板载频率,slack 是很大的正数;重点是养成「Fitter 完先看时序红不红,红了不上板」的习惯。
SDC 与 XDC 的关系:同源不同名
两者底层都是 Tcl 风格的 SDC(Synopsys Design Constraints),时钟约束几乎逐字相同:
create_clock -name clk -period 20 [get_ports clk]
derive_pll_clocks
derive_clock_uncertainty差异主要在管脚/物理约束:XDC 用 set_property PACKAGE_PIN ... [get_ports ...],Quartus 用 QSF 里的 set_location_assignment PIN_.. -to .. 和 set_instance_assignment -name IO_STANDARD .. -to ..。也就是说,时序约束(create_clock / set_false_path / set_multicycle_path)的概念和写法跨家通用,物理管脚约束语法各家长得不一样。XDC 入门看 XDC 约束入门,管脚与时序深入看 管脚与时序约束。
六、.sof / .pof 与两种下载方式
FPGA 是 SRAM 工艺,芯片本身不存配置,上电必须从某处加载比特流,于是有两种加载方式(Xilinx 的 .bit/烧 QSPI 完全对应,见 比特流与配置 Flash):
- JTAG 直下
.sof:Programmer 经 USB-Blaster 把.sof写进 FPGA 内部配置 SRAM,立即运行,掉电即失。开发调试反复改就用它,几秒钟一版。 - 固化
.pof到配置芯片:板子上通常有一颗 EPCS/EPCQ 串行配置 Flash。Assembler 生成/Convert 出.pof,Programmer 里 Mode 切到 Active Serial Programming(或在 JTAG 模式下勾选对应配置器件),Add.pof、勾 Program,烧入后每次上电 FPGA 自动从该 Flash 配置,掉电不丢。注意:烧配置芯片用的下载模式和直下 FPGA 的 JTAG 模式不同,选错会「找不到器件」。
Programmer 里几个开关的含义:Program/Configure(写主配置数据)、Verify(回读校验,建议勾)、Blank-check / Erase(配置 Flash 专用)。进度条卡住或报 Can't access JTAG chain,先查线缆/驱动/供电/模式。
七、Platform Designer(Qsys)什么时候才用
纯 Verilog 工程完全不需要碰 Platform Designer。它是 Intel 的图形化「系统集成」工具,对应 Vivado 的 Block Design(IPI):
- 你在画布上添加 Nios II 软核 CPU、片上 RAM、Avalon-MM/AXI 总线、PIO(GPIO)、UART、DMA、DDR/Flash 控制器等 IP,画「总线连线」,工具自动生成地址译码、总线仲裁、中断、互联逻辑,导出成一个
.qsys系统,Quartus 综合时它就是一个大模块。 - 典型用途是做「软核 CPU + 一堆外设」的嵌入式系统:底层高速数据流用 FPGA 逻辑,控制/协议栈/人机交互在 Nios II 上跑 C 代码,类似 Xilinx 的 MicroBlaze/Zynq PS。
- 什么时候学:等你需要软核、需要多 IP 用总线互联、或要挂现成接口 IP 时再学;入门阶段把「RTL → 综合 → Fitter → 时序 → 下载」这条主线跑熟更重要。总线概念(Avalon/AXI)在 IP 核怎么调 里先有个印象即可。
八、第一次用 Quartus / USB-Blaster 的环境避坑
- 版本与器件支持:Quartus Prime 分 Lite(免费,支持 Cyclone 等中低端)/Standard/Pro。入门板用 Lite 即可,但很老的 Cyclone IV 只在 Quartus 13.x 等旧版里受支持,新版装了反而找不到器件;下载安装时务必勾选对应 Cyclone 器件库。工程也基本「向上不向下」兼容,团队统一版本。
- 路径与中文:工程路径、用户名、目录名不要有中文/空格/特殊符号,放短路径、移出同步盘,否则 Fitter/Programmer 偶发莫名失败。
- USB-Blaster 驱动:Windows 第一次插入要在设备管理器里手动指定 Quartus 安装目录下的驱动;识别成功后 Programmer 的 Hardware Setup 能看到
USB-Blaster [USB-0]。Linux 需配置 udev 规则。 - 下载线/线序:先用一根确认能传数据的 USB 线;JTAG 排针(TCK/TMS/TDI/TDO)接反或虚接会报 JTAG chain 错误;多器件链要在链配置里加对顺序。
- 能下载但不运行:查配置模式管脚(MSEL)、配置芯片是否真的烧对、时钟是否起振、复位是否一直接在有效电平、LED/按键极性与原理图是否一致。
- 仿真器:Quartus 不带免费波形仿真时,常用 ModelSim-Quartus Starter Edition 或通用 EDA 工具;testbench 写法跨平台一致,见 Testbench 与仿真。
- 命令行/可复现构建:界面操作可用
quartus_sh、quartus_map、quartus_fit、quartus_asm、quartus_sta等命令行复现,.qsf/.tcl是文本可入版本库;这与 Vivado 一切皆 Tcl 的自动化思路一致(见 开发板与工具链)。
九、自测要点与学习地图
自测:① 把 Quartus 四步(Analysis & Synthesis / Fitter / Assembler / Programmer)分别对应到 Vivado 的哪一步、产物是什么;② 说出 .sof 与 .pof 的区别、各自的下载模式、为什么掉电会丢;③ 解释 Fmax 和 slack、红绿如何判断,它们与 WNS/WHS 的关系;④ 管脚分配有哪两种写法、IO_STANDARD 为什么必须设;⑤ SDC 里 create_clock 周期怎么按板载晶振算;⑥ Platform Designer 解决什么问题、纯 RTL 工程是否需要它;⑦ Programmer 找不到 JTAG 链按什么顺序排查。
学习地图:先用 Vivado 主线打牢通用流程 Vivado 上手 与 开发全流程;约束对照 XDC 入门;动手 LED 计数器;时序深入进阶 静态时序分析;调试看 ILA 初用(Intel 对应 SignalTap);做软核系统时再回头啃 Platform Designer/Nios II。
九之二、跟着算一遍:分频常数、位宽与资源
很多「LED 不闪 / 闪得太快」的问题,本质是晶振频率、RTL 计数常数、SDC 周期三处没对齐。以 50MHz Cyclone 板、想让 LED 每秒翻转一次(亮灭各 0.5s)为例:
- 时钟周期
T = 1/50MHz = 20ns; - 0.5 秒包含
50,000,000 × 0.5 = 25,000,000个时钟周期; - 模 N 计数器从 0 数到 N−1,所以比较值是
N-1 = 24,999,999; - 位宽
W = ⌈log₂ 25,000,000⌉:2²⁴=16,777,216不够,2²⁵=33,554,432够,故用reg [24:0] cnt(25 位)。
把这个 25 位计数器写进工程,全编译后在 Compilation Report → Fitter → Resource Section 里会看到大约二十几个 LE/ALM 和 25 个寄存器——你声明几位寄存器,综合后基本就是几个 FF,这是把「代码」和「芯片资源」对应起来的第一次直观验证。若 SDC 写成 -period 10(当成 100MHz)而板子其实是 50MHz,RTL 行为不变(行为只取决于你数了多少拍),但 STA 会按错误频率判断,时序结论全错。这就是反复强调三处一致的原因。资源看法见 资源利用率怎么读,计数器写法见 计数器与分频。
全编译报告该按什么顺序看
初学者面对 Compilation Report 上百行容易发懵,按这个顺序即可:①Flow Summary 顶部一眼看总资源占用、有没有 Error;②Analysis & Synthesis 的 warnings(inferred latch、multi-driven、width mismatch);③Fitter 的 Pin-Out(确认管脚真的分配上了)、Routing/Resource(利用率别到 100%);④TimeQuest/Timing Analyzer 的 Fmax/slack 红绿;⑤Assembler 是否产出 .sof/.pof。和 Vivado「先错误、再关键警告、再资源、再时序」的阅读顺序一致。
九之三、把 Vivado 肌肉记忆迁移到 Quartus
学第二家工具最快的方法不是重学概念,而是建一张「同义对照表」,把已经理解的东西换个名字而已:
| 你在 Vivado 里的说法 | Quartus 里的对应 |
|---|---|
| Design Run / synth_1、impl_1 | Compilation 阶段(map/fit/asm) |
| LUT、Slice、CLB | LE(Cyclone IV)/ ALM(新家族) |
| Block Design(IPI) | Platform Designer(Qsys) |
| MicroBlaze / Zynq PS | Nios II 软核 |
.bit(JTAG)/ QSPI 固化 | .sof(JTAG)/ .pof 烧 EPCS/EPCQ |
| Hardware Manager + 下载线 | Programmer + USB-Blaster |
| master XDC | master .qsf + .sdc |
| WNS / WHS | setup/hold slack、Fmax |
| ILA 片上抓信号 | SignalTap II Logic Analyzer |
| DCP checkpoint | .qar 归档 / 数据库目录 |
真正需要「重新适应」的只有三点:术语/菜单名、物理约束语法、下载线与配置芯片的操作;而 RTL 怎么写、组合/时序怎么分、非阻塞、STA 原理、Fmax/slack、CDC、流水线——这些跨厂商一字不改。这也是为什么入门阶段选哪一家并不重要,把第一家的概念吃透,第二家通常一两周就能上手(家族与定位见 厂商与器件家族)。
常见报错对号入座
| 报错/现象 | 大概率原因 | 处理 |
|---|---|---|
Top-level design entity "xxx" is undefined | top 名与 module/工程名不一致 | Settings 里改 Top-level entity,注意大小写 |
Can't find node / 管脚没生效 | QSF 端口名拼错或该信号被优化 | 核对端口名、保留未用信号 |
Can't access JTAG chain | 线/驱动/供电/链顺序 | 换数据线、装 USB-Blaster 驱动、查 TCK/TMS/TDI/TDO |
| Fitter 报管脚冲突或 bank 电压 | IO_STANDARD 与 bank 不匹配 | 按原理图设同一 bank 兼容电平 |
| Timing Analyzer 全是未约束时钟 | SDC 没加进工程或端口名错 | Settings 加 .sdc、核对 get_ports |
| 下载成功但灯不闪 | 时钟/复位管脚、极性、配置 | 查晶振管脚、复位电平、LED 极性 |
| 改了代码现象不变 | 没重跑 Assembler/下的是旧 .sof | 重新全编译再 Program |
九之四、片上调试:SignalTap 与多文件/IP 工程
仿真能解决功能问题,但「仿真对、上板不对」时需要在真实芯片里看信号,Intel 平台的工具是 SignalTap II Logic Analyzer,对应 Xilinx 的 ILA(ILA 初用)。用法思路一致:
- 新建
.stp(SignalTap 文件)加入工程; - 添加要抓的信号(建议用
(* keep *)/synthesis preserve保留可能被优化掉的内部网线)、选采样时钟(一般用系统时钟)、设采样深度(占 M9K/M20K 块 RAM,越深越费)和触发条件(如found==1或某计数器到某值); - 重新全编译(SignalTap 要把抓信号的逻辑编进比特流,这一点和 ILA 一样,改一次抓的信号就要重编);
- 下载
.sof,SignalTap 里 Run Analysis(单次)/Autorun(连续),等触发后看波形。
调试状态机直接抓 state、调试通信抓 tx/tick 信号,比反复猜管脚和时钟快得多(通用方法见 仿真对上板错怎么办 与进阶 调试方法论)。
多文件与 IP 工程怎么组织
- 一个模块一个
.v,顶层只做例化和连线;全编译前用 Add/Remove 把所有子模块文件加进工程(或放进工程目录让 Quartus 自动发现),否则报模块未定义。模块/例化规则见 module 与端口。 - 用 PLL/RAM/FIFO 等 IP 时走 IP Catalog(MegaWizard),生成后要把生成的
.qip/文件加入工程;IP 改参数也要重新生成再编译(通用做法见 IP 核怎么调)。PLL 出来的时钟记得在 SDC 里derive_pll_clocks,否则派生时钟不受约束。 - 需要别的时钟频率/相位,优先用 ALTPLL/Clock IP(对应 MMCM),不要拿计数器翻转的信号当时钟,原因见 计数器与分频 与 时钟与复位。
- 版本管理建议提交:RTL、
.qsf、.sdc、.qsf引用的 IP 配置/.qip、重建脚本;db/、incremental_db/、output_files/*.sof等产物可忽略(见 RTL 版本管理)。
第一次在 Cyclone 板上跑通的检查清单
照这份清单逐项打勾,能避开 90% 的首日卡点:
- [ ] Quartus 版本(Lite/Standard)支持你这颗 Cyclone,器件库已装;
- [ ] 工程目录无中文/空格,工程名与顶层 module 同名;
- [ ] 器件型号、封装、速度档与板子丝印一致;
- [ ] 全部
.v/IP 已加入工程,Top-level entity 大小写正确; - [ ] clk/rst/LED 管脚来自板子原理图或 master QSF,IO_STANDARD 与 bank 电压一致;
- [ ] SDC 的 create_clock 周期 = 板载晶振周期,RTL 分频常数按该频率算过;
- [ ] 全编译 0 Error、关键 Warning(latch/管脚/多驱动)已清;
- [ ] TimeQuest 无红色 setup/hold 违例、无未约束时钟;
- [ ] Programmer 能看到 USB-Blaster 与 JTAG 链,先下
.sof验证; - [ ] 要掉电不丢再切 Active Serial 烧
.pof到配置芯片。
工程文件都有什么、最小例程长什么样
工程目录里常见文件分工:.qpf 是 Quartus 工程文件(双击打开);.qsf 是设置文件(工程设置、加了哪些源文件、管脚与电平约束,纯文本,最常看/常提交);.sdc 是时序约束;.qpf/.qsf 之外,db/、incremental_db/ 是编译数据库,output_files/ 放 .sof/.pof/.rpt,后两者都是可再生产物。看懂这点,换台机器只要拿到 RTL+.qsf+.sdc+IP 配置就能重建工程,不必拷贝几个 GB 的产物目录。
最小的可综合 LED 例程(50MHz、约 1Hz 闪烁,配合前面的 25,000,000 分频常数):
module led_blink(
input wire clk, // 50MHz, 管脚与电平在 QSF 里约束
input wire rst_n, // 低有效复位按键
output reg led
);
reg [24:0] cnt;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin cnt <= 25'd0; led <= 1'b0; end
else if (cnt == 25'd24999999) begin cnt <= 25'd0; led <= ~led; end
else cnt <= cnt + 25'd1;
endmodule注意它与时序/约束的呼应:所有寄存器共用同一个 clk(干净时钟走专用网络),复位用 negedge rst_n 异步复位,分频常数、25 位位宽、50MHz 三者一一对应;管脚和 create_clock 在 QSF/SDC 里给定。这个小例子已经包含了 FPGA 设计 80% 的基本功:时钟、复位、计数器、非阻塞、参数、管脚约束、时序约束、下载固化。把它在 Quartus 上独立跑通一遍,比看十篇工具教程都管用。等你能自如地在 Vivado 与 Quartus 之间切换,就会真正理解一件事:工具界面只是外壳,LUT/FF、STA、时钟与复位、模块层次这些概念才是 FPGA 工程里跨厂商、跨年代都不变的内核。
十、Quartus 工程在磁盘上的文件构成与迁移
新手常把整个工程目录一股脑打包发给别人,结果对方一打开全是报错,这往往是因为没有分清哪些文件是"源",哪些文件是工具生成的"产物"。一个 Quartus 工程里,真正需要纳入版本管理、需要随工程一起交付的,只有描述设计意图的那一小撮:.qpf 是工程文件、.qsf 是设置文件(里面用文本记录了顶层名、器件型号、加入了哪些源文件、管脚分配、时序约束引用等),.v/.sv/.vhd 是 RTL 源码,.sdc 是时序约束,.mif/.hex 是存储器初始化数据,自行添加的 .qip 是 IP 打包文件。而 db/、incremental_db/、output_files/、.sof/.pof、各种 .rpt/.map.rpt/.fit.rpt 报告以及一堆中间文件,全都是编译过程中重新生成的产物,既不需要备份,也不应该提交进 git——它们动辄成百上千个,混进去只会让仓库膨胀、diff 噪声变大。
理解这层区分有两个实际好处。第一是迁移和分享工程时,只要保留源文件集合,拷到另一台没编译过的机器上,用 Quartus 重新打开 .qpf、完整跑一遍编译就能原样复现比特流;反过来若只拷了 output_files 而漏了 .qsf,管脚和器件信息就全丢了。第二是排错时思路清晰:当你怀疑"工具是不是抽风了",标准动作是执行 Project 菜单里的 Clean,或直接删掉 db/、incremental_db/ 和输出目录后全编译——增量编译偶尔会因为旧产物残留出现一些匪夷所思的现象,干净重建能排除掉一大类问题。.qsf 是纯文本这一点也值得记住,团队协作时可以直接在里面按行评审:谁加了源文件、谁改了管脚、谁引了新的 SDC,版本差异一目了然,比在图形界面里点来点去可靠得多。
十一、编译之外:Programmer、SignalTap 与命令行流
综合、布局布线只是把设计变成比特流,真正闭环还需要下载和观测两类工具,它们在 Quartus 里分别对应 Programmer 和 SignalTap II(在新版 Intel Quartus Prime 中叫 Signal Tap Logic Analyzer)。Programmer 里首先要分清下载模式:JTAG 直接下载到 FPGA 的是 .sof,掉电即失,适合反复调试验证;要让板子上电自动加载,得把 .pof(或转换出的 .jic)写进外挂的配置 Flash(EPCS/EPCQ 一类),这一步选错文件或选错器件型号是"明明下载成功、重新上电却还是旧逻辑"的头号原因。Hardware Setup 里如果看不到 USB-Blaster,多半不是软件问题,而是驱动没装好或下载器被别的软件占用,重装驱动、换一根质量好的 USB 线往往就能解决。
SignalTap 是 Quartus 自带的片上逻辑分析仪,原理是在综合前把一段探针逻辑和触发电路一起塞进设计,占用真实的 LUT/FF 和片上 RAM,再通过 JTAG 把采样到的波形回传到电脑。因此它有几条新手必须知道的纪律:一是加了 SignalTap 必须重新全编译,探针不是外挂的、而是设计的一部分;二是观测信号越多、采样深度越大,吃的资源越多,常常一个深度上万的采样就耗掉一块 M9K,要在"看得全"和"装得下"之间取舍;三是被优化掉的信号抓不到,必要时用综合属性或把信号接到输出上"保活"。除了图形界面,Quartus 还提供完整的命令行工具链:quartus_sh、quartus_map、quartus_fit、quartus_tan、quartus_asm 分别对应工程操作、综合、布局布线、时序分析、生成比特流,可以写成脚本在没有界面的服务器上做无人值守编译和持续集成。入门阶段不必立刻精通,但应当知道"凡是能在界面里点的按钮,基本都有对应的命令行版本",这为以后做自动化构建、批量回归埋好伏笔。
十二、从 Quartus 切到 Vivado 时的心智对照
学校和小公司常用 Quartus 配合 Intel/Altera 器件,而工业界大量岗位用 Vivado 配合 AMD/Xilinx 器件,两者界面差别很大,但只要抓住"同一套 FPGA 概念、不同的名词和文件格式",切换成本远比想象的低。最核心的对应关系是:Quartus 的工程设置文件 .qsf 对应 Vivado 的 .xpr/.xdc,管脚与时序约束在 Quartus 里用 QSF 的 set_location_assignment 加 SDC,在 Vivado 里统一写进 XDC(XDC 本质就是 Tcl 形式的 SDC 超集);Quartus 的全编译按钮内部串起 Analysis & Synthesis、Fitter、Assembler,Vivado 则显式分成 synth_design、opt_design、place_design、route_design、write_bitstream 几个步骤,本质都是"综合→布局→布线→出比特流"。
下载侧,Programmer 对应 Vivado 的 Hardware Manager,sof/pof 对应 bit/bin,JTAG 调试器 USB-Blaster 对应 Platform Cable 或板载 FTDI;片上探针 SignalTap 对应 Vivado 的 ILA,二者原理几乎一样,都是"把探针和触发逻辑综合进设计、经 JTAG 回传波形",所以前面讲的 SignalTap 纪律可以原样迁移。IP 使用上,Quartus 的 IP Catalog 配出 .qip,Vivado 配出以 XCI 为核心的 IP 产物,两者都会生成例化模板,照着复制端口连接即可。报告阅读也相通:资源使用率、fmax/WNS、未约束路径这些关键信息两家都有,只是名字和摆放位置不同。真正需要重新建立的习惯主要有两条:一是 Vivado 以 Tcl 为一等公民,几乎所有操作都能在 Tcl Console 里复现并写成脚本,工程目录也因此比 Quartus 更"重",产物更多,更要分清源文件与 generated 产物;二是 Vivado 的基于块设计(Block Design)图形连线流程在 Quartus 里没有完全对等物,做 Zynq 类异构设计时要额外学。先在一个工具上把"时钟、复位、约束、综合、下载、探针"这条主线彻底打通,换工具就只是换菜单和关键词,而不是重新学一门手艺。
最后给一条很实用的学习建议:把同一个小工程(比如带使能的计数器加 UART 回显)在 Quartus 和 Vivado 上各完整做一遍,刻意对照两套产物。你会发现管脚约束、时序约束、资源报告、下载固化、片上抓波形这五件事在概念层完全一一对应,差别只在文件后缀和菜单位置。当你能用一句话互相翻译两套术语,例如把 Fitter 对应到 place/route、把 TimeQuest/Timing Analyzer 对应到 Vivado 的 Timing Summary、把 SignalTap 对应到 ILA,工具就不再是束缚,而真正退回到它应有的位置——实现你硬件设计意图的手段。招聘要求里"会 Quartus"或"会 Vivado"的门槛,本质考的都是同一套 FPGA 内核,先在一个工具上形成完整闭环、再做一次对照迁移,是性价比最高的上手路径,也能避免把时间浪费在背菜单这种会随版本变化的表层知识上。
常见坑对照
| 坑 | 现象 | 正确做法 |
|---|---|---|
| 只下 .sof 就以为固化 | 掉电程序没了 | 烧 .pof 到配置芯片 |
| 顶层模块名不匹配 | 综合找不到 top | Settings 指定 top entity |
| USB-Blaster 驱动未装 | Programmer 找不到硬件 | 装驱动、识别到器件 |
| 器件型号选错 | 管脚/资源不对 | 按丝印选 Cyclone 具体型号 |
| 不写时钟约束 | Fmax 报告不可信 | SDC create_clock |
相关与延伸
一句话总结
Quartus(Intel/Altera)流程与 Vivado 一一对应:New Project Wizard 选 Cyclone/Arria 器件→Analysis & Synthesis 综合→Fitter 布局布线(看 Timing Analyzer 的 Fmax/slack)→Assembler 生成配置文件→Programmer 经 USB-Blaster 下载;图形化搭系统用 Platform Designer(Qsys,对应 Block Design,用 Avalon/AXI 连 Nios II 软核和 IP),约束用 SDC(和 XDC 同为 Tcl 语法)。下载分两种:.sof 直接下 FPGA 立即运行但掉电丢(调试用),.pof 烧到 EPCS/EPCQ 配置芯片、上电自动加载掉电不丢(固化用),对应 Xilinx 的 .bit 调试/烧 QSPI 固化。新手选 Cyclone 开发板(与 Artix-7 同定位),先 LED 跑通全流程——时序、约束、综合/布局布线这些概念跨厂商完全通用,学会一家再上另一家只需一两周适应工具。