FFT算法实现之fft IP核
文章目录
- 端口详解
- matlab实验
- vivado实验结果
- 代码
- ip核配置
- 仿真结果
- 难点
端口详解
输入端
data端口组:
- tdata: 设置16位数据这里会是32位,因为考虑虚部
- tlast:当输入序列最后一位进入时, 要求tlast拉高,这对于连续的信号处理有必要, 如果只处理一次可以不管
- tready:代表IP核允许接收第二次数据
- tvalid: 数据数据有效信号, 代表当前数据有效
config端口组:
- tdata:1–》正变换;0–》反变换;
- tready、tvalid 只有在勾选“Run time Configurable Transform Length”时需要设置, 因为此时配置信息(tdata)允许在工作周期中更改
输出端
status端口组:
- m_axis_status_tready 非必选,外部系统准备好接收状态信号的时候输入高电平。仅用于非实时状态。
- m_axis_status_tvalid 状态信息有效信号
- m_axis_status_tdata 携带BLK_EXP以及OVFLO信息,两个信息不能同时通过该输出口显示。当缩放模式选择scaled时m_axis_status_tdata代表OVFLO,代表数据是否溢出。
当缩放模式选择块浮点时,携带BLK_EXP信息。BLK_EXP代表缩放位数,会自动选择在不溢出的情况下缩放的最大值。比如BLK_EXP的值为00101(二的五次方),意思就是输出的结果为实际结果的32分之一。
data端口组:
- m_axis_data_tdata 输出数据的实部虚部。
- m_axis_data_tlast 输出数据的最后一位到来拉高。
- m_axis_data_tready 非必选,外部系统准备好接收数据信号的时候输入高电平。仅用于非实时状态。
----未完待续—
https://www.bilibili.com/video/BV18h4y1k7PZ/?spm_id_from=333.1387.homepage.video_card.click&vd_source=f12f53fed02a66a1da6584b2c947cacf
matlab实验
clc;
clear all;
close all;
%fs=10e6;
fs=50e6 %对应vivado系统时钟50MHZ?
N = 2048;
f1=4e6;
f2=3e6;n=0:N-1;
t=n/fs;
f=fs*n/N;s1=sin(2*pi*f1*t);
s2=sin(2*pi*f2*t);
mixsls2=s1.*s2;
mixsls2=mixsls2+0i;
subplot (2,1,1)
plot (mixsls2)
fftsls2=fft (mixsls2);
fftabs=abs (fftsls2);%
subplot(2,1,2)
plot (fftabs)
%xlim([0, 10e6]);
vivado实验结果
代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/07/22 10:33:56
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////module test(input clk ,
// input rst ,output [ 31: 0] fft_out );
//---------------------------------------------------------------------------------------
// 内部端口定义
//--------------------------------------------------------------------------------------- wire [ 7: 0] sin1 ;wire [ 7: 0] sin2 ;wire signed [ 15: 0] sin_mux ;//---------------------------------------------------------------------------------------
// fft端口定义 wire s_axis_config_tready, s_axis_data_tready,m_axis_data_tvalid,m_axis_data_tlast;wire [ 7: 0] m_axis_status_tdata ;wire signed [ 31: 0] m_axis_data_tdata ;// fft输出wire m_axis_status_tvalid ;wire m_axis_status_tready ;wire sin_m_axis_data_tvalid ;wire [ 23: 0] m_axis_data_tuser ;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 ;wire [ 31: 0] fft_input ;assign fft_input = {16'b0,sin_mux};assign sin1_m_axis_data_tvalid = 1'b1;// 直接赋值为1,表示数据有效;assign m_axis_status_tready = 1'b1;assign sin_m_axis_data_tvalid = 1'b1;
//--------------------------------------------------------------------------------------- wire signed [ 15: 0] a,b ;// fft输出的实部和虚部分量 wire signed [ 31: 0] Pa, Pb;//分量平方wire [ 10: 0] index ;assign {a, b} = m_axis_data_tdata;assign fft_out = Pa+Pb;assign index = m_axis_data_tuser[10:0];// fft输出的index
//---------------------------------------------------------------------------------------
// IP核调用
//---------------------------------------------------------------------------------------
xfft_0 fft1 (.aclk (clk ),// input wire aclk.s_axis_config_tdata (8'b1 ),// input wire [7 : 0] s_axis_config_tdata.s_axis_config_tvalid (1 ),// input wire s_axis_config_tvalid.s_axis_config_tready (s_axis_config_tready ),// output wire s_axis_config_tready.s_axis_data_tdata (fft_input ),// input wire [31 : 0] s_axis_data_tdata.s_axis_data_tvalid (sin_m_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 (1 ),// input wire s_axis_data_tlast.m_axis_data_tdata (m_axis_data_tdata ),// output wire [31 : 0] m_axis_data_tdata.m_axis_data_tuser (m_axis_data_tuser ),// output wire [23 : 0] m_axis_data_tuser.m_axis_data_tvalid (m_axis_data_tvalid ),// output wire m_axis_data_tvalid.m_axis_data_tready (1 ),// input wire m_axis_data_tready.m_axis_data_tlast (m_axis_data_tlast ),// output wire m_axis_data_tlast.m_axis_status_tdata (m_axis_status_tdata ),// output wire [7 : 0] m_axis_status_tdata.m_axis_status_tvalid (m_axis_status_tvalid ),// output wire m_axis_status_tvalid.m_axis_status_tready (m_axis_status_tready ),// input wire m_axis_status_tready.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
);//---------------------------------------------------------------------------------------
// 计算平方
mult_gen_1 PA (.CLK(clk), // input wire CLK.A(a), // input wire [15 : 0] A.B(a), // input wire [15 : 0] B.P(Pa) // output wire [31 : 0] P
);
mult_gen_1 PB (.CLK(clk), // input wire CLK.A(b), // input wire [15 : 0] A.B(b), // input wire [15 : 0] B.P(Pb) // output wire [31 : 0] P
);
//---------------------------------------------------------------------------------------DDS u_DDS(.clk (clk ),.sin1 (sin1 ),.sin2 (sin2 ),.sin_mux (sin_mux )
);endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/07/22 10:33:56
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////module DDS(input clk ,output [ 7: 0] sin1 ,output [ 7: 0] sin2 ,output signed [ 15: 0] sin_mux );wire sin_m_axis_data_tvalid;//---------------------------------------------------------------------------------------
// IP核调用
//---------------------------------------------------------------------------------------mult_gen_0 mult1 (.CLK (clk ),// input wire CLK.A (sin1 ),// input wire [7 : 0] A.B (sin2 ),// input wire [7 : 0] B.P (sin_mux ) // output wire [15 : 0] P
);dds_compiler_0 dds1 (.aclk (clk ),// input wire aclk.m_axis_data_tvalid (sin_m_axis_data_tvalid ),// output wire m_axis_data_tvalid.m_axis_data_tdata (sin1 ) // output wire [7 : 0] m_axis_data_tdata
);
dds_compiler_1 dds2 (.aclk (clk ),// input wire aclk.m_axis_data_tvalid (sin_m_axis_data_tvalid ),// output wire m_axis_data_tvalid.m_axis_data_tdata (sin2 ) // output wire [7 : 0] m_axis_data_tdata
);endmodule
ip核配置
仿真结果
与matlab一致
难点
- IP核端口参数以及接线设置,matlab参数与vivado参数对应(fs >>>时钟频率?,N>>>IP核N设置 )
- vivado数据位宽设置, 我是跟着教程(B站老乔FPGA)写的代码, 自己写能知道吗。。