Vivado FFT IP核

本文详细介绍了FFTIP核的配置选项,包括通道数、变换长度、架构选择和接口功能,以及如何生成测试波形和进行仿真验证。作者通过实例展示了如何配置和使用该IP核,以及如何解读输出结果。
摘要由CSDN通过智能技术生成


参考文档:pg109

一、FFT IP核的配置

参考:P59~P62

1.1 Configuration

在这里插入图片描述

Number of channels:FFT通道数目,可以选择多通道,实现多帧数据同时进行FFT运算
Transform length:FFT变换长度
Target clock frequency:采样时钟
Target data throughput:数据时钟
Architecture choice:FFT架构选择,根据需求选择

  • Automatically select:自动选择所需要的FFT架构
  • Pipelined streaming IO:并行流水线结构,处理时间最短,资源消耗最大,多通道不支持pipeline架构
  • Radix-4 burst i/o:基4 IO突发结构

Run Time Configurable Transdorm Legth:选中后可以通过设置s_axis_config_tdata中NFFT字段的长度来改变FFT变换的长度

1.2 Implementation

在这里插入图片描述

Data format:数据类型

  • 定点数
  • 浮点数

Scaling options:缩放选项

  • Block floating point:不管输入的格式如何,FFT变化内部都采用浮点,会根据每一级的数据情况自动缩放。这个模式的输入输出位宽一致,便于调用。
  • Scaled:在m_axis_data_tuser中会有5bit表示每一级的缩放情况,在s_axis_config_data中会有相应的字段配置来配置缩放因子。
  • Unscaled:不用担心变化过程中出现溢出,但是输入是32bit的话,输出是64bit。

Aresetn:复位信号
Rounding modes:截断方式
Output ordering:输出顺序

  • Nature order:就是FFT变化后的输出已经调整了的顺序,按照xk_index自然顺序列出变化结果。
  • Bit/digital reserved order:按照变化后的顺序直接输出,是倒序输出,需要自己后续处理。

Cylic prefix insertion:循环前缀插入,在进行IFFT后可以根据s_axis_config_data中的CP长度配置自动添加CP。

Optional output fileds:选项输出字段

  • Xk_index:FFT变化的结果索引,在m_axis_data_user中有相应的字段。
  • OVFLO:是变换中溢出的指示信号,对应event_fft_overflow。

1.3 接口

参考:P10~P28

在这里插入图片描述

端口意义
s_axis_config_tdata用于配置IP核,置1时做FFT运算,置0时做IFFT运算。
s_axis_config_tvalidIP核配置输入有效,一般直接置1。
s_axis_config_tready表示已准备好接受数据
s_axis_data_tready表示从设备已经准备好接收一次数据传输。
s_axis_data_tdata输入数据,[31:16]是虚部,[15:0]是实部。
s_axis_data_tvalid输入数据有效。
s_axis_data_tlast传输结束信号,一般发送完N点数据后置1,s_valid置1到s_last置1所用时间即为做FFT所耗费的时间。
m_axis_data_tdata输出的频谱数据,[47:24]对应的是虚部数据,[23:0]对应的是实部数据,高位补符号位。
m_axis_data_tvalid输出数据有效
m_axis_data_tuser输出FFT的索引值,该值*fs/N即为对应频点,N为FFT点数。
m_axis_data_tready表示从设备已经准备好接收一次数据传输。
event_frame_started当核开始处理一个新的帧时声明,输入数据时拉高一个时钟周期。
event_tlast_unexpected当内核在非帧中最后一个数据采样的s_axis_data_tlast为高电平时触发。
event_tlast_missing在帧的最后一个数据样本上s_axis_data_tlast为低时声明。
event_fft_overflow当在m_axis_data_tdata上传输的数据样本中看到溢出时在每个时钟周期声明,只有当溢出是一个有效的选项时才出现。
event_data_in_channel_halt内核从数据输入通道请求数据,并且没有数据可用时声明。
event_data_out_channel_halt内核尝试将数据写入数据输出通道,并且无法执行时声明。
event_status_channel_halt内核尝试将数据写入状态通道,并且无法执行时声明。

二、生成测试波形

参考代码:

clc;
clear;
close all;
f=2e6; %信号频率为2MHz
fs= 50e6 ; 
N=1024;
t =(0:N-1)/fs; 
x=cos(2*pi*f*t)*2^10 ; %范围为-1024~1024

%时域波形
figure(1);
plot(t,x);

%频域波形
f = (-N/2: N/2-1) * (fs/N) ;
mag=abs(fft(x));
figure(2) ;
plot(f, fftshift(mag)) ;

for i=1:N
    if(x(i)>0)
       x(i)=round(x(i));
    elseif(x(i)==0)
       x(i)=0;
    else
        x(i)=round(x(i))+2^12;%加2^12是求负数补码,12是因为-1024需要12位二进制表示
    end
end

fid = fopen('wave.txt', 'wt') ; 
fprintf(fid, '%x\n', x) ;%以16进制写入文件中
fclose(fid) ;

📄 对于负的输入,需要求它的补码,再送入IP核,FFT IP核会将输入数据视为有符号数来处理。

  • 对于一个N位的负数,其最高位是符号位,求它的补码的方法是 2 N 2^N 2N
  • 例如,-5(1101),加 2 4 = 16 2^4=16 24=16后为11(1011),1011正是-5的补码。

三、仿真

`timescale 1ns / 1ps

module tb();

//IP核接口信号
reg aclk;
reg aresetn;

wire s_axis_config_tready;

reg signed [31:0] s_axis_data_tdata;
reg s_axis_data_tvalid;
wire s_axis_data_tready;
reg s_axis_data_tlast;

wire signed [47 : 0] m_axis_data_tdata;
wire [15 : 0] m_axis_data_tuser;
wire m_axis_data_tvalid ;
reg m_axis_data_tready;
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;

reg [11:0] Data[1023:0];
reg [10:0] cnt;

reg signed [23:0] fft_data_real;
reg signed [23:0] fft_data_imag;
wire signed [48:0] fft_power;
wire signed [15:0] data_display;

initial begin
    aclk=1'b0;
    aresetn=1'b0;
    $readmemh("你的输入数据存放路径",Data);
    m_axis_data_tready=1'b1;
    #15;
    aresetn=1'b1;
end    
always #10 aclk=~aclk;

//求模平方
assign fft_power=fft_data_real*fft_data_real+fft_data_imag*fft_data_imag;
assign data_display=s_axis_data_tdata[15:0];//取输入的低16位观察波形
//送入数据,每1024个数据产生一个last
always@(posedge aclk or negedge aresetn)begin
    if(!aresetn)begin
        cnt<='b0;
        s_axis_data_tdata<='b0;
        s_axis_data_tvalid<='b0;
        s_axis_data_tlast<='b0;
    end
    else if(s_axis_data_tready)begin
        if(cnt<1023)begin
            s_axis_data_tlast<=1'b0;
            s_axis_data_tvalid<=1'b1;
            s_axis_data_tdata<={16'b0,{4{Data[cnt][11]}},Data[cnt]};
            cnt<=cnt+1'b1;
        end
        else begin
           s_axis_data_tlast<=1'b1;
           s_axis_data_tvalid<=1'b1;
           cnt<=11'b0;
           s_axis_data_tdata<={16'b0,{4{Data[cnt][11]}},Data[cnt]}; 
        end
    end
    else begin
        s_axis_data_tvalid<=1'b0;
        s_axis_data_tlast<=1'b0;
        s_axis_data_tdata<=s_axis_data_tdata;
    end
end

always@(posedge aclk or negedge aresetn)begin
    if(!aresetn)begin
       fft_data_real<='b0;
       fft_data_imag<='b0; 
    end
    else if(m_axis_data_tvalid)begin
       //取输出频谱的实部和虚部
       fft_data_real<=m_axis_data_tdata[23:0];
       fft_data_imag<=m_axis_data_tdata[47:24]; 
    end
    else begin
        fft_data_real<=fft_data_real;
        fft_data_imag<=fft_data_imag;
    end
end
//例化IP核
xfft_0 xfft_u (
  .aclk(aclk),                                                 // input wire aclk
  .aresetn(aresetn),                                          // input wire aresetn
  .s_axis_config_tdata(1'b1),                                 // input wire [7 : 0] s_axis_config_tdata
  .s_axis_config_tvalid(1'b1),                                // 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 [47 : 0] m_axis_data_tdata
  .m_axis_data_tuser(m_axis_data_tuser),                      // output wire [15 : 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

📄输出频谱有两个谱峰,一个大概对应于tuser=42,一个大概对应于tuser=983。这里解释一下,FFT IP核的输出结果其实是它的真实谱的正频部分搬移至负频左侧并对应于0~1023点的结果。这其实有些类似于我们使用MATLAB中的fft函数做N点FFT后,得到的结果不经过fftshift函数转换而直接绘制全部频谱的情况。可以认为,真实谱的零点对应于第1023点,所以负频部分大概对应于1023-42=981的位置。这其中难免有微小的误差,所以983可以认为是正确的负频。
📄而正如在1.3中提到的tuser*fs/N就是真实的频点,这里可以计算验证一下,即 42 ∗ 50 M / 1024 ≈ 2 M 42*50M/1024\approx2M 4250M/10242M,和在MATLAB中设置的信号频率相符。

在这里插入图片描述

### 回答1: Vivado FFT IP核是Xilinx公司提供的一种用于高性能快速傅里叶变换(FFT)的可编程逻辑器件,可用于信号处理通信系统、雷达、音频处理和图像处理等领域。 Vivado FFT IP核的主要功能是实现快速傅里叶变换,这是一种将时域信号转换为频域信号的数学技术。FFT是一种高效的算法,能够在较短的时间内对信号进行频谱分析和频率测量。Vivado FFT IP核提供了多种FFT算法,包括基于蝶形算法、流水线和并行化等技术,可以根据应用的需求选择适合的算法。 Vivado FFT IP核提供了多种配置选项,可以实现不同数据宽度、数据精度和时域点数的FFT计算。用户可以通过Vivado设计环境来配置和生成FFT IP核,方便地集成到自己的设计中。IP核的接口支持AXI4-Stream和AXI4-Lite等标准接口,与其他系统组件进行数据交换。 通过使用Vivado FFT IP核,用户可以在FPGA上快速实现高性能的FFT计算,提高系统的性能和效率。IP核的可编程性使得用户可以根据应用需求进行定制,并且可以随着设计的迭代进行功能增强或优化。此外,使用IP核还可以减少设计开发时间和复杂度,提高设计的可重用性。 综上所述,Vivado FFT IP核是一种用于快速傅里叶变换的可编程逻辑器件,具有灵活的配置选项和高性能的计算能力。使用该IP核可以快速实现高性能的FFT计算,提高系统的性能和效率。 ### 回答2: Vivado FFT IP核是Xilinx公司提供的一种用于快速傅里叶变换(FFT)运算的IP核FFT是一种用于信号频谱分析的算法,广泛应用于数字信号处理领域。Vivado FFT IP核通过硬件加速的方式,实现了高效的FFT计算。 Vivado FFT IP核具有以下主要特点: 1. 高性能:Vivado FFT IP核使用专门的FFT硬件来执行计算,速度比软件实现的FFT更快。它能够在很短的时间内完成大规模FFT计算。 2. 可定制性:Vivado FFT IP核提供了许多可定制的选项。用户可以根据具体的需求选择不同的FFT大小、输出数据宽度、输入数据格式等。这样有助于优化设计,提高系统整体性能。 3. 多种接口:Vivado FFT IP核支持多种接口,如AXI4-Stream接口、AXI4-Lite接口等,方便与其他IP核或外部系统进行连接。 4. 低功耗:Vivado FFT IP核经过优化设计,能够在低功耗下运行,节约能源消耗。 Vivado FFT IP核的应用范围广泛。在通信领域中,它可以用于信号解调、频谱分析、通道估计等。在图像处理领域中,它可以用于图像压缩、图像增强等。此外,在雷达、声音处理、金融分析等其他领域也有广泛的应用。 Vivado FFT IP核的使用步骤相对简单。首先,在Vivado设计工具中导入该IP核,在设计中进行配置和参数设置。然后,将IP核与其他系统进行连接,并根据需要编写相应的控制和数据处理逻辑。最后,生成比特流文件(bitstream)并下载到目标设备中进行验证和调试。 总之,Vivado FFT IP核是一种高性能、可定制的FFT计算IP核,广泛应用于信号处理等领域,为设计人员提供了快速可靠的FFT计算解决方案。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hi小瑞同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值