精华内容
下载资源
问答
  • Xilinx FPGA FFT IP核完整的Vivado工程,用于实现FFT算法,可直接进行波形仿真,测试过没问题,另外还包含matlab仿真文件,时序波形仿真结果和matlab结果一致。
  • 在这里我将使用vivado软件实例化一个长度为64的快速傅里叶变换IP核,并将运算结果和matlab中的运算结果相比较。 二、使用步骤 1.新建工程 新建工程没啥好说的,如果有开发板,那就按照对应的型号芯片来创建,...

    前言

    我是fpga小白,在vivado软件上实例化fft单元的时候,走了不少弯路;记录下来,能加深记忆,也希望能够帮助向我一样的小白,快速上手fft。


     

    一、FFT

    fft就是快速傅里叶变换,具体理论,课堂上课本上博客上都有,不赘述了。在这里我将使用vivado软件实例化一个长度为64的快速傅里叶变换IP核,并将运算结果和matlab中的运算结果相比较。

    二、使用步骤

    1.新建工程

    新建工程没啥好说的,如果有开发板,那就按照对应的型号芯片来创建,然后点击一万个next一万个finish就好了。

    下面是我建立好的工程:

    截图的时候我的相关文件代码都搞好了,所以design sources后面的()里面是3,新建的应该都是零。

    2.配置IP核

    2.1 按照途中顺序操作:

    2.2 configuration

    双击完了axi4-stream的那个fft就弹出来了配置页面

    图中最关键的就是Transform Length,就是fft的点数,我设置的是64;Number of Channel应该指的是例化fft的个数,如果是1,就是一个64位的fft单元,如果是2,就是有两个64位的单元,组成了两个通道,这样就避免了重复配置。

    2.3  implementation

    下面是implementation子目录截图:

    数据格式,定点,初次学习,定点方便理解;浮点数比较复杂,可以单独去学习;剩下的就按照图中配置,记得给xk_index打上钩,这个是fft结果的索引,换个说法,如果fft结果是个数据流,那打了对勾,这个数数据流就自带下标。

    剩下的也是如图配置;在latency标签下面可以看到最终的延迟:

    点击ok生成等待,ip核就可以用了,怎么用,下面讲。

    3.驱动IP的top文件

    vivado软件很人性化,会自动生成ip核的调用方式的模板,位置如图所示:

    双击.veo也就是Verilog版本的例化模板可以看到这些东西:

    把选中的部分复制下来;开始写top文件,也就是驱动这个ip核的文件;一开始我就很疑惑,为什么要驱动它?例化好了不能直接用么?按道理讲是可以用的,但是会很繁琐,有了top文件专门去驱动这个ip核,这样工程逻辑就很清晰,代码也容易读懂。

    点击add source,选择第二个,下一步

    create file ,起个名字,下一步,除了名字啥都不用写,下一步,完成。我起的名字是fft_test_2,也就是第2个,其他两个不用管,和本文无关。

    双击打开之后是空白,自己编辑,复制来的例化模板粘贴上去,然后按照要求喂数据就好了,懒得动,可以用我的代码:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2020/09/01 10:16:27
    // Design Name: 
    // Module Name: fft_test_2
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module fft_test_2(
        input   wire    clk,
        input   wire    [15:0]  din,
        input   wire    last,
        input   wire    s_axis_data_tvalid,
    
        output  wire     [22:0]  m_axis_data_tdata_r,
        output  wire     [22:0]  m_axis_data_tdata_i,
        output  wire     [7:0]   index
    );
    
        
        wire [31:0]s_axis_data_tdata;
        wire [7:0]s_axis_config_tdata = {7'b0,1'b1};//NO need run time change length!
        wire s_axis_config_tvalid = 1;
        wire s_axis_config_tready ;
        wire            s_axis_data_tready ;
        //wire            s_axis_data_tlast = 0;
        //wire            s_axis_data_tvalid = 1 ;
        
        //wire    [7:0]  index;
        wire            m_axis_data_tvalid;
        wire            m_axis_data_tready = 1;
        wire            m_axis_data_tlast=0;
        
        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;
        
        wire    [47:0]    m_axis_data_tdata;
        
        assign s_axis_data_tdata  = {16'b0,din};
    //    assign  m_axis_data_tdata_r = m_axis_data_tdata[15:0];
    //    assign  m_axis_data_tdata_i = m_axis_data_tdata[31:16];
        assign  m_axis_data_tdata_r = m_axis_data_tdata[22:0];
        assign  m_axis_data_tdata_i = m_axis_data_tdata[46:24];
       
    xfft_2 fft_2 (
      .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),                      // 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(last),                      // 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_tdata(m_axis_data_tdata),                      // output wire [47 : 0] m_axis_data_tdata// output wire [47 : 0] m_axis_data_tdata
      .m_axis_data_tuser(index),                                   // output wire [7 : 0] m_axis_data_tuser// output wire [7 : 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
    );
    endmodule
    

     

    需要注意的是,有一个s_axis_data_tvalid,使用的时候给fft喂数据就enable(1),数据喂完了就disable(0),不然结果会出错,这也是我改了很久才发现的,在fft_test那个文件就是我失败的记录。

    编辑好了记得保存,这个时候文件目录那边就会自动把ip核放到咱们写的文件的下面了:(之前ip核和自己的fft_test是并列的)

     

    4.testbench仿真文件

    add source,注意选择第三个:

    然后还是下一步finish套餐处理它,名字自己取,我取的是tb_fft_test

    打开它,编辑如下:

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2020/09/01 10:23:56
    // Design Name: 
    // Module Name: tb_fft_2
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module tb_fft_2();
        reg clk;
        reg     [15:0]  din;
        reg     [15:0]  stimulus[1:64]; //64 
        integer count;
        integer i;
        integer file;
    //    wire    [15:0]  data_real;
    //    wire    [15:0]  data_image;
        wire    [22:0]  data_real;
        wire    [22:0]  data_image;
        wire    [7:0]  index;
        reg    last;
        reg     s_axis_data_tvalid;
        initial begin
            clk = 0;
            din = 0;
            count = 0;
            last = 0;
            s_axis_data_tvalid = 0;
            #10;
            $readmemb("D:/Program Files/MATLAB/MatlabCode/FPGA/data_before_fft.txt", stimulus);
            
            file = $fopen("D:/Program Files/MATLAB/MatlabCode/FPGA/data_FPGA.txt","w");  //注意路径/
            #10;      
            for(i = 1;i<=64;i = i+1)begin
                s_axis_data_tvalid = 1;
                din = stimulus[i];
                #4;
            end
            last = 1;
            s_axis_data_tvalid = 0;
            din = 16'b0;       
        end
       
        always # 2 clk = ~clk;
            always @(posedge clk) begin
            $fwrite(file,"%h\n", data_real);  //data_o为需要保存的信号数据
            if(count > 2500)
                $fclose(file);
             count = count + 1;
        end
        fft_test_2 fft2(
            .clk(clk),
            .din(din),
            .last(last),
            .s_axis_data_tvalid(s_axis_data_tvalid),
            .m_axis_data_tdata_r(data_real),
            .m_axis_data_tdata_i(data_image),
            .index(index)
        );  
    endmodule
    

    其中的那个

    $readmemb("D:/Program Files/MATLAB/MatlabCode/FPGA/data_before_fft.txt", stimulus);

    涉及到的文件我上传到了这里,有需要自己下载:data_before_fft.txt

    如果要对比matlab结果,可以不用下载,直接到后面matlab部分,看代码,那里有说怎么生成测试用的数据。

    保存,就可以仿真了!

     

    在仿真页面,将数据的显示格式改一改:(jndex也是无符号十进制)

    仿真结果:

    5.matlab测试结果对比

    新建一个.m文件,代码如下:

    Fs=1e9;                         %采样率1ns一个点
    t=0:1/Fs:63/Fs;                 %数据时长:64个采样周期
    length = 64;
    n = 1:length;
    %% 生成测试信号
    f1 = 31.25e6;                   %
    f2 = 300e6;                     %
    s1 = cos(2*pi*f1*t);    
    s2 = cos(2*pi*f2*t);
    signalN = s1 + s2 ;
    data_before_fft = 100* signalN;  %系数放大100倍
    %% 把数据写到txt里面,让fpga调用
    fp = fopen('data_before_fft.txt','w');
    for i = 1:length
       if(data_before_fft(i)>=0)
           temp= dec2bin(data_before_fft(i),16);
       else
           temp= dec2bin(data_before_fft(i)+2^16+1, 16);
       end
    %     temp = s_bin(i,:);
        for j=1:16
            fprintf(fp,'%s',temp(j));
        end
        fprintf(fp,'\r\n');
    end
    fclose(fp);
    %% 把测试信号fft看看
    data_after_fft1 = fft(data_before_fft);
    data_after_fft = data_after_fft1';
    data_real = real(data_after_fft);
    data_imag = imag(data_after_fft);
    data_r_i = [data_real,data_imag];
    

     

    运行之后可以在数据框里面看看,逐个对比计算差异:

    完毕!散花!


    总结

    matlab和fpga之间的数据互通应该还有别的方式,奈何技艺不精只有这种拙劣的方式(又不是不能用哈哈哈u(~ ̄▽ ̄)~);还有testbench代码里面的涉及到打开电脑本地文件的字符串里面,文件夹的斜杠和windows里面的斜杠是相反的!不然打不开!具体fft里面驱动是怎么写的,为什么是1为什么是0,这个按照需求去查阅,文件在

    C:\Users\Qiang\Documents\XilinxDocs\IP\documentation\ip_documentation\xfft\v9_0

    这个地方,qiang是我的用户名,改成自己的就行了。也可以下载 pg109-xfft.pdf

    展开全文
  • 大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在...首先咱们来了解一下vivadoIP核,IP核(IP Core):Vivado中有很多IP核可以直接使用,例如数学运算(乘法器、除法器、浮点运...
    229a3ccd78a4f45a11a499f9c91c274a.gif大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

    今天给大侠带来Vivado调用IP核详细操作步骤,手把手教学,请往下看。话不多说,上货。

    dcb35f078c893b334e8c103946886467.png首先咱们来了解一下vivado的IP核,IP核(IP Core):Vivado中有很多IP核可以直接使用,例如数学运算(乘法器、除法器、浮点运算器等)、信号处理(FFT、DFT、DDS等)。IP核类似编程中的函数库(例如C语言中的printf()函数),可以直接调用,非常方便,大大加快了开发速度。5e39d9c42c3e752230039c85cc86a182.png

    使用Verilog调用IP核

    c257e0a94b3e486ce449d6c1c7ce110b.png21724287833642c74630ca22dcec56ef.png一、添加IP核1. 点击Flow Navigator中的IP Catalog。2da87836e15cebd9b67088d9a5ec77b2.png2. 选择Math Functions下的Multiplier,即乘法器,并双击。4c21bd028a57fb5475b39b172dd5e8b9.png 3. 将弹出IP核的参数设置对话框。点击左上角的Documentation,可以打开这个IP核的使用手册查阅。这里直接设置输入信号A和B均为4位无符号型数据,其他均为默认值,点击OK。f3e7b7c61ada05f6a3a7507bd8b0b077.png 4. 稍后弹出的窗口,点击Generate。82a406e701b8a1064c62779a3fca3241.pnga7b0bc6850e5e5ef92bad57bf84eb82b.png二、调用IP核1. 选择IP Sources,展开并选择mult_gen_0 - Instantiation Template - mult_gen_0.veo,可以打开实例化模板文件。如图,这段代码就是使用Verilog调用这个IP核的示例代码。e6d4a400e96c684b9d0e39d2e817dbd6.png 2. 将示例代码复制到demo.v文件中,并进行修改,最终如下。代码中声明了无符号型的4位变量a和b,分别赋初值7、8,作为乘数使用;无符号型的8位变量p,用于保存计算结果。clk为Testbench编写的周期20ns的时钟信号;mult_gen_0 mul(...)语句实例化了mult_gen_0类型的模块对象mul,并将clk、a、b、p作为参数传入。17df5a01baa6b746c5f5868c272ed850.pnga7b0bc6850e5e5ef92bad57bf84eb82b.png三、行为仿真验证以demo为顶层模块,启动行为仿真,即可输出波形。设置a、b、p显示为无符号十进制(右击选择Radix - Unsigned Decimal)。如图,可以看到a=7, b=8,第一个时钟上升沿后p = a * b = 56。3402aa756b5bfe2e2ecff1dcdb1a0f91.pnga3fdf94bc60c402bf3dbebd8f8ccf433.png

    框图(Block Design)中调用IP核

    e72221195ceaf00ccaded72dcb5c73f3.pnga38b20b5eb58972c12a71454e1ef172e.png这里举一个简单的例子,通过调用乘法器IP核,产生一个能计算平方的新模块。d197de3388c7bad248ac0f9f2f98f8b8.png一、创建框图设计文件1. 选择Flow Navigator中的Create Block Design,创建一个框图设计文件。f3c82ad7c86c0724c348cd295b4395c4.png2. 输入文件名并点击OK。006d9bce42c4e07c93d7c0991b5c91dc.pnge502fb38c38d8d3b294a6fb990681c96.png二、添加IP核1. 在框图空白处右击,选择Add IP。89e60b72bc8d064cbb0c1b2d6c90d081.png2. 可以直接搜索需要的IP核,双击确认。10158d88ff7e175ec52e60649d2d6971.png3. IP核即可被添加进来,可以用导线将其与其他器件连接。20aa3a2103dd049361594c5508747780.png4. 双击这个IP核符号,可以打开参数设置对话框。点击左上方的Documentation可以查看IP核的手册。这里将输入的A、B均设置为4为无符号型,其他为默认值,点击OK确认。 275537ff96f5a2c96c5b911000330c05.pnge502fb38c38d8d3b294a6fb990681c96.png三、绘制电路1. 右击Diagram窗口空白处,选择Create Port。cfeced028f770516b4db14f9dde136aa.png2. 弹出窗口中,设置端口a为4位输入信号,并点击OK。01620f3c50097a556faa077a9f6814e2.png3. 将a与A、B都连接起来。b8da4d9559e1d39488375956565cba21.png4. 同样的方法,添加一个8位输出端口p,与P连接。f2d35fe4e7c0de929993c15f11c15636.png5. 再添加一个clk时钟输入端口,与CLK连接。ecebf6b9e51ddb7e2aa3db19ba80e668.png6. 最终结果如图。51dcddf1d83ad32a8278b011d1c92ee0.pnge502fb38c38d8d3b294a6fb990681c96.png

    四、仿真测试

    1. 右击框图设计文件design_1,选择Create HDL Wrapper。

    a892be83d7b1ee91a364b8b6ee62a7b4.png2. 选择第二项并点击OK。a0351897a0c04d4d4632edc7af80a9c2.png3. 打开生成的design_1_wrapper.v文件如图,红框中的代码用来调用前面画好的Block Design模块。1a623d1d78ff1da3a681dc96208e505f.png4. 在design_1_wrapper.v文件中,添加Testbench代码即可进行行为仿真。修改代码如下,给输入信号a赋初值为8,clk连接到Testbench生成的时钟信号c上。ff9f5668b96d119fdfe446fe347a8ced.png 5. 在Simulation Sources文件夹下,设置design_1_wrapper.v为行为仿真的顶层文件(右击,选择Set as Top)。e088f319a4b18d490abc76fb9f0e5744.png启动行为仿真,最终输出的波形如下。可以看到,在clk的第一个上升沿后,就有 p = a*a = 64,即实现了平方运算。END后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。大侠们,江湖偌大,继续闯荡,愿一切安好,有缘再见!907129d2bde26132c967e6f8c7947046.png精彩推荐Verilog HDL 语法学习笔记VHDL语法学习笔记:一文掌握VHDL语法Vivado 2017.2 安装教程(含多版本各类安装包)叁芯智能科技 FPGA开发板,热销中!ecb26a7e4418bc837326c4a103cd4ae4.gif

    e81501e14f50780c1a098ef2f52159d6.png

    FPGA技术江湖广发江湖帖

    无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有,QQ微信双选,FPGA技术江湖打造最纯净最专业的技术交流学习平台。

    FPGA技术江湖微信交流群

    3a3cd0a2c5dd4f0fd4453605d2d27387.png

    加群主微信,备注职业+方向+名字进群

    FPGA技术江湖QQ交流群

    e1d904b3699703d28e66457c9edd320a.png

    备注地区+职业+方向+名字进群

    f45d54fbf9bf2579683dea21b705a3e2.png

    展开全文
  • FFT Vivado IP核实现

    2020-11-09 20:30:41
    2、将数据存入rom ip核中 rom核的应用见:https://blog.csdn.net/qq_39005414/article/details/109552835 3、FFT ip核配置 `timescale 1ns / 1ps module rom_fft( input sys_clk_n, input sys_clk_p, input rst_n, ...

    1、首先用matlab产生16bit二进制正弦信号数据,存入rom:

    %设置参数
    fi=5000;
    L=1024;
    N=16;
    fs=20000;
    
    %产生信号
    t=0:1/fs:(L-1)/fs;
    theta=rand()*2*pi;
    si=sin(2*pi*fi*t+theta);
    
    f_s=si/max(abs(si));
    Q_s=round(f_s*(2^(N-1)-1));
    
    fid=fopen('C:\Users\HLPC\Desktop\Sin.txt','w');
    for k=1:length(Q_s)
        B_s=dec2bin(Q_s(k)+(Q_s(k)<0)*2^N,N);
        for j=1:N
            if B_s(j)=='1'
                tb=1;
            else
                tb=0;
            end
            fprintf(fid,'%d',tb);
        end
        fprintf(fid,'\r\n');
    end
    fprintf(fid,';');
    fclose(fid);
    

    2、将数据存入rom ip核中
    rom核的应用见:https://blog.csdn.net/qq_39005414/article/details/109552835
    在这里插入图片描述
    3、FFT ip核配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    `timescale 1ns / 1ps
    module rom_fft(
        input sys_clk_n,
        input sys_clk_p,
        input rst_n,
        output [9:0] a,
        output reg [15:0]data_i,
        output m_axis_data_tvalid,  
        output [63:0] data_o,
        output reg [26:0]fft_re,
        output reg [26:0]fft_im,
        output reg [54:0]fft_amp
        );
    wire clk;    
    wire [15:0]spo;
    reg s_axis_config_tvalid;   
    wire s_axis_config_tready; 
    reg s_axis_data_tvalid;
    reg s_axis_data_tlast;
    wire m_axis_data_tlast;
    wire s_axis_data_tready;
    wire [63:0] m_axis_data_tdata;
    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;
    reg cnt_flag;
    reg [10:0]cnt;
    wire [53:0] xkre_square, xkim_square;
    assign data_o =  m_axis_data_tdata;   
    IBUFDS CLK(
        .I(sys_clk_n),
        .IB(sys_clk_p),
        .O(clk)   
    );
    
    xfft_0 your_instance_name (
      .aclk(clk),                                                // input wire aclk
      .aresetn(rst_n),
      .s_axis_config_tdata(8'd1),                  // 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({16'd0,data_i}),                      // 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(1'b1),                    // 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
    ); 
    
    reg [9:0] cnt1;
    always @(posedge clk)begin
        if(~rst_n)
            cnt1 <= 1'b0;
        else if(cnt1 < 10'd200)
            cnt1 <= cnt1 + 1'b1;
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            cnt_flag <= 1'b0;
        else if(s_axis_config_tvalid)
            cnt_flag <= 1'b1;
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            s_axis_config_tvalid <= 1'b0;
        else if(cnt1 < 10'd200)
            s_axis_config_tvalid <= 1'b1;  
        else
            s_axis_config_tvalid <= 1'b0;  
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            cnt <= 11'd0;
        else if(cnt_flag  )
            if(cnt <= 11'd1023)
                cnt <= 11'd1 + cnt;
            else
                cnt <= cnt;
        else
            cnt <= 11'd0;        
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            s_axis_data_tvalid <= 1'b0;
        else if(cnt_flag && cnt <= 11'd1023)
            s_axis_data_tvalid <= 1'b1;
        else  
            s_axis_data_tvalid <= 1'b0;   
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            s_axis_data_tlast <= 1'b0;
        else if(cnt == 11'd1023)
            s_axis_data_tlast <= 1'b1;
        else  
            s_axis_data_tlast <= 1'b0;   
    end
    
    always @(posedge clk)begin
        if(~rst_n)
            fft_im <= 27'd0;    
        else  
            fft_im <= data_o[58:32];   
    end
    always @(posedge clk)begin
        if(~rst_n)
            fft_re <= 27'd0;    
        else  
            fft_re <= data_o[26:0];   
    end
    
    mult_gen_0 your_instance_name3 (
      .CLK(clk),  // input wire CLK
      .A(fft_re),       // input wire [26 : 0] A
      .B(fft_re),       // input wire [26 : 0] B
      .P(xkre_square)  // output wire [53 : 0] P
    );
    
    mult_gen_0 your_instance_name4 (
      .CLK(clk),  // input wire CLK
      .A(fft_im),       // input wire [26 : 0] A
      .B(fft_im),       // input wire [26 : 0] B
      .P(xkim_square)  // output wire [53 : 0] P
    );
    
    always @(posedge clk)
       if(~rst_n)
          fft_amp <= 55'd0;
       else
          fft_amp <= xkre_square + xkim_square;
    
    dist_mem_gen_0 your_instance_name1 (
      .a(a),                // input wire [9 : 0] a
      .clk(clk),            // input wire clk
      .qspo_rst(~rst_n),  // input wire qspo_rst
      .qspo(spo)          // output wire [15 : 0] qspo
    );  
    
    assign a = cnt;        
     always@(posedge clk or negedge rst_n)begin
        if(~rst_n )
            data_i <=  16'd0;
        else if(a <= 10'd1023)
            data_i <= spo; 
        end
    
    endmodule
    

    testbench仿真

    module vtf_test(
    
        );
        
    wire sys_clk_n;      
    reg sys_clk_p; 
    reg rst_n;
    wire [15:0] data_i;
    wire  [63:0] data_o;
    wire  [26:0] fft_re;
    wire  [26:0] fft_im;
    wire  [54:0] fft_amp;
    wire [9:0] a;
    wire clk;
    wire m_axis_data_tvalid;
    
    rom_fft u_rom_fft(
        .sys_clk_n(sys_clk_n),
        .sys_clk_p(sys_clk_p),
        .rst_n(rst_n),
        .a(a),
        .data_i(data_i),
        .m_axis_data_tvalid(m_axis_data_tvalid),
       .data_o(data_o),
       .fft_re(fft_re),
       .fft_im(fft_im),
       .fft_amp(fft_amp)
        );
        
      
    initial begin
        rst_n = 0;
        sys_clk_p = 0;
        #20;
        rst_n = 1;
        #2000000;
    end
    
    IBUFDS CLK(
        .I(sys_clk_n),
        .IB(sys_clk_p),
        .O(clk)   
    );
    
    integer file_out;
    initial 
    begin
       //文件放置在"工程目录\simulation\modelsim"路径下                                                  
    	file_out = $fopen("out.txt");
    	if(!file_out)
    		begin
    			$display("could not open file!");
    			$finish;
    		end
    end
    always @(posedge clk)begin    
        if(m_axis_data_tvalid)
    	   $fdisplay(file_out,"%d",fft_amp);
    end
    
    integer file_out1;
    initial 
    begin
       //文件放置在"工程目录\simulation\modelsim"路径下                                                  
    	file_out1 = $fopen("out1.txt");
    	if(!file_out)
    		begin
    			$display("could not open file!");
    			$finish;
    		end
    end
    always @(posedge clk)begin
        if((a>0) && (a<10'd1023))
    	   $fdisplay(file_out1,"%d",data_i);
    end
    
    always #5 sys_clk_p=~sys_clk_p;  
    assign  sys_clk_n=~sys_clk_p; 
    
    endmodule
    

    仿真结果
    在这里插入图片描述
    4、将结果输出和matlab fft后的结果对比:

    subplot(2,1,1)
    cstr = textread('D:\fpga_test\rom_fft\rom_fft.sim\sim_1\behav\xsim\out.txt','%d');
    plot(cstr)
    subplot(2,1,2)
    cstr1 = textread('C:\Users\HLPC\Desktop\Sin.txt','%d');
    plot(abs(fft(cstr1)))
    

    在这里插入图片描述

    展开全文
  • vivado FFT IP核中文翻译版本,是有道翻译的版本。Fast Fourier Transform v9.1
  • VIVADO(VHDL语言) FFT IP核简单使用、8点FFT的实现一、VIVADO FFT IP核的调用、配置和生成二、个人配置示例三、个人对IP核的使用,以及引脚含义的理解四、收获仿真 一、VIVADO FFT IP核的调用、配置和生成 点击...

    一、VIVADO FFT IP核的调用、配置和生成

    1. 点击IP Catalog查找到vivado的fft IP核Fast Fourier Transform,双击进入配置界面。
      在这里插入图片描述

    2. 界面介绍,主要分为两大块,左边区域为IP核整体信息介绍部分,右边为详细配置部分。按照自己需求进行配置后可查看左边生成的IP核信息。具体的IP核配置界面介绍和参数分析可查看以下链接中大佬们阐述的内容。
      在这里插入图片描述
      !!!!!!☟☟☟不懂必看系列☟☟☟!!!!!!
      vivado 的IFFT/FFT IP核的配置及调用
      Vivado中FFT9.1 IP核的使用(1)

    看完上面的链接后,可根据自己需求配置IP核
    这里有三个需要注意的点:
    ①:时钟要设置正确,并且仿真或者硬件输入要匹配。如果硬件输入时钟与你的FFT IP核时钟不一致,可以使用MMCM时钟IP核进行转换。仿真时也要记得给对正确的时钟。
    ②:FFT IP核的复位引脚(ARESETn)最好使用,怎么使用?–把时钟IP核输出的locked引脚赋给FFT的复位引脚,并且在locked引脚为低时给FFT IP核一系列输入引脚均赋予初值。时钟IP核locked引脚代表意义:时钟IP核输出的时钟是否稳定有效,低时不稳定,高时表明时钟IP核输出时钟稳定
    ③:FFT IP核的输出模式,依据自己需要进行选择,默认为倒序输出,一般选择为自然输出。

    二、个人配置示例

    还有什么对FFT IP核不懂的均可直接查看官方数据手册,毕竟官方的东西就是牛逼!!
    网上找不到可以进入赛灵思官网,搜索pg109。那里有你最需要的东西!!

    以我调用的FFT IP核配置供大家参考,我定义的FFT IP核时钟为10MHZ,数据通道个数为1,变换点数N=8,输入数据为16位定点可截断数据,并使用了复位引脚(ARESETn),输出模式为自然输出模式(Natural Output),以下是配置截图。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    三、个人对IP核的使用,以及引脚含义的理解

    • 首先从FFT IP核引脚分布来分析,大约可分为五大块
      ①:寄存器配置部分(S_AXIS_CONFIG):它包含三个引脚,分别为TDATA,TREADY,TVALID。配置信息包含在tdata里面,tdata的位宽以及位定义在你配置好IP核后就已经确定,查看IP核信息部分中的IP Symbol栏即可按照正确配置方式在代码中进行寄存器配置。tready,tvaild两兄弟的作用可参考上面链接中详细阐述。

    在这里插入图片描述
    ②:输入数据部分(S_AXIS_DATA):四个引脚TDATA,TREADY,TVALID,TLAST。首先说的是S_AXIS_DATA_TDATA的位宽是你配置FFT IP核时输入数据位宽的两倍,同样位定义可以在IP Symbol查看,为什么是两倍?因为FFT IP核既可以做顺序运算也可做逆运算→也就是IFFT,意思就是给你准备了虚数部分的位定义。S_AXIS_DATA_TDATA低位为实数部分,高位为虚数部分。在哪里配置?在S_AXIS_CONFIG_TDATA里面配置。TREADY,TVALID两兄弟不说了,TLAST是起到一个输入数据末端指示作用,比如你作8点FFT运算,你要给8个数据给IP核吧,在最后一个数据期间你把TLAST拉高就行了,意思是告诉IP核,这一组的8个数据都给你带过来了,这是最后一个。IP核一验算,整整齐齐8个,就不会找你麻烦了。
    ③:输出数据部分(M_AXIS_DATA):输出和输入差不多,使用时将M_AXIS_DATA_TREADY一直拉高即可。
    ④:时钟和复位(aclk/aresetn):时钟和复位正常使用,注意事项上面(一、2、②)已经阐述,遇到问题可参考。
    ⑤:事件报告部分总共七个引脚,具体含义可直接查看手册,一般高有效,主要报告芯片工作状态以及出错情况。

    在这里插入图片描述

    • FFT IP核使用说明及注意事项
      ①:**关于复位引脚的使用,建议大家都用上,保证电路稳点可靠。**如上面(一、2、②)所说,复位引脚可使用时钟IP核输出引脚locked作为复位信号,locked为低时,可以使FFT IP核复位;为高时,时钟输出稳定,并且FFT IP核也正常运行。至于赋FFT IP核输入信号的初值,也可以在locked为低时赋值,这样保证输入信号也达到一个初始化的稳定状态。
      ②:FFT IP核输入数据赋值:当IP核的S_AXIS_DATA_TREADY引脚拉高时,表示核本身已经准备好接收数据,这时,你把S_AXIS_DATA_TDATA拉高N个时钟周期来传N个数据,并同时在每个时钟里都塞入数据,到达数据输入终点时的最后一个数据传输时钟里将S_AXIS_DATA_TDATA拉高一个时钟周期,即完成数据输入。
      ③:始终均可拉高的引脚:S_AXIS_CONFIG_TVALID,S_AXIS_DATA_TREADY。别问,问就是不知道。

    四、收获仿真

    • 我的是8个点的FFT IP核,输入数据简单点,就弄了序列X=[1,2,3,4,5,6,7,8];
      matlab的fft数据如下:

    在这里插入图片描述

    • 我的仿真结果如下:
      输入为8点数据,分别为1-8,使用的是ROM IP核输出的,有关ROM IP核的使用请自行学习,也很简单哦!
      输出自然也为8点,我的FFT IP核输出的是32位数据,低16位为实部,高16位为实部,程序中我已分开输出。
      整体波形
      重点:FFT输入数据波形
      重点:FFT输入、输出数据波形
      ![重点:real_out:输出数据实部、imag_out:输出数据虚部

    五、总结

    • 关于实现代码:希望大家都能从理论上论证学习再到实操实践,自己动手远比拿着别人的结果看一看会收获得多。这里附上vivado VHDL语言的工程文件,有需要的可以下载!
      VIVADO VHDL 8点FFT的简单实现project文件
    • 此文章介绍的FFT IP核内容有限,还不够详细!帮助自己总结,也希望能稍微帮到你们一点,网上论坛和博客中均含有使用FFT IP核的类似文章,我也是一边看网上实操加上看官网提供的IP核数据手册-pg109(这玩意是最准确有效的法宝)才慢慢摸索出来的,不是很难,但也绝非容易。
    • 再强调一下,迷茫的时候大家根据需求多看数据手册,看懂了就没太大问题了。
    • 怕大家没看到,这两篇链接再放出来一下,很好的文章。
      vivado 的IFFT/FFT IP核的配置及调用
      Vivado中FFT9.1 IP核的使用(1)
    • 最后,欢迎大家指正讨论!哔哔完*&……¥撒花✿✿ヽ(°▽°)ノ✿!
    展开全文
  • 最近在忙着仿真FFT IP核,正好在使用FFT IP核的过程中要接触到...FFT IP核的设置这里做最简单的设置,打开Vivado,点开IP Catalog,找到FFT IP核。设置界面如下:Configuration 设置设置的参数意义如下:Numbers o...
  • Xilinx vivado FFT IP核v9.0官方手册 pg109
  • IP核手册,需要的自行下载吧。这个手册详细解释了FFT的使用方法,非常详细。
  • FPGA数字信号处理(九)Vivado FFT IP核实现

    万次阅读 多人点赞 2018-06-14 16:27:45
    该篇是FPGA数字信号处理的第9篇,选题为DSP系统中极其常用的FFT运算。上篇介绍了Quartus环境下FFT IP核的使用“FPGA数字信号处理(八)...本文将介绍在Vivado开发环境下使用Xilinx提供的FFT IP核进行FFT运算的设...
  • Vivado FFT IP核实现

    2019-09-26 16:05:36
    VIVADO中建立一个FFT核,只要依下图步骤就可以开始配置一个FFT核: 需要配置的参数有三个标签页,需要一一配置 第一个标签页里主要配置通道数,点数,时钟,吞吐量,结构,以及是否可以运行时配置,需要注意的是...
  • Xilinx vivado FFT IP v9.0 详解

    万次阅读 多人点赞 2018-08-16 15:36:29
    Xilinx FFT IP v9.0 在线设置变换长度详解 IP介绍 FFT IP核支持三种数据类型: 1. 定点全精度 1. 定点缩减位宽 1. 块浮点 有四种可选择的FFT运算方式: 1. PipelinedStreaming I/O 1. Radix-4Burst I/O 1...
  • vivado FFT IP模块datasheet

    2017-10-07 16:15:35
    fft技术文档;详细介绍FFT模块的端口以及一些功能等;
  • 这是vivado里面付费LTE-FFT IP核的技术文档,在xilinx官网上只能下载到此IP核的简略文档,此版本是详细文档,望有购买需求或者使用需求的开发人员能看到文档之后进一步对此IP核有多了解。
  • VIVADO FFT IP核配置以及端口说明

    千次阅读 2020-04-27 16:37:37
    (以下内容均是在学习了别人博客后,自己小结出来的) 原文链接1:https://blog.csdn.net/FPGADesigner/article/details/80694673 ...#FFT IP核配置说明 第一个选项是同时进行几路数据流并行。 第二个选项是变换的...
  • VivadoFFT IP核的使用

    千次阅读 热门讨论 2020-05-03 17:42:37
    FFT(快速傅里叶变换)作为数字信号处理的核心算法具有重要的研究价值,可应用于傅里叶变换所能涉及的任何领域,如图像处理、音频编码、频谱分析、雷达信号脉冲压缩等数字信号处理领域。FFT的鲜明特征之一是计算离散...
  • 【超详细】VIVADO FFT IP v9.0 进阶

    千次阅读 2020-02-27 12:27:58
    第一次用FFT IP的时候,被吓到了,用过三四次以后基本摸清了使用方法,但是也只是简单的使用,这里写个指南,希望指导小白。 FFT界面 这里以4096为例,图中红圈内可以改点数,一般我下面都是...
  • Vivado Xilinx FFT IP核v9.0 使用详解(附仿真实例) 前几天我导让我研究研究在FPGA上做FFT,作为一个迈进FPGA大门的小白,摸索之旅相当艰难~,现把学习FFT IP核的过程记录下来,为各位同胞提供参考。 一 傅里叶变换...
  • 01FFT简介快速傅里叶变换 (Fast Fourier Transform,FFT), 即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。DFT是实现了从频域(频域分析往往比时域分析更优越)对信号与系统进行分析。然而...

空空如也

空空如也

1 2 3 4 5 6
收藏数 119
精华内容 47
关键字:

fftipvivado