🏠

Polyphase Channelizer System Integration 模块详解

概述

Polyphase Channelizer System Integration 是一个高性能多相信道化器的完整系统级实现,专为 AMD Versal™ 自适应 SoC 设备设计。该模块展示了如何将 AI Engine (AIE) 的可编程逻辑与可编程逻辑 (PL) 资源协同工作,以实现高达 10.5 GSPS 输入采样率的多通道数字下变频处理。

想象一下,你有一个高速数据流(就像一条繁忙的高速公路),其中包含了16个不同频道的信号(就像16条并行的车道)。传统的做法是为每个频道单独设置一个接收器——这就像为每条车道建一座收费站,成本高昂且效率低下。多相信道化器采用了一种巧妙的"分而治之"策略:它使用一种数学上等效但更高效的架构,通过共享计算资源同时处理所有频道,就像一个智能交通枢纽,能够同时服务所有车道而无需重复建设基础设施。

该设计的核心挑战在于:如何在保持极高吞吐量的同时,优雅地处理数据重排序、循环缓冲和频率变换等复杂操作。这正是 AIE-PL 异构架构的价值所在——AIE 负责计算密集型的滤波和 DFT 运算,而 PL 则擅长灵活的数据路由和格式转换。


架构概览

整体数据流图

flowchart LR subgraph DDR["LPDDR Memory"] MEM[(Input/Output Buffers)] end subgraph PL["Programmable Logic (312.5 MHz)"] DMA_SRC["dma_stream_src
DMA Source Kernel"] --> PERMUTE_I["permute_i
Input Permutation"] PERMUTE_O["permute_o
Output Permutation"] --> CYCLIC["cyclic_shift
Cyclic Shift"] CYCLIC --> DMA_SNK["dma_snk
DMA Sink Kernel"] end subgraph AIE["AI Engine Array (1.25 GHz)"] FBANK["Filterbank
8 Tiles, 2 Channels/Tile"] DFT["IDFT (Matrix Multiply)
16 Tiles, 4x4 Array"] end MEM <-- AXI4 --> DMA_SRC PERMUTE_I -- 8 streams --> FBANK FBANK -- 8 streams --> PERMUTE_O CYCLIC -- 8 streams --> DFT DFT -- 8 streams --> DMA_SNK DMA_SNK <-- AXI4 --> MEM

核心组件职责

组件 类型 时钟频率 核心功能
dma_stream_src HLS Kernel (PL) 312.5 MHz 从 LPDDR 加载输入样本,通过 7 路 AXI Stream 输出到信道化器
m16_ssr8_permute_fb_i HLS Kernel (PL) 312.5 MHz 执行"蛇形移位"和"发牌式"置换,为滤波器组准备正确顺序的数据
m16_ssr8_filterbank_graph AIE Graph 1.25 GHz 8 个 AIE Tile 实现多相 FIR 滤波,每个 Tile 处理 2 个通道
m16_ssr8_permute_fb_o HLS Kernel (PL) 312.5 MHz 移除滤波器组的置换,恢复正确的通道顺序
m16_ssr8_cyclic_shift HLS Kernel (PL) 312.5 MHz 应用周期性循环移位,补偿 IDFT 的频率相关相移
m16_ssr8_dft_graph AIE Graph 1.25 GHz 16 个 AIE Tile 以 4×4 阵列实现矩阵乘法形式的 IDFT
dma_stream_snk HLS Kernel (PL) 312.5 MHz 捕获输出流,支持选择性存储和 DFT 输出置换模式

关键设计决策与权衡

1. SSR=8 的超采样率选择

问题背景:信道化器需要处理 10.5 GSPS 的输入速率,而 AIE 的典型时钟为 1.0-1.3 GHz。这意味着每个时钟周期需要处理多个样本。

设计选择:采用 SSR (Super Sample Rate) = 8,即每个时钟周期处理 8 个样本。

权衡分析

  • SSR=4:AIE 时钟需达 2.625 GHz,超出器件能力范围
  • SSR=8:AIE 时钟约 1.25 GHz,在 -2M 速度等级器件的可行范围内
  • SSR=16:增加 I/O 复杂度,但降低单路带宽压力;本设计未采用因为 M=16 与 SSR=8 配合良好

关键约束:选择 P/Q = 8/7 的过采样比时,输出采样率为 750 MSPS = 10.5G × 8/7 / 16。这要求输入采样率 Fs 包含因子 Q=7,以确保输出速率为整数个时钟周期。

2. AIE vs PL 的功能划分

核心原则:计算密集型任务交给 AIE,数据重排序和路由交给 PL。

功能块 实现位置 理由
Circular Buffer 逻辑 PL (permute_fb_i) 需要复杂的"蛇形移位"和状态管理,PL 的路由更灵活
Polyphase FIR AIE (8 tiles) 高度并行的 MAC 运算,AIE 每周期 16 次 MAC 的高效计算能力
Cyclic Shift PL (cyclic_shift) 纯数据置换无计算,PL 更适合
IDFT/IFFT AIE (16 tiles) 采用矩阵乘法而非蝶形运算,充分利用 AIE 的向量处理能力

为什么不用传统 FFT 架构? 传统 Radix-2 FFT 需要 4 级蝶形运算(共 32 个蝶形),在 2 周期内完成 16 点变换对地址生成和流水线控制要求极高。本设计采用直接矩阵乘法实现 IDFT:将 [1×16] × [16×16] 的向量-矩阵乘分解为 32 个 [1×2] × [2×4] 的 OP 操作,每个 AIE Tile 每周期完成 1 个 OP,16 个 Tile 正好在 2 周期内完成整个变换。

3. 滤波器组的"发牌"映射策略

这是本设计最精妙的部分之一。Circular Buffer 的 M×K 数组中,绿色矩形区域内的样本时间索引是"混乱"的——它们不像普通 FIR 那样呈现时间平移特性。但黄色框内的样本却表现出正常的时移特性!

解决方案

  1. 物理 Tile 与逻辑通道的动态映射:不同时间周期,同一个逻辑通道(某一行)的数据被"发牌"到不同的物理 AIE Tile
  2. PL 负责发牌和收牌permute_fb_i 按特定模式分发数据,permute_fb_o 按逆模式收集结果
  3. AIE Tile 内部保持简单:每个 Tile 看到的数据始终具有正常的时间平移特性,可用标准 FIR 实现

这种设计让 AIE 代码保持简洁高效,而将复杂的调度逻辑卸载到 PL 的布线资源中——PL 的 LUT 和 MUX 非常适合这种确定性置换。

4. 时钟域与数据宽度设计

层级 时钟 数据宽度 说明
PL Kernels 312.5 MHz 128-bit AXI4-Stream 4 个 cint16 样本打包在一个 128-bit 事务中
AIE PLIO 1.25 GHz (内部) 64-bit PLIO Vitis 自动处理跨时钟域转换
AIE Array 1.25 GHz 32-bit per sample cint16 类型,复数运算原生支持

为什么选择 312.5 MHz?

  • 312.5 MHz × 4 samples/cycle = 1.25 Gsamples/s per stream
  • 7 路输入流合计 8.75 Gsamples/s,匹配 10.5 GSPS × 7/8 = 9.1875 Gsamples/s 的有效需求(考虑 P/Q=8/7 的过采样)
  • 是 1.25 GHz AIE 时钟的 1/4,简化跨时钟域设计

子模块详细说明

DMA Stream Endpoints HLS Kernels

包含 dma_stream_srcdma_stream_snk 两个核:

  • Source:从 LPDDR 通过 AXI4 突发读取样本,存入内部 BRAM 缓冲区,然后通过 7 路 AXI Stream 输出
  • Sink:从 8 路 AXI Stream 接收样本,支持循环选择和 DFT 置换模式,最终写回 LPDDR

SSR8 Reordering and Cyclic Shift HLS Kernels

包含三个关键的 PL 数据重排序核:

  • m16_ssr8_permute_fb_i:输入置换核,实现 Circular Buffer 的"蛇形移位"和"发牌"逻辑
  • m16_ssr8_permute_fb_o:输出置换核,逆向恢复通道顺序
  • m16_ssr8_cyclic_shift:循环移位核,基于 8 状态 FSM 补偿 IDFT 相移

Vitis Final System Kernel Instances

system.cfg 定义了完整的系统集成配置:

  • 5 个 HLS PL 核的实例化和连接关系
  • 32 个 PLIO 接口(16 入/16 出)连接到 AIE Graph
  • 统一 312.5 MHz 时钟域配置
  • AXI Stream 和 AXI4 内存接口的完整连接拓扑

数据流端到端追踪

输入路径:LPDDR → Filterbank

LPDDR (线性样本序列)
    ↓ AXI4 burst read
DMA_SRC internal BRAM[7][512] (stream-oriented layout)
    ↓ 7 × AXI4-Stream @ 312.5 MHz
PERMUTE_I unpacks 128-bit → 4×cint16 samples
    ↓ 状态驱动的 serpentine shift + card-dealing permutation
PERMUTE_I outputs 8 × AXI4-Stream
    ↓ PLIO adapters
AIE Filterbank (8 tiles, each processes 2 channels interleaved)

关键细节permute_fb_iunpack_samples 函数维护了一个 2 样本的状态历史(prev_data),用于处理连续数据块之间的重叠。这是因为 Circular Buffer 每次引入 S = M×Q/P = 14 个新样本,剩余 2 个来自历史。

计算路径:Filterbank → IDFT

Filterbank Output (8 streams, permuted channel order)
    ↓
PERMUTE_O removes card-dealing permutation
    ↓ latency alignment (2 cycles)
CYCLIC_SHIFT applies state-dependent circular shift
    ↓ 8 × AXI4-Stream
AIE IDFT Input (broadcast to 4 rows of the 4×4 tile array)
    ↓ cascade accumulation
IDFT Output (bottom row produces final results)
    ↓
DMA_SNK captures with optional dft_perm reordering

关键细节:IDFT 采用广播+累加拓扑。输入数据通过 stream 广播到 4 行的所有 Tile,每行内部通过 cascade stream 垂直累加。底部行的 Tile 输出最终结果。这种架构实现了完全的计算并行度,每个 Tile 的利用率达 100%。


性能特征与瓶颈分析

理论吞吐量

阶段 计算需求 实际能力 利用率
Filterbank 16 channels × 8 taps = 128 MACs/sample 8 tiles × 16 MAC/cycle × 50% duty = 64 MAC/cycle I/O bound (~50%)
IDFT 16×16 complex multiply = 256 muls/sample 16 tiles × 8 muls/cycle = 128 muls/cycle Compute bound (100%)

Filterbank 是 I/O 受限 的:每个 Tile 每 4 周期只收到 4 个样本,尽管它有每周期 16 MAC 的计算能力。这是 VLIW 架构的限制——无法在一个 Tile 内调度 4 个滤波器的 II=8 循环。

IDFT 是 计算受限 的:精心设计的矩阵乘法模式让每个 Tile 每周期都在执行有效的 MAC 操作,没有气泡。

资源占用

根据 README 中的 die sizing 图:

  • AIE Tiles:24 个(Filterbank 8 个 + IDFT 16 个)
  • AIE Buffers:22 个 Tile 用于缓冲
  • PLIO:32 个(16 入/16 出)
  • PL Resources:主要由 5 个 HLS 核消耗,包括 BRAM 用于内部缓冲和 LUT 用于置换逻辑

新贡献者注意事项

1. 隐式契约与前置条件

HLS Kernels 的数组分区:所有关键数组都使用了 #pragma HLS array_partition,这保证了并行访问能力,但也意味着:

  • 修改数组维度时必须同步更新 partition 指令
  • 未分区的数组会成为流水线瓶颈(II 增加)

AIE Kernel 的参数注册REGISTER_PARAMETER 宏用于将构造函数参数暴露给 AIE 编译器:

static void registerKernelClass( void )
{
  REGISTER_FUNCTION( polyphase_fir::run_i );
  REGISTER_PARAMETER( taps0 );  // 必须注册所有指针/引用参数
  REGISTER_PARAMETER( taps1 );
}

忘记注册会导致运行时参数传递失败。

2. 状态管理的静态变量陷阱

HLS 内核中的 static 变量用于在调用之间保持状态(如 FSM 状态、乒乓缓冲区索引):

static ap_uint<3> fsm_state = 0;
#pragma HLS reset variable=fsm_state  // 确保可综合复位

注意

  • 必须使用 #pragma HLS reset 否则综合后行为不可预期
  • 静态变量的初始化只在仿真中有效,硬件上电后是未定义的
  • 多实例化核时,每个实例有独立的静态变量副本

3. AIE 的 VLIW 限制

Filterbank 设计中提到:虽然每个 AIE Tile 有两路输入和两路输出 stream,但 VLIW 硬件限制只能同时使用:

  • 两入一出,或
  • 一入两出,或
  • 一入一出

这就是为什么需要 8 个 Tile 而不是 4 个——无法在单个 Tile 内调度 II=8 的四滤波器循环。

4. 数据类型一致性

整个系统中 cint16 的使用必须保持一致:

  • PL HLS:ap_uint<32> 表示一个 cint16(实部 16bit + 虚部 16bit)
  • PL HLS 打包:128-bit AXI4-Stream = 4 × cint16
  • AIE:cint16 原生类型
  • 位宽不匹配会导致数据解释错误,且难以调试

5. 时序收敛风险点

  • m16_ssr8_cyclic_shift 设置了 clock_uncertainty=27%,表明这是一个时序紧张的设计
  • 置换核中的大查找表(permute[NSTATE][M] = 8×16)可能导致长组合逻辑延迟
  • 如果修改置换模式,务必重新检查时序报告

与其他模块的关系

上游依赖

下游使用者

  • channelizer_ifft_and_tdm_fir_graphs/channelizer_graph_application:本模块是信道化器应用的底层实现基础

相关教程


参考资料

  1. MATLAB Model: model/channelizer.mlapp 提供了算法的黄金参考模型
  2. System Configuration: vitis/final/system.cfg 完整系统连接配置
  3. AIE Graph: aie/m16_ssr8/m16_ssr8_graph.h 顶层 AIE 图定义
  4. README: 原始教程文档位于 04-Polyphase-Channelizer/README.md
On this page