System Configuration (system.cfg) 子模块文档
概述
system.cfg 是整个 Farrow 滤波器系统的集成蓝图,它就像是建筑项目的施工图纸——定义了各个组件如何连接、时钟如何分配、内存如何映射。没有这份配置,HLS 内核和 AIE Graph 只是孤立的零件,无法协同工作。
在 Vitis 工具链中,system.cfg 被链接阶段 (v++ -l) 使用,负责生成最终的 FPGA 比特流。
核心职责
- 内核实例化:声明需要多少个 HLS 内核实例,并给它们命名
- 时钟配置:统一设置 PL 侧的时钟频率
- 内存映射:指定每个内核的 AXI4-MM 接口连接到哪个存储器
- 流式连接:定义 AXI4-Stream 端口之间的连接关系
- 实现策略:控制 Vivado 布局布线的优化选项
配置详解
1. 时钟配置
freqhz=312500000:dma_src1.ap_clk,dma_src2.ap_clk,dma_snk.ap_clk
关键洞察:
- 所有 DMA 核共享同一个 312.5 MHz 时钟源
- 这个频率与 HLS 配置中的
clock=3.2ns完全对应 - 与 AIE 的 1250 MHz 形成精确的 1:4 比例,简化跨时钟域设计
为什么不是独立的时钟? 虽然可以为每个核配置独立时钟,但会增加时钟树复杂度和功耗。对于同步工作的数据搬运器,共享时钟是更简洁的选择。
2. 内核实例化
nk = farrow_dma_src_wrapper:2:dma_src1,dma_src2
nk = farrow_dma_snk_wrapper:1:dma_snk
语法解析:nk = <kernel_name>:<num_instances>:<instance_names>
| 组件 | 实例数 | 实例名 | 用途 |
|---|---|---|---|
| farrow_dma_src_wrapper | 2 | dma_src1, dma_src2 | 信号输入 + 延迟参数输入 |
| farrow_dma_snk_wrapper | 1 | dma_snk | 滤波结果输出 |
为什么是 2 个 Source 实例? Farrow 滤波器有两个独立的输入流:
sig_i: 复数信号样本 (cint16)del_i: 分数延迟参数 (int16)
使用两个独立的 DMA 通道可以确保它们以精确对齐的方式送达 AIE,避免单通道时分复用带来的同步复杂性。
3. 内存映射
sp=dma_src1.mem:LPDDR
sp=dma_src2.mem:LPDDR
sp=dma_snk.mem:LPDDR
语法解析:sp=<instance>.<port>:<memory_bank>
LPDDR vs HP DDR:
- LPDDR (Low Power DDR):位于 PS 端,适合小数据量、低功耗场景
- HP DDR (High Performance DDR):位于 PL 端,适合大数据量、高带宽场景
本设计选择 LPDDR 是因为数据量适中(4096 样本 × 4 字节 ≈ 16 KB),且便于 Host PS 直接访问。
4. 流式连接
# PL DMA Source to AIE Farrow
sc = dma_src1.sig_o:ai_engine_0.PLIO_i_0
sc = dma_src2.sig_o:ai_engine_0.PLIO_i_1
# AIE Farrow to PL DMA SINK
sc = ai_engine_0.PLIO_o_0:dma_snk.sig_i
语法解析:sc=<source>:<sink>
连接拓扑分析:
sig_o] SRC2[dma_src2
sig_o] SNK[dma_snk
sig_i] end subgraph AIE[AIE Array] PLIO0[PLIO_i_0] PLIO1[PLIO_i_1] PLIO2[PLIO_o_0] K1[farrow_kernel1] K2[farrow_kernel2] end SRC1 -->|sc| PLIO0 SRC2 -->|sc| PLIO1 PLIO2 -->|sc| SNK PLIO0 --> K1 PLIO1 --> K2 K1 --> K2 K2 --> PLIO2 style PL fill:#e1f5fe style AIE fill:#fff3e0
关键观察:
dma_src1→PLIO_i_0→farrow_kernel1:信号样本路径dma_src2→PLIO_i_1→farrow_kernel2:延迟参数路径farrow_kernel2→PLIO_o_0→dma_snk:滤波结果输出路径
注意 farrow_kernel1 的输出是通过内部缓冲区连接到 farrow_kernel2,而不是通过 PLIO。
5. Vivado 实现选项
[vivado]
prop=run.impl_1.steps.phys_opt_design.is_enabled=1
prop=run.impl_1.steps.post_route_phys_opt_design.is_enabled=1
param=project.enableUnifiedAIEFlow=true
选项说明:
| 选项 | 作用 |
|---|---|
phys_opt_design.is_enabled=1 |
启用物理优化,改善时序收敛 |
post_route_phys_opt_design.is_enabled=1 |
布线后再次物理优化,进一步提升性能 |
enableUnifiedAIEFlow=true |
启用统一 AIE 流程,在 Vivado 中显示 AIE 资源 |
注释掉的选项(供调试用):
#impl.strategies=Performance_Explore,...
#impl.jobs=8
这些选项可以启用多策略探索和并行作业,但会增加编译时间。
完整配置参考
#
# Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
# SPDX-License-Identifier: MIT
#
# Author: Faisal El-Shabani
# ------------------------------------------------------------
# Clocks
# ------------------------------------------------------------
freqhz=312500000:dma_src1.ap_clk,dma_src2.ap_clk,dma_snk.ap_clk
[connectivity]
# ------------------------------------------------------------
# HLS PL Kernels:
# ------------------------------------------------------------
nk = farrow_dma_src_wrapper:2:dma_src1,dma_src2
nk = farrow_dma_snk_wrapper:1:dma_snk
# ------------------------------------------------------------
# AXI Stream Connections (PL to AIE)
# ------------------------------------------------------------
sp=dma_src1.mem:LPDDR
sp=dma_src2.mem:LPDDR
sc = dma_src1.sig_o:ai_engine_0.PLIO_i_0
sc = dma_src2.sig_o:ai_engine_0.PLIO_i_1
sc = ai_engine_0.PLIO_o_0:dma_snk.sig_i
sp=dma_snk.mem:LPDDR
# ------------------------------------------------------------
# Vivado PAR
# ------------------------------------------------------------
[vivado]
prop=run.impl_1.steps.phys_opt_design.is_enabled=1
prop=run.impl_1.steps.post_route_phys_opt_design.is_enabled=1
param=project.enableUnifiedAIEFlow=true
常见错误与调试
错误 1: 端口名称不匹配
症状:链接阶段报错 Port 'sig_o' not found
原因:sc 语句中的端口名必须与 HLS 代码中的接口名完全一致:
#pragma HLS interface axis port=sig_o // 这里定义的端口名
错误 2: 时钟频率不一致
症状:时序违例或功能错误
原因:system.cfg 中的 freqhz 必须与 hls.cfg 中的 clock 对应:
- 312.5 MHz = 3.2 ns 周期
- 如果 HLS 按 3.2ns 综合,但系统按 400MHz 运行,会出现时序问题
错误 3: 内存 bank 不存在
症状:链接报错 Memory bank 'LPDDR' not available
原因:目标平台可能没有 LPDDR,或者名称不同(如 DDR4, HP_DDR)
检查方法:查看平台的 .xpfm 文件中的可用存储器列表。
错误 4: PLIO 方向错误
症状:AIE 编译报错或仿真死锁
原因:PLIO_i_* 是 AIE 的输入,PLIO_o_* 是 AIE 的输出。方向反了会导致数据流无法建立。
与其他配置文件的关系
构建流程:
- HLS 编译器根据
hls.cfg生成.xo文件(内核对象) - AIE 编译器生成 AIE 部分的设计
- Vitis 链接器根据
system.cfg将所有组件链接成最终.xclbin
扩展指南
添加更多 DMA 通道
如果需要增加第三个输入流:
# 1. 实例化新的内核
nk = farrow_dma_src_wrapper:3:dma_src1,dma_src2,dma_src3
# 2. 配置时钟
freqhz=312500000:...,dma_src3.ap_clk
# 3. 内存映射
sp=dma_src3.mem:LPDDR
# 4. 流式连接
sc = dma_src3.sig_o:ai_engine_0.PLIO_i_2
同时需要修改 AIE Graph 以接受新输入。
切换到 HP DDR
如果需要更高带宽:
sp=dma_src1.mem:HP_DDR
sp=dma_src2.mem:HP_DDR
sp=dma_snk.mem:HP_DDR
注意:HP DDR 通常需要额外的 PL 逻辑进行协议转换。
调整时钟频率
如果需要不同的吞吐量:
# system.cfg
freqhz=400000000:dma_src1.ap_clk,... # 400 MHz
# hls.cfg 同步修改
clock=2.5ns # 400 MHz
然后重新计算带宽公式验证是否满足需求。
本文档详细说明了系统配置文件的结构和用法。正确理解这些配置项是成功部署 Versal AIE 设计的关键。