Export to Vivado 基础系统连接配置
一句话概述
本模块定义了Vitis Export to Vivado 流程的最小可行系统——通过 system.cfg 配置将 AIE 引擎、HLS 内核(polar_clip)和 DMA 数据搬运器连接成一个闭环数据通路,构成异构计算的"Hello World"。
核心组件
1. system.cfg —— 系统连接蓝图
文件路径:Vitis_Platform_Creation/Feature_Tutorials/03_Vitis_Export_To_Vivado/vitis_impl/system.cfg
配置语义逐行解析:
# 频率约束(前置时钟配置)
freqhz=200MHz:stream_in.ap_clk
# 含义:stream_in 内核的 ap_clk 端口运行在 200MHz
[connectivity]
# 内核实例化 (nk = number of kernel)
nk=stream_out:1:stream_out
# 语法:nk=<kernel_name>:<instance_count>:<instance_names>
# 含义:实例化 1 个 stream_out 内核,实例名为 stream_out
nk=stream_in:1:stream_in
# 实例化 1 个 stream_in 内核(S2MM)
nk=polar_clip:1:polar_clip
# 实例化 1 个 polar_clip HLS 内核
# 流连接 (sc = stream connect)
# 格式: sc=<source>:<destination>
sc=stream_out.s:ai_engine_0.DataIn1
# 连接: stream_out 的 s 端口到 AIE 的 DataIn1 端口
sc=ai_engine_0.clip_in:polar_clip.in_sample
# 连接: AIE 的 clip_in 到 polar_clip 的 in_sample
sc=polar_clip.out_sample:ai_engine_0.clip_out
# 连接: polar_clip 的 out_sample 到 AIE 的 clip_out
sc=ai_engine_0.DataOut1:stream_in.s
# 连接: AIE 的 DataOut1 到 stream_in 的 s 端口
[clock]
freqHz=100000000:polar_clip.ap_clk
# polar_clip 运行在 100MHz(与 stream_in 的 200MHz 异步)
配置语法总结表:
| 指令 | 语法 | 示例 | 说明 |
|---|---|---|---|
nk |
nk=<kernel>:<count>:<names> |
nk=polar_clip:2:pc1.pc2 |
实例化内核 |
sc |
sc=<src>:<dst> |
sc=a.b:c.d |
连接流端口 |
freqHz |
freqHz=<hz>:<inst>.<clk> |
freqHz=100000000:pc.ap_clk |
绑定时钟 |
2. 数据流完整轨迹
主机 DDR 内存
│ AXI4-Full (突发传输)
▼
stream_out (MM2S DMA)
│ AXI4-Stream (32-bit)
▼
ai_engine_0 (AIE 阵列)
│ clip_in (PLIO 接口)
▼
polar_clip (HLS 内核)
│ clip_out (PLIO 接口)
▼
ai_engine_0 (AIE 阵列)
│ AXI4-Stream
▼
stream_in (S2MM DMA)
│ AXI4-Full (突发传输)
▼
主机 DDR 内存
关键数据交换点:
- DDR ↔ MM2S/S2MM:AXI4-Full 协议,突发长度通常为 16-64 beat,64-bit 地址支持 >4GB 空间
- MM2S/S2MM ↔ AIE:AXI4-Stream 协议,32-bit 数据宽度,
TVALID/TREADY握手机制 - AIE ↔ polar_clip:通过 PLIO(Programmable Logic I/O)接口连接,AIE 侧是 64-bit 宽度的流接口,PL 侧是 32-bit AXI4-Stream
设计决策分析
决策 1:单实例配置的选择
问题:为什么选择 nk=polar_clip:1:polar_clip 而非多实例?
决策理由:
- 最小可行系统:单实例排除了多实例竞争、负载均衡等复杂因素,聚焦于基础连通性验证
- 资源最小化:便于在小型开发板(如 VCK190)上运行,降低入门门槛
- 调试友好性:单数据通路简化了波形追踪和问题定位
扩展路径:多实例配置见 export_to_vivado_custom_ip_and_multi_instance_connectivity。
决策 2:异步时钟域的设计
问题:为什么 polar_clip 使用 100MHz 而 stream_in 使用 200MHz?
决策理由:
| 内核 | 时钟 | 原因 |
|---|---|---|
| polar_clip | 100MHz | CORDIC 算法涉及多级移位/加法,组合逻辑深度大,100MHz 提供宽松时序裕量 |
| stream_in/out | 200MHz | DMA 引擎逻辑简单(主要是 FIFO 和 AXI 协议转换),可运行在更高频率以提升带宽 |
CDC 处理:AIE 到 PL 的接口(clip_in/clip_out)自动包含 CDC 电路,无需手动处理。PL 内部跨时钟域(如 polar_clip 输出到 200MHz 域)通过 hls::stream 的异步 FIFO 实现。
与其他模块的关系
上游依赖
- polar_clip_kernel_data_types:
system.cfg中的polar_clip.in_sample和out_sample端口依赖 polar_clip 内核的准确数据类型定义(ap_axis<32,0,0,0>)。若内核修改位宽,配置必须同步更新。
下游消费者
-
export_to_vivado_custom_ip_and_multi_instance_connectivity: 本配置是基础模板。
system_custom_ip.cfg移除了stream_out,添加了自定义 IP 接口;system_new.cfg扩展为双实例并行流水线。 -
platform_validation_aie_reference_data_movers: AIE 验证流程基于本配置定义的连接拓扑。验证内核的端口名(如
mm2s_1)和连接关系(如sc=stream_out.s:ai_engine_0.DataIn1)必须与本配置保持一致。
新贡献者指南
快速验证本配置是否工作
# 1. 进入实现目录
cd Vitis_Platform_Creation/Feature_Tutorials/03_Vitis_Export_To_Vivado/vitis_impl
# 2. 使用 v++ 链接生成 XCLBIN
# 注意:需要已编译的 AIE 图(libadf.a)和 PL 内核(.xo)
v++ -l -t hw_emu \
--platform xilinx_vck190_base_202320_1 \
--config system.cfg \
../pl_kernels/polar_clip.xo \
../../04_platform_validation/ref_files/aie_validation/mm2s_1.xo \
../../04_platform_validation/ref_files/aie_validation/s2mm_1.xo \
../aie/libadf.a \
-o system.xclbin
# 3. 运行硬件仿真验证
./host_app system.xclbin
修改配置时的注意事项
-
保持端口名一致性:
sc=行中的端口名(如polar_clip.in_sample)必须与内核源码中的hls::stream变量名完全匹配(包括大小写)。 -
时钟频率单位:
freqHz使用赫兹(Hz)而非 MHz。freqHz=100000000表示 100MHz,不要误写为freqHz=100。 -
实例名与内核名区别:
nk=polar_clip:1:pc1中polar_clip是内核名(对应 .xo 文件名),pc1是实例名(用于sc=连接)。修改实例名后必须同步更新所有sc=行。 -
AIE 端口命名规则:
ai_engine_0.DataIn1中的DataIn1必须与生成的 AIE 图的 PLIO 名称匹配。若 AIE 源码修改了input_port名称,配置需同步更新。