DSP中最常用最基础的FFT运算。

创建FFT核

首先,什么是IP核

在集成电路中,IP(intellectual property)核是指某一方提供的、形式为逻辑单元、芯片设计的可重用模块。

类似于库函数。

在FPGA的设计中,适当的调用IP核可以提高设计效率,节省设计时间。同时,有些IP核比如 高速接口IP,与FPGA底层的硬件电路资源息息相关。我们在调用IP核时,需要先翻阅IP核的参考资料,了解IP核的结构以及接口定义,方便我们在设计中调用。可以在matlab中调用!!!

可以调用xilinx提供的IP核、第三方的IP核、自己封装的IP核。

Xilinx FFT IP核是一种计算DFT的有效方式,FFT是计算DFT的高效算法,把计算N点DFT的乘法运算量从N2降低到N/2*log2N次。

采用FPGA实现FFT:FPGA具有并行处理、流水线处理、易编程、片上资源丰富等特点,用于实现高速、大点数的FFT优势明显

配置FFT核:

IP核

只要IP catalog界面中Fast fourier transform 的license状态为“included”即可正常使用。

双击Fast Fourier Transform,选择Customize IP,主界面如下:

vivado的FFT IP核配置起来更加复杂,功能也更加强大。左边是IP核的接口图(IP Symbol)、实现消耗的资源等信息(Implementation Details)、计算FFT所需的时间(Latency);右边是configuration、Implementation和Detailed Implementation三个标签卡。

需要配置的参数有三个标签页,需要一一配置

第一个标签页IP Symbol,主要配置通道数、点数、时钟、吞吐量、可以运行时配置,需要注意的是结构的配置回影响调整因子。

vivado的FFT IP核支持多通道输入(Number of channels)、实时更改FFT的点数(Run time configurable tranform length)、FFT的点数(transform length)、工作时钟(target clock frequency)、选择一种FFT结构,包括pipelined streaming、基4 burst、基2 burst、轻量级基2 burst,计算速度和消耗的资源依次减少。

补充:FFT IP核提供了四种可选择的计算结构架构,可以在资源和转换时间之间进行权衡,具体包括:

流水线I/O:允许连续数据处理;

Radix-4突发I/O:使用迭代方法分别加载和处理数据。使用资源大小比流水线解决方案小,但是转换时间较长;

Radix-2突发I/O:使用与基-4相同的迭代方法,但蝶形较小。使用资源比基-4更少,但是转换时间更长;

Radix-2 Lite突发I/O:基于基2体系结构,该变体使用时间复用方法使用更小的内核执行蝶形运算,代价是转换时间更长。

第二个配置页(implementation),主要是 数据宽度、格式、控制信号、输出方式、可选的控制信号。

implementation标签卡下设置FFT的数据格式为定点fixed point或者浮点float point;设置输入数据的位宽(input data width)和相位因子位宽( phase factor width )(相当于旋转因子);还有一些可选的附件信号;output ordering设置FFT计算结果以自然顺序(nature order)或位/数值反序(bit/digit reversed order)输出。

第三配置页(detailed implementation)主要配置内部数据块的使用和优化方式、存储类型、是否使用DSP单元等于综合、实现有关的信息,比如可以选择复数乘法器和蝶形运算单元的实现结构。

所有这些配置完成后,可以在左侧一列中查看配置的结果,IP symbol中主要查看各种接口;implementation detals中有较多的信息,比如 结构、长度、数据带宽等,需要注的是CONFIG TDATA这一项,与配置接口的参数有关,在使用中需要正确配置。在当前的配置, FWD_INV使用1bit,bit10:bit1用于调整因子,前面已经说过不同的结构调整因子不同,详细的可以参看FFT的核文献;latency显示出计算FFT所需的时间。

点击OK就可以完成配置,生成FFT核,并可以找到IP Sources,核的模板是xfft_0.veo,我们就是用这个模板创建的实例,我们根据需要对它进行重新配置和封装。

核的模板是xfft_0.veo,以下xfft_0 your_instance_name ()部分是 配置好 IP核后,从xfft_0.veo复制过来的,也就是对配置好的IP核进行例化。

设计源文件:
module fft_core_test(
    clk,
    config_en,
    dat_rdy,
    dat_last,
    dat_in_RE,
    dat_in_IM,
    fft_core_rdy,
    freq_o_en,
    freq_o_RE,
    freq_o_IM  
    );
    
    input clk;
    input config_en;
    input dat_rdy;
    input dat_last;
    input [15:0] dat_in_RE,dat_in_IM;
    output fft_core_rdy;
    output freq_o_en;
    output [15:0] freq_o_RE,freq_o_IM;
 
    wire fft_core_rdy;   
    wire freq_o_en;
    wire [15:0] freq_o_RE,freq_o_IM;
    //fft core
    wire aclk = clk;
    wire [15 : 0] s_axis_config_tdata = 16'b0_0000_0000_0000_00_1;     //scal_sch:  [14:1]   FWD_INC:[0]    
    wire s_axis_config_tvalid = config_en;
    wire s_axis_config_tready;
    wire [31 : 0] s_axis_data_tdata = {dat_in_IM,dat_in_RE};
    wire s_axis_data_tvalid = dat_rdy;
    wire s_axis_data_tready;
        assign fft_core_rdy = s_axis_data_tready;
    wire s_axis_data_tlast = dat_last;
    wire [31 : 0] m_axis_data_tdata;
    assign  {freq_o_IM,freq_o_RE} = m_axis_data_tdata;
    
    wire m_axis_data_tvalid;
    assign freq_o_en = m_axis_data_tvalid;
    wire m_axis_data_tready = 1'b1;
    wire m_axis_data_tlast;
    wire event_frame_started;
    wire event_tlast_unexpected;
    wire event_tlast_missing;    
    wire event_status_channel_halt;
    wire event_data_in_channel_halt;
    wire event_data_out_channel_halt;
    
   
 
xfft_0 your_instance_name (
  .aclk(aclk),                                                // input wire aclk ,系统时钟,给它一个时钟
  .s_axis_config_tdata(s_axis_config_tdata),                  // input wire [15 : 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 [31 : 0] m_axis_data_tdata
  .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
);    
endmodule

仿真源文件:

module sim_fft( );
 
    reg all_en;
    reg clk;
    reg config_ena;
    reg dat_rdy;
    reg dat_last;
    reg [15:0] dat_c;
    wire [15:0] dat_in_RE,dat_in_IM;
    wire fft_core_rdy_t;
    wire freq_o_en_t;
    wire [15:0] freq_o_RE_t,freq_o_IM_t;
    
    integer handle1;
    initial
    begin//sequence block    
      handle1 =$fopen("/自己的地址/fsave.txt");       
      #200000  $fclose(handle1);
      $stop;
    end 
    
    
    initial 
    begin
        clk = 0;
        dat_rdy = 0;
        dat_last = 0;
        //dat_in_RE=0;
        dat_c =0;
        config_ena = 0;
        all_en=0;
        #200 all_en = 1;
        //#20 config_ena =1;
        //#100 config_ena =0;
        forever #10 clk = ~clk;        
    end
    //
    reg [15:0]  cnt=0;
    reg [15:0] index = 0;
    always @(posedge clk)
    begin
        if(all_en)
            begin
            cnt <= cnt + 1'b1;
            if(cnt == 0)     
            begin     
                config_ena  <=1;    
            end
            else if(cnt == 3)
                config_ena  <= 0;
            else if(cnt == 5)
            begin    
                dat_rdy <= 1;
                dat_c <= 0;
               // dat_in_IM <= 0;
                index = 0;
            end        
            else if(cnt == 16'd1028)
            begin        
                dat_last <= 1'b1;                
                dat_c <= (dat_c + 12'h100);                
            end
            else if(cnt == 16'd1029)
            begin
                dat_rdy <= 1'b0;
                dat_last <= 1'b0;
            end
            else
            begin            
                //dat_last <= 1'b0;
                dat_c <=(dat_c + 12'h100);                
            end
            
            if(dat_rdy)
                index <= index +1;
        end
    end 
 
    always @(posedge clk)
    begin
        if(dat_rdy)        
            $fwrite(handle1,"%d  %d \n",dat_in_RE,dat_in_IM);  
        else if(freq_o_en_t)        
            $fwrite(handle1,"%d  %d \n",freq_o_RE_t,freq_o_IM_t);        
    end
    
    
     assign dat_in_RE ={ 8'b0,{ dat_c[15]? ~dat_c[15:8] : dat_c[15:8]}};
     assign dat_in_IM =0;
fft_core_test   fft_core_inst(
    .clk(clk),
    .config_en(config_ena),
    .dat_rdy(dat_rdy),
    .dat_last(dat_last),
    .dat_in_RE(dat_in_RE[15:0]),
    .dat_in_IM(dat_in_IM[15:0]),
    .fft_core_rdy(fft_core_rdy_t),
    .freq_o_en(freq_o_en_t),
    .freq_o_RE(freq_o_RE_t),
    .freq_o_IM(freq_o_IM_t)  
    );
endmodule

Run Behavior Simulation,仿真结果如下,可以看到有输入、输出的信息,以及FFT IP核引脚的情况:

在前面的fft_sim仿真文件中,生成了三角波用于测试;并且把 输入到FFT核的数据 和 FFT核输出的数据 保存下来,以便用于matlab分析,如下。

clear;
 
file_name='fsave.txt';
fid = fopen(file_name,'r');
c = fscanf(fid,'%d');
fclose(fid);
 for i=1: length(c)
    if(c(i)>32767)
        b(i) =  c(i)-65536;
    else b(i) =  c(i);
    end
end
d1=b(1:2:end);
d2=b(2:2:end);
comp1=d1(1:1024) + j*d2(1:1024);
comp2=d1(1025:2048) + j*d2(1025:2048);
 
c1avr=sum(comp1)/length(comp1);
c1=comp1-c1avr;
%  c1=comp1;
 
c1fft=abs(fft(c1,1024));
c2fft=abs(comp2);
plot(c1);
figure
subplot(2,1,1);
plot(c1fft);
subplot(2,1,2);
plot(c2fft);
figure
subplot(2,1,1);
plot(c1fft(1:50));
subplot(2,1,2);
plot(c2fft(1:50));

FFT核输出的数据 保存下来的数据,直接画出的锯齿波,这里进行了去直流的过程,所以MATLAB进行FFT的结果中不含直流分量,而FFT核 运算出的数据中应该有直流分量。

直流分量:就是信号的平均值,它是一个与时间无关的常数。为了准确得到有效信息,直流偏置以及叠加在上面的干扰都需要去除,这样再进行信号放大和后续处理才更有意义。

第一个MATLAB进行FFT得到的频谱图(这是一个FFT之后的幅度谱,峰指处说明三角波的频率大小,小的峰也是频率,忽略掉即可。详情https://www.renrendoc.com/p-51066532.html。幅度谱是频谱取绝对值,时域信号fft后变成频域上的幅度),第二个FFT 核输出的结果,FFT IP核输出有直流分量。

只看前50个点的数据,可以看到两种方式输出数据中的频率分量都是对准的,在第二个图中(FFT核输出数据),可以看到有直流分量。

参考:

原文链接https://blog.csdn.net/yanshanyan/article/details/82386575?biz_id=102&utm_term=vivado2020%20FFT&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-82386575&spm=1018.2118.3001.4187

vivado FFT的实现--preject_1相关推荐

  1. FPGA数字信号处理(九)Vivado FFT IP核实现

    该篇是FPGA数字信号处理的第9篇,选题为DSP系统中极其常用的FFT运算.上篇介绍了Quartus环境下FFT IP核的使用"FPGA数字信号处理(八)Quartus FFT IP核实现h ...

  2. Xilinx IP解析之 Fast Fourier Transform(FFT) v9.1

    Xilinx IP解析之 Fast Fourier Transform(FFT) v9.1 前言--两个FFT IP核的区分 在Vivado的IP中搜索FFT,会显示出FFT和LTE FFT,如下图所 ...

  3. 关于解决vivado error:add_1 must be in range [-1,DEPTH-1] 问题

    在仿真vivado fft ip 核时出现关于解决vivado error:add_1 must be in range [-1,DEPTH-1] 问题 经查找资料与亲自实践得出如下结论 1.拉高m_ ...

  4. FPGADesigner《FPGA数字信号处理系列》目录与传送门

    FPGA数字信号处理(1)数字混频(NCO与DDS的使用): https://blog.csdn.net/fpgadesigner/article/details/80512067 FPGA数字信号处 ...

  5. 基于FPGA的FM信号解调

    这是本人第一次写博客,写的不好请多多担待. 本次实验是将一个已知的FM信号通过FPGA进行解调,解调出波形并进行FFT得到调制频率fm,并且每一步都通过MATLAB进行波形的验证. 开发工具 VIVA ...

  6. 基于vivado实现FFT/IFFT

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

  7. vivado实现FFT和IFFT信号处理

    一,FFT的物理意义 FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了.这就是很多信号分析采用FFT变换的原 ...

  8. Vivado中的FFT IP核使用(含代码)

    本文介绍了Vidado中FFT IP核的使用,具体内容为:调用IP核>>配置界面介绍>>IP核端口介绍>>MATLAB生成测试数据>>测试verilog ...

  9. vivado wdb文件 matlab,fft_ex1 基于verilog的FFT设计,使用vivado作为开发平台 VHDL-FPGA- 274万源代码下载- www.pudn.com...

    文件名称: fft_ex1下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Others 文件大小: 4477 KB 上传时间: 2017-04-17 下载次数: 0 提 供 者: k ...

  10. Vivado环境下基于FPGA的IP实现FFT变换

    这里写自定义目录标题 环境 层次结构 仿真 实现 HDL 顶层文件 仿真文件 dds文件 IP配置 FFT ROM COE文件生成 reference 环境 Vivado Modelsim 仿真 层次 ...

最新文章

  1. 西门子断开延时定时器_在PLC编程中定时器的一些针对现场不同情况的一些妙用...
  2. PoE供电中功率损耗问题
  3. 【C/C++】代码优化技巧
  4. 反思供应链项目:实践出真知 多反思提升效率的方法
  5. CentOS 6.5安装与配置PostgreSQL9.2
  6. SAP ABAP Netweaver系统的传输请求类型和原始系统的含义
  7. 使用directX 7结合C#进行2D游戏编程
  8. kswapd0 挖矿_bioset linux_linux bioset 进程 腾讯云
  9. [Python]网络爬虫(七):Python中的正则表达式教程
  10. 在hibernate框架中配置显示sql语句
  11. 苹果下半年推出M2芯片MacBook Air 配色更多更轻薄
  12. Android开机动画过程
  13. 谷歌浏览器安装apizza
  14. php 微信 40125,微信请求发生错误!错误代码:40125
  15. 聊聊索引失效?失效的原因是什么?
  16. 机器学习为什么也可以像人一样认识cang老师
  17. 实践:Linux上安装nginx后同一服务器进行多域名反向代理
  18. win11资源管理器总是自动重启的解决方法
  19. 局域网自建对讲服务器,Windows 局域网语音对讲
  20. 问题记录:键盘win键无法使用,组合键无反应,win+L不能锁屏

热门文章

  1. 排队购票问题分析与解决
  2. judge() java中_Java 方法
  3. 【无标题】JAVA IO流学习笔记
  4. 参数设置类毕业论文文献都有哪些?
  5. Cacti监控软件安装与应用
  6. 百度熊掌号对SEO有哪些作用
  7. Linux进入ubuntu蓝屏重启的解决方法
  8. HoloLens2代 安装过程
  9. 【鸿蒙应用ArkTS开发系列】- Har包中子组件中监听生命周期实现
  10. 【AUTOSAR】 MCAL配置说明(十二)----MCAL fls_Pmu模块配置