当前位置:   article > 正文

Xilinx vivado FFT IP v9.0 详解_pipelined streaming

pipelined streaming

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

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

这里写图片描述

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

IP设置

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

这里写图片描述

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

IP输入输出信号

这里写图片描述

整个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个时钟周期以上,之后送入配置命令即可。

命令格式:

这里写图片描述
这里写图片描述
可以看到命令长度的低5位就是我们在线更改变换点数的命令位置。
这里写图片描述
按照官方的命令格式就可以编写自己需要的点数了。

代码和运行截图

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
  • 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

运行截图

开始初始化可以看到进行的16点变换
这里写图片描述
之后复位,重新修改命令
这里写图片描述
可以看到已经编程64点变换了。

这里写图片描述

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

闽ICP备14008679号