🏠

ifft64k_2d_dataflow_integration 模块深度解析

一句话概述

本模块实现了 64K 点二维 IFFT(逆快速傅里叶变换)的数据流管道集成,通过 AIE(AI Engine)与 PL(Programmable Logic)HLS 内核的协同,完成大规模频域到时域转换的高效硬件加速。

想象一个数字信号处理工厂:数据像原材料从仓库(DDR)流出,经过 AIE 的"精密加工车间"进行 IFFT 计算,再通过转置单元(Transpose)进行数据重排以实现二维变换,最终成品(结果数据)流回仓库存储。整个流水线以 312.5 MHz 的时钟频率持续运转,追求极致的吞吐效率。

问题空间与设计动机

为什么要做这个模块?

在雷达信号处理、5G 基带、医疗超声成像等领域,二维 IFFT 是核心计算密集型操作。一个 64K 点(256×256)的二维 IFFT 涉及:

  1. 巨大的计算量:单次二维 IFFT 需要 \(O(N^2 \log N)\) 次复数运算,64K 点规模在 CPU 上实时处理极为困难
  2. 严格的延迟要求:雷达信号处理要求微秒级响应,通用处理器无法满足
  3. 数据移动开销:大规模数据在片外 DDR 和计算单元间的搬移需要精心设计的 DMA 策略

为什么不用纯 AIE 或纯 PL 方案?

纯 AIE 方案的局限

  • AIE 擅长向量运算,但大规模转置操作需要复杂的数据重排,纯 AIE 实现会浪费宝贵的计算资源
  • AIE 的本地存储有限,64K 点数据无法全驻留,需要频繁与外部交换

纯 PL(HLS)方案的局限

  • PL 的 DSP slice 虽然可配置,但 IFFT 蝶形运算的吞吐量难以匹敌 AIE 的向量处理器阵列
  • 纯 PL 实现复杂控制流会消耗大量 LUT,降低整体能效

异构协同的最优解: 本模块采用 "AIE 负责核心 IFFT 计算,PL HLS 负责数据搬移与转置" 的分工模式,充分发挥各自优势:

  • AIE 的 SIMD 向量单元高效执行蝶形运算
  • PL HLS 实现高吞吐量的 DMA 和转置逻辑
  • 通过 AXI4-Stream 接口实现零拷贝数据流

核心抽象与心智模型

系统架构全景

flowchart LR subgraph DDR["片外存储 LPDDR"] MEM["输入/输出数据缓冲区"] end subgraph PL["PL HLS 内核"] SRC["DMA Source
数据 ingress"] SNK["DMA Sink
数据 egress"] TR["Transpose
行列转置"] end subgraph AIE["AI Engine 阵列"] AIE_F["IFFT 第一阶段
行/列变换"] AIE_B["IFFT 第二阶段
列/行变换"] end MEM -->|"m_axi
突发传输"| SRC SRC -->|"axis
5 路并行"| AIE_F AIE_F -->|"axis
5 路并行"| TR TR -->|"axis
5 路并行"| AIE_B AIE_B -->|"axis
5 路并行"| SNK SNK -->|"m_axi
突发传输"| MEM

关键抽象概念

1. 五路并行数据流(5-Way Parallel Streaming)

本模块采用 SSR(Super Sample Rate) 架构,将数据流拆分为 5 路并行通道。想象一条高速公路被划分为 5 条车道,每辆车(数据样本)按固定车道行驶,5 辆车同时前进。

这种设计的原因是 64K 点 IFFT 的数据吞吐需求极高,单路 AXI4-Stream 的带宽无法满足。通过 5 路并行,有效带宽提升 5 倍,同时每路的数据率降低,简化时序收敛。

2. 转置作为数据重排枢纽(Transpose as Data Reordering Hub)

二维 IFFT 的核心挑战在于:先对行做 IFFT,再对列做 IFFT(或反之)。但数据在内存中是按行存储的,直接访问列会导致极差的缓存/内存访问模式。

Transpose 内核充当"数据重排枢纽":

  • 第一阶段 IFFT(假设按行)完成后,数据通过 5 路 axis 流入 Transpose
  • Transpose 执行行列转置,将行连续的数据变为列连续
  • 转置后的数据流入第二阶段 IFFT(按列计算)

3. DMA 作为数据搬运 orchestrator(DMA as Data Movement Orchestrator)

DMA Source 和 Sink 是系统的"进出口海关":

  • DMA Source:从 LPDDR 读取输入数据,转换为 AXI4-Stream 格式,注入 AIE 阵列
  • DMA Sink:接收 AIE 阵列的输出流,转换为 AXI4-Stream 转 m_axi 的突发传输,写回 LPDDR

关键设计:使用 m_axi 接口进行 DDR 访问,支持突发传输(burst)以最大化内存带宽;使用 axis 接口进行 PL↔AIE 通信,支持流式处理的低延迟特性。

关键设计决策与权衡

1. HLS 与 AIE 的职责划分

决策:PL HLS 负责数据搬移(DMA)和转置,AIE 负责核心 IFFT 计算。

权衡分析

维度 替代方案 本方案优势 代价
计算效率 纯 PL 实现 IFFT AIE 的 SIMD 单元提供 4-8 倍更高的蝶形运算吞吐 异构编程复杂性增加
内存效率 纯 AIE 实现转置 PL 的 BRAM 可构建高效的二维缓冲转置结构 额外的 PL 资源消耗
灵活性 固定功能加速器 保持软件可编程性,支持不同规模 IFFT 的参数调整 峰值性能略低于硬连线逻辑

核心洞察:AIE 的强项是密集向量运算(蝶形操作),PL HLS 的强项是复杂数据流控制(DMA、转置)。异构协同实现了 1+1>2 的效果。

2. 五路并行(5-Way)vs 其他并行度

决策:选择 5 路并行数据流。

权衡分析

5 是一个非典型的并行度(通常选择 2 的幂次如 4、8)。选择 5 的原因:

  1. 算法匹配性:64K 点 IFFT 的分解结构(256×256)与 5 路并行存在特定的映射关系,使得数据分配均衡
  2. 资源利用率:Versal 器件的 AIE 阵列和 PL 资源在 5 路配置下达到较优的利用平衡点
  3. 时序收敛:5 路并行使每路的数据率降低,简化时序约束,相比 8 路更容易在高频(312.5 MHz)下收敛

代价

  • 非 2 的幂次导致某些缓冲区的地址计算稍微复杂
  • 数据对齐和填充(padding)需要特殊处理

3. PLIO 接口与 AIE 的连接拓扑

决策:使用 PLIO(Programmable Logic I/O)接口连接 PL HLS 内核与 AIE 阵列,每路数据使用独立的 PLIO 通道。

权衡分析

system.cfg 可以看到连接方式:

sc = dma_src.sig_o_0:ai_engine_0.PLIO_front_i_0
sc = dma_src.sig_o_1:ai_engine_0.PLIO_front_i_1
...

替代方案:使用 AXI4-Stream 直接连接(通过 AXI-S switches/routers)。

当前方案优势

  1. 确定性延迟:PLIO 提供从 PL 到 AIE tile 的直接、确定性的点对点连接,没有交换机引入的仲裁延迟
  2. 独立时钟域:每路 PLIO 可在独立的时钟域运行(虽然本设计统一使用 312.5 MHz),提供灵活性
  3. 物理布局友好:PLIO 连接在物理布局上与特定的 AIE tile 绑定,便于 floorplanning

代价

  • PLIO 资源有限(每 AIE tile 有限数量的 PLIO 端口),5 路并行消耗较多 PLIO 资源
  • 连接关系固定,缺乏运行时动态路由的灵活性

4. 单一时钟域 vs 多时钟域

决策:所有 PL HLS 内核(DMA Source、Transpose、DMA Sink)和 AIE PLIO 接口使用统一的 312.5 MHz 时钟。

权衡分析

freqhz=312500000:dma_src.ap_clk,transpose.ap_clk,dma_snk.ap_clk

替代方案

  • DMA 使用较低频率(如 200 MHz)以简化时序,AIE 接口使用更高频率(如 400 MHz)以提高吞吐

当前方案优势

  1. 简化跨时钟域(CDC)处理:无需处理异步 FIFO 和时钟域跨越带来的复杂度,降低设计风险
  2. 统一时序分析:单一时钟域使静态时序分析(STA)更直接,易于收敛
  3. 功耗可预测:统一时钟使功耗分析更简单,避免多时钟域的动态功耗峰值

代价

  • 312.5 MHz 对某些复杂逻辑(如转置的地址计算)可能是挑战,需要仔细优化 HLS 代码以满足时序
  • 无法针对不同功能模块的最优频率进行调优,可能在某些场景下牺牲峰值性能

数据流端到端追踪

让我们跟随一组 64K 点(256×256)的频域数据,走完完整的处理流程:

阶段 1:DMA Source - 数据入口 orchestration

起点:数据在 LPDDR 中按行优先顺序存储,每行 256 个复数样本,共 256 行。

操作

  1. ifft_dma_src_wrapper(HLS 内核)通过 m_axi 接口发起突发读请求,从 LPDDR 读取数据块
  2. 内核内部将读取的平面数据重新组织为 5 路并行流(sig_o_0sig_o_4
  3. 每路流通过 axis 接口输出,连接到 AIE 的 PLIO 输入

关键设计:DMA Source 不仅做数据搬运,还负责数据分片(Striping)——将连续数据按特定模式分配到 5 路流,以匹配 AIE 内部的并行处理结构。

阶段 2:AIE 第一阶段 IFFT - 行变换

输入:5 路并行流通过 PLIO_front_i_0PLIO_front_i_4 进入 AIE 阵列。

处理

  1. AIE 内核接收数据,执行第一维 IFFT(假设为行方向,256 点 IFFT)
  2. 利用 AIE 的 SIMD 向量单元,每个周期可处理多个蝶形运算
  3. 5 路并行使 AIE 阵列的计算资源得到充分利用

输出:行变换结果通过 PLIO_front_o_0PLIO_front_o_4 输出到 PL 的 Transpose 内核。

阶段 3:Transpose - 数据重排枢纽

输入sig_i_0sig_i_4 接收来自 AIE 的行变换结果。

核心操作

  1. ifft_transpose_wrapper 内部维护一个二维缓冲结构(通常是 ping-pong buffer)
  2. 数据按行写入缓冲,然后按列读出(或反之,取决于转置方向)
  3. 5 路并行流通过特定的地址映射模式访问缓冲,确保无冲突读写

为什么必须转置? 二维 IFFT 要求先对行做 IFFT,再对列做 IFFT。但内存中的数据按行连续存储,直接访问列会导致极差的缓存局部性。转置操作将"列优先访问"转换为"行优先访问",使第二阶段 IFFT 能高效执行。

输出:转置后的数据通过 sig_o_0sig_o_4 输出,通过 PLIO_back_i_0PLIO_back_i_4 返回 AIE。

阶段 4:AIE 第二阶段 IFFT - 列变换

输入:转置后的数据通过 PLIO_back_i 端口进入 AIE。

处理

  1. AIE 执行第二维 IFFT(列方向,256 点 IFFT)
  2. 由于数据已转置,列访问变为连续的内存访问模式,AIE 可高效处理

输出:最终的二维 IFFT 结果通过 PLIO_back_o_0PLIO_back_o_4 输出到 DMA Sink。

阶段 5:DMA Sink - 数据出口 orchestration

输入sig_i_0sig_i_4 接收来自 AIE 的最终结果。

操作

  1. ifft_dma_snk_wrapper 接收 5 路并行流
  2. 内核将 5 路数据重新合并为连续的数据块
  3. 通过 m_axi 接口以突发写模式将结果写回 LPDDR

关键设计:DMA Sink 执行与 Source 相反的数据重组操作,确保最终写入 DDR 的数据格式符合上层软件预期。

模块职责与子模块划分

本模块由三个协同工作的子模块组成,形成完整的数据流管道:

1. dma_source_ingress_pipeline

职责:数据入口 orchestration,负责从 LPDDR 读取原始频域数据,转换为 5 路并行 AXI4-Stream 格式,注入 AIE 阵列。

核心组件ifft_dma_src_wrapper(HLS 内核)

技术要点

  • m_axi 接口突发读优化 DDR 带宽利用率
  • 数据分片(Striping)策略匹配 AIE 并行结构
  • axis 接口 5 路并行流生成

2. transpose_compute_stage

职责:二维 IFFT 的关键数据重排枢纽,执行矩阵转置操作,使行/列变换能够连续访问内存。

核心组件ifft_transpose_wrapper(HLS 内核)

技术要点

  • Ping-pong 缓冲实现无停顿流水线
  • 5 路并行地址映射避免访问冲突
  • hls::stream 深度优化匹配 AIE 数据率

3. dma_sink_egress_pipeline

职责:数据出口 orchestration,接收 AIE 处理完成的 5 路并行结果流,重组为连续数据块,写回 LPDDR。

核心组件ifft_dma_snk_wrapper(HLS 内核)

技术要点

  • 5 路流合并与数据对齐
  • m_axi 突发写最大化内存带宽
  • 与 Source 对称的数据重组逻辑

跨模块依赖关系

本模块位于系统集成的关键路径上,向上承接上层应用的数据请求,向下调用底层 HLS 内核和 AIE 图:

向上依赖(本模块依赖的外部模块)

模块 依赖关系 说明
AIE_Design_Graphs_and_Algorithms-large_scale_ifft2d_pipeline_and_support_blocks 强依赖 本模块的 AIE 处理部分依赖该模块的 IFFT 计算内核(ifft256 阶段和旋转子图)
AIE_ML_PL_HLS_Integration-prime_factor_fft_hls_kernels 参考依赖 DMA 和转置内核的设计参考了素因子 FFT 的 HLS 数据搬运模式

向下依赖(依赖本模块的外部模块)

本模块是系统集成的叶节点模块,主要被上层系统集成配置调用。在模块树中,它是 AIE_Design_System_Integration 的叶节点,通常被 Versal 平台的顶层系统集成配置所引用。

新贡献者需知:陷阱与最佳实践

⚠️ 关键陷阱

1. 五路流的数据对齐陷阱

5 路并行流的时序必须严格对齐。如果某一路因反压(back-pressure)停滞,整个管道将停滞。修改 HLS 代码时,必须确保所有 5 路流的 hls::stream 深度足够缓冲 AIE 与 PL 的速率差异。

2. 转置的地址计算溢出

转置内核的地址计算涉及 256×256 矩阵索引。使用 16 位整数在计算 row*256 + col 时可能发生溢出。确保地址计算使用 32 位或更宽的数据类型。

3. DMA 突发对齐要求

m_axi 接口的突发传输要求起始地址和数据长度对齐到突发边界(通常为 64 字节)。确保 DMA 内核的 buffer 指针和 size 满足对齐要求,否则可能引发总线错误或性能骤降。

4. AIE-PL 接口的时钟域 crossing

虽然本设计使用统一的 312.5 MHz 时钟,但如果修改设计使用不同时钟,必须注意 AIE PLIO 和 PL 逻辑之间的时钟域 crossing(CDC)问题。确保使用适当的 FIFO 或握手协议进行同步。

✅ 最佳实践

1. 模块化验证策略

本模块的三个子模块(DMA Source、Transpose、DMA Sink)可以独立进行 C/RTL 协同仿真。建议先单独验证每个 HLS 内核,确认功能正确后再进行系统集成。

2. 使用 hls::task 进行 DATAFLOW 建模

在 HLS 代码中,使用 hls::task(或 #pragma HLS DATAFLOW)建模数据流任务,明确表达 producer-consumer 关系。这有助于 HLS 工具识别并行性并生成高效的流水线架构。

3. 性能分析重点关注 PLIO 带宽

使用 Vitis Analyzer 分析设计时,重点关注 PLIO 接口的带宽利用率。如果某路 PLIO 的带宽远低于理论值(约 1.25 GB/s @ 312.5 MHz),可能表明存在反压或流控问题。

4. 文档化数据格式约定

DMA Source 和 Sink 对数据的解释方式(复数格式、样本排列顺序、5 路分片策略)必须文档化并与 AIE 侧保持一致。建议创建一个共享的 header 文件定义数据布局,避免双方假设不一致。

参考与延伸阅读

On this page