ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FPGA入门必看:Quartus安装配置、工程创建与下载调试全流程指南

FPGA入门必看:Quartus安装配置、工程创建与下载调试全流程指南 很多刚接触FPGA的朋友第一次打开Quartus的时候都是懵的。界面密密麻麻的按钮新建工程一堆选项综合、布局布线、引脚分配、下载程序每一步都有讲究。更麻烦的是版本还特别多什么Quartus II 13.1、Quartus Prime 18.1、Lite版、Standard版网上一搜教程截图对不上号的比比皆是。这篇东西就是给准备入坑FPGA、或者已经在用但一直被各种细节绊住的朋友写的把Quartus从选版本、装环境到建工程、写代码、跑仿真、下板子这条完整链路讲清楚同时也聊几个我自己用的时候踩过的坑。不论你是学生做课程设计还是工程师转来做FPGA开发这套流程应该都能帮你少走不少弯路。1. 版本选择先把Quartus家族谱理清楚1.1 从Quartus II到Quartus Prime改名背后的逻辑Quartus这个工具Altera时代叫Quartus II后面Intel收购了Altera工具改名为Quartus Prime。这不只是换个名字那么简单整个工具链的许可模式、器件支持范围、软件架构都发生了变化。网上你搜到很多老的教程标题里带Quartus II的很多是2015年以前的产物对应的器件还是Cyclone III、Cyclone IV这些老一代FPGA。而Quartus Prime按功能分成三个版本Pro版、Standard版、Lite版。Pro版面向高端器件比如Arria 10、Stratix 10这些界面和编译策略跟传统Quartus差异很大很多老工程师第一次用Pro版也会不习惯。Standard版定位中端支持Cyclone V、Cyclone 10这些。Lite版是免费精简版支持Cyclone IV、Cyclone V、MAX 10这些常用器件功能上砍掉了一些高级特性但对教学和大部分项目开发来说完全够用。对初学者来说我建议优先考虑Lite版。原因很简单免费、安装包小、对电脑配置要求低而且支持Cyclone IV和MAX 10这两个在淘宝上最常见的FPGA芯片。很多开发板用的EP4CE6、EP4CE10、EPM240这些芯片Lite版都能直接覆盖。1.2 各版本支持的器件和适用场景整理了一份简单的对照表方便你按自己手头的芯片选版本版本典型器件系列授权方式界面风格适合场景Quartus II 13.1Cyclone I-IV、MAX II、MAX V需要License文件经典界面老开发板、老教程配套Quartus Prime 18.1 LiteCyclone IV、Cyclone V、MAX 10免费新界面深色主题入门学习、常规项目Quartus Prime 18.1 StandardCyclone V、Arria V、Stratix V付费订阅新界面中端项目开发Quartus Prime ProArria 10、Stratix 10付费订阅新界面差异大高端FPGA开发Quartus Prime Lite 20.1Cyclone IV、Cyclone V、MAX 10免费新界面推荐日常使用有个比较典型的坑如果你手头的开发板是Cyclone II或者Cyclone III老芯片比如EP2C5、EP3C16那新版Quartus Prime Lite根本不支持必须用Quartus II 13.0或13.1版本。反过来如果你用Cyclone 10或者更新的器件老版本又编译不了。所以选版本的第一步先看芯片型号再看支持列表别盲目追新。1.3 安装时的一些小决策装哪些组件、装哪里Quartus安装有几点注意。第一安装路径不要带中文不要带空格这是老生常谈了但总有朋友图省事装在“D:\程序\Quartus”这种路径下后面编译的时候各种莫名其妙的问题都来了。第二组件选择上如果只做FPGA逻辑开发不需要装DSP Builder这些跟Matlab联合仿真的东西ModelSim或者Questasim可以单独装也可以只用Quartus自带的仿真工具。第三USB Blaster驱动一定要装这就是热搜里“quartus下载器驱动在哪个文件夹”这个问题的由来。安装完成后默认驱动目录在quartus安装路径下的drivers文件夹里里面有blaster相关的inf文件。如果你的电脑是Win10或Win11插入USB Blaster之后如果设备管理器里显示未知设备或者带感叹号需要手动指向这个文件夹安装驱动。如果还是不行多半是驱动签名问题需要在开机时禁用驱动程序强制签名装完驱动再恢复。这一步很多新手卡住后面问题排查部分我细说。2. 第一个工程从新建到点灯的全流程实操2.1 工程结构规划先想清楚再动手新建工程之前建议先建一个清晰的目录结构。我在实际项目里一般这样组织project_root/ ├── doc/ # 文档、引脚分配表、芯片手册 ├── rtl/ # 所有Verilog/VHDL源码 ├── sim/ # 仿真测试文件和testbench ├── ip/ # Quartus IP核生成的文件 ├── constr/ # 约束文件主要是.qsf和.sdc └── output/ # 编译输出文件sof、pof、jic等Quartus默认把编译产物放在工程目录下的output_files文件夹这个可以不用改。但是源码文件一定要自己管理好别一股脑跟.qpf、.qsf文件放在同一个目录。工程文件是文本格式的后面用Git管理版本时这些文件混在一起会非常痛苦。2.2 新建工程的具体步骤和选项含义打开QuartusFile - New Project Wizard。这一步有几个选项容易让人困惑第一个是工程目录和工程名工程名最好跟顶层模块名保持一致虽然Quartus没有强制但保持一致能在后面减少不少莫名其妙的问题。第二个是顶层实体名称这里填的就是你顶层Verilog模块的module名。第三个是器件选择界面这里有两个选项一个是“Empty project”空工程一个是“Project template”工程模板。建议选空工程别用模板模板会带入很多用不到的文件和设置。器件选择这一步需要根据开发板上的具体芯片型号来选。比如很多开发板用的是EP4CE10F17C8那就在Family选Cyclone IV E具体器件选EP4CE10F17C8封装FQFP144速度等级C8。如果不确定看开发板包装盒上的标签或者直接问卖家。选错器件编译也能过但生成的配置文件和引脚分配可能对不上下载的时候会出问题。2.3 用点灯工程跑通完整流程第一次用Quartus我建议直接写一个最简单的LED闪烁程序把整个流程跑通先别管什么复杂逻辑。新建一个Verilog文件代码如下module led_blink( input wire clk, input wire rst_n, output reg led ); parameter CNT_MAX 24_999_999; // 50MHz时钟0.5秒翻转一次 reg [24:0] cnt; always (posedge clk or negedge rst_n) begin if (!rst_n) begin cnt 0; led 0; end else if (cnt CNT_MAX) begin cnt 0; led ~led; end else begin cnt cnt 1b1; end end endmodule这里有个细节计数器位宽cnt [24:0]是因为CNT_MAX是24,999,999换算成二进制需要25位2^2416,777,2162^2533,554,432不要只留24位否则计数到不了目标值就回绕了LED频率会比预期快很多。写完后在工程里右键点击这个文件选择Set as Top-Level Entity确保顶层模块是led_blink然后开始编译。全编译快捷键CtrlL会依次执行分析与综合、布局布线、汇编、时序分析四个步骤。编译通过后下一步是引脚分配。打开Assignments - Device确认器件型号没错之后再打开Assignments - Pin Planner。在Pin Planner里把clk、rst_n、led这三个信号跟开发板的物理引脚关联起来。这一步务必对照开发板的原理图来比如晶振接在PIN_23按键接在PIN_87LED灯接在PIN_88照着原理图一个个填就行。引脚分配完别急着下载先重新编译一次让约束生效。2.4 下载程序SOF和JIC的区别生成的下载文件有几种格式.sof是SRAM对象文件下载后掉电就丢失主要用于调试阶段.pof是编程对象文件烧写到FPGA配置芯片里掉电不丢失用于最终固化.jic是JTAG间接配置文件通过JTAG接口把配置数据写进板子上的EPCS芯片。调试阶段用.sof就够每次上电重新下载一次也没多麻烦。工程定稿之后再把.sof转成.jic烧进去。具体操作File - Convert Programming FilesProgramming file type选JTAG Indirect Configuration File (.jic)Configuration device选你板子上配的EPCS芯片型号然后添加SOF文件最后Generate。生成完在Programmer里加载.jic文件勾选Program/Configure点Start。这个转换步骤有个容易漏的地方Configuration device选错了会烧不进去或者烧进去不启动。EPCS1、EPCS4、EPCS16这些型号容量不同按板子实际配置选拿不准就拆开看芯片丝印。3. 仿真验证与SignalTap调试别急着上板3.1 Testbench怎么写才高效很多初学者写完代码直接编译下载上板发现现象不对然后一脸懵。正确做法是先在仿真环境里验证一遍逻辑。Quartus Lite版自带ModelSim Starter Edition也可以用QuestaSim功能上基本够学习使用。写Testbench时有几个习惯值得养成。第一时钟和复位用task或者initial块统一生成别在每个测试用例里重复写。第二用时间延迟#参数来控制激励时序同时配合$display或者波形观察来确认输出。第三大型模块建议分层次仿真——先仿真底层模块再仿真顶层集成这样定位问题快得多。一个最简单的Testbench示例timescale 1ns/1ps module led_blink_tb; reg clk; reg rst_n; wire led; initial begin clk 0; rst_n 0; #100; rst_n 1; #100; // 仿真时间足够长观察LED翻转 #2_000_000_000; $finish; end always #10 clk ~clk; // 50MHz时钟周期20ns led_blink uut( .clk(clk), .rst_n(rst_n), .led(led) ); endmodule然后把Testbench文件加入工程并设为仿真顶层在Assignments - Settings - EDA Tool Settings - Simulation里把仿真工具设为ModelSim点击Compile test bench添加刚才的测试文件。之后在Tools - Run Simulation Tool - RTL Simulation里启动仿真就能看到波形了。3.2 SignalTap II板上信号的照妖镜仿真能覆盖大部分功能问题但有些问题只有在真实硬件上才会出现比如亚稳态、时序冲突、外部接口干扰。这时候SignalTap II就有用了。SignalTap是Quartus自带的逻辑分析仪通过JTAG口实时采集FPGA内部信号不需要额外的硬件设备。使用流程在.qsf里添加SignalTap文件.stp选择要观察的信号设置采样深度和触发条件然后重新编译并下载程序。下载完成后打开SignalTap窗口运行采集就能看到信号波形。但SignalTap有个很头疼的限制编译后信号名经常被优化掉。你明明在代码里定义了一个中间信号结果SignalTap的信号列表里就是找不到。这是因为综合器认为这个信号是冗余的直接优化掉了。解决办法有两个一个是给信号加(* keep true *)综合属性另一个是在SignalTap配置界面右键选择“添加所有节点”在弹出的对话框里跑一遍Node Finder但前提是综合工具没把信号吞了。另一个问题是SignalTap采集会增加资源消耗和时序收敛难度。采样深度设得越大消耗的存储块越多触发条件设得太复杂编译时间会明显变长。我一般是先设1024深度采样确认波形正常后再调大或关闭。调试完一定要记得把SignalTap文件从工程里移除或者禁用否则它会影响最终编译的时序结果给项目埋雷。3.3 时序约束入门SDC文件的三个关键命令说到时序约束很多初学者觉得这是FPGA工程师才干的事其实基础约束一点都不难。最常用的约束就三条创建时钟、设置输入延迟、设置输出延迟。创建时钟是必须的一条简单的约束create_clock -name clk -period 20.000 -waveform {0 10.000} [get_ports {clk}]这条指令告诉工具时钟端口clk的频率是50MHz上升沿在0ns下降沿在10ns。如果你不创建时钟Quartus在时序分析时会把时钟当作理想时钟处理很多真实路径上的时序问题检查不出来。等跑时序分析时看到一堆violated path才想起来没写约束就晚了。输入延迟表示外部信号相对于时钟边沿到达FPGA引脚的时间输出延迟表示FPGA输出信号相对于时钟边沿到达外部器件的时间。这两条在涉及外部接口时序时需要根据芯片手册精确设置学习阶段可以先不设。SDC文件在工程里添加路径Assignments - Settings - Timing Analyzer - 在SDC File列表里添加你的.sdc文件编译后Timing Analyzer会自动加载并分析。跑完看Meeting summary全部是绿色满足就说明时序收敛了。4. 高频问题排查与避坑清单4.1 编译错误的三个高频来源我见过太多新手的编译错误扒开来看其实就三类。第一类模块例化时port名写错或者漏连。Verilog例化时端口连接有两种方式按顺序连接和按名字连接。按顺序连接看着省事但一旦模块定义改了顺序调用处就全乱了。推荐始终用按名字连接明确写清楚每个信号连到哪个端口。编译报错里看到“port not declared”或者“cannot bind wire”之类的提示先检查例化代码。第二类位宽不匹配导致的warning甚至error。比如一个8位信号赋值给一个4位寄存器Quartus会报truncation warning要看是数字常量的位宽问题还是真实逻辑错误。一个个warning都看一遍别用“本来就是warning不影响”这种心态。很多在硬件上表现出来的诡异问题源头就是这些被忽略的warning。第三类多个驱动源驱动同一个信号。在testbench里初始化信号时如果既有initial块里的赋值又有wire类型的连续赋值就可能出现多驱动报错。还有组合逻辑里同一个信号在多个always块里赋值也是很多新手容易犯的错一个信号只允许在一个always块里赋值这是Verilog的基本规则。4.2 USB Blaster驱动装不上的完整排查思路驱动问题是Quartus用户里出现频率最高的硬件问题热搜里“quartus下载器驱动在哪个文件夹”就能看出大家有多头疼。这里给一套完整的排查思路。第一步确认设备管理器里能看到USB Blaster。插上下载器后如果“通用串行总线控制器”下拉菜单里出现带黄色感叹号的Altera USB-Blaster说明硬件识别到了只是驱动没装上。如果什么都看不到检查下载器是否插紧、线是否损坏或者换个USB口试试台式机建议插机箱后面的USB口前面的USB口供电和信号质量有时候不太行。第二步手动更新驱动。右键黄色感叹号的设备选择更新驱动程序 - 浏览我的电脑以查找驱动程序 - 让我从计算机上的可用驱动程序列表中选取 - 从磁盘安装然后浏览到Quartus安装目录下drivers\usb_blaster文件夹选择对应的.inf文件。Win10/11在安装这种没有数字签名的驱动时可能会提示“无法验证此驱动程序的发布者”需要选择“仍要安装”。第三步如果系统提示找不到驱动签名大概率是系统强制签名校验拦截了。解法是禁用驱动程序强制签名再装。Win10/11的操作路径设置 - 更新和安全 - 恢复 - 高级启动 - 立即重新启动然后在选项界面依次选择疑难解答 - 高级选项 - 启动设置 - 重启开机后按7选择禁用驱动程序强制签名。装完驱动后再恢复签名校验不影响日常使用。第四步驱动装上后打开Quartus的Programmer确认硬件连接。如果硬件设置里显示No Hardware检查Tools - Options - JTAG Settings - JTAG Server Settings确认没有把JTAG server关掉或者直接用USB-Blaster时把Port口选对。4.3 下载失败配置文件加载成功但没反应有次同事拿新做的板子让我帮忙看Programmer显示下载完成Progress到100%但是板子上的LED死活不亮。排查下来发现是配置芯片型号和实际不符——他用的EPCS4芯片但在Convert Programming Files里选了EPCS16生成的.jic文件大小跟芯片容量不匹配烧录时虽然是“成功”的但数据根本没写进正确的位置。这个场景提醒两点第一下载前一定要确认.sof文件对应的器件版本和实际芯片匹配版本选错轻则下载报错重则烧错配置文件导致整个板子启动异常。第二配置芯片的选型不是越大越好不同型号的地址映射不同Quartus在生成.jic的时候会按照配置文件里的器件型号来计算配置数据的偏移选错了就白烧。另外还要注意工程里的Device设置和实际芯片是否对应。经常有人拿到开发板时芯片是EP4CE10结果工程里默认选的是EP4CE6编译、综合都没问题下载时Programmer就会报错。有时还表现为下载界面选了对应的.sof还是提示cant discover device这是因为JTAG链路上有多个器件或者下载器的固件版本比较老需要更新USB Blaster固件。4.4 常见问题速查表现象可能原因解决方法编译报错error: cant resolve file工程引用文件路径不对Project - Add/Remove Files in Project重新添加文件时序分析大量violated path没写时钟约束添加create_clock约束重新编译综合后信号在SignalTap中找不到信号被综合器优化加(* keep true *)属性Programmer显示No Hardware驱动未装或服务异常重装USB Blaster驱动检查jtag server设置下载成功但板上无现象引脚分配错/未重新编译检查Pin Planner里的分配保存后重新全部编译引脚分配时报错pin not fit引脚被其他功能占用检查是否启用了配置引脚确认器件封装选择正确Quartus启动闪退安装路径有中文或显卡驱动问题重新安装到纯英文路径更新显卡驱动ModelSim仿真启动不了工程设置里仿真工具未配置Settings - EDA Tool Settings - Simulation选择ModelSim5. 工程管理的几个经验之谈5.1 用版本管理工具管理FPGA工程FPGA工程的.qpf、.qsf这些文件看起来是文本格式但里面包含的路径信息、器件设置、引脚分配在项目迭代时很容易产生冲突。我自己的习惯是用Git管理整个工程目录但忽略编译生成的中间文件。在.gitignore里至少要包含这几类output_files目录、db目录、incremental_db目录、.qwsQuartus会话文件、.jdi调试信息文件。这些文件每次编译都会变化而且动辄几百MB放进版本库只会让仓库迅速膨胀。保留的是所有源码文件、约束文件、工程设置文件、文档、脚本。提交信息建议写清楚这次改了什么逻辑、为什么改别用“update”“修改”这种没有信息量的消息。几个月后回来看提交记录一份清晰的log比什么都管用。5.2 TCL脚本自动化从重复劳动里解放出来Quartus的很多操作其实是可以通过TCL脚本自动化的。比如每次新建工程都要手动选器件、加文件这些步骤可以写成一个脚本一键执行。再比如批量修改引脚分配、批量设置约束TCL脚本的效率远高于在GUI里一个个点。一个简单的工程创建脚本示例# create_project.tcl load_package flow project_new led_blink -overwrite set_global_assignment -name FAMILY Cyclone IV E set_global_assignment -name DEVICE EP4CE10F17C8 set_global_assignment -name TOP_LEVEL_ENTITY led_blink set_global_assignment -name VERILOG_FILE rtl/led_blink.v set_global_assignment -name SDC_FILE constr/led_blink.sdc project_close在命令行里执行quartus_sh -t create_project.tcl一个工程就创建好了。后面需要调整工程配置直接改脚本再跑一遍就行比在GUI里点来点去可靠多了。这个能力在需要管理多个工程、或者做自动化构建时尤其有用。5.3 引脚分配的备份与比对引脚分配是FPGA开发中容易出错但又必须仔细的环节尤其是引脚数量多、信号类型丰富的大工程。每次分配完引脚建议把Pin Planner里的Assignment Editor内容导出一份CSV存档。后面修改了原理图或者换了板子可以通过比对两份CSV来快速定位差异不用一个个引脚去查。另外引脚分配规则里有个容易被忽略的点不同电气标准的引脚不能混用比如给普通IO分配了LVDS差分对引脚编译时会报错。还有时钟专用引脚和普通IO引脚是有区别的全局时钟信号尽量分配到专用时钟引脚上否则布线时时钟网络质量会受影响。6. Python脚本辅助让Quartus更好用6.1 批量生成引脚约束文件手写几百行的引脚约束既枯燥又容易出错但是用Python脚本生成就简单了。开发板的原理图一般都有引脚对应的Excel表格把Excel导成CSV然后用几行Python代码就能生成Quartus格式的引脚分配命令。我之前用过一个比较取巧的方式直接分析开发板厂商提供的Excel文件把信号名、网络名、引脚号提取出来生成set_location_assignment命令然后整体贴到.qsf文件里。整个过程从头到尾几分钟比手动在GUI里敲几百个引脚快多了而且不容易敲错。写这类脚本时注意两点一是排针的命名规则很多开发板同一排针上相邻引脚之间会跨越不同的bank如果搞错了bank的电压域功能可能正常但信号质量会很差二是要过滤掉电源和地引脚那些不需要分配约束。6.2 自动保存编译日志与错误提取使用quartus_sh的命令行编译模式配合Python脚本解析编译日志中的Error和Warning可以做一个简单的CI流程。比如每天晚上定时拉去代码更新自动编译把结果发到群里或者邮件里。这样第二天到公司打开邮件就能看到昨天晚上提交的代码有没有把编译搞挂。解析日志时有个小技巧Quartus的错误信息格式一般是“Error (xxxxx): 具体描述”Warning格式类似。Python里用正则表达式把Error信息抓出来统计数量再按文件和模块分类。这样即使那天编译报错也能快速知道错在哪个文件哪一行不用再打开GUI重新编译一次。这些自动化手段在一个人做小项目时可能觉得没啥必要但在团队协作或者长时间维护一个项目时省下来的时间非常可观。我现在的习惯是建工程用脚本、编引用命令行、日志用程序分析GUI只用来做前期的引脚分配和后期的时序分析其他能自动化的全部自动化。
返回列表