说明:通过对比Matlab实践来运用Xilinx FFT IP核实现复数的FFT。
代码下载:Xilinx FFT IP核 Verilog代码实现
工程下载:FFT工程
主要包括配置接口、时域数据输入接口、时钟复位接口、频域数据输出接口、状态接口。
IP核主要端口介绍:
名称 | 方向 | 说明 |
---|---|---|
aclk | 输入 | 模块工作时钟,上升沿有效 |
aclken | 输入 | 时钟使能信号,高电平有效,低电平时内核暂停工作,可通过此信号降低内核运行的最大时钟频率 |
aresetn | 输入 | 低电平同步复位信号,优先级高于aclken,低电平至少持续两个时钟周期 |
配置: | ||
s_axis_config_tvalid | 输入 | 配置通道的 tvalid,由外部主机断言以表示它能够提供数据 |
s_axis_config_tready | 输出 | 配置通道的 tready,由内核断言以表示它已准备好接收数据 |
s_axis_config_tdata | 输入 | 配置通道的tdata,携带配置信息,NFFT、FWD/INV、CP_LEN和SCALE_SCH |
输入数据: | ||
s_axis_data_tvalid | 输入 | 输入数据通道tvalid,由外部主机断言以表示它能够提供数据 |
s_axis_data_tready | 输出 | 输入数据通道tready,由内核断言以表示它能够接收数据 |
s_axis_data_tdata | 输入 | 输入数据通道tdara,由外部主机提供待处理的数据 |
s_axis_data_tlast | 输入 | 输入数据通道tdara,由外部主机断言表示最后一组数据。 只在生成事件event_tlast_unexpected 和 event_tlast_missing时,内核才使用它 |
输出数据: | ||
m_axis_data_tvalid | 输出 | 输出数据通道tvalid,由内核断言表示它能够提供数据 |
m_axis_data_tready | 输入 | 输出数据通道tready,由外部丛机断言表示它能够接收数据 |
m_axis_data_tdata | 输出 | 输出数据通道tdata,由内核提供FFT后的数据 |
m_axis_data_tuser | 输出 | 输出数据通道tuser,由内核提供XK_INDEX,OVFLO,BLK_EXP信息 |
m_axis_data_tlast | 输出 | 数据数据通道tlast,由内核断言表示最后一个输出数据 |
… |
s_axis_data_tdata 输入数据格式:
根据你的配置比如1024个点,每个点为32bit,高16bit为虚部,低16bit为实部。
s_axis_config_tdata 配置数据格式: :
m_axis_data_tdata 输出数据格式: :
根据你的配置比如1024个点,每个点为32bit,高16bit为虚部,低16bit为实部。
IP核配置
①:通道数,1~12。
②:变换点数,8~65536。
③:工作时钟频率,1~1000。
④:数据比特率。
⑤:根据时钟频率与比特率自动选择。
⑥:流水线IO,允许连续数据处理,仅当使用单通道时,流水线IO可选。
⑦:碟4,突发IO,使用迭代方法分别加载和处理数据。它的资源消耗比流水线架构小,但转换时间更长
一点不同:蝶4架构的变换点数为64 ~ 65536,其它架构点数为 8 ~ 65536。
⑧:碟2,突发IO,使用与 Radix-4 相同的迭代方法,但蝶形运算单元更小。
它的资源消耗比 Radix-4 架构的尺寸更小,但转换时间更长。
⑨:碟2 -Lite,突发IO,基于 Radix-2 架构,此变体使用分时复用方法实现蝶形运算单元,
以实现更少的资源消耗,但代价是转换时间更长。
⑩:运行期间可配置变换点数。
①:数据格式,定点、浮点。
②:缩放选项,。
③:数据省入模式。
④:输入数据宽度。
⑤:相位因子宽度。
⑥:输出位序。
⑦:输出序号。
⑧:数据溢出标志。
①:数据。
②:相位因子。
③:重排序缓冲。
④:复数乘法器。
⑤:蝶形运算单元。
Matlab产生原实信号 s,将1024点的数据写入FPGA的ROM
采样率为1000Hz,信号为100Hz、200Hz、300Hz叠加,FFT点数为1024。
clc
clear all;
row=3;
column=1;
N=1024;
fs=1000; %采样间隔为1/1000
t=(1:1024)/fs; %时间轴
f0=100; %载频频率
f1=200; %载频频率
f2=300; %载频频率
y1=100*exp(1i*2*pi*f0*t);
y2=100*exp(1i*2*pi*f1*t);
y3=100*exp(1i*2*pi*f2*t);
y=y1+y2+y3; %信号产生
real_y = int32(real(y)); %实部
imag_y = int32(imag(y)); %虚部
a=[real_y;imag_y];
s = int32(bitshift(imag_y,16)+real_y);%将实部和虚部拼接为32bit(实部16bit+虚部16bit)
s = s'; %此数据输出到FPGA
%绘制原信号
subplot(row,column,1);
plot(t,y);
title("时域");
xlabel('t');
ylabel('y');
grid on;
%FFT
f=(0:N-1)*(fs/N);
fft_y=fft(y,N); %FFT
abs_fft_y=abs(fft(y,N)); %FFT取绝对值
subplot(row,column,2); %FFT波形
plot(f,fft_y);
title("FFT");
xlabel('t');
ylabel('y');
grid on;
subplot(row,column,3); %FFT取绝对值波形
plot(f,abs_fft_y);
title("FFT取绝对值");
xlabel('t');
ylabel('y');
grid on;
FPGA端IP核的配置:
将时域数据写入ROM,通过FFT IP核后得到以下结果:
结果展现:
FPGA FFT波形,第三通道是时域数据,第五通道是FFT,第六通道是FFT取绝对值的波形。
采样率为1000Hz,1024个点。
观察下图中f变量(可以表示频率的横轴),三个峰值对应的频率为100Hz,200Hz,300Hz。
Verilog代码:
Xilinx FFT IP核 Verilog代码实现
Matlab产生原实信号 s,将8192点的数据写入FPGA的ROM
采样率为2.5GHz,信号为100Hz、350Hz、500Hz叠加,FFT点数为1024。
clc
clear all;
close all;
row=3;
column=1;
N=8192;
fs=2.5e9; %采样间隔为1/1000
t=(1:N)/fs; %时间轴
f0=100e6; %载频频率
f1=350e6; %载频频率
f2=500e6; %载频频率
y1=20*exp(1i*2*pi*f0*t);
y2=20*exp(1i*2*pi*f1*t);
y3=20*exp(1i*2*pi*f2*t);
y=y1+y2+y3; %信号产生
real_y = int32(real(y)); %实部
imag_y = int32(imag(y)); %虚部
a=[real_y;imag_y];
s = int32(bitshift(imag_y,16)+real_y);%将实部和虚部拼接为32bit(实部16bit+虚部16bit)
s = s'; %此数据输出到FPGA
%绘制原信号
subplot(row,column,1);
plot(t,y);
title("时域");
xlabel('t');
ylabel('y');
grid on;
%FFT
f=(0:N-1)*(fs/N);
fft_y=fft(y,N); %FFT
abs_fft_y=abs(fft(y,N)); %FFT取绝对值
subplot(row,column,2); %FFT波形
plot(f,fft_y);
title("FFT");
xlabel('t');
ylabel('y');
grid on;
subplot(row,column,3); %FFT取绝对值波形
plot(f,abs_fft_y);
title("FFT取绝对值");
xlabel('t');
ylabel('y');
grid on;
结果展示:第四通道是时域数据,第六通道是FFT取绝对值的波形。
观察图中f变量(可以表示频率的横轴),三个峰值对应的频率为100Hz,350Hz,500Hz。
Verilog代码:
Xilinx FFT IP核 Verilog代码实现