首页 / 资讯中心 / 文章详情

Quartus FPGA开发全流程:建工程、约束、仿真与下载调试

Quartus FPGA开发全流程:建工程、约束、仿真与下载调试 ★ FEATURED ARTICLE
装完 Quartus、双击图标、界面弹出来然后呢很多人第一次打开的时候会发现 Start Compilation 是灰的Pin Planner 点了没反应Project Navigator 里空空如也——不是软件坏了是还没有工程。更常见的情况是跟着视频点了一遍编译也过了下载也显示成功板子上的灯就是不亮于是开始怀疑线坏了、板子坏了、芯片烧了。我带过几届学生的课程设计也帮同事从头调过 Cyclone 的板子可以很确定地说Quartus 的使用流程里真正卡人的从来不是哪个按钮在哪而是每一步背后的默认行为和你没告诉它的那些信息。这篇东西就按一个真实项目的推进顺序把 Quartus 从选版本、建工程、写代码、加约束、跑仿真、到上板调试的完整链路拆开讲一遍顺带把几个高频踩坑点说透。不管你是第一次接触 FPGA 的学生还是从单片机转过来想做点逻辑的工程师按这个顺序走一遍基本能跑通。1. 版本和安装路径先定死这一步错后面全是坑1.1 Lite、Standard、Pro 到底怎么选Quartus 的版本谱系比大多数人想象的复杂。2013 年之前的叫 Quartus II版本号停在 13.1之后改名 Quartus Prime分成 Lite、Standard、Pro 三条线。这三条线最大的区别不是功能多少而是支持的器件范围——装错版本你手里的芯片根本不会出现在器件列表里后面所有流程都无从谈起。Lite免费面向 Cyclone 系列和 MAX 系列覆盖 Cyclone IV、Cyclone V、Cyclone 10 LP、MAX II/V/10 这些。教学板、入门开发板、课程实验板上的芯片几乎全在这个范围内个人学习和课程设计用它就够了不需要任何额外的东西。Standard面向上一个档次的器件比如 Arria 系列和部分 Stratix同时保留了 Cyclone 的高端型号。Pro面向 Stratix 10、Agilex 这类高性能器件工程结构和高端的编译流程跟 Lite 差别不小。关键点在于版本越新砍掉的旧器件越多。老版本 Quartus II 13.1 能认出 Cyclone II而新版 Quartus Prime Lite 里根本没有 Cyclone II 这个选项——如果你手上是十年前那种带 EP2C5 或者 EP2C35 的实验箱唯一的办法就是回到 Quartus II 13.0sp1 或者更早的版本。反过来如果板子上是 EP4CE6、EP4CE10 这类 Cyclone IV E用 Quartus Prime Lite 20.1 或者 18.1 都可以再新的版本能不能认最好去官方那一份 Device Support List 里核一下系列名别凭感觉。配套的仿真器也要一起考虑。老版本 Quartus II 9.1、13.1 时代配的是 ModelSim-Altera Starter Edition从 Quartus Prime 之后改叫 Questa Intel FPGA Starter Edition免费版对代码行数有限制但对课程实验这种规模完全够用。安装的时候把仿真器跟 Quartus 装在同一层目录下NativeLink 自动就能找到省掉后面手动指路径的麻烦。不要去找来路不明的第三方打包版本官方 Lite 加官方 Starter 仿真器这条免费链路是完整的省下来的时间远大于折腾安装包的时间。1.2 安装路径、器件库和下载器驱动安装路径这件事我见过太多人栽在上面。三个硬性要求不要有中文、不要有空格、不要装在需要管理员权限的目录比如 Program Files。原因很直接Quartus 底层会调用一堆命令行工具quartus_map、quartus_fit、quartus_asm这些工具在处理带空格或非 ASCII 字符的路径时某些版本会把参数拆错表现就是综合到一半报奇怪的 file not found或者 IP 核生成失败。一个稳妥的路径长这样D:\intelFPGA_lite\20.1\quartus D:\intelFPGA_lite\20.1\questa_fse安装向导会问你装哪些器件库这一步别偷懒全勾。全部勾上大概是几十 GB 的体量装完磁盘直接少一半。按手里的板子只勾对应的系列比如 Cyclone IV E、Cyclone V、MAX 10能省下十几到二十几 GB。器件库是可以在后面单独补装的安装包保留着就行。下载器的驱动不在安装向导里它是安装完之后手动装的。路径随版本和安装位置变化常见位置整理在下面这张表里找不到的时候先按这个顺序翻版本/安装位置驱动目录相对安装根目录Quartus Prime Lite 20.1 及以后quartus\drivers\usb-blasterQuartus Prime 18.1 / 17.1quartus\drivers\usb-blaster老 Quartus II13.1 及以前quartus\drivers\usb-blaster支持 USB-Blaster II 的版本同级还有quartus\drivers\usb-blaster-ii装驱动的流程是设备管理器里找到带黄色感叹号的未知设备插上下载器之后才会出现右键更新驱动程序选择浏览我的电脑以查找驱动程序把路径指到上面那张表里的目录勾上包括子文件夹。装成功之后设备会出现在通用串行总线控制器下面名字是 Altera USB-Blaster。如果装不上去先换一个 USB 口优先用主板后置的 USB 2.0 口前面板或者 USB Hub 供电不稳的时候识别会时好时坏。1.3 想把 Quartus 卸干净得动这几个地方怎么彻底删除 Quartus这个问题被问得很多原因是直接删安装目录会留一堆垃圾。正确的顺序是这样先在控制面板或者安装目录下的卸载程序里把 Quartus 和配套的仿真器分别卸载它是按组件分开的器件库可能也要单独卸。卸载完检查安装根目录通常还会剩下quartus、questa_fse、device_libraries之类的文件夹和一堆未删干净的文件手动清掉。老版本 Quartus II 会在用户配置目录下留配置一般在%APPDATA%\Altera下新版可能在%APPDATA%\Intel或者用户目录下的.altera相关目录里视版本而定里面的quartus2.ini、.qdf之类的东西不清掉重装之后会继承上一份的窗口布局和最近工程列表有时会出现打开就报错的情况。下载器驱动是独立于软件安装的卸载 Quartus 不会把驱动带走。要么留着以后用要么在设备管理器里卸载设备并勾选删除此设备的驱动程序软件。环境变量里可能残留QUARTUS_ROOTDIR确认一下指向已经不存在的路径就删掉。留着旧版本同时装新版本是可以的它们互不干扰但不要把两个版本装成父子目录关系比如D:\altera\13.1里再装一个D:\altera\13.1\20.1这样很容易在命令行工具调用时搞混路径。2. 新建工程时最容易埋雷的三个设置2.1 工程目录规范和顶层实体命名工程目录我建议从一开始就养成固定结构后面加仿真、加约束、加脚本的时候不用来回挪文件led_blink/ ├── prj/ # .qpf / .qsf 等工程文件 ├── rtl/ # 设计源码 .v ├── sim/ # testbench 和仿真脚本 ├── con/ # .sdc 约束文件 ├── ip/ # IP 核生成目录 └── doc/命名上有三条铁律。第一顶层模块名module 名必须和它所在的文件名一致Verilog 里叫led_blink的模块文件必须是led_blink.v不然综合会报 top-level entity 找不到。第二工程名最好跟顶层模块名保持一致虽然技术上允许不同但当你同时开着三四个工程的时候不统一的名字会让你在 Programmer 的最近文件列表里彻底迷失。第三文件名和目录名里不要出现中文、空格、括号、#这条和安装路径的理由一样。还有一个隐蔽的坑Windows 下文件名大小写不敏感Linux 下敏感。你在 Windows 上写了Led_Blink.v模块名叫led_blink本机编译一点问题没有等把工程打包发给别人或者在 Linux 服务器上跑一次综合立刻报错。从一开始就统一用小写加下划线能省掉这类无意义的返工。2.2 器件选型和 EDA 工具设置New Project Wizard 里最关键的一页就是器件选择。要选三个东西系列、封装、速度等级。这三个必须和板子上芯片表面的丝印完全一致。举个具体的例子同样叫 Cyclone IV EEP4CE6E22C8 和 EP4CE6F17C8 的封装不同引脚编号完全不一样如果你的引脚约束是按 E22 写的器件选了 F17编译会在 Fitter 阶段报一堆引脚不存在的错误或者更糟——它悄悄把信号分配到了别的引脚上你下载完发现灯亮的顺序全乱。速度等级最后那个 C8、C6 之类影响时序分析的宽松程度选错了不会导致编译失败但会让时序报告的数字跟实际不符。板子丝印上的完整型号抄下来在器件列表里按型号搜基本不会错。同一页上还有 EDA Tool Settings这里要指定仿真工具。如果你打算用 ModelSim/Questa 做仿真就在 Simulation 那一栏选上对应的工具ModelSim-Altera 或者 Questa Intel FPGA格式选 Verilog HDL 或者 VHDL。这一步填了后面 NativeLink 一键仿真才能用不填的话后面得手动写 .do 脚本去跑多绕一圈。个人偏好是建工程时就把仿真工具配好反正也就多点两下。2.3 设计文件什么时候加进来New Project Wizard 的 Add Files 那一页可以现在加也可以留空后面在 Project Navigator 的 Files 标签页右键 Add/Remove Files 再补。两种都行区别在于工程建好之后加文件记得右键那个文件选 Set as Top-Level Entity否则 Quartus 默认拿第一个编译成功的模块当顶层如果你的工程里恰好有多个模块很容易出现我改的明明是顶层怎么编译出来一点变化没有这种诡异现象其实就是它在编译另一个模块。顺带说一下工程里几个文件的角色搞清楚了做版本管理会清爽很多文件/目录作用要不要进版本库.qpf工程文件记录工程名和修订版本要.qsf设置文件引脚约束、编译选项全在里面要rtl/*.v设计源码要con/*.sdc时序约束要db/、incremental_db/综合和增量编译的中间产物不要output_files/、*.sof、*.rbf编译产出一般不要simulation/仿真中间文件不要.qsf是纯文本的里面按行记着所有的引脚分配和编译设置这意味着一件事引脚约束完全可以手写不必非得在图形界面上拖。后面第 4 节会详细说这件事为什么重要。3. 设计输入Verilog、原理图和 IP 核怎么混着用3.1 手写 Verilog 的骨架与几个低级但致命的错误Quartus 支持多种设计输入方式最主流的是 Verilog/VHDL 文本输入。一个能直接跑通的骨架大概长这样就拿最常见的 LED 闪烁举例假设板子给的是 50 MHz 时钟module led_blink ( input wire clk, input wire rst_n, output reg led ); reg [24:0] cnt; always (posedge clk or negedge rst_n) begin if (!rst_n) begin cnt 25d0; led 1b0; end else if (cnt 25d24_999_999) begin cnt 25d0; led ~led; end else begin cnt cnt 1b1; end end endmodule这里的计数上限是算出来的不是拍的50 MHz 意味着每秒 50,000,000 个时钟周期要让 LED 每 0.5 秒翻转一次就需要数满 25,000,000 个周期从 0 数到 24,999,999 正好是 25,000,000 个数。位数取 25 位因为 2^25 33,554,432刚好装得下。凡是写计数器先把这个算术做一遍位宽给少了会被截断循环周期完全不对位宽给多了会浪费寄存器资源在大一点的工程里这种浪费会累积。新手在这个阶段的错误高度集中在几个地方我列出来对照着自查位宽不匹配reg [7:0] a; reg [15:0] b; b a;这种不会报错但高位补零逻辑上往往不是你要的。组合逻辑里写成了 latchalways 块里用if但没写else或者 case 没写 default综合出来会生成锁存器。锁存器在 FPGA 里是可以用但时序分析麻烦而且大多数时候它根本不是你的本意。同一个信号在多个 always 块里被赋值这是硬错误综合直接报 multiple drivers。忘记复位状态机和计数器没有复位路径上电后状态是随机的表现就是有时候能用有时候不能用。用了不可综合的语句initial块里的赋值、#10延时、$display这些在仿真里好用在综合里会被忽略或者报 warning。要清楚仿真模型和可综合模型是两个东西别指望同一份代码两个场合都完美。3.2 原理图输入BDF什么时候还值得用Quartus 里可以新建 Block Diagram/Schematic File.bdf用图形化的方式连线和摆元件。课程实验里尤其是数字电路实验那种用 74 系列逻辑搭一个加法器/计数器的题目BDF 其实挺直观老师看图上连线一眼就知道你做了啥。但放到真实的项目里BDF 有两个绕不开的缺点一是没法做版本管理二进制图形文件出冲突基本没法手工解决二是规模一大就完全失控几十个模块连在一起那根线从哪来到哪去只有画的人自己清楚。我的建议是课程实验用 BDF 交作业没问题但自己练手和做项目一律用 VerilogBDF 最多用来做一个顶层的示意图把各个模块的端口关系画出来当文档用。BDF 和 Verilog 是可以混合的在 BDF 里放一个 symbol 指向你的 Verilog 模块右键 Insert → Symbol选到对应的 .v 文件或者反过来在 Verilog 里例化一个 BDF 生成的符号。混用的时候注意顶层到底是谁编译前在 Project Navigator 里确认一下 top-level entity。3.3 IP 核和 Platform Designer 的调用流程稍微像样一点的工程都会用到 IP 核最常见的三个PLL锁相环用来倍频分频和调整时钟相位、片上 RAM、FIFO。流程是 Tools → IP Catalog找到需要的核双击打开参数配置界面MegaWizard 风格配完参数之后它会问你要生成哪种输出——一定要选 Verilog 或者 VHDL 源码形式并且勾上生成例化模板不要只生成黑盒。以 PLL 为例实际接线的时候有个细节经常被忽略PLL 的输入时钟是外部晶振送进来的那一根输出c0、c1……才是你送给后面逻辑的时钟。很多人第一次用 PLL直接把输入时钟接到逻辑上然后抱怨我明明设了 100 MHz怎么还是 50 MHz。另外 PLL 有个 locked 信号它拉高之后才代表输出时钟已经稳定复位逻辑里把 locked 也纳进去会更稳wire clk_100m; wire pll_locked; pll_100m u_pll ( .inclk0 (clk_50m), .c0 (clk_100m), .locked (pll_locked) );Platform Designer老版本叫 Qsys是用来搭总线系统的比如你想要一个 Nios 软核加几个外设就在里面挂 IP、连总线、分配地址生成一个系统模块再到顶层例化。它的学习曲线比单个 IP 核陡一些但流程逻辑是一样的配置 → 生成 → 例化。注意生成出来的目录不要随手挪动里面有一堆相对路径引用挪了之后 IP 核更新会失败。4. 从综合到 .sof编译流程每一步在干什么4.1 编译各阶段的实际工作点一下 Start Compilation快捷键 CtrlL之后Quartus 其实按顺序干了好几件事界面左下角那个进度条走到哪一步对应的工作内容差别很大阶段工具干的事出问题时的典型表现Analysis Synthesisquartus_map解析 HDL、推断逻辑、优化语法错、latch 警告、资源超限Partition Mergequartus_cdb合并分区用了增量编译才有意义分区端口不匹配Fitterquartus_fit布局布线把逻辑映射到具体资源引脚冲突、资源不够、找不到合法位置Assemblerquartus_asm生成配置文件 .sof/.pof一般不会单独出错Timing Analyzerquartus_sta静态时序分析算 slack 和 Fmax建立/保持时间违例EDA Netlist Writerquartus_eda生成仿真用网表不生成网表的话仿真会跑旧版本读懂这个表最大的价值是排错时知道该看哪一段报告。比如资源不够的报错只会在 Fitter 里出现综合阶段是不会拦你的而 latch 推断的警告在 Analysis Synthesis 阶段就会给出来如果你只盯着最后那句Compilation successful这些警告就被漏掉了。养成习惯编译完先看 Messages 面板的 Critical Warning 数量那个数字不为零就别急着去下载。4.2 引脚约束和 I/O 标准综合过了不代表能上板。Quartus 在引脚没有约束的时候会自己随便分配它会挑一些物理上存在、但跟你的外设毫无关系的引脚。结果就是编译通过、下载成功、板子上一点反应没有。这是新手遇到最多的问题没有之一。约束引脚有两条路。图形界面是 Assignments → Pin Planner在下面的表格里按信号名找到对应行双击 Location 那一列输入引脚编号比如 PIN_E1再把 I/O Standard 设成板上对应的电平标准教学板基本都是 3.3-V LVTTL。这条路直观缺点是每次改完都要重新编译而且换个版本界面布局又变了。另一条路是直接写.qsf文件这也是我更推荐的方式set_location_assignment PIN_E1 -to clk set_instance_assignment -name IO_STANDARD 3.3-V LVTTL -to clk set_location_assignment PIN_M23 -to rst_n set_instance_assignment -name IO_STANDARD 3.3-V LVTTL -to rst_n set_location_assignment PIN_A15 -to led set_instance_assignment -name IO_STANDARD 3.3-V LVTTL -to led手写的好处很实在文本可比对、可复用、可提交到版本库换一块板子只需要改这一份文件。缺点是引脚编号得从板子的原理图或者引脚分配表里一个个抄抄错了 Quartus 会在编译时报引脚不存在或者分配冲突反而比图形界面更容易发现错误。我的做法是第一次用一块新板子用 Pin Planner 把引脚一次性配好然后把生成的.qsf那几行抄出来存成模板以后新工程直接复制粘贴改信号名。还有一处容易忽略的全局设置Assignments → Device → Device and Pin Options → Unused Pins建议设成As input tri-stated。默认状态下未使用的引脚可能被驱动成输出某些板子上这会跟外部器件抢总线严重的会发热。另外在同一个对话框的 Dual-Purpose Pins 里确认一下那些复用引脚比如 nCEO、配置相关引脚你确实没用到用到了就改成 regular I/O。4.3 时序约束不写不会报错但会出问题Quartus 在没有任何时序约束的情况下也能编译出.sofTiming Analyzer 会告诉你no clocks defined然后报一堆 0 的 slack。这时候你如果以为时序全过那是个危险的误会——它只是没东西可分析。最小可用的 SDC 约束长这样放在con/timing.sdc里然后在 Settings → Timing Analysis Settings 里指定这个文件create_clock -name sys_clk -period 20.000 [get_ports clk] derive_pll_clocks derive_clock_uncertainty第一行告诉工具clk 这个端口上是一个 20 ns 周期的时钟也就是 50 MHz。第二行让工具自动推导 PLL 输出时钟的约束用了 PLL 就一定要加。第三行让工具考虑时钟不确定性不写也能过但加上更贴近实际。有了这几行Timing Analyzer 才能算出真实的 Fmax 和 slack。Setup slack 为正、Hold slack 为正才代表这套设计在你指定的频率下能稳定工作。如果 setup slack 是负的三条路可以试降低时钟频率、在关键路径上插寄存器流水线、让综合器更卖力地优化Settings → Compiler Settings → Synthesis 里的优化力度。顺便提一个常见误解仿真波形好看不等于硬件能跑。仿真尤其是不带时序信息的门级以下仿真里没有布线延时逻辑正确就能过硬件里信号要经过实际的走线和逻辑单元延时大了就违例。仿真管逻辑对不对时序分析管能不能跑两件事不能互相替代。4.4 编译报告里值得盯的几个数字编译完打开 Compilation Report信息量很大但真正需要每次都看的没几个Flow Summary 里的 Total logic elements / Total registers资源用了多少。留个 20% 以上的余量比较安心用得太满会让 Fitter 很难找到合法布局编译时间暴涨时序也更容易违例。Total pins引脚用了多少直接关系到引脚约束能不能全部分配下去。Total memory bits用了片上 RAM 多少。Fitter 的 Critical Warning这一类警告我建议当成错误处理绝大多数情况下它意味着某个引脚没分下去、某个时钟没接对、某个 IP 核版本不匹配都是会直接影响功能的。Timing Analyzer 的 Slow 900mV 100C Model 下的 Setup/Hold slack这才是最坏情况下的时序结果别只看 Fast 模型。5. ModelSim/Questa 联仿把逻辑错误挡在上板之前5.1 NativeLink 配置与 testbench 生成在工程设置里配好仿真工具之后Assignments → Settings → EDA Tool Settings → Simulation把工具选成 ModelSim-Altera 或 Questa Intel FPGA格式选 Verilog HDL然后就可以走 NativeLink 的一键流程。testbench 的骨架可以让 Quartus 帮你生成先 Analysis Synthesis 编一遍然后 Processing → Start → Start Test Bench Template Writer它会在simulation/modelsim/下面生成一个xxx.vht或者xxx.vt模板把里面的端口和实例化部分拿去改成自己的激励就行。这个模板的价值在于它把被测模块的端口列表和参数都填好了省掉手抄端口名抄错的麻烦。跑仿真就是 Tools → Run Simulation Tool → RTL Simulation功能仿真或者 Gate Level Simulation门级仿真。RTL 仿真快、波形干净用来验证逻辑门级仿真带上了综合后的延时信息慢很多一般在时序有疑问的时候才跑。5.2 一个可以反复用的 testbench 骨架timescale 1ns/1ps module tb_led_blink; reg clk 1b0; reg rst_n 1b0; wire led; // 50 MHz周期 20 ns always #10 clk ~clk; led_blink u_dut ( .clk (clk), .rst_n (rst_n), .led (led) ); initial begin rst_n 1b0; #200; rst_n 1b1; #2_000_000; // 2 ms 足够看几次翻转 $stop; end endmodule这段东西里有几个点值得说。timescale 1ns/1ps决定了#10到底是 10 ns 还是别的写错的话整个时间轴都错。always #10 clk ~clk用取反的方式产生时钟比手写交替赋值简洁也不容易错。仿真时长要算一下LED 翻转周期是 1 秒如果真跑 1 秒仿真波形文件会大到打不开所以这里只跑 2 ms 看几次翻转就够了——跑仿真前先想清楚我要看到什么现象就够别一上来就跑到天亮。5.3 波形不对的时候按什么顺序查看着波形发愁的时候我一般按这个顺序往下走。先确认时钟有没有在跳很多人调了半天逻辑最后发现是 testbench 里时钟根本没产生或者复位一直没释放。再看复位信号的电平极性rst_n是低有效如果你的代码里写成了if (rst_n)判复位那行为就完全反了。接着看信号的位宽和进制显示ModelSim 默认可能用十六进制或者十进制显示看着像 0 的其实是 X未初始化。最后才怀疑逻辑本身。X 状态是个高频问题。仿真里出现 X通常来源有三个寄存器上电没有初值、多驱动冲突、访问了未初始化的存储器。综合后的硬件里上电值是有确定性的一般是 0但仿真里是 X这个差异意味着仿真报 X 的地方硬件里未必是错但你不能靠它碰运气该加的复位还是得加。6. 上板下载和在线调试6.1 下载器连接和驱动检查下载之前先做两件事板子通电下载器插好。Tools → Programmer 打开如果是第一次用Hardware Setup 里应该能看到 USB-Blaster看不到就回到第 1.2 节的驱动部分。JTAG 连接的可靠性对线长很敏感那种二三十厘米的杜邦线连 JTAG很容易出现能识别但下载失败换短一点的排线通常就好了。Mode 选择上JTAG 是最常用的直接烧到 FPGA 的 SRAM 里断电就丢Active Serial Programming 是烧到板上的配置芯片EPCS/EPCQ里断电不丢。第一次调试基本都用 JTAG 模式因为快。6.2 .sof、.pof、.jic 到底该烧哪个这三个文件经常被搞混其实差别很清楚文件生成方式烧到哪里掉电后.sof默认编译产出FPGA 内部 SRAM丢失需重新下载.pof转换后用于 AS 模式串行配置芯片保留上电自动加载.jic用于 JTAG 间接配置配置芯片保留上电自动加载日常调试用.sof改一次下一次最灵活。等功能稳定了要做成上电就跑的成品用 File → Convert Programming Files 把.sof转成.jic然后在 Programmer 里选 JTAG 模式烧进去。注意转换的时候要正确选配置芯片的型号EPCS16、EPCQ64 之类看板子原理图选错了会导致配置失败表现是上电后 FPGA 完全不工作但 JTAG 直接下.sof又是好的——这个现象基本可以确诊是配置芯片型号选错了。6.3 Programmer 打开文件时卡顿的几种原因Programmer 点开文件对话框要卡十几秒甚至半分钟这个问题我遇到过好几次排查下来原因基本集中在下面几类都不是软件坏了文件对话框在枚举网络位置。Windows 的打开对话框会去访问网络和映射的网络驱动器如果公司环境里有已经断开但还挂在资源管理器里的网络盘每次打开都要等它超时。解决方式是把网络盘断开或者在对话框里直接用地址栏粘贴完整路径回车绕过枚举。最近文件列表里有已经不存在的路径。.qsf或者用户配置里记着上一次的.sof路径那个目录被删了或者换了盘符每次刷新都要重试。清一下最近文件列表或者手动把.qsf里相关行删掉。jtagserver / jtagd 进程状态异常。这个后台进程负责跟下载器通信偶尔会卡住表现是 Programmer 打开慢、Hardware Setup 转圈。直接在任务管理器里结束这几个进程重新打开 Programmer它会自己重启一份。杀毒软件实时扫描。.sof文件本身不大但 Programmer 打开时还会去读一堆相关文件实时防护每个都扫一遍就慢了。把工程目录和 Quartus 安装目录加进白名单。同时开了多个 Programmer 实例或者工程很大内存吃紧。老版本 Quartus II 32 位进程有内存上限同时开多个实例很容易卡。顺带说一句.sof文件本身最好放在本地磁盘别放在网络共享盘或者同步盘目录里同步软件在后台锁定文件会让 Programmer 读文件失败这个坑比卡顿更难查。6.4 SignalTap II 抓内部信号板子跑起来之后如果现象不对最快的手段是 SignalTap II 嵌入式逻辑分析仪。它是把一小块采样存储器和触发逻辑综合进你的设计里通过 JTAG 把采样结果读回来在 Quartus 里显示波形本质上就是个片内示波器。使用流程Tools → SignalTap II Logic Analyzer新建一个.stp指定采样时钟一般用系统时钟把要观察的信号从 Node List 里拖进来信号必须是综合后存在的被优化掉的信号加不进来加不了就在综合设置里给它加个 keep 属性设好采样深度和触发条件保存之后整个工程需要重新编译一次因为逻辑变了然后下载、运行、抓波形。有两个经验点。采样深度吃的是片上 RAM深度设得太大可能直接把 RAM 用光导致布局失败一般几千到几万采样点就够用了。调试完了记得把 SignalTap 关掉再重新编译一次出正式版本否则它会一直占着资源和引脚白白浪费。另外被观察信号如果是跨时钟域的采样时钟选不对会看到一堆跳变这不是逻辑错是采样方式的问题。7. 几个反复踩到的坑和能省时间的习惯7.1 编译太慢怎么办全编译一次几分钟到几十分钟都正常跟器件规模、资源占用率、代码复杂度都有关系。想快一点有这么几个方向。开多核并行编译。Settings → Compiler Settings → Parallel compilation把 processor 数量设成物理核心数。默认是关的打开之后大工程的综合和布局能快不少。只跑到你需要的阶段改了点逻辑只是验证功能用 Processing → Start → Start Analysis Synthesis不用全编译引脚改了就只跑 Fitter 之后的阶段。保持工程干净把不用的旧文件从工程里移出去尤其是那些早就废弃的模块综合器一样会去解析它们。7.2 增量编译和工程归档工程规模上去之后改一行代码全编译一次就太痛苦了。增量编译的思路是把设计切成几个分区Design Partition每个分区单独综合和布局改了一个分区只重编那一个其余复用上次的结果。配置入口在 Assignments → Design Partitions Window。划分的原则是按功能模块切比如把 PLL 和内存控制器这种基本不会动的部分切成一个分区把常改的业务逻辑切成另一个。代价是分区边界会限制优化整体资源和时序可能略微变差还有分区的端口一旦变了就要全部重编。所以我一般只在编译时间确实受不了的时候才上增量编译小工程顺手全编译反而简单。工程备份和迁移用 Project → Archive Project它会自动把需要的源文件、约束、IP 核打包成一个.qar重新导入用 Restore Archived Project。这个功能比手工压缩目录靠谱因为它知道哪些中间文件不用带。7.3 一些我会一直保持的小习惯写 Verilog 的时候模块端口一律明确写input wire/output reg不省类型每个 always 块上面写一句注释说明它在干什么状态机用参数定义状态编码而不是直接写数字。这些习惯在几十行的实验代码里看不出价值等到几百行的工程里要找 bug 的时候价值就出来了。每次改完引脚约束之后重新看一眼 Pin Planner 里有没有红色的冲突标记比等到下载失败再去查要快。每完成一个能跑通的功能点就提交一次版本.qsf和.sdc一起提交因为**为什么昨天还能跑今天就不行了这种问题九成能在.qsf的差异里看出来**。最后再分享一个小技巧关于新板子上手的顺序先不要急着跑你的功能写一个最简单的 LED 闪烁加上一个按键输入把引脚按板子原理图约束好编译下载跑一遍。这一步通了说明工具链、驱动、引脚约束、时钟、复位全都是对的你后面遇到的任何问题都可以限定在我的逻辑这个范围内。这一步不通就别往下做了先把它弄通不然你会在调试业务逻辑和调试工具链之间反复横跳效率极低。这七八年里我见过太多人跳过这一步然后在错误的层里查了好几天。
阅读完成 · 觉得有帮助?
咨询建站