实例化FFT(vivado) 以及matlab和fpga的fft结果对比

您所在的位置:网站首页 verilog浮点数fft 实例化FFT(vivado) 以及matlab和fpga的fft结果对比

实例化FFT(vivado) 以及matlab和fpga的fft结果对比

2024-07-03 00:29| 来源: 网络整理| 查看: 265

前言

我是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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3