FFT的全称是快速傅里叶变换,将时域信号转换为频域,相比传统的DFT计算复杂度更低,为现代通信、音频处理和图像分析提供核心数学支撑。
如需了解DFT和FFT,可阅读前两篇文章:
3分钟掌握离散傅里叶变换(DFT):数字世界的“频率解码器”
快速傅里叶变换(FFT):从数学公式到5G信号,揭开数字世界的“频率密码”
FFT的蝶形计算,使用Verilog手搓一个,开发时间较长,且灵活性较差,不如直接调用FPGA厂商的FFT IP,今天分享一下vivado FFT IP,包括配置要点以及使用难点,让读者快速上手。
一、VIVADO FFT IP核 基本介绍
Vivado FFT IP 高效实现了快速傅里叶变换(FFT)和逆变换(IFFT),支持多种配置,适用于实时信号处理、通信系统等场景。
1、主要功能与特点
算法支持:支持FFT和IFFT,可配置为正向或反向变换。
点数灵活:支持2^N点(基2)或混合基(如基4、基2),点数范围通常为 8到65536。
数据精度:
- 定点数(Fixed-point):资源占用少,适合高性能设计。
- 块浮点(Block Floating Point):动态调整小数位,平衡精度与资源。
流水线架构:
- Pipelined Streaming I/O:高吞吐量,适合连续数据流。
- Radix-2 Burst I/O:资源较少,但处理需分阶段完成。
- Radix-4 Burst I/O:更高计算效率,但延迟可能增加。
实时配置:支持运行时动态调整FFT长度和方向。
缩放控制:提供自动或手动缩放,防止数据溢出。
2、关键配置参数
变换长度(N):FFT/IFFT的点数(如1024点)。
数据位宽:输入/输出信号的位宽(如16位定点数)。
旋转因子位宽:影响计算精度,通常与数据位宽匹配。
时钟频率与吞吐量:根据架构选择优化速度或资源。
存储器选项:使用块RAM或分布式RAM存储中间数据。
3、接口说明
AXI4-Stream接口:标准流式接口,易于与其他IP核集成。
输入:`S_AXIS_DATA`(时域数据)。
输出:`M_AXIS_DATA`(频域数据),`M_AXIS_STATUS`(状态信息)。
配置接口:可选AXI4-Lite接口,用于动态调整参数(如变换方向)。
事件信号:如`event_frame_started`标记帧处理开始。
详细介绍:
aclk:输入时钟信号
aclken: 时钟使能,可选,一般不选
aresetn: 同步清零,可选,建议选上,需要保持两个周期以上的低电平才有效,可复位整个ip
s_axis_config_tdata:配置IP核数据,做FFT运算设置1,做IFFT运算设置0,其它详细配置,可参考官方手册。
s_axis_config_tvalid: 配置数据输入有效,一般直接置1。
s_axis_config_tready:表示 IP是否已准备好接收配置数据。
s_axis_data_tready:表示IP核是否已准备好接收时域数据输入。
s_axis_data_tdata:输入时域数据,[31:16]是虚部,[15:0]是实部。
s_axis_data_tvalid:输入时域数据有效。
s_axis_data_tlast:输入时域数据结束信号。
m_axis_data_tdata:输出的频谱数据,[47:24]对应的是虚部数据,[23:0]对应的是实部数据,高位补符号位。
m_axis_data_tvalid:输出频谱数据有效
m_axis_data_tuser:输出FFT的索引值,该值*fs/N即为对应频点,N为FFT点数。
m_axis_data_tready:表示从设备已准备好接收频谱数据传输。
二、配置IP核
1、启动vivado工程
打开IP Catalog,搜索“FFT”,双击“Fast Fourier Transform”。
配置主界面:
左边是IP核接口示意图(IP Symbol)、资源消耗信息(Implementation Details)和计算延时(Latency)。
右边是Configuration、Implementation和Detailed Implementation三个标签卡。
3、Configuration配置界面
Number of Channels:通道数设置,选择 1 到 12 之间的通道数。 这里我们不需要多通道,设为1即可。
Transform Length:FFT的变换点数,从 8 到 65536 的所有 2 的幂均可用,如果选择了最下面的‘run time configurable transdorm legth’,则该参数是FFT变化的最大长度,一般不选。这里我们选择设置1024点。
Target Clock Frequency:目标时钟频率,这个设置越大计算速度越快。这里我们设定为250mhz
Target Data Throughput:目标数据吞吐量。这里我们设定为50。
Architecture Choice:FFT结构选择计算速度和消耗的资源依次减少,包括自动模式,Pipelined, StreamingI/O(流水线Streaming),Radix-4, Burst /0
(基4 Burst),Radix-2, Burst /0
(基2 Burst)和Radix-2 Lite, Burst I/0
(轻量级基2 Burst),可在左侧Latency界面查看延迟,根据实际工程需求选择。这里我们选择“基2 Burst”。
4、Implementation配置界面
Data Format:FFT的数据格式,可选定点Fixed Point或浮点Float Point,默认选Fixed Point;
Scaling Options:缩放选项
Scaled 缩放
,防止数据溢出,决定了数据在 FFT 阶段之间的缩放方式,可配置。 unscaled 不做缩放
,输出位宽会非常大,一般情况为了后续的信号处理,不建议用。 Block Floating-Point 块浮点
FFT计算内部都采用浮点数据格式,输入输出位宽一致,便于调用,没有特殊需求可用这个。
Rounding Modes:舍入模式
truncated :直接截断 convergent rounding:收敛性舍入,当数字的小数部分正好等于二分之一时,如果数字是奇数,则收敛舍入向上舍入;如果数字是偶数,则向下舍入。
Precision Options:精度选项
Input data Width 输入数据位宽,可独立配置为 8 至 34 位(含)的宽度 phase factors,相位因子,可独立配置为 8 至 34 位(含)的宽度。
Control Signals控制信号配置
时钟使能 ( aclken ) 和同步清除 ( aresetn ) 是可选引脚。
复位信号aresetn要勾选,至少保持两个时钟的低电平,可复位整个IP。
Output Ordering输出数据位序排序
Bit/Digit Reversed Order,位/数字逆序 Natural Order,自然顺序
Optional Output Fields 可选输出字段
XK_INDEX是可选字段“数据输出通道”, 是否输出FFT 变换的结果索引,可在m_axis_data_user中有相应的字段。 OVFLO是数据输出通道和状态通道中的可选字段,是变换中溢出的指示信号,对应event_fft_overflow.
Throttle Schemes 节流方案选择性能和数据时序要求之间的权衡。
Real Time 实时模式通常提供更小、更快的设计,但对必须提供和使用数据的时间有严格的限制。
Not Real Time 非实时模式没有这样的限制,但设计可能更大、更慢。
5、Detailed Implementation配置界面
Memory Options:内存选项,受数据格式和相位因子影响,可配置选择块 RAM 或分布式 RAM。
Optimize Options:优化选项Complex Multipliers 复数乘法器
Use CLB logic,使用CLB逻辑,适用于性能要求较低的目标应用程序或具有很少 DSP 片的目标设备。 Use 3-multiplier structure (resource optimization),使用3乘法结构(资源优化),所有复数乘法器均使用三个实数乘法、五个加/减结构,其中乘法器使用 DSP Slice。这减少了 DSP 切片数量,但使用了一些切片逻辑。这种结构可以利用DSP Slice预加器来减少或消除对额外Slice逻辑的需要,并提高性能。 Use 4-multiplier structure (performance optimization) 使用4乘法器结构(性能优化),所有复数乘法器均使用四个实数乘法、两个加/减结构,并使用 DSP 片。这种结构可产生最高的时钟性能,但需要更多的专用乘法器。在具有 DSP Slice 的设备中,加/减运算在 DSP Slice 内实现。对于原生浮点数据格式,使用 4 乘法器结构。
Butterfly Arithmetic 蝶形运算
Use CLB logic 使用CLB逻辑 Use XtremeDSP Slices 使用 XtremeDSP 切片,此选项强制使用 DSP 片中的加法器/减法器来实现所有蝶形级。
6、左侧资源消耗信息(Implementation Details)和计算延时(Latency)
1、找到IP调用接口
xfft_0 your_instance_name ( .aclk(aclk), // input wire aclk .aresetn(aresetn), // input wire aresetn .s_axis_config_tdata(s_axis_config_tdata), // input wire [7 : 0] s_axis_config_tdata .s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid .s_axis_config_tready(s_axis_config_tready), // output wire s_axis_config_tready .s_axis_data_tdata(s_axis_data_tdata), // input wire [31 : 0] s_axis_data_tdata .s_axis_data_tvalid(s_axis_data_tvalid), // input wire s_axis_data_tvalid .s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready .s_axis_data_tlast(s_axis_data_tlast), // input wire s_axis_data_tlast .m_axis_data_tdata(m_axis_data_tdata), // output wire [47 : 0] m_axis_data_tdata .m_axis_data_tuser(m_axis_data_tuser), // output wire [15 : 0] m_axis_data_tuser .m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid .m_axis_data_tready(m_axis_data_tready), // input wire m_axis_data_tready .m_axis_data_tlast(m_axis_data_tlast), // output wire m_axis_data_tlast .event_frame_started(event_frame_started), // output wire event_frame_started .event_tlast_unexpected(event_tlast_unexpected), // output wire event_tlast_unexpected .event_tlast_missing(event_tlast_missing), // output wire event_tlast_missing .event_status_channel_halt(event_status_channel_halt), // output wire event_status_channel_halt .event_data_in_channel_halt(event_data_in_channel_halt), // output wire event_data_in_channel_halt .event_data_out_channel_halt(event_data_out_channel_halt) // output wire event_data_out_channel_halt );
daima
2、测试运行效果
2Mhz信号频谱
20Mhz信号频谱
文章来源:FPGA入门到精通