当前位置:网站首页>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
边栏推荐
- Web worker introduction and use cases
- 资深猎头团队管理者:面试3000顾问,总结组织出8大共性(茅生)
- 【IDEA】IDEA 格式化 代码技巧 idea 格式化 会加 <p> 标签
- MySQL删除表后如何使ID从1开始
- Advertising is too "wild", Yoshino "surrenders"
- 华为伙伴暨开发者大会2022 | 麒麟软件携手华为共建计算产业,共创数智未来
- Senior headhunting team manager: interviewed 3000 consultants, summarized and organized 8 commonalities (Mao Sheng)
- Discuz小鱼游戏风影传说商业GBK+UTF8版模板/DZ游戏网站模板
- Summary of various loams (laser SLAM)
- CUDA error:out of memory caused by insufficient video memory of 6G graphics card
猜你喜欢

Redis principle - string

Spark BUG實踐(包含的BUG:ClassCastException;ConnectException;NoClassDefFoundError;RuntimeExceptio等。。。。)

Discuz小鱼游戏风影传说商业GBK+UTF8版模板/DZ游戏网站模板

webService

Livox Lidar+海康Camera 基于loam的实时三维重建生成RGB彩色点云

Advertising is too "wild", Yoshino "surrenders"

Design of STM32 and rc522 simple bus card system

因美纳陷数据泄露“丑闻”:我国基因数据安全能交给美企吗?

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

To build a "strong core" in Nansha, the first IC Nansha conference was held in Nansha
随机推荐
One to many association in MySQL to obtain the latest data in multiple tables
Discuz淘宝客网站模板/迪恩淘宝客购物风格商业版模板
Introduction to MySQL operation (IV) -- data sorting (ascending, descending, and multi field sorting)
“顶流爱豆制造机”携手四个产业资本,做LP
webService
Summary of various loams (laser SLAM)
移动端避免使用100vh[通俗易懂]
Spug - 轻量级自动化运维平台
跟着存档教程动手学RNAseq分析(四):使用DESeq2进行DE分析的QC方法
MySQL删除表后如何使ID从1开始
【经典干货书】数据科学中的信息理论方法,561页pdf
华为伙伴暨开发者大会2022 | 麒麟软件携手华为共建计算产业,共创数智未来
游戏手机平台简单介绍
【IDEA】IDEA 格式化 代码技巧 idea 格式化 会加 <p> 标签
「R」使用ggpolar绘制生存关联网络图
NDSS 2022 接收的列表
OData - API using SAP API hub in SAP S4 op
用pytorch进行CIFAR-10数据集分类
pytorch实现kaggle猫狗识别
Spark BUG实践(包含的BUG:ClassCastException;ConnectException;NoClassDefFoundError;RuntimeExceptio等。。。。)