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

