前言
傅里叶变换能将信号的时域变换到频域。在频域中,系统响应等于信号与系统传函的频域相乘(时域上是卷积)。相比于直接在时域做卷积,先进行傅里叶变换,再在频域相乘,最后通过逆傅里叶变换反变换回来的步骤看似更长,但在工程技术上却相对容易实现。
传统的傅里叶变换属于工程数学范畴,主要针对连续时间信号。离散傅里叶变换(DFT)针对离散时间信号。DFT 算法时间复杂度为 O(n^2),快速傅里叶变换(FFT)将其优化至 O(nlogn)。
本文主要以 FPGA 中实现快速傅里叶变换为主,介绍如何配置 FFT IP 核并获取频谱数据。
一、原理与目的
1. 傅里叶变换
傅里叶变换是将任意信号通过多种不同频率的正弦信号叠加而成。不同频率的正弦信号具有不同的幅值,通过频率与幅值的一一对应,得到任意信号的幅频特性曲线。
2. 快速傅里叶变换
在傅里叶变换基础上加入对离散时间信号的应用,即离散傅里叶变换;对 DFT 算法进行优化,得到快速傅里叶变换(FFT)。FFT 的核心是蝶形运算和旋转因子。重点关注二进制逆序排列的操作,以及时域抽取、频域抽取中的逆序排列位置。
3. 目的
学会配置 FFT,知道如何获取频谱数据,并利用频谱数据进行后续操作。
二、配置 FFT
在 IP Catalog 中搜索 FFT,双击选项进行命名。从上到下解读每个选项:
1. Transform
- Length(长度):即 N 点 FFT。N 的大小与采样频率 Fs 和频率分辨率 dF 的关系是 dF = Fs / N。N 越大,频率分辨率越高,但占用资源也越大。根据资源情况选择合适长度,例如 1024 点。
- Direction(方向):指 FFT 运算方向,包括正向(Forward)、反向(Reverse)和双向(Bi-directional)。此处选择双向变换。
2. I/O
- Data Flow(数据流):代表输入方式。Streaming(流水线)具有高速度,Burst(爆发)占用资源低。由于对内存理解有限,选择最直接的 Streaming 输入方式。虽然占用较高资源,但运算速度快,输入一个周期数据后下一个周期即可输出。
- Input Order/Output Order:选择 Streaming 后,只能选择 Nature(自然数)。
3. Data and Twiddle
- Representation(表示):Fixed Point(固定点)资源消耗最低但有溢出风险;Single Floating Point(单浮点)精度高但资源占用多;Block Floating Point(块浮点)介于两者之间,是大部分 FFT 模块的配置选择。
- Data Input Width/Twiddle Width:位宽越宽,精度越高。
三、实例化
生成 HDL 工作后确认模块引脚。实例化分为前期数据准备、芯片接入、后期数据处理三个步骤。
1. 芯片接入
- clk/reset_n:时钟信号和低电平复位信号。
- inverse:0 代表正变换,1 代表逆变换。
- sink_valid:直接输入 1。
- sink_ready:芯片给外部发出可以输入信号的'准备好了'信号。
- sink_error:直接输入 2'b00。高电平代表引脚功能生效(数据错误),不进行运算。
- sink_sop/sink_eop:输入信号的起始标识和结束标识,一般间隔为设置的 N 点 FFT 的 N 倍时钟,高电平有效。
- sink_real/sink_imag:输入信号的实部和虚部。正变换通常只有实部,虚部置 0;反变换分别放入实部和虚部。
- source_exp:配合 source_real 和 source_imag 使用,提供公共指数值。

