Xilinx vivado FFT IP v9.0 详解

Xilinx FFT IP v9.0 详解

IP介绍

FFT IP核支持三种数据类型:
1. 定点全精度
1. 定点缩减位宽
1. 块浮点

有四种可选择的FFT运算方式:
1. PipelinedStreaming I/O
1. Radix-4Burst I/O
1. Radix-2Burst I/O
1. Radix-2 Lite Burst I/O

四种方式区别主要体现在运算速度和所占资源上:

Xilinx vivado FFT IP v9.0 详解_第1张图片

本IP核可进行2^M(M=3~16)点的FFT、IFFT,同时支持在线更改变换点数和正负fft的功能。需要注意的是在线变更感换点数功能不支持PipelinedStreaming I/O、Radix-4Burst I/O这两种模式。
同时,IP核支持多数据并行运算,即多个数据流同时进行运算与输出。

IP设置

下面以配置一个在线可更改变换点数的FFT IP 核为目标,具体说明各个部分。
创建工程、添加IP核,并进行IP核的设置。

Xilinx vivado FFT IP v9.0 详解_第2张图片

第一个选项是同时进行几路数据流并行。
第二个选项是变换的实际点数,需要注意的是我们这里设计可以在线更改变换点数的FFT,所以这里选择的点数是所需要的最大的FFT点数。
下面的五选一选项选择Redix-2 Burst I/O。可以发现当点数小于64时,不支持Radix-4Burst I/O模式。
Xilinx vivado FFT IP v9.0 详解_第3张图片
最后勾选Run Time Configurable Transform Length,这个就是配置可在线更改的FFT IP核。如果不进行勾选,再怎么这传输配置信号也没有作用。
Xilinx vivado FFT IP v9.0 详解_第4张图片
第二页选择整数、不压缩数据、和取整模式。
其他选项如图所示。
Xilinx vivado FFT IP v9.0 详解_第5张图片
第三页同样如图所示。
在配置完成之后可以看到模块的相关信息,比较有用的是latency(延迟)。
Xilinx vivado FFT IP v9.0 详解_第6张图片

IP输入输出信号

Xilinx vivado FFT IP v9.0 详解_第7张图片

整个IP的信号线可以分为三个部分:

  • 三个AXI4-Stream的总线分别完成数据的输入输出和命令的输入。
  • 时钟线和复位线是IP核的基本信号。
  • 之后是一大堆的状态线,以event开头,标志了IP核的不同状态和遇到的各种问题。

下面简单说明一下AXI4-Stream:

总的来说AXI4-Stream总线分为主(一般开头带个m)从(一般开头带个s)两部分组成。一个主连接一个从,形成了一个严密的握手结构。在整个通信过程中,tdata是数据的通路,tready、tvalid两个信号分别由一个主一个从控制,主(或从)准备好接受(或发送)数据时,会拉高自己控制的信号线,如果两边都准备好了(即两个线都拉高了)开始传数据。tlast信号的作用是:当前的数据是一组数据的最后一个时tlast信号会拉高,用于数据对齐,同时还有一定的数据判错作用。还有一个tuser信号,会表明当前周期传递的信号是第几个数据。

各个状态线及其作用:

event_frame_started:每一新的次fft开始时上跳一次。
event_tlast_unexpected:当s_axis_data_tlast上跳,但IP核认为这并不是最后一个数据时上跳一次。
event_tlast_missing:当IP核认为这是最后一个数据,但s_axis_data_tlast还是低的时候,该信号上跳。
event_fft_overflow:在从数据输出通道输出的数据样本中发现溢出时上跳。只有当overflow选项被选择有效时才出现。
event_data_in_channel_halt:当IP核需要新的输入数据但输入口并没有提供足够的数据时拉高。
event_data_out_channel_halt:当 IP核尝试输出数据但无法输出时(可能时输出对象没有给IP核输出接收使能信号)拉高。只在Non-Realtime 模式下有效。
event_status_channel_halt:当 IP核尝试输出数据到状态通道但无法输出时拉高。只在Non-Realtime 模式下有效。

在线修改变换点数。

在设置正确之后,修改变换点数非常简单,只要拉低复位线3个时钟周期以上,之后送入配置命令即可。

命令格式:

Xilinx vivado FFT IP v9.0 详解_第8张图片
Xilinx vivado FFT IP v9.0 详解_第9张图片
可以看到命令长度的低5位就是我们在线更改变换点数的命令位置。
Xilinx vivado FFT IP v9.0 详解_第10张图片
按照官方的命令格式就可以编写自己需要的点数了。

代码和运行截图

testbench

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/08/09 11:29:26
// Design Name: 
// Module Name: fft_Tes_TB
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module fft_Tes_TB;

 reg aclk;
 reg aresetn;
 reg [15 : 0] s_axis_config_tdata;
 reg s_axis_config_tvalid;
 wire s_axis_config_tready;
 reg [63 : 0] s_axis_data_tdata;
 reg s_axis_data_tvalid;
 wire s_axis_data_tready;
 reg s_axis_data_tlast;
 wire [79 : 0] m_axis_data_tdata;
 wire [7 : 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] mem0_re[256:0]; 
 reg    [7:0] op_sample= 0;
 reg op_sample_first = 1;
 reg    [7:0] ip_frame=0;
 reg    [7:0] op_frame=0;

 initial $readmemh("C:/Users/74339/Desktop/vivado_code/fft_test/signal.txt",mem0_re);
 integer i;
 reg s_data;

 fft_Tes uut (                                           
   .aclk(aclk), // input wire aclk
   .aresetn(aresetn), // input wire aresetn
   .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 [63 : 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 [79 : 0] m_axis_data_tdata
   .m_axis_data_tuser(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
 ); 

 always #5 aclk = !aclk;

 initial begin
  // Initialize Inputs
  aclk = 0;
  aresetn = 0;
  s_axis_config_tvalid = 0;
  s_axis_config_tdata = 0;
  s_axis_data_tvalid = 0;
  s_axis_data_tdata = 0;
  s_axis_data_tlast = 0;
  m_axis_data_tready = 0;
  s_data = 0;
  i = 0;
  // Wait 100 ns for global reset to finish
  #150;
  aresetn = 1;
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  s_axis_config_tdata = 16'b0101100101000100; // FFT desired (and not IFFT
  //s_axis_config_tdata = 24'b100100000000000100; // FFT desired (and not IFFT

  s_axis_data_tlast = 1;
  s_axis_data_tdata = 96'h000000;  
  s_axis_data_tvalid = 0;

  #3000;
  aresetn = 0;
  #300;
  aresetn = 1;  
  m_axis_data_tready = 1;
  s_axis_config_tvalid = 1;
  s_axis_config_tdata = 16'b0101100101000110; // FFT desired (and not IFFT
  //s_axis_config_tdata = 24'b100100000000000111; // FFT desired (and not IFFT

  s_axis_data_tlast = 1;
  s_axis_data_tdata = 96'h000000;  
  s_axis_data_tvalid = 0;


 s_axis_data_tvalid = 0;
 end

 always @(posedge aclk)
 begin
  if(s_axis_data_tready == 1)
  begin
   s_axis_data_tvalid <= 1;
   //s_axis_data_tdata <= s_data;
   //s_data = s_data +1;
   s_axis_data_tdata <= mem0_re[i];
   $display("mem_a[%d] = %h", i, mem0_re[i]);

   if((i % 16)==0)
    s_axis_data_tlast <= 1;
   else
    s_axis_data_tlast <= 0;
   i = i + 1;
  end
 end
endmodule

运行截图

开始初始化可以看到进行的16点变换
Xilinx vivado FFT IP v9.0 详解_第11张图片
之后复位,重新修改命令
Xilinx vivado FFT IP v9.0 详解_第12张图片
可以看到已经编程64点变换了。

Xilinx vivado FFT IP v9.0 详解_第13张图片

你可能感兴趣的:(ZYNQ)