一,FFT的物理意义

FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外在频谱分析方面,FFT可以将一个信号的频谱提取出来。一个模拟信号,经过ADC采样(采样频率要大于信号频率的两倍)之后,就变成了数字信号。采样得到的数字信号,就可以做FFT变换了。N个采样点,经过FFT之后,就可以得到N个点的FFT结果。为了方便进行FFT运算,通常N取2的整数次方。

IFFT (Inverse Fast Fourier Transform) 就是快速傅里叶逆变换。其为OFDM技术中的一个实现方式:各个子信道的正交调制和解调可以分别通过采用IDFT(Inverse Discrete Fourier Transform)和DFT实现,在子载波数很大的系统中,可以通过采用IFFT(Inverse Fast Fourier Transform)和FFT实现。

二,FFT的Vivado 实现步骤:

运行 Matlab程序 产生测试数据, 绘制 cos  时域和频域波形,运行产生 1 组 cos波形的 1000 个采样点数据,存在time_domain_cos.txt文件,每个数据位宽16bit。

matlab绘制出时域和频域的波形

clc;clear `all;close all;format long gFs = 1000;                    % Sampling frequency
T = 1/Fs;                     % Sampling period
L = 1000;                     % Length of signal
t = (0:L-1)*T;                % Time vectorx1 = cos(2*pi*50*t)*(2^13);          % First row wave
%output time domain data
x1_fix = round(x1,0);    %convert to fixed signed(3.13)
x1_fix(find(x1_fix<0)) = x1_fix(find(x1_fix<0))+(2^16);
fid0 = fopen('time_domain_cos.txt', 'wt');
fprintf(fid0, '%16x\n', x1_fix);
fid0 = fclose(fid0);
fid1 = fopen('frequency_domain_cos.txt', 'wt');
fprintf(fid1, '%g\n', Y);
fid1 = fclose(fid1);%fft
x1 = x1/2^15;   %signed(.15)
figure(1);
plot(t(1:100),x1(1:100))
title(['Cos in the Time Domain'])n = 2^nextpow2(L);
Y = fft(x1,n);%draw wave
y = abs(Y/n);
t1 = (0:n);                % Time vectorfigure(2);
plot(t1(1:n),y(1:n))
title(['Cos in the Frequency Domain'])%IFFT and draw wave
IY = ifft(Y,n);
figure(3);
plot(t(1:100),IY(1:100))
title(['Cos after FFT and IFFT'])

1,打开 IP Catalog ,搜索 FFT 或者找到分类 Core -> Digital Signal Processing->Transform ->ffts ,Fast Fourier Transform 。

2,Configuration 页面如图,配置 IP 通道数(Number of Channels )、 FFT 转换长度(Transform Length)、目标时钟频率(Target Clock Frequency )和 FFT 实现架构(Architecture
Choice)

3,Implementation 页面,可以配置数据格式(Data Format)、缩放模式(Scaling Options)、数据末尾处理方式(Rounding Modes)、输入数据和相位的位宽(Input Data
Width)和数据输出顺序(Output Ordering)等。

4,Detailed Implement 页面中,可以对 FPGA 存储器或乘法器相关的资源配置

5,在配置页面左侧,可以查看 IP 接口( IP Symbol )、实现信号位宽细节( Implementation Details)和输出延时(Latency)

6,顶层代码

`timescale 1ns / 1ps`timescale 1ns/1ps
module fft_sim();reg clk;
reg rst_n;  reg [7 : 0] s_axis_config_tdata;
reg s_axis_config_tvalid;
wire s_axis_config_tready;reg [15 : 0] s_axis_data_tdata_img,s_axis_data_tdata_real;    //signed(1.15)
reg s_axis_data_tvalid;
wire s_axis_data_tready;
reg s_axis_data_tlast;wire [26 : 0] m_axis_data_tdata_img,m_axis_data_tdata_real;
wire [31 : 27] m_axis_data_null;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;//xilinx pg109-xfft.pdf page24
parameter FFTCONFIG_FWD_INV_FFT     = 1'b1;       //FFT
parameter FFTCONFIG_FWD_INV_IFFT    = 1'b0;       //IFFT//FFT IP Core wire event_frame_started;
wire event_tlast_unexpected;
wire event_tlast_missing;
wire event_data_in_channel_halt;xfft_0  uut_xfft_0 (.aclk                           (clk),                               // input wire aclk.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_img,s_axis_data_tdata_real}),                 // 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_img,m_axis_data_null,m_axis_data_tdata_real}),                 // output wire [63 : 0] m_axis_data_tdata.m_axis_data_tvalid         (m_axis_data_tvalid),                // output wire m_axis_data_tvalid.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_data_in_channel_halt  (event_data_in_channel_halt)         // output wire event_data_in_channel_halt
);integer i,j;reg[15:0] data_mem [999:0];initial #500 $readmemh("../../time_domain_cos.txt",  data_mem);      initial beginclk = 0;rst_n = 0;s_axis_config_tdata <= 8'd0;s_axis_config_tvalid <= 1'b0;s_axis_data_tdata_img <= 16'd0;s_axis_data_tdata_real <= 16'd0;s_axis_data_tvalid <= 1'b0;s_axis_data_tlast <= 1'b0;#1000;@(posedge clk);s_axis_config_tdata <= {7'd0,FFTCONFIG_FWD_INV_FFT};s_axis_config_tvalid <= 1'b1;   repeat(2) begin @(posedge clk); ends_axis_config_tvalid <= 1'b0;      #1000;@(posedge clk);i <= 1;#10000;@(posedge clk);        #100_000;$fclose(w1_file);$fclose(w2_file);#1000;$stop;
end always @(*) beginif((i>0) && (i<1001)) s_axis_data_tdata_real <= data_mem[i-1];else s_axis_data_tdata_real <= 16'd0;
end always @(posedge clk) beginif(i == 0) i <= 0;else if(i <= 1024) begin    if(s_axis_data_tready && s_axis_data_tvalid) i <= i+1;else ;endelse if(i < 1050) i <= i+1;else ;
endalways @(posedge clk)
beginif((i>=1) && (i<=1023)) s_axis_data_tvalid <= 1'b1;   else s_axis_data_tvalid <= 1'b0;
endalways @(posedge clk)
beginif(i==1023) s_axis_data_tlast <= 1'b1;else s_axis_data_tlast <= 1'b0;
endalways #10 clk = ~clk;
integer w1_file,w2_file;initial w1_file = $fopen("./fft_result_real.txt","w");
initial w2_file = $fopen("./fft_result_image.txt","w");    always @(posedge clk)
beginif(m_axis_data_tvalid) begin$fwrite(w1_file, "%x\n", m_axis_data_tdata_real);$fwrite(w2_file, "%x\n", m_axis_data_tdata_img);  $display("%x    ,    %x",m_axis_data_tdata_real,m_axis_data_tdata_img);end
end endmodule

7,Flow Navigator 面板中,展开 Simulation ,点击 Run Simulation ,弹出菜单中点击 Run Behavioral Simulation仿真

打开**.sim\sim_1\behav 文 件 夹 下 fft_result_real.txt 和fft_result_image.txt 文本,分别存储 FFT 结果的实部和虚部。这里需要注意定点的小数问题

8,FFT的MATLAB验证

clc;clear `all;close all;
format long g
FFT_NUM = 1024;
%input file
fid1 = fopen('fft_result_real.txt', 'r');
fft_real = fscanf(fid1,'%x');
fclose(fid1);
fid2 = fopen('fft_result_image.txt', 'r');
fft_image = fscanf(fid2,'%x');
fclose(fid2);for i=1:FFT_NUMif fft_real(i) >= 2^26fft_real(i) = fft_real(i)-2^27;endif fft_image(i) >= 2^26fft_image(i) = fft_image(i)-2^27;end
endy = sqrt(fft_real.*fft_real + fft_image.*fft_image)/2^15/FFT_NUM;
t = (0:FFT_NUM);                % Time vector
figure(1);
plot(t(1:FFT_NUM),y(1:FFT_NUM))

三,IFFT的vivado实现

`timescale 1ns/1ps
module ifft_sim();
//接口定义reg clk;
reg rst_n;
reg [7 : 0] s_axis_config_tdata;
reg s_axis_config_tvalid;
wire s_axis_config_tready;reg [7 : 0] si_axis_config_tdata;
reg si_axis_config_tvalid;
wire si_axis_config_tready;reg [15 : 0] s_axis_data_tdata_img,s_axis_data_tdata_real;
reg s_axis_data_tvalid;
wire s_axis_data_tready;
reg s_axis_data_tlast;reg [26 : 0] si_axis_data_tdata_img,si_axis_data_tdata_real;
reg si_axis_data_tvalid;
wire si_axis_data_tready;
reg si_axis_data_tlast;wire [26 : 0] m_axis_data_tdata_img,m_axis_data_tdata_real;
wire [31 : 27] m_axis_data_null;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;wire [37 : 0] mi_axis_data_tdata_img,mi_axis_data_tdata_real;
wire [39 : 38] mi_axis_data_null;
wire mi_axis_data_tvalid;
wire mi_axis_data_tlast;//xilinx pg109-xfft.pdf page24
parameter FFTCONFIG_FWD_INV_FFT     = 1'b1;       //FFT
parameter FFTCONFIG_FWD_INV_IFFT    = 1'b0;       //IFFT//FFT IP Core wire event_frame_started;
wire event_tlast_unexpected;
wire event_tlast_missing;
wire event_data_in_channel_halt;xfft_0  uut_xfft_0 (.aclk                           (clk),                               // input wire aclk.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_img,s_axis_data_tdata_real}),                 // 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_img,m_axis_data_null,m_axis_data_tdata_real}),                 // output wire [63 : 0] m_axis_data_tdata.m_axis_data_tvalid         (m_axis_data_tvalid),                // output wire m_axis_data_tvalid.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_data_in_channel_halt  (event_data_in_channel_halt)         // output wire event_data_in_channel_halt
);xfft_1    uut_xfft_1 (.aclk                           (clk),                                              // input wire aclk.s_axis_config_tdata          (si_axis_config_tdata),                // input wire [7 : 0] s_axis_config_tdata.s_axis_config_tvalid           (si_axis_config_tvalid),              // input wire s_axis_config_tvalid.s_axis_config_tready           (si_axis_config_tready),              // output wire s_axis_config_tready.s_axis_data_tdata         ({5'd0,si_axis_data_tdata_img,5'd0,si_axis_data_tdata_real}),                    // input wire [63 : 0] s_axis_data_tdata.s_axis_data_tvalid          (si_axis_data_tvalid),                  // input wire s_axis_data_tvalid.s_axis_data_tready         (si_axis_data_tready),                  // output wire s_axis_data_tready.s_axis_data_tlast         (si_axis_data_tlast),                    // input wire s_axis_data_tlast.m_axis_data_tdata          ({mi_axis_data_tdata_img,mi_axis_data_null,mi_axis_data_tdata_real}),                    // output wire [79 : 0] m_axis_data_tdata.m_axis_data_tvalid           (mi_axis_data_tvalid),                  // output wire m_axis_data_tvalid.m_axis_data_tlast         (mi_axis_data_tlast),                    // output wire m_axis_data_tlast.event_frame_started           (),                // output wire event_frame_started.event_tlast_unexpected        (),          // output wire event_tlast_unexpected.event_tlast_missing          (),                // output wire event_tlast_missing.event_data_in_channel_halt    ()  // output wire event_data_in_channel_halt
);//初始化
integer i,j;reg[15:0]   data_mem [999:0];
reg[26:0]   fft_data_mem_real [1023:0];
reg[26:0]   fft_data_mem_image [1023:0];initial #500 $readmemh("../../time_domain_cos.txt",  data_mem);       reg flag_fft;   //1--fft, 0--ifftinitial beginclk = 0;rst_n = 0;s_axis_config_tdata <= 8'd0;s_axis_config_tvalid <= 1'b0;si_axis_config_tdata <= 8'd0;si_axis_config_tvalid <= 1'b0;s_axis_data_tdata_img <= 16'd0;s_axis_data_tdata_real <= 16'd0;s_axis_data_tvalid <= 1'b0;s_axis_data_tlast <= 1'b0;//FFT#1000;@(posedge clk);s_axis_config_tdata <= {7'd0,FFTCONFIG_FWD_INV_FFT};s_axis_config_tvalid <= 1'b1;    repeat(2) begin @(posedge clk); ends_axis_config_tvalid <= 1'b0;      flag_fft = 0;#1000;@(posedge clk);i <= 1;#100_000;$fclose(w1_file);$fclose(w2_file);//IFFTflag_fft = 1;  #1000;@(posedge clk);si_axis_config_tdata <= {7'd0,FFTCONFIG_FWD_INV_IFFT};si_axis_config_tvalid <= 1'b1;    repeat(2) begin @(posedge clk); endsi_axis_config_tvalid <= 1'b0;         #1000;@(posedge clk);i <= 1;#100_000;$fclose(w3_file); #1000;$stop;
end always #10 clk = ~clk; //产生FFT IP核的输入数据
always @(*) beginif(!flag_fft) begins_axis_data_tdata_img <= 0;if((i>0) && (i<1001)) s_axis_data_tdata_real <= data_mem[i-1];else s_axis_data_tdata_real <= 16'd0;endelse beginsi_axis_data_tdata_real <= fft_data_mem_real[i-1];si_axis_data_tdata_img <= fft_data_mem_image[i-1];end
end always @(posedge clk) beginif(i == 0) i <= 0;else if(i <= 1024) beginif(!flag_fft)beginif(s_axis_data_tready && s_axis_data_tvalid) i <= i+1;else ;endelse beginif(si_axis_data_tready && si_axis_data_tvalid) i <= i+1;else ;endendelse if(i < 1050) i <= i+1;else ;
endalways @(posedge clk)
beginif(!flag_fft) beginif((i>=1) && (i<=1023)) s_axis_data_tvalid <= 1'b1;    else s_axis_data_tvalid <= 1'b0;endelse beginif((i>=1) && (i<=1023)) si_axis_data_tvalid <= 1'b1; else si_axis_data_tvalid <= 1'b0;end
endalways @(posedge clk)
beginif(!flag_fft) beginif(i==1023) s_axis_data_tlast <= 1'b1;else s_axis_data_tlast <= 1'b0;   endelse beginif(i==1023) si_axis_data_tlast <= 1'b1;else si_axis_data_tlast <= 1'b0;    end
end//文件存储IP核输出数据integer w1_file,w2_file,w3_file;initial w1_file = $fopen("./fft_result_real.txt","w");
initial w2_file = $fopen("./fft_result_image.txt","w");
initial w3_file = $fopen("./ifft_result.txt","w"); integer k = 0;     always @(posedge clk)
beginif(m_axis_data_tvalid && !flag_fft) begin$fwrite(w1_file, "%x\n", m_axis_data_tdata_real);$fwrite(w2_file, "%x\n", m_axis_data_tdata_img); fft_data_mem_real[k] <= m_axis_data_tdata_real;fft_data_mem_image[k] <= m_axis_data_tdata_img;k <= k+1;endelse if(mi_axis_data_tvalid && flag_fft) begin$fwrite(w3_file, "%x\n", mi_axis_data_tdata_real[25:10]);end
end endmodule

vivado实现FFT和IFFT信号处理相关推荐

  1. 基于vivado实现FFT/IFFT

    文章目录 前言 一.基本过程 二.vivado配置 1.新建工程 2.调用DDS的IP核 2.调用FFT的IP核 三.编写Verilog程序 1.顶层文件fft.v 2.仿真文件fft_tb.v 四. ...

  2. C语言实现的FFT与IFFT源代码,不依赖特定平台

    目录 源码 FFT.c FFT.h 使用方法 初始化 输入数据 FFT 快速傅里叶变换 解算FFT结果 使用python绘制FFT波形 IFFT 快速傅里叶逆变换 解算IFFT结果 Windows 1 ...

  3. TMS320C6455二维FFT和IFFT实现

    目录 FFT原理简介 DSPLib配置 图像数据生成 DSPLib中的FFT和IFFT 二维FFT和IFFT实现 图像分析工具(Image Analyzer) 测试结果 相关资源链接 参考资料: Ra ...

  4. 【kissfft】使用kiss_fftr做FFT与iFFT

    类似与kiss_fft的调用,本章具体使用kiss_fftr接口做FFT与iFFT的使用 代码举例 static kiss_fft_scalar rand_scalar(void) {kiss_fft ...

  5. 【kissfft】使用kiss_fft做FFT与iFFT

    长时间没有使用kissfft有点忘记API的使用了,这里记录一下最最基本的使用. FFT与iFFt FFT 使用FFT的时候先初始化kiss_fft_cfg,其中第二个参数0/1表示是做fft还是if ...

  6. MATLAB中的快速傅里叶变换FFT与IFFT

    背景 FFT (Fast Fourier Transform)是离散傅立叶变换的快速算法,可以将一个信号从时域变换到频域.同时与之对应的是IFFT(Inverse Fast Fourier Trans ...

  7. matlab的fft与ifft,fft与ifft区别

    OFDM是如何利用FFT和IFFT技术实现的_信息与通信_工程科技_专业资料.1.LTE 在广义上说只有一个载波,FDD 是上行和下行的载波分配在不同的频点,TDD 是在 同一个...... Matl ...

  8. FFT专题:IFFT后信号如何重建

    ifft(outFFTData, g_fft_temp, inFFTData, g_twiddle_ifft, twiddle_stride, F_WLEN);//思考ifft输出的复数结果怎么给到硬 ...

  9. ifft变换用java_利用FFT 及 IFFT实现傅立叶正反变换 | 学步园

    貌似是很久没有写日志了,前段时间一直很想写关于矩阵特征值在迭代 毕业设计貌似也跟仿真有关,所以重拾matlab来做一些小的仿真,先说说利用FFT 和 IFFT来实现傅立叶正反变换吧.看了很多资料,网上 ...

最新文章

  1. Python -- 连接数据库SqlServer
  2. 【数据展示】matplotlib中label框亮度设置
  3. 【ELK】ELK集群搭建(ElasticSearch Logstash Kinaba)
  4. java中的reader_java中BufferedReader 有什么用
  5. 用for和do..while两种方法:键盘录入一个数 求阶乘的和
  6. 解决:The ‘Access-Control-Allow-Origin‘ header contains multiple values‘x, *‘, but only one is allowed.
  7. php测试号推送消息失败,信息发送失败是什么原因
  8. Linxu:磁盘分区
  9. nacos 配置动态刷新_使用 Spring Cloud Alibaba Nacos Config 作为配置中心
  10. Hash碰撞的解决方案
  11. MySQL基于复制的架构方案
  12. iOS 报错 : dyld: Library not loaded: @rpath/
  13. IDC发布人工智能白皮书:信息流引领人工智能新时代
  14. 腾讯云永久修改主机名
  15. Android 亮度调节
  16. java怎样实现换肤功能_JavaScript实现换肤功能
  17. html页面刷新回到顶部_HTML5 回到顶部
  18. 利用Python与HFSS联合仿真设计一个微带天线
  19. 浙江大学计算机学院孙凌云,浙江大学计算机科学与技术学院导师介绍 孙凌云...
  20. [error]stack smashing detected

热门文章

  1. 微信防封汇总,解决办法及数据分析
  2. 农民抗征地住帐篷夜间起火1死3伤
  3. 游戏场景offset坐标系关联正六边形cube坐标系
  4. 集成环信easeUI添加联系人详情页面ListView的显示处理步聚
  5. 计算机安装不了cad2007,win10系统电脑中安装cad2007不兼容无法打开的还原方法
  6. error: cannot lock ref ‘refs/remotes/origin/master‘
  7. [CTFSHOW]中期测评WP(差512和514)
  8. 2017年美亚杯资格赛 个人赛 writeup
  9. 面试太卷,我选择背八股。。。
  10. 如何在 Excel 表格中查找数据