4. Quartus工程管理
在Quartus Prime中,一个可交付的FPGA工程远不止一个.qpf文件。真正决定工程能否被团队复用、能否稳定复现、能否在同一套RTL上产出多个SKU的,是工程目录结构、版本控制策略、参数化机制与多配置管理这四件事的组合。本节围绕这四点展开,并给出可直接落地的目录模板与配置示例。
一、工程目录结构:把“可编译”升级为“可交付”
Quartus默认把.qpf、.qsf、.sof、数据库目录db/、增量编译目录incremental_db/混放在同一层。这种结构在单人调试时无碍,但一旦进入版本控制,就会把大量二进制中间产物提交进仓库,导致仓库膨胀、冲突频发。推荐采用“源码与产物分离”的目录结构:
prj_uart_bridge/
├── rtl/ # 可综合RTL,按功能分子目录
│ ├── core/
│ └── periph/
├── ip/ # 生成的IP核(.ip/.qip/.v)
├── constr/ # 约束文件
│ ├── pin.sdc
│ └── timing.sdc
├── sim/ # 仿真testbench与脚本
├── scripts/ # 编译、烧录、回归脚本
├── cfg/ # 多配置参数文件
│ ├── sku_a.tcl
│ └── sku_b.tcl
├── output/ # 编译产物(不入库)
│ ├── sof/
│ └── rbf/
└── doc/ # 寄存器手册、接口说明
关键原则有三条:其一,db/、incremental_db/、output/、*.qws、*.sof、*.rbf一律写入.gitignore,只保留源码、约束、脚本与IP描述文件;其二,.qsf中所有路径使用相对路径,避免换机器后路径失效;其三,IP核只提交.ip与.qip,不提交其生成的HDL副本,由qsys-generate或quartus_ipgenerate在编译时重建。
二、版本控制:让每次编译都可追溯
Quartus工程入库时,建议把.qpf、.qsf、.sdc、.ip、RTL与脚本全部纳入Git。为便于追溯“哪个commit对应哪版bit流”,可在编译脚本中自动写入版本信息:
# scripts/build.tcl
set rev [exec git rev-parse --short HEAD]
set_property LAST_COMPILATION_REVISION $rev [get_current_revision]
这样在output/目录中生成的.sof即可与Git提交号一一对应。对于多人协作,.qsf是冲突高发文件,建议按功能拆分为多个.qsf片段(如pin.qsf、timing.qsf),通过source方式在主.qsf中引用,减少同一文件的并发修改。
三、参数化工程:一套RTL,多种形态
参数化是Quartus工程复用的核心手段,常见有三层:Verilog参数、IP参数、Tcl脚本参数。以UART桥接器为例,波特率、FIFO深度、数据位宽均可参数化:
module uart_bridge #(
parameter CLK_FREQ = 50_000_000,
parameter BAUD = 115200,
parameter FIFO_DEPTH = 16
)(
input wire clk,
input wire rst_n,
input wire rx,
output wire tx
);
localparam BAUD_DIV = CLK_FREQ / BAUD;
// ...
endmodule
在工程层面,通过.qsf中的VERILOG_MACRO或Tcl的set_global_assignment把参数注入顶层:
set_global_assignment -name VERILOG_MACRO "BAUD=115200"
set_global_assignment -name VERILOG_MACRO "FIFO_DEPTH=16"
这样同一份RTL即可通过不同宏定义生成不同配置,无需复制源码。
四、多配置管理:Revision与Tcl脚本协同
Quartus的Revision机制允许在同一工程下维护多个编译配置,每个Revision拥有独立的.qsf设置、引脚约束与编译结果。典型做法是:主工程.qpf下建立sku_a、sku_b两个Revision,分别对应不同封装或不同外设组合。切换与编译可通过Tcl脚本自动化:
# cfg/sku_a.tcl
set_current_revision sku_a
set_global_assignment -name FAMILY "Cyclone IV E"
set_global_assignment -name DEVICE EP4CE10F17C8
set_global_assignment -name VERILOG_MACRO "SKU=A"
source constr/pin_sku_a.sdc
执行quartus_sh -t cfg/sku_a.tcl即可完成配置切换,再调用quartus_map、quartus_fit、quartus_asm完成全流程编译。多配置管理的价值在于:同一套RTL、同一套约束框架,通过Revision与宏参数组合,产出多个SKU的bit流,且每个SKU的编译结果独立存放、互不干扰。
output/<revision>/子目录,避免不同SKU的.sof互相覆盖。五、落地检查清单
在工程交付前,建议逐项核对:.gitignore是否覆盖全部中间产物;.qsf是否全部使用相对路径;IP是否只保留描述文件;每个Revision是否有独立的Tcl配置脚本;编译脚本是否自动写入版本号;output/是否按Revision分目录。完成这六项,工程即从“能编译”升级为“可交付、可复现、可扩展”。
db/,可能导致引脚分配或时序约束串扰。建议在Tcl脚本中显式执行execute_module -tool map前先清理对应Revision的db/目录,或使用quartus_sh --clean。