当前位置:   article > 正文

在VIVADO中实现FFT/IFFT_vivado ifft配置

vivado ifft配置

主要思路:(这应该是最简单的方法了)

  1. DDS生成一个固定频率的正交信号
  2. 例化两个FFTIP核分别用作FFT核IFFT变换
  3. 将DDS信号输入到FFT,再将FFT的信号输出到IFFT中

1. dds生乘固定频率正弦信号

调用DDS IP核,进行如下设置,生成10MHz正弦信号:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.调用FFT IP核 进行如下设置

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

3.编写Verilog程序,例化IP核,将3个模块连接起来

代码如下,例化了一个DDS输出10MHz正交信号,例化2个FFT,分别用作FFT/IFFT

`timescale 1ns / 1ps
//
// Company: UESTC
// Engineer: RJY
// 
// Create Date: 2019/05/24 10:32:04
// Design Name: 
// Module Name: fft
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 用于实现DDS输出信号的FFT和IFFT
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module fft(
    input aclk,
    input aresetn,
    output [7:0] fft_real,
    output [7:0] fft_imag,
    output [7:0] ifft_real,
    output [7:0] ifft_imag
    );

    //-----------------DDS core(44.96MHz)------------------
    wire [15:0] dds_m_data_tdata;
    wire fft_s_data_tready;
    wire dds_m_data_tvalid;
    wire dds_m_data_tlast;//未使用
    dds_compiler_0 dds_MHz (
        .aclk(aclk),
        .aresetn(aresetn),
        .m_axis_data_tdata(dds_m_data_tdata),
        .m_axis_data_tready(fft_s_data_tready),
        .m_axis_data_tvalid(dds_m_data_tvalid)
    );

    //----------------------FFT core-------------------
    wire [7:0] fft_s_config_tdata;//[0:0]FWD_INV_0
    wire fft_s_config_tready;
    wire fft_s_config_tvalid;

    wire [7:0] fft_m_status_tdata;
    wire fft_m_status_tready;
    wire fft_m_status_tvalid;

    wire [15:0] fft_m_data_tdata;
    wire fft_m_data_tlast;
    wire ifft_s_data_tready;
    wire [23:0] fft_m_data_tuser;//[11:0]XK_INDEX
    wire fft_m_data_tvalid;

    wire fft_event_frame_started;
    wire fft_event_tlast_unexpected;
    wire fft_event_tlast_missing;
    wire fft_event_status_channel_halt;
    wire fft_event_data_in_channel_halt;
    wire fft_event_data_out_channel_halt;

    wire [11:0] xk_index;
    assign xk_index = fft_m_data_tuser[11:0];
    assign fft_s_config_tdata = 8'd1;//定义FFT模块配置信息(第0位为1表示用FFT,为0表示用IFFT)
    assign fft_s_config_tvalid = 1'd1;//FFT模块配置使能,从一开始就拉高,表示已经准备好要传入的配置数据了
    xfft_0 usr_fft(
        .aclk(aclk),//Rising-edge clock
        .aresetn(aresetn),//(低有效)Active-Low synchronous clear (optional, always take priority over aclken); A minimum aresetn active pulse of two cycles is required
        //S_AXIS_DATA
        .s_axis_data_tdata(dds_m_data_tdata),//IN Carries the unprocessed sample data: XN_RE and XN_IM
        .s_axis_data_tlast(dds_m_data_tlast),//IN Asserted by the external master on the last sample of the frame
        .s_axis_data_tready(fft_s_data_tready),//OUT Used by the core to signal that it is ready to accept data
        .s_axis_data_tvalid(dds_m_data_tvalid),//IN Used by the external master to signal that it is able to provide data
        //S_AXIS_CONFIG
        .s_axis_config_tdata(fft_s_config_tdata),//IN Carries the configuration information
        .s_axis_config_tready(fft_s_config_tready),//OUT Asserted by the core to signal that it is ready to accept data
        .s_axis_config_tvalid(fft_s_config_tvalid),//IN Asserted by the external master to signal that it is able to provide data
        //M_AXIS_STATUS
        .m_axis_status_tdata(fft_m_status_tdata),
        .m_axis_status_tready(fft_m_status_tready),
        .m_axis_status_tvalid(fft_m_status_tvalid),
        //M_AXIS_DATA
        .m_axis_data_tdata(fft_m_data_tdata),//OUT Carries the processed sample data XK_RE and XK_IM
        .m_axis_data_tlast(fft_m_data_tlast),//OUT Asserted by the core on the last sample of the frame
        .m_axis_data_tready(ifft_s_data_tready),//IN Asserted by the external slave to signal that it is ready to accept data. Only present in Non-Realtime mode
        .m_axis_data_tuser(fft_m_data_tuser),//OUT Carries additional per-sample information: XK_INDEX, OVFLO and BLK_EXP
        .m_axis_data_tvalid(fft_m_data_tvalid),//OUT Asserted by the core to signal that it is able to provide status data
        //EVENTS
        .event_frame_started(fft_event_frame_started),//Asserted when the core starts to process a new frame
        .event_tlast_unexpected(fft_event_tlast_unexpected),//Asserted when the core sees s_axis_data_tlast High on a data sample that is not the last one in a frame
        .event_tlast_missing(fft_event_tlast_missing),//Asserted when s_axis_data_tlast is Low on the last data sample of a frame
        .event_status_channel_halt(fft_event_status_channel_halt),//Asserted when the core tries to write data to the Status channel and it is unable to do so
        .event_data_in_channel_halt(fft_event_data_in_channel_halt),//Asserted when the core requests data from the Data Input channel and none is available
        .event_data_out_channel_halt(fft_event_data_out_channel_halt)//Asserted when the core tries to write data to the Data Output channel and it is unable to do so
    );
    
    //-----------------------------IFFT core----------------------------
    wire [7:0] ifft_s_config_tdata;//[0:0]FWD_INV_0
    wire ifft_s_config_tready;
    wire ifft_s_config_tvalid;

    wire [7:0] ifft_m_status_tdata;
    wire ifft_m_status_tready;
    wire ifft_m_status_tvalid;

    wire [15:0] ifft_m_data_tdata;
    wire ifft_m_data_tlast;
    wire ifft_m_data_tready;
    wire [23:0] ifft_m_data_tuser;//[11:0]XK_INDEX
    wire ifft_m_data_tvalid;

    wire ifft_event_frame_started;
    wire ifft_event_tlast_unexpected;
    wire ifft_event_tlast_missing;
    wire ifft_event_status_channel_halt;
    wire ifft_event_data_in_channel_halt;
    wire ifft_event_data_out_channel_halt;

    wire [11:0] ixk_index;
    assign ixk_index = ifft_m_data_tuser[11:0];
    assign ifft_s_config_tdata = 8'd0;//定义FFT模块配置信息(第0位为1表示用FFT)
    assign ifft_s_config_tvalid = 1'd1;//FFT模块配置使能,从一开始就拉高,表示已经准备好要传入的配置数据了
    assign ifft_m_data_tready = 1'd1;//从一开始就拉高,表示已经准备好接收IFFT模块输出的数据
    xfft_0 usr_ifft(
        .aclk(aclk),//Rising-edge clock
        .aresetn(aresetn),//(低有效)Active-Low synchronous clear (optional, always take priority over aclken); A minimum aresetn active pulse of two cycles is required
        //S_AXIS_DATA
        .s_axis_data_tdata(fft_m_data_tdata),//IN Carries the unprocessed sample data: XN_RE and XN_IM
        .s_axis_data_tlast(fft_m_data_tlast),//IN Asserted by the external master on the last sample of the frame
        .s_axis_data_tready(ifft_s_data_tready),//OUT Used by the core to signal that it is ready to accept data
        .s_axis_data_tvalid(fft_m_data_tvalid),//IN Used by the external master to signal that it is able to provide data
        //S_AXIS_CONFIG
        .s_axis_config_tdata(ifft_s_config_tdata),//IN Carries the configuration information
        .s_axis_config_tready(ifft_s_config_tready),//OUT Asserted by the core to signal that it is ready to accept data
        .s_axis_config_tvalid(ifft_s_config_tvalid),//IN Asserted by the external master to signal that it is able to provide data
        //M_AXIS_STATUS
        .m_axis_status_tdata(ifft_m_status_tdata),
        .m_axis_status_tready(ifft_m_status_tready),
        .m_axis_status_tvalid(ifft_m_status_tvalid),
        //M_AXIS_DATA
        .m_axis_data_tdata(ifft_m_data_tdata),//OUT Carries the processed sample data XK_RE and XK_IM
        .m_axis_data_tlast(ifft_m_data_tlast),//OUT Asserted by the core on the last sample of the frame
        .m_axis_data_tready(ifft_m_data_tready),//IN Asserted by the external slave to signal that it is ready to accept data. Only present in Non-Realtime mode
        .m_axis_data_tuser(ifft_m_data_tuser),//OUT Carries additional per-sample information: XK_INDEX, OVFLO and BLK_EXP
        .m_axis_data_tvalid(ifft_m_data_tvalid),//OUT Asserted by the core to signal that it is able to provide status data
        //EVENTS
        .event_frame_started(ifft_event_frame_started),//Asserted when the core starts to process a new frame
        .event_tlast_unexpected(ifft_event_tlast_unexpected),//Asserted when the core sees s_axis_data_tlast High on a data sample that is not the last one in a frame
        .event_tlast_missing(ifft_event_tlast_missing),//Asserted when s_axis_data_tlast is Low on the last data sample of a frame
        .event_status_channel_halt(ifft_event_status_channel_halt),//Asserted when the core tries to write data to the Status channel and it is unable to do so
        .event_data_in_channel_halt(ifft_event_data_in_channel_halt),//Asserted when the core requests data from the Data Input channel and none is available
        .event_data_out_channel_halt(ifft_event_data_out_channel_halt)//Asserted when the core tries to write data to the Data Output channel and it is unable to do so
    );

    //----------------将FFT/IFFT处理完的信号传出(虚部/实部分别传出)-------
    assign fft_real = fft_m_data_tdata[7:0];
    assign fft_imag = fft_m_data_tdata[15:8];
    assign ifft_real = ifft_m_data_tdata[7:0];
    assign ifft_imag = ifft_m_data_tdata[15:8];

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166

4. 编写仿真文件

具体代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2019/05/22 12:11:32
// Design Name: 
// Module Name: fft_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module fft_tb(

    );
    reg aclk,aresetn;
    wire [7:0] fft_real,fft_imag;
    wire [7:0] ifft_real,ifft_imag;

    fft fft_test(      
        .aclk(aclk),
        .aresetn(aresetn),
        .fft_real(fft_real),
        .fft_imag(fft_imag),
        .ifft_real(ifft_real),
        .ifft_imag(ifft_imag)
    );

    initial
    begin
        aclk = 0;
        aresetn = 0;//低有效
        #10 aresetn = 1;
    end

    always #5 aclk=~aclk;//时钟频率100MHz

    //-----------将FFT变换结果写入文件-------------(下面的可以删除)
    integer w_file;
    initial w_file = $fopen("C:/Users/luobl/Desktop/fft_test/fft_real.txt");
    always @(posedge aclk)
    begin
        $fdisplay(w_file,"%b",fft_real);//写数据
    end
    
    integer w_file2;
    initial w_file2 = $fopen("C:/Users/luobl/Desktop/fft_test/fft_imag.txt");
    always @(posedge aclk)
    begin
        $fdisplay(w_file2,"%b",fft_imag);
    end

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

5. run behavier simulation 运行仿真

生成图形如下:
在这里插入图片描述
下图可以看到FFT输出的模拟波形尖峰处对应的index为409;
那么对应的频率应该是 409*100e6/4096 = 9.985e6,约等于10MHz;
其中100e6是采样频率,4096是FFT点数
在这里插入图片描述
将IFFT波形信号调整为模拟有符号十进制,可以看到下图IFFT输出的波形,可以根据图中的时钟信号计算出波形周期为100ns,即频率为10MHz
在这里插入图片描述
这应该是最简单的方式实现FFT/IFFT了吧,如果大家有更好的方法,可以留言交流~

文中的完整工程文件可以在这里下载:https://download.csdn.net/download/luobluesky/11200680

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/511076
推荐阅读
相关标签
  

闽ICP备14008679号