返回竞赛作品

Competition · 2023

基于 FPGA 的 FFT 算法并行优化

第十二届中国软件杯 · 基 4 MDC 流水线

把基线基 2 SDF 换成 4 路并行的基 4 MDC。1024 点在同样 20 ns 时钟下从 2057 拍降到 513 拍,约 4.01 倍;末级可切基 4 / 基 8,覆盖 16 点以上的 2ⁿ 点。

时间:2023 · 本科三年级

职责:算法负责人

奖项:第十二届「中国软件杯」大学生软件设计大赛 · 国家级二等奖

国家二等奖
中国软件杯
4.01×
相对基 2 SDF
513 拍
1024 点延迟
~76 dB
定点 SNR

01

项目背景

场景与任务

通信、雷达和部分机载场景要把连续数据流做实时谱分析。指令流平台吞吐不够,GPU 功耗偏高,赛题要求把 FFT 做到 FPGA 上,并相对基线再提速。

赛题要求

赛题要求两件事:1024 点在相同时钟下相对基 2 SDF 提速 4 倍;算法能伸缩到 2048、4096。验证落在 Vivado 2018.3 + Modelsim 功能仿真,用 MATLAB 出激励和 SNR。

为什么难

  • 全并行面积太大,基 2 SDF 单路吞吐又不够 4 倍。
  • 纯基 4 只能算 4ⁿ 点,2048 这类 2ⁿ 点要补零,浪费拍数。
  • 4 路数据必须按级对齐,换向或旋转因子错一拍,频谱就对不上。
  • 定点复乘会溢出、截位,必须和 MATLAB 金标准对上。

02

系统架构

顶层按点数生成 log₄N 级流水。中间级是标准 MDC 单元,末级是基 4/8 蝶形。每级 4 路并行:蝶形 → 打拍 → 复乘 → 延迟 → 换向 → 再延迟。

系统架构:4路输入经多级MDC流水和基4/8末级后4路输出;单级内蝶形、复乘、换向由控制和ROM驱动
顶层按点数展开流水线。中间级走标准 MDC,末级接基 4/8。
基4蝶形:四路输入进入蝶形单元,F1直通,F2到F4再乘旋转因子
基 4 蝶形一次吃齐 4 点。第 1 路 W=1 直通,后三路再复乘。
四路换向:data_sel 四态循环,把行排列转成列排列
换向按 S0–S3 循环,把行排列转成列排列,对齐下一级蝶形。

第一路旋转因子恒为 1,不进复乘。控制模块用同一个计数器同时给出换向选择和旋转因子地址。

03

核心系统设计

01

用 R4MDC 换基线 R2SDF

问题:基 2 SDF 单路串行,1024 点要 2057 拍,到不了赛题的 4 倍。

改动:改成 4 路 Multi-path Delay Commutator,按 log₄N 级流水;1024 点 5 级。

效果:同样 20 ns 时钟,50 ns 进到 10310 ns 出,共 513 拍,相对基线 4.01 倍。

02

基 4 蝶形一次吃 4 点

问题:基 2 级数多,复乘次数也多。

改动:每级用基 4 加减完成复加;第 1 路 W=1 直通,另外 3 路再复乘。

效果:复乘次数大约是基 2 的 3/4,每级只留 3 个复数乘法器。

03

延迟换向,把 4 路对齐

问题:4 路到达时刻不同,直接进下一级会乘错旋转因子。

改动:复乘后按 D、2D、3D 延迟;换向做行列转置;再延迟收齐。控制 FSM 和一个计数器同时出 data_sel 和旋转因子地址。

效果:各级数据对得上,控制流和数据流拆开,少占一套计数逻辑。

04

末级基 4/8,解决伸缩

问题:传统基 4 MDC 只能算 4ⁿ 点。2048 要补零,多算很多拍。

改动:末级改成基 4/8:4ⁿ 只走基 4;2ⁿ 但非 4ⁿ 时再补一级基 2(W₈¹ / W₈³)。

效果:同一套顶层覆盖 16 点以上任意 2ⁿ,2048 / 4096 不用另开工程。

05

旋转因子只存 N/8+1

问题:离线存满 N 个旋转因子太占 ROM;在线生成又拉长关键路径。

改动:MATLAB 预生成前 N/8+1 点;其余按八分圆对称做保留、取反或实虚互换。

效果:存储从 N 降到 N/8+1,查表延迟仍是一拍。

06

定点复乘防溢出

问题:64 bit 补码乘完会超出位宽,截位不当频谱会歪。

改动:数据与旋转因子都用 32 实 + 32 虚;旋转因子走 Q 格式,复乘后右移 16 再截位。

效果:三组 1024 点双音 SNR 约 76 dB,和 MATLAB 金标准对得上。

末级基4/8:基4之后按选通信号决定是否再做基2
末级。4ⁿ 直接出基 4;否则再乘 W₈ 做基 2。
旋转因子按八分圆分成 A 到 H 八个区,只存 A 区
只存 A 区。B–F 由对称性生成。

04

仿真与验证

验证分三步:先用 Modelsim 看模块对不对,再量整条流水线从进到出的拍数,最后把输出拉回 MATLAB 对频谱和 SNR。激励是双音信号,放大 1000 倍写成 64 bit 定点。金标准是自写基 2 DIF。差值超过 200 报警。工具是 Vivado 2018.3 和 Modelsim DE-64 10.6c。

4.01×
加速比

2057 / 513,相对基 2 SDF

513 拍
1024 点延迟

时钟 20 ns,50 ns 进到 10310 ns 出

~76 dB
1024 点 SNR

三组双音,差值阈值 200

16–4096
可配点数

2048 / 4096 点 SNR 仍约 75 dB

组 1 · 1 kHz

200 + 300 Hz 等幅双音,1024 点。超阈值 0 处,SNR 75.94 dB。

组 2 · 1 MHz

200 k + 300 kHz,1024 点。超阈值 0 处,SNR 75.94 dB。

组 3 · 100 kHz

10 k + 20 kHz,幅度 1:2。超阈值 1 处,SNR 76.05 dB。

伸缩

同组 1 激励扩到 2048 / 4096 点,SNR 75.01 / 75.82 dB。

模块级波形

先确认控制、蝶形、换向和单级流水各自能跑通,再接到顶层。下面四张都是 Modelsim 功能仿真,黑底绿线是信号取值。

  • 控制:data_sel 四路错开一拍,旋转因子地址跟着计数器走。
  • 蝶形:data_i_en 拉高后,四路立刻拆成实虚部并算出 data_o。
  • 换向:data_sel 按 0–3 循环时,四路输出完成行列转置。
  • 单级:蝶形 → 复乘 → 延迟 → 换向,中间量依次出现再传到 data_o。

控制模块

Modelsim:控制模块产生 clk_1、data_o_en、data_sel 和旋转因子地址
黄线附近 data_o_en 拉高。data_sel_1…4 同时跳到下一态(2→3、1→2、0→1、3→0),twiddle_addr 同步更新。

基 4 蝶形

Modelsim:基4蝶形四路输入被拆成实虚部并正确组合输出
data_i_en=1 时,data_i_real / data_i_imag 从 64 bit 输入切开,data_o_1…4 在同一拍给出复加结果。

四路换向

Modelsim:data_sel 四态循环下四路数据完成重排
data_sel 以 0,1,2,3 循环。对照 data_i 和 data_o,同一拍四路位置在轮转,对应 S0–S3 的行列转置。

单级流水线

Modelsim:单级流水线从蝶形、复乘、延迟到换向的完整数据流
从左到右看 data_bf → data_mul → data_mul_delay → data_change → data_o。延迟拍过完,data_o_en 才拉高。

顶层时序与 4 倍加速

模块接好后,用 16 点看延迟是否对得上理论;再用 1024 点量整次变换的拍数。时钟 20 ns。基线基 2 SDF 要 2057 拍,这里要压到 514 拍以内。

  • 16 点:输入使能结束后再过几拍,四路输出才出现,延迟和级数相符。
  • 1024 点输入:50 ns 开始灌 4 路,对应报告里的起始光标。
  • 1024 点输出:约 10310 ns 收口。 (10310−50)/20 = 513 拍,2057/513 ≈ 4.01 倍。

16 点顶层

Modelsim:16点顶层四路输入后延迟数拍再四路输出
data_i_en 在前半段为高,data_o_en 错后才拉高。用来核对流水线填满所需拍数,而不是用来算 4 倍加速。

1024 点 · 输入起点

Modelsim:1024点测试从 50 ns 开始灌入四路数据
黄线在 50 ns。rstn 已释放,data_i_en 拉高,四路 data_i 开始进数。加速比从这里起算。

1024 点 · 输出终点

Modelsim:1024点测试在 10310 ns 附近输出结束
黄线在 10310 ns。data_o_en 仍有效,四路 data_o 即将收完。50 ns → 10310 ns 共 513 拍。

频谱对照与 SNR

硬件输出写成 test_real_out / test_imag_out,再送回 MATLAB。上面一张是金标准,下面一张是流水线 FFT。谱峰位置和相对幅度对得上,再算 SNR。

  • 组 1:200 Hz 和 300 Hz 各一根谱线,两侧幅度差在小数点后,SNR 75.94 dB。
  • 组 3:10 kHz / 20 kHz,幅度约 1:2,用来看定点有没有把小峰吃掉,SNR 76.05 dB。

组 1 · 等幅双音

1024点等幅双音:MATLAB 与流水线 FFT 频谱对齐在 200 Hz 和 300 Hz
采样率 1 kHz,1024 点。上下两图峰都在 200.2 / 299.8 Hz,幅度约 937。超阈值 0 处。

组 3 · 幅度 1:2

幅度1:2双音:MATLAB 与流水线 FFT 都在 10 kHz 和 20 kHz 出峰
采样率 100 kHz。10 kHz 矮峰、20 kHz 高峰,比例约 1:2。超阈值 1 处,SNR 仍有 76.05 dB。

05

个人职责

主责

算法负责人:把基线从 R2SDF 换成 R4MDC,推 4 倍加速对应的拍数,设计边界对齐、末级混合基和旋转因子压缩,并用 MATLAB 金标准卡 SNR。

VerilogR4MDC混合基定点VivadoModelsimMATLAB

06

证书

第十二届中国软件杯决赛国家级二等奖,点击可查看原件 PDF。

获奖证书

第十二届中国软件杯 · 国家级二等奖 · 2023 年 8 月
第十二届中国软件杯 · 国家级二等奖 · 2023 年 8 月