前面我们已经讲解过Xilinx中FFT IP的使用,但是使用的时候IP的配置接口我们没有进行相应的讲解,直接使用GUI配置好的接口,这在现实应用中很不方方便,会让人感觉到还不如自己手写一个FFT算法,当然博主也可完全手撕FFT、CORDIC代码,但是把IP用好了绝对比我们手写的代码要好用的多。这篇博客主要讲解FFT IP的重配置及其参数的意义,最后将给出Modelsim与MATLAB的两盒验证。
本次实验所使用的软硬件环境如下:
1、VIVADO 2019.1
2、Modelsim 10.7
3、MATLAB 2015b
这里再多说一句,从博主之前的文章中可以发现MATLAB在信号处理中的正确性,所以绝对不要说MATLAB不重要。而且一般Xilinx的IP核都可以生成相应的m文件,也就是说我们可以实现MATLAB与Modelsim完全一致的验证。 所以要想做信号处理或算法得FPGA实现一定要掌握MATLAB。
我们在定制FFT IP核得时候就已经对FFT进行了配置,但是我们实际使用IP得时候经常可以碰见IP得重配置,这一块内容直至一年前我进行PLL得重配置得时候还是无从下手,但是这篇文章我们主要讲解FFT IP得重配置,可以让大家学习到Xilinx IP重配置得设计技巧。这里我们首先强调技术手册得重要性,因为市面上没有这方面得资料,所以我们要学习相应IP得重配置必须学习技术手册。我们首先看FFT IP得技术手册如下:
总共不到100页,是值得浏览一遍的,因为其他得IP基本上也是这几部分。C Model我们上篇博客已经进行了介绍,主要是为了我们在MATLAB中验证该模块得正确性来使用的。
首先我们来看FFT IP核的接口引脚:
其中FFT的接口主要可以分为6组如上图:
1、FFT的重配置接口
2、FFT的数据输入接口,遵循AXI-Stream协议
3、FFT的时钟、时钟使能、复位信号(注意复位信号要多给几个时钟)
4、FFT的数据输出接口,遵循AXI-Stream协议
5、可以输出FFT IP的当前的状态(一般不常使用)
6、可以输出一些FFT的错误信息,比如输入的last未知不正确或没有,数据溢出等等
上面是简要介绍了FFT IP的接口描述。具体的功能引脚的定义还是需要我们查找技术手册,我们这篇博客主要讲解IP的重配置,不会对AXI-Stream进行过多的介绍。
从FFT IP技术手册的首页我们可以发现,FFT可以完成的功能:
上面也是我们进行重配置的主要内容:
1、FFT最大变换的点数
2、FFT正变换还是逆变换
3、每级蝶形运算缩放因子的输入
4、CP_LEN的长度(这个具体的所用,我也不知道,知道的同学可以在评论里讨论一下)
要想配置上面的这些信息,我们就一定要进行配置数据的输入,配置数据的不同位数代表不同的功能,如下:
上面为什么会有PAD,主要是因为字节对齐,每个配置功能占整数个字节。其中除了SCALE_SCH上面的位宽都是确定的,如下:
上面每位的取值情况如下:
上面的功能需要大家仔细读,尤其是SCALE_SCH,这里我给大家稍微解读一下。
1、每两个比特位构成的数字作为一级蝶形运算的缩放比例。2位比特位构成了0,1,2,3,这三个数代表分别代表蝶形运算之后的结果移位的个数。
2、SCALE_SCH的位数对于基-4 FFT算法是 2 ∗ c e i l ( N F F T 2 ) 2*ceil(\frac{NFFT}{2}) 2∗ceil(2NFFT),其中ceil是指向上取整;对于基-2 FFT算法是 2 ∗ N F F T 2*NFFT 2∗NFFT,相信熟悉FFT蝶形运算的同学很容易明白,其实这就是蝶形运算的个数然后乘以2。
关于FFT重配置的理论我们就讲到这里,下面我们给出相应的代码供大家学习,并且将代码与上篇博客中的MATLAB生成的结果相互验证,从而使得MATLAB与VIVADO实现双重验证。
tx_ifft_op模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : tx_ifft_op.v
// Create Time : 2020-06-04 16:33:48
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module tx_ifft_op(
input sclk ,
input rst_n ,
input cfg_vld ,
output reg p1_start ,
input s_config_tvalid ,
input [29:0] s_config_tdata ,
input s_data_tvalid ,
input [23:0] s_data_tdata ,
input s_data_tlast ,
output reg s_axis_config_tready ,
output reg s_axis_data_tready ,
output reg [31:0] m_axis_data_tdata ,
output [23:0] m_axis_data_tuser ,
output reg m_axis_data_tvalid ,
input m_axis_data_tready ,
output reg m_axis_data_tlast ,
output [ 7:0] m_axis_status_tdata ,
output m_axis_status_tvalid ,
input m_axis_status_tready ,
output event_frame_started ,
output event_tlast_unexpected ,
output event_tlast_missing ,
output event_fft_overflow ,
output event_status_channel_halt ,
output event_data_in_channel_halt ,
output event_data_out_channel_halt ,
output [ 9:0] NOFDM
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 9:0] NOFDM_CNT ;
wire [39:0] s_axis_config_tdata ;
wire s_axis_config_tvalid ;
wire [31:0] s_axis_data_tdata ;
wire s_axis_data_tvalid ;
wire s_axis_data_tlast ;
wire [ 4:0] NFFT ;
wire [13:0] SCALE_SCH ;
wire [11:0] RE_DATA ;
wire [11:0] IM_DATA ;
wire DATA_LAST ;
wire DATA_EN ;
wire FWD_INV ;
wire fft_config_en ;
wire [31:0] m_axis_data_tdata_store ;
wire m_axis_data_tvalid_store;
wire m_axis_data_tlast_store ;
reg p1_start_D ;
wire [12:0] CP_LEN ;
reg last_delay ;
wire Neg_ifft_tlast ;
reg [ 4:0] rstn_cnt ;
wire s_axis_data_tready1 ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign Neg_ifft_tlast = last_delay&&(~m_axis_data_tlast_store);
always@(posedge sclk)
last_delay <= m_axis_data_tlast_store;
always @(posedge sclk)
if(rst_n == 1'b0)
NOFDM_CNT <= 10'd0;
else if(NOFDM_CNT == NOFDM+1'b1 && NOFDM != 10'd0)
NOFDM_CNT <= 10'd0;
else if(Neg_ifft_tlast == 1'b1)
NOFDM_CNT <= NOFDM_CNT + 1'b1;
always @(posedge sclk)
if(rst_n == 1'b0)
rstn_cnt <= 5'h1f;
else if(cfg_vld == 1'b1)
rstn_cnt <= 5'd0;
else if(rstn_cnt == 5'h1f)
rstn_cnt <= rstn_cnt;
else
rstn_cnt <= rstn_cnt + 1'b1;
always @(posedge sclk)
if(rst_n == 1'b0)
p1_start <= 1'b0;
else if(rstn_cnt == 5'h1e)
p1_start <= 1'b1;
else if(NOFDM_CNT == NOFDM+1'b1 && NOFDM != 10'd0)
p1_start <= 1'b1;
else
p1_start <= 1'b0;
always @(posedge sclk)
if(rst_n == 1'b0)
s_axis_data_tready <= 1'b1;
else if(Neg_ifft_tlast == 1'b1)
s_axis_data_tready <= 1'b1;
else if(s_data_tlast == 1'b1)
s_axis_data_tready <= 1'b0;
always @(posedge sclk)
p1_start_D <= p1_start;
always @(posedge sclk)
if(rst_n == 1'b0)
s_axis_config_tready <= 1'b0;
else if(p1_start_D == 1'b1)
s_axis_config_tready <= 1'b0;
else if(Neg_ifft_tlast == 1'b1)
s_axis_config_tready <= 1'b1;
always @(posedge sclk)
begin
m_axis_data_tdata <= m_axis_data_tdata_store;
m_axis_data_tvalid <= m_axis_data_tvalid_store && m_axis_data_tready;
m_axis_data_tlast <= m_axis_data_tlast_store;
end
ifft_op_map ifft_op_map
(
.sclk (sclk ),
.rst_n (rst_n ),
.s_config_tvalid (s_config_tvalid ),
.s_config_tdata (s_config_tdata ),
.s_data_tvalid (s_data_tvalid ),
.s_data_tdata (s_data_tdata ),
.s_data_tlast (s_data_tlast ),
.RE_DATA (RE_DATA ),
.IM_DATA (IM_DATA ),
.DATA_EN (DATA_EN ),
.DATA_LAST (DATA_LAST ),
.fft_config_en (fft_config_en ),
.NFFT (NFFT ),
.CP_LEN (CP_LEN ),
.SCALE_SCH (SCALE_SCH ),
.FWD_INV (FWD_INV ),
.NOFDM (NOFDM )
);
/*===================================================================
====================================================================*/
fft_sig_comp fft_sig_comp
(
.sclk (sclk ),
.rst_n (rst_n ),
.P1_EN (DATA_EN ),
.RE_P1_DATA (RE_DATA ),
.IM_P1_DATA (IM_DATA ),
.data_LAST (DATA_LAST ),
.fft_config_en (fft_config_en ),
.NFFT (NFFT ),
.CP_LEN (CP_LEN ),
.SCALE_SCH (SCALE_SCH ),
.FWD_INV (FWD_INV ),
.s_axis_config_tdata (s_axis_config_tdata ),
.s_axis_config_tvalid (s_axis_config_tvalid ),
.s_axis_data_tdata (s_axis_data_tdata ),
.s_axis_data_tvalid (s_axis_data_tvalid ),
.s_axis_data_tlast (s_axis_data_tlast )
);
tx_xfft_0 tx_xfft_0 (
.aclk (sclk ),
.aresetn (rst_n ),
.s_axis_config_tdata (s_axis_config_tdata ),
.s_axis_config_tvalid (s_axis_config_tvalid ),
.s_axis_config_tready (sim_config_tready ),
.s_axis_data_tdata (s_axis_data_tdata ),
.s_axis_data_tvalid (s_axis_data_tvalid ),
.s_axis_data_tready (s_axis_data_tready1 ),
.s_axis_data_tlast (s_axis_data_tlast ),
.m_axis_data_tdata (m_axis_data_tdata_store ),
.m_axis_data_tuser (m_axis_data_tuser ),
.m_axis_data_tvalid (m_axis_data_tvalid_store ),
.m_axis_data_tready (m_axis_data_tready ),
.m_axis_data_tlast (m_axis_data_tlast_store ),
.m_axis_status_tdata (m_axis_status_tdata ),
.m_axis_status_tvalid (m_axis_status_tvalid ),
.m_axis_status_tready (m_axis_status_tready ),
.event_frame_started (event_frame_started ),
.event_tlast_unexpected (event_tlast_unexpected ),
.event_tlast_missing (event_tlast_missing ),
.event_fft_overflow (event_fft_overflow ),
.event_status_channel_halt (event_status_channel_halt ),
.event_data_in_channel_halt (event_data_in_channel_halt ),
.event_data_out_channel_halt (event_data_out_channel_halt)
);
endmodule
ifft_op_map模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : ifft_op_map.v
// Create Time : 2020-06-04 16:49:13
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module ifft_op_map
(
input sclk ,
input rst_n ,
input s_config_tvalid ,
input [29:0] s_config_tdata ,
input s_data_tvalid ,
input [23:0] s_data_tdata ,
input s_data_tlast ,
output reg [11:0] RE_DATA ,
output reg [11:0] IM_DATA ,
output reg DATA_EN ,
output reg DATA_LAST ,
output reg fft_config_en ,
output reg [ 4:0] NFFT ,
output reg [12:0] CP_LEN ,
output reg [13:0] SCALE_SCH ,
output reg FWD_INV ,
output reg [ 9:0] NOFDM
);
/*===================================================================
====================================================================*/
wire [ 1:0] fft_mode ;
wire [ 9:0] nofdm ;
wire [ 2:0] cp_pro ;
wire [13:0] scale ;
wire inv ;
reg [ 2:0] PRO ;
reg [ 1:0] MODE ;
reg [ 1:0] MODE1 ;
reg [ 9:0] NOFDM1 ;
reg [ 2:0] PRO1 ;
reg [13:0] SCALE_SCH1 ;
reg FWD_INV1 ;
reg fft_config_en1 ;
assign fft_mode = s_config_tdata[1:0];
assign nofdm = s_config_tdata[11:2];
assign cp_pro = s_config_tdata[14:12];
assign scale = s_config_tdata[28:15];
assign inv = s_config_tdata[29];
always @(posedge sclk)
begin
if(rst_n == 1'b0)begin
MODE1 <= 2'b00;
NOFDM1 <= 10'd0;
PRO1 <= 3'b000;
SCALE_SCH1 <= 14'd0;
FWD_INV1 <= 1'b0;
end else if(s_config_tvalid)begin
MODE1 <= fft_mode;
NOFDM1 <= nofdm;
PRO1 <= cp_pro;
SCALE_SCH1 <= scale;
FWD_INV1 <= inv;
end
end
always@(posedge sclk)begin
MODE <= MODE1;
NOFDM <= NOFDM1;
PRO <= PRO1;
SCALE_SCH <= SCALE_SCH1;
FWD_INV <= FWD_INV1;
end
always @(posedge sclk)begin
RE_DATA <= s_data_tdata[23:12];
IM_DATA <= s_data_tdata[11:0];
DATA_EN <= s_data_tvalid;
DATA_LAST <= s_data_tlast;
end
always@(posedge sclk)
begin
fft_config_en1 <= s_config_tvalid;
fft_config_en <= fft_config_en1;
end
always @(posedge sclk)
if(PRO1 == 3'd0)
CP_LEN <= 13'd0;
else if(PRO1 == 3'd1)//1/32
CP_LEN <= 13'd32;
else if(PRO1 == 3'd2)//1/16
CP_LEN <= 13'd64;
else if(PRO1 == 3'd3)//1/8;
CP_LEN <= 13'd128;
else if(PRO1 == 3'd4)//1/4;
CP_LEN <= 13'd256;
else
CP_LEN <= 13'd0;
always @(posedge sclk)
case(MODE1)
2'b00: NFFT <= 5'b01010;//1k
2'b01: NFFT <= 5'b01011;//2k
2'b10: NFFT <= 5'b01100;//4k
2'b11: NFFT <= 5'b01101;//8k
default:NFFT <= 5'b00000;
endcase
endmodule
fft_sig_comp模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : fft_sig_comp.v
// Create Time : 2020-06-04 16:55:01
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module fft_sig_comp(
input sclk ,
input rst_n ,
input P1_EN ,
input [11:0] RE_P1_DATA ,
input [11:0] IM_P1_DATA ,
input data_LAST ,
input fft_config_en ,
input [ 4:0] NFFT ,
input [12:0] CP_LEN ,
input [13:0] SCALE_SCH ,
input FWD_INV ,
output [39:0] s_axis_config_tdata ,
output s_axis_config_tvalid,
output [31:0] s_axis_data_tdata ,
output s_axis_data_tvalid ,
output s_axis_data_tlast
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [39:0] s_axis_config_tdata_reg ;
reg s_axis_config_tvalid_reg;
reg [31:0] s_axis_data_tdata_reg ;
reg s_axis_data_tvalid_reg ;
reg s_axis_data_tlast_reg ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign s_axis_config_tdata = s_axis_config_tdata_reg;
assign s_axis_config_tvalid = s_axis_config_tvalid_reg;
assign s_axis_data_tdata = s_axis_data_tdata_reg;
assign s_axis_data_tvalid = s_axis_data_tvalid_reg;
assign s_axis_data_tlast = s_axis_data_tlast_reg;
always @(posedge sclk)
s_axis_config_tdata_reg <= {1'b0,SCALE_SCH,FWD_INV,3'b000,CP_LEN,3'b000,NFFT};
always @(posedge sclk)
s_axis_config_tvalid_reg <= fft_config_en;
always @(posedge sclk)
s_axis_data_tdata_reg <= {4'b0000,IM_P1_DATA,4'b0000,RE_P1_DATA};
always @(posedge sclk)
s_axis_data_tvalid_reg <= P1_EN;
always @(posedge sclk)
s_axis_data_tlast_reg <= data_LAST;
endmodule
上面的代码联系之前的理论部分,便可以学会FFT的重配置,包括经过这篇博客的学习要学会其他Xilinx常用IP的重配置,比如:DDS、FIR等等。
tb_tx_ifft_op模块:
`timescale 1ns / 1ps
module tb_tx_ifft_op;
reg sclk ;
reg rst_n ;
reg cfg_vld ;
reg s_config_tvalid ;
reg [29:0] s_config_tdata ;
reg s_data_tvalid;
reg s_data_tvalid_delay,s_data_tvalid_delay1;
reg [23:0] s_data_tdata;
reg s_data_tlast;
reg m_axis_data_tready ;
reg m_axis_status_tready ;
wire s_axis_config_tready ;
wire s_axis_data_tready ;
wire [31:0]m_axis_data_tdata ;
wire [23:0]m_axis_data_tuser ;
wire m_axis_data_tvalid ;
wire m_axis_data_tlast ;
wire [7:0] m_axis_status_tdata ;
wire m_axis_status_tvalid ;
wire event_frame_started ;
wire event_tlast_unexpected ;
wire event_tlast_missing ;
wire event_fft_overflow ;
wire event_status_channel_halt ;
wire event_data_in_channel_halt ;
wire event_data_out_channel_halt ;
wire [9:0] NOFDM ;
wire p1_start ;
reg [1:0] fft_mode ;
reg [9:0] nofdm ;
reg [2:0] cp_pro ;
reg [13:0]scale ;
reg inv ;
reg [11:0]re_data ;
reg [11:0]im_data ;
always @(posedge sclk)
begin
s_data_tvalid_delay <= s_data_tvalid;
s_data_tvalid_delay1 <= s_data_tvalid_delay;
end
initial
begin
#0;
sclk =1'b0;
rst_n=1'b0;
cfg_vld = 1'b0;
m_axis_data_tready = 1'b1;
m_axis_status_tready = 1'b1;
s_config_tvalid = 1'b0;
s_config_tdata = 30'd0;
fft_mode=2'b01;
nofdm = 10'd1;
cp_pro = 3'b000;
scale = 14'b01_0110_1010_1010;
//scale = 14'd0;
inv = 1'b0;
s_data_tvalid = 1'b0;
s_data_tlast = 1'b0;
repeat(1) @(posedge sclk)#1;
cfg_vld = 1'b1;
repeat(1) @(posedge sclk)#1;
cfg_vld = 1'b0;
repeat(30) @(posedge sclk)#1;
rst_n =1'b1;
repeat(30) @(posedge sclk)#1;
s_config_tvalid = 1'b1;
s_config_tdata = {inv,scale,cp_pro,nofdm,fft_mode};
repeat(1) @(posedge sclk)#1;
s_config_tvalid = 1'b0;
repeat(300) @(posedge sclk)#1;
s_data_tvalid = 1'b1;
s_data_tlast = 1'b0;
repeat(1) @(posedge sclk)#1;
s_config_tvalid = 1'b0;
repeat(2047) @(posedge sclk)#1;
s_data_tlast = 1'b0;
s_data_tvalid = 1'b0;//mark for test
repeat(1) @(posedge sclk)#1;
s_data_tlast = 1'b1;
repeat(1) @(posedge sclk)#1;
s_data_tlast = 1'b0;
end
always #10 sclk = ~sclk;
//=========================================================================
// input
//=========================================================================
integer fid1;
integer fid2;
initial
begin
fid2 = $fopen("IM_DATA.txt","r");
fid1 = $fopen("RE_DATA.txt","r");
end
always@(posedge sclk)
begin
if(s_data_tvalid)begin
$fscanf(fid1,"%d",re_data);
$fscanf(fid2,"%d",im_data);
end
end
always @(posedge sclk)
begin
s_data_tdata <= {re_data,im_data};
end
//=========================================================================
// output
//=========================================================================
wire signed [11:0] re_out;
wire signed [11:0] im_out;
assign re_out = {m_axis_data_tdata[15],m_axis_data_tdata[10:0]};
assign im_out = {m_axis_data_tdata[31],m_axis_data_tdata[26:16]};
integer fid3;
initial
begin
fid3 = $fopen("re_fft_data.txt","w");
end
always@(posedge sclk)
begin
if(m_axis_data_tvalid)
$fwrite(fid3,"%d\n",re_out);
end
integer fid4;
initial
begin
fid4 = $fopen("im_fft_data.txt","w");
end
always@(posedge sclk)
begin
if(m_axis_data_tvalid)
$fwrite(fid4,"%d\n",im_out);
end
tx_ifft_op uut
(
.sclk (sclk ),
.rst_n (rst_n ),
.cfg_vld (cfg_vld ),
.p1_start (p1_start ),
.s_config_tvalid (s_config_tvalid ),
.s_config_tdata (s_config_tdata ),
.s_data_tvalid (s_data_tvalid_delay1 ),
.s_data_tdata (s_data_tdata ),
.s_data_tlast (s_data_tlast ),
.m_axis_data_tready (m_axis_data_tready ),
.m_axis_status_tready (m_axis_status_tready ),
.s_axis_config_tready (s_axis_config_tready ),
.s_axis_data_tready (s_axis_data_tready ),
.m_axis_data_tdata (m_axis_data_tdata ),
.m_axis_data_tuser (m_axis_data_tuser ),
.m_axis_data_tvalid (m_axis_data_tvalid ),
.m_axis_data_tlast (m_axis_data_tlast ),
.m_axis_status_tdata (m_axis_status_tdata ),
.m_axis_status_tvalid (m_axis_status_tvalid ),
.event_frame_started (event_frame_started ),
.event_tlast_unexpected (event_tlast_unexpected ),
.event_tlast_missing (event_tlast_missing ),
.event_fft_overflow (event_fft_overflow ),
.event_status_channel_halt (event_status_channel_halt ),
.event_data_in_channel_halt (event_data_in_channel_halt ),
.event_data_out_channel_halt(event_data_out_channel_halt),
.NOFDM (NOFDM )
);
endmodule
有关MATLAB对FFT IP核调用的部分,我们上篇博客已经进行了详细的讲解,在这里我们将给出MATLAB与Modelsim生成的数据相对比的代码:
clc;
clear all;
load fft_data_com.mat
sim_options = struct(...
'MODE', '2k' ... %fft模式 1k 2k 4k 8k
);
tx_nFrame=1;
%------------------------------------------------------------------------------
% Parameters Definition
%------------------------------------------------------------------------------
switch sim_options.MODE
case '1k'
NFFT = 1024; % FFT number of points
case '2k'
NFFT = 2048; % FFT number of points
case '4k'
NFFT = 4096; % FFT number of points
case '8k'
NFFT = 8192; % FFT number of points
otherwise, error('sim_options UNKNOWN MODE');
end
fid1 = fopen('re_fft_data.txt','r');
real_data_sim = fscanf(fid1,'%d');
fid1 = fopen('im_fft_data.txt','r');
imag_data_sim = fscanf(fid1,'%d');
start_Idx = NFFT*(tx_nFrame - 1);
if(isempty(real_data_sim))
real_data_result = 0;
imag_data_result = 0;
else
real_data_result = sum(abs(real(fft_data_com(start_Idx+1:start_Idx+NFFT)) - real_data_sim(start_Idx+1:start_Idx+NFFT)));
imag_data_result = sum(abs(imag(fft_data_com(start_Idx+1:start_Idx+NFFT)) - imag_data_sim(start_Idx+1:start_Idx+NFFT)));
end
a = real_data_result + imag_data_result
运行结果如下:
从上面结果可以验证我们实验的正确性,从而说明MATLAB与VIVADO输出的数据完全相同,两者相互验证了实验的正确性。
[1]、电子发烧友学院
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: