当前位置:网站首页>Vivado FFT IP的使用说明
Vivado FFT IP的使用说明
2022-06-27 20:50:00 【ML__LM】
Vivado FFT IP的使用说明
1 IP说明
1.1 Configuration Channel



1.2 管脚描述






2 例化IP
2.1 DDS IP
输出频率字的计算公式:deta_theta=f_out*(2^B)/f_clk
B:相位位宽,这里为32
/f_clk :125M。注意,例化DDS IP时,输入信号的频率也必须为125M。


2.2 FFT IP
第一页配置(Configuration):
(1)Number of Channels:多通道输入。FFT转换通道的个数
(2)Transform Length :FFT的点数
(3)Architecture Configuration:
Target Clock Frequency:工作时钟;
Architecture choice:选择一种FFT结构。包括自动匹配、流水线Streaming、基4 Burst、基2 Burst和轻量级基2 Burst,它们的计算速度和消耗的资源依次减少,可根据工程实际进行选择。
(4)Run Time Configurable Transform Length:实时更改FFT的点数。

第二页配置(Implementation):
(1)Data Format:设置FFT的数据格式为定点Fixed Point或浮点Float Point;
(2)Scaling Option:输出截位方式选择。不截位(Unscaled),截位(Scaled),块浮点(Block Floating Point);
(3)Precision Option:设置输入数据的位宽和相位因子位宽;
(4)Control Signals:时钟使能(ACLKEN),复位信号(ARESETn,低有效);
(5)Output Ordering Option:用以选择FFT计算结果以自然顺序(Nature Order)或位倒序(Bit/Digit Reversed Order)输出。

第三页配置(Detailed Implementation):
可设置优化方式、存储的类型。
存储类型分为两种:Block RAM(块RAM)和Distributed RAM(分布式RAM)
优化方式可选择资源最优或者速度最优。


3 程序
3.1 程序结构

3.2 top模块
`timescale 1ns / 1ps
//模块功能:1024个点的FFT变换,并得到幅度谱
module top(
input clk ,
input rst_n
);
//----------2、根据频率字,利用DDS生成参考信号{RtI,RtQ}
wire [31:0] m_axis_data_PINC;
dds_sin Inst_dds_sin (
.aclk(clk), // input wire aclk
.s_axis_config_tvalid(1'b1), // input wire s_axis_config_tvalid
.s_axis_config_tdata(32'd343597384), // 频率字 对应频率10M
.m_axis_data_tvalid(), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_PINC), // output wire [31 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata() // output wire [31 : 0] m_axis_phase_tdata
);
wire [15:0] RtI ;//参考信号的实部 与频率字相对应
wire [15:0] RtQ ;
assign RtI=m_axis_data_PINC[31:16];
assign RtQ=m_axis_data_PINC[15:0];
wire [31:0] tdata_i ;
assign tdata_i={
16'd0,RtI};
//---------2、例化FFT,实现1024个点的FFT变换,并得到幅度谱
wire fft_s_data_tready;
wire [63:0] fft_m_data_tdata ;
wire [63:0] fft_abs ;
wire fft_abs_valid ;
fft_test fft_test_inst(
//input
.clk (clk ),
.rst_n (rst_n ),
.tvalid_i (1'b1 ),
.tdata_i (tdata_i ),
//output
.fft_s_data_tready (fft_s_data_tready ),//必须有,否则第一次的数据无法进行FFT
.fft_m_data_tdata (fft_m_data_tdata ),
.fft_abs (fft_abs ),
.fft_abs_valid (fft_abs_valid )//幅度谱结果有效
);
wire [63:0] data_max ;
wire DataMax_Vaild ;
Max_Get Inst_Max_Get(
//input
.clk (clk ),
.reset (!rst_n ),
.En (fft_abs_valid ),
.data_in (fft_abs ),
//output
.data_max (data_max ) ,
.DataMax_Vaild (DataMax_Vaild)
);
endmodule
## 3.2 fft_test模块```
```cpp
// I:实部 Q:虚部
// fft_m_data_tuser) 输出频谱的索引该值* fs/N,即为输入信号的频点
//fs(65M)和N(Transform Length)的值见FFT IP 设置
/* 3、NFFT:可选,本次设计没有使用 位宽为5 Point size of the transform,NFFT can be the size of the maximum transform or any smaller point size. For example, a 1024-point FFT can compute point sizes 1024, 512, 256, and so on. The value of NFFT is log2 (point size). 如果是2048个采样点 NFFT=log2(2048)=11=01011 The transform point size can be set through the NFFT field in the Configuration channel if the run time configurable transform length option is selected. 只有选中run time configurable transform length这个选项,NFFT才可以配置。 2、CP_LEN:(Cyclic prefix length) 可选,本次设计没有使用 位宽为log2(采样点数) The number of samples from the end of the transform that are initially output as a cyclic prefix, before the whole transform is output. CP_LEN can be any number from zero to one less than the point size. This field is only present with cyclic prefix insertion. 只有选中 cyclic prefix insertion这个选项时,CP_LEN才可以配置。。 1、FWD_INV: 必须 位宽为:1 bit per FFT data channel Indicates if a forward FFT transform or an inverse FFT transform is performed. FWD_INV = 1, a forward transform is computed. FFT变换 FWD_INV = 0, an inverse transform is computed. IFFT变换 Each FFT data channel has an assigned FWD_INV field 0、SCALE_SCH: 可选,本次设计没有使用 for Pipelined Streaming I/O and Radix-4 Burst I/O architectures,位宽为:2*ceil(NFFT/2) for Radix-2, Burst I/O and Radix-2 Lite Burst I/O architectures 位宽为:2*NFFT This field is only available with scaled arithmetic (not unscaled, block floating-point or singleprecision floating-point). 只有选中scalingOption的 scaled 这个选项时,SCALE_SCH才可以配置。 All fields with padding should be extended to the next 8-bit boundary if they do not already finish on an 8-bit boundary. */
//模块功能:1024个点的FFT变换,并得到幅度谱
module fft_test(
input clk ,// 时钟信号
input rst_n ,// 复位信号
input tvalid_i ,//表示外界输入数据有效,此时能够给FFT IP核提供数据
input [31:0] tdata_i ,//提供给FFT IP核的外界输入数据(时域信号)
output fft_s_data_tready ,// 表示FFT IP核准备好接受数据
output [63:0] fft_m_data_tdata ,// FFT 变换后的结果(频域信号)
output reg [63:0] fft_abs , // 幅度谱
output fft_abs_valid
);
//----------FFT IP从端的输入数据和valid信号控制-----------//
// 控制什么时候给FFT IP给输入数据以及输入给FFT IP的数据是否有效
reg fft_s_data_tvalid;
reg [31:0] fft_s_data_tdata;
reg fft_s_data_tlast;
reg [10:0] count;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
fft_s_data_tvalid<=1'b0;
fft_s_data_tdata<=32'dx;
fft_s_data_tlast<=1'b0;
count<=11'd0;
end
else if (tvalid_i)
//else if (tvalid_i && fft_s_data_tready) //外界输入数据有效,且FFT IP准备好接收数据,表示握手成功
begin
fft_s_data_tvalid<=1'b1; //输入给FFT IP的数据有效
fft_s_data_tdata<=tdata_i; //给FFT IP灌数据
if(count==1024) //最后一个数据
begin
fft_s_data_tlast<=1'b1;//last信号拉高
count<=11'd0; //计数器清零
end
else
begin
fft_s_data_tlast<=1'b0;//last信号拉低
count<=count+1; //计数器的值+1
end
end
else //外界数据无效或者且FFT IP没有准备好接收数据,握手不成功
begin
fft_s_data_tvalid<=1'b0; // FFT IP的从端数据无效
fft_s_data_tdata<=32'dx; //数据保持,不给新数据
fft_s_data_tlast<=1'b0;
count<=count;
end
end
//-----------------例化FFT IP--------------//
//wire fft_m_data_tvalid ;
wire fft_m_data_tlast ;
wire [15:0]fft_m_data_tuser ;
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 ;
xfft_0 xfft_0_inst(
//FFT的时钟、时钟使能、复位信号(注意复位信号要多给几个时钟)
.aclk(clk), // input wire aclk
.aresetn(rst_n), // input wire aresetn
// FFT的重配置接口
.s_axis_config_tdata(8'd1), // input wire [7 : 0] s_axis_config_tdata
.s_axis_config_tvalid(1'b1), // input wire s_axis_config_tvalid
.s_axis_config_tready(), // output wire s_axis_config_tready
//FFT的数据输入接口,遵循AXI-Stream协议
.s_axis_data_tdata(fft_s_data_tdata), // input wire [31 : 0] s_axis_data_tdata
.s_axis_data_tvalid(fft_s_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(fft_s_data_tready), // output wire s_axis_data_tready
.s_axis_data_tlast(fft_s_data_tlast), // input wire s_axis_data_tlast
//FFT的数据输出接口,遵循AXI-Stream协议
.m_axis_data_tdata(fft_m_data_tdata), // output wire [63 : 0] m_axis_data_tdata
.m_axis_data_tuser(fft_m_data_tuser), // output wire [15 : 0] m_axis_data_tuser
.m_axis_data_tvalid(fft_abs_valid), // output wire m_axis_data_tvalid
.m_axis_data_tready(1'b1), // input wire m_axis_data_tready
.m_axis_data_tlast(fft_m_data_tlast), // output wire m_axis_data_tlast
//可以输出一些FFT的错误信息,比如输入的last未知不正确或没有,数据溢出等等
.event_frame_started(fft_event_frame_started), // output wire event_frame_started
.event_tlast_unexpected(fft_event_tlast_unexpected), // output wire event_tlast_unexpected
.event_tlast_missing(fft_event_tlast_missing), // output wire event_tlast_missing
.event_status_channel_halt(fft_event_status_channel_halt), // output wire event_status_channel_halt
.event_data_in_channel_halt(fft_event_data_in_channel_halt), // output wire event_data_in_channel_halt
.event_data_out_channel_halt(fft_event_data_out_channel_halt) // output wire event_data_out_channel_halt
);
//---------------得到信号的幅度谱---------------//
reg [31:0] dati_out;
reg [31:0] datq_out;
// I:实部 Q:虚部
always @(posedge clk)
begin
if(fft_abs_valid)
begin
datq_out<=fft_m_data_tdata[63:32];//虚部
dati_out<=fft_m_data_tdata[31:0];//实部
end
end
always @(posedge clk)
begin
// fft_abs<=$signed(dati_out)* $signed(dati_out)+ $signed(datq_out)* $signed(datq_out);
fft_abs<=($signed(dati_out)* $signed(dati_out)+ $signed(datq_out)* $signed(datq_out))/1024;
end
endmodule
3.3 Max_Get模块```
`timescale 1ns / 1ps
// 寻找寻找一串序列(1024个点)的最大值
module Max_Get(
input clk ,
input reset ,
input En ,//寻找最大值模块开始工作的使能信号
input [63:0] data_in ,// 输入数据
output reg [63:0] data_max ,//搜索得到的最大值
output reg DataMax_Vaild
);
reg [63:0] data_max_temp; //最大值寄存器
reg [3:0] ST_max_search;//状态机
reg [15:0] count;//计数器
[email protected](posedge clk)
begin
if(reset)
begin
data_max_temp<=64'd0;
ST_max_search<=4'd0;
count<=16'd0;
DataMax_Vaild<=1'b0;
end
else
begin
case(ST_max_search)
0:
begin
if(En==1'b1)//使能有效,模块开始工作
begin
ST_max_search<=4'd1;
end
else
begin
ST_max_search<=4'd0;
end
end
1:
begin
if(count<16'd1024)//还没有比较到1024个点
begin
count<=count+1'd1;
ST_max_search<=4'd1;//
if(data_in>data_max_temp)
data_max_temp<=data_in;
else
data_max_temp<=data_max_temp;
end
else//if(count==16'd1024)
begin
count<=16'd0;
ST_max_search<=4'd0;
data_max<= data_max_temp;
data_max_temp<=64'd0;//最大值数据寄存器数据归零,避免影响下一次寻求最大值
DataMax_Vaild<=1'b1;
end
end
default:
ST_max_search<= 4'd0;//跳到状态0 end
endcase
end
end
endmodule
3.4 testbench
`timescale 1ns / 1ps
module sim_top;
//input
reg clk;
wire clk_125M;
reg rst_n;
output
//wire fft_s_data_tready;
//wire [63:0] fft_m_data_tdata;
//wire [63:0] fft_abs ;
//-----------例化top模块----------//
top top_inst(
//input
.clk (clk_125M ),
.rst_n (rst_n )
// //output
// .fft_s_data_tready (fft_s_data_tready ),
// .fft_m_data_tdata (fft_m_data_tdata ),
// .fft_abs (fft_abs )
);
initial
begin
clk=0;
rst_n=0;
#50
rst_n=1;
end
always #5 clk=~clk;//10ns 100M
clk_wiz_0 Inst_clk_wiz_0
(
// Clock out ports
.clk_out1(clk_125M), // output clk_out1 125M
// Status and control signals
.reset(~rst_n), // input reset
.locked(), // output locked
// Clock in ports
.clk_in1(clk)//100M
); // input clk_in1
endmodule
4 仿真结果分析
DDS产生的信号频率为10M,T=100ns
FFT IP计算出来的信号频率:输出频谱的索引该值* fs/N=82*125M/1024=10.0097M.和DDS的输出信号频率一致
两次FFT估计出来的信号的幅度误差:(266210147231-256096801523)/256096801523=0.0395
边栏推荐
- MapReduce初级编程实践
- Azure Kinect DK realizes 3D reconstruction (PC non real time version)
- 资深猎头团队管理者:面试3000顾问,总结组织出8大共性(茅生)
- Web worker introduction and use cases
- EasyCVR平台路由日志功能的技术实现过程【附代码】
- Fsnotify interface of go language to monitor file modification
- UESTC (shenhengtao team) & JD AI (Mei Tao team) proposed a structured dual stream attention network for video Q & A, with performance SOTA! Better than the method based on dual video representation!
- 树莓派(以及各种派)使用指南
- Classification of cifar-10 dataset with pytorch
- Workflow automation low code is the key
猜你喜欢

What problems should be paid attention to in the serpentine wiring of PCB?

Mysql database experiment report (I)

Summary of various loams (laser SLAM)

netERR_ CONNECTION_ Refused solution

Is the dog virtue training with a monthly salary of 30000 a good business?

元气森林的5元有矿之死

Spark bug Practice (including bug: classcastexception; connectexception; noclassdeffounderror; runtimeexceptio, etc.)

Introduction to MySQL operation (IV) -- data sorting (ascending, descending, and multi field sorting)

Livox Lidar+海康Camera实时生成彩色点云

基于 ESXi 的黑群晖 DSM 7.0.1 安装 VMware Tools
随机推荐
本机部署一个MongoDB单节点服务器,并启用auth验证、开启oplog
Livox Lidar+海康Camera 基于loam的实时三维重建生成RGB彩色点云
Batch processing - Excel import template 1.1- support multiple sheet pages
EXCEL 打印设置公共表头
Death of 5 yuan youkuang in Yuanqi forest
Liuleifeng, a "good man in Guangzhou" in the first quarter of 2022, has a strong sense of integrity and food safety
Zabbix6.0 upgrade Guide - how to synchronize database upgrades?
What problems should be paid attention to in the serpentine wiring of PCB?
Classification of cifar-10 dataset with pytorch
CUDA error:out of memory caused by insufficient video memory of 6G graphics card
Hiplot 在线绘图工具的本地运行/开发库开源
Bibliothèque d'exploitation / de développement locale open source pour l'outil de dessin en ligne hiplot
MySQL删除表后如何使ID从1开始
未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。 不是有效的 Win32 应用程序。 (异常来自 HRESULT:0x800700C1)
Feign implements path escape through custom annotations
陈云pytorch学习笔记_用50行代码搭建ResNet
Small chip chiplet Technology
Using xgboost with tidymodels
pytorch基础(1)
电子科大(申恒涛团队)&京东AI(梅涛团队)提出用于视频问答的结构化双流注意网络,性能SOTA!优于基于双视频表示的方法!