专业网站发展趋势,电商网站用什么做的,网站 微信,wordpress产品展示类工具#xff1a;vivado2018.3#xff0c;modelsim10.6d
场景#xff1a;在进行数据进行频谱分析的时候#xff0c;使用FPGA来完成FFT的计算可以加快数据的计算速度。
下面使用仿真完成DDS产生的数据的FFT以及IFFT。原始数据使用DDSIP产生#xff0c;通过IP产生的波形数据…工具vivado2018.3modelsim10.6d
场景在进行数据进行频谱分析的时候使用FPGA来完成FFT的计算可以加快数据的计算速度。
下面使用仿真完成DDS产生的数据的FFT以及IFFT。原始数据使用DDSIP产生通过IP产生的波形数据直接输入到FFT进行傅里叶正变换。然后再使用FFT对数据进行IFFT傅里叶逆变换还原波形数据。过程中完成了fftshift将零频分量搬移到频谱中心以及使用cordic计算平方根的过程。
FFT端口说明 端口名称 方向 描述 aclk I 时钟 aresetn I 复位 s_axis_config_tvalid I 配置有效 s_axis_config_tready O 配置准备好 s_axis_config_tdata I 针对配置通道的TDATA。携带配置信息 CP_LEN、FWD/INV、NFFT和SCALE_SCH。关于FWD/INV为FFTIP的方式1为FFT0为IFFT。当选择FFT点数可配置时NFFT为点数。SCALE_SCH为缩放计划以确保在计算过程中不溢出。对于不同的IO架构有不同的规则。 s_axis_data_tdata I 输入数据 s_axis_data_tvalid I 数据有效 s_axis_data_tready O 数据准备好 s_axis_data_tlast I 输入的一帧最后一个数据 m_axis_data_tvalid O 输出数据有效 m_axis_data_tready I 输出数据准备好 m_axis_data_tdata O 输出数据 m_axis_data_tuser O 输出数据状态参数。包含XK_INDEX, OVFLO, and BLK_EXP. XK_INDEX输出数据索引 OVFLO溢出标志 BLK_EXP块指数字段中出现的值表示在转换过程中数据被缩放的比特总数。例如如果BLK_EXP的值为00101 5这意味着相关的输出数据XK_REXK_IM被缩放为5位向右移5位或者换句话说被除以32以充分利用输出数据路径的可用动态范围而不会溢出。 m_axis_data_tlast O 输出的最后一个数据。 m_axis_status_tvalid O 状态有效 m_axis_status_tready I 状态准备好 m_axis_status_tdata O 状态数据。包含每一帧的状态休息。 event_frame_started O 事件帧开始 event_tlast_unexpected O 当核心在不是帧中最后一个的数据样本上看到s_axis_data_tlast高时有效 event_tlast_missing O 当一帧的最后一个数据样本上的s_axis_data_tlast为低时断言。 event_fft_overflow O 当正在从数据输出通道卸载的数据样本中出现溢出时断言。仅在溢出是一个有效的选项时才会出现。 event_data_in_channel_halt O 当核心从数据输入通道请求数据而没有数据可用时断言。 event_data_out_channel_halt O 当核心从数据输入通道请求数据而没有数据可用时断言。 event_status_in_channel_halt O 当核心试图将数据写入状态通道而无法这样做时将被断言。仅在非实时模式下出现。 FFT IP的配置界面 Channels从1到12中选择通道数。三种Burst I/O架构均可使用多通道操作。对于浮点格式通道必须为1。
Transform Length: 选择一次处理所需点的大小。
The Pipelined Streaming I/O运行连续处理。
Radix-4Radix-2Radix-2 Lite Burst I/O。几种不同的实现方式延迟依次增大资源依次减少。
Run time configurable Transform Length允许运行的过程中改变点数。勾选此后注意s_axis_config_tdata的字段的意义。 DataFormat选择输入和输出数据样本是否为定点格式或在IEEE-754单精度32位浮点格式中。浮点格式不是当核心处于多通道配置时可用。
Scaling Options
Scaling用户自定义缩放格式。注意s_axis_config_tdata的字段需要配置每个阶段的缩放信息。
Block Floating-Point:由核心来判断所需的缩放程度以实现对可用动态范围的最佳利用并以块指数的形式报告缩放因子。注意m_axis_data_tuser字段的块指数报告。
Output ordering自然顺序和反转顺序。这里使用自然顺序。
Optional Output FieldsXK_INDEX输出数据索引。 资源消耗设置界面。
关于matlab仿真产生1MHZ的正弦波余弦波信号采样率为100MHZ。共计1024个点。对其进行FFT。
matlab仿真程序
% 生成正弦波
fc 1e6; % 频率
fs 100e6; % 采样率
t1 0:1/fs:1e-3; % 时间序列,1微秒
t t1(1:1024); %RW需要取整数计算出的频率是真实sin_wave sin(2 * pi * fc * t);
cos_wave cos(2 * pi * fc * t);% 复数
plural_wave cos_wave 1i*sin_wave;% 加噪声
data awgn(cos_wave,100) ;
% data awgn(plural_wave,100) ;% 绘制原始正弦波数据
figure;
subplot(1,1,1);
plot(t*1e9, imag(plural_wave));
title(原始正弦波);
xlabel(时间 (ns));
ylabel(幅值);%%做FT变化算平均功率谱并画谱输出
FFT_data data; N length(FFT_data); w blackman(N);Fs 100e6;
% Sf_I_Q_wavefftshift(fft((FFT_data).*w,N)*2.381);
% w gausswin(N);%高斯窗函数窗长度为N
gauss_data fft((FFT_data).*w,N)*2.396;%%做FFT变换加窗并还原窗系数
Sf_I_Q_wavefftshift(gauss_data);
Sf_I_Q_wave_dBm (abs(Sf_I_Q_wave));
% Sf_I_Q_wave_dBm 20*log10(1/N*abs(Sf_I_Q_wave));
X_freqFs.*(-N/2:N/2-1)/N;figure(2);plot(X_freq,Sf_I_Q_wave_dBm);title(plural_wave原始数据普);
对实信号余弦波进行傅里叶变换频谱图如下。 对复信号进行进行傅里叶变换频谱。 在逻辑中我们使用DDSIP来产生我们需要的波形数据。
DDS IP配置界面 可以看到我需要控制DDS的控制字来生成不同频率的波形数据输出数据的格式为高16位为正弦低16位为余弦。
输出频率计算公式。 其中X为频率控制字Fs采样率即系统时钟。N为多少位的控制字。要输出1MHZ的波形信号的控制字为X655。 输出波形正好为一个周期1000ns。即1MHZ。
1024点FFT实信号输入。
FFTSHIFT频谱搬移模块
对于FFTSHIFT模块我们打开matlab帮助后可以发现搬移的效果就是以频谱中心左右两端谱线互换。 ABS求平方根模块
求复数的模定义为
复数的
在逻辑中我们使用cordic来计算平方根。
cordicIP配置如下所示 模块仿真
timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/08/12 14:14:51
// Design Name:
// Module Name: vtf_fft_test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module vtf_fft_test;
//fft
//input
wire [31:0] s_axis_data_tdata ;
wire s_axis_data_tvalid ;
wire s_axis_data_tready ;
wire s_axis_data_tlast ;
//output
wire [31:0] m_axis_data_tdata ;
wire m_axis_data_tvalid ;
wire m_axis_data_tready ;
wire m_axis_data_tlast ;
wire [23:0] m_axis_data_tuser ; //dds
wire m_dds_tvalid ;
wire [31:0] m_dds_tdata ; //system signal
reg clk ;
reg rst_n ;
reg data_gen ;
reg data_flog ;
reg douta_vld ;
reg [15:0] cnt ; //fftshift
wire [31:0] fftshift_data ; //
wire fftshift_data_valid ; //
wire [9:0] fftshift_cnt ; // //abswire [15:0] abs_data ; // (output)
wire abs_data_valid ; // (output)
//system signal//
assign s_axis_data_tdata douta_vld ? m_dds_tdata : 32h0;//给复信号
//assign s_axis_data_tdata douta_vld ? {16d0,m_dds_tdata[15:0]} : 32h0;//实信号
assign s_axis_data_tvalid douta_vld;
assign s_axis_data_tlast (cnt 16d1023 );assign m_axis_data_tready 1b1;//FFT后数据
//取实部
wire [15:0] f_imag ;
wire [15:0] f_real ;
wire [31:0] f_abs ; assign f_imag m_axis_data_tdata[31:16];
assign f_real m_axis_data_tdata[15:0];
assign f_abs f_imag f_real;//
dds_compiler_0 u_dds (.aclk (clk ), // input wire aclk.s_axis_config_tvalid (1b1 ), // input wire s_axis_config_tvalid.s_axis_config_tdata (16d655 ), // input wire [15 : 0] s_axis_config_tdata.m_axis_data_tvalid (m_dds_tvalid ), // output wire m_axis_data_tvalid.m_axis_data_tdata (m_dds_tdata ), // output wire [31 : 0] m_axis_data_tdata.m_axis_phase_tvalid ( ), // output wire m_axis_phase_tvalid.m_axis_phase_tdata ( )// output wire [15 : 0] m_axis_phase_tdata
);//
xfft_0 u_fft (.aclk ( clk ), // input wire aclk.aresetn ( rst_n ), // input wire aresetn.s_axis_config_tdata (8d1 ), // input wire [7 : 0] s_axis_config_tdata.s_axis_config_tvalid (1b1 ), // input wire s_axis_config_tvalid.s_axis_config_tready ( ), // output wire s_axis_config_tready.s_axis_data_tdata (s_axis_data_tdata ), // input wire [31 : 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 [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 (m_axis_data_tready ), // input wire m_axis_data_tready.m_axis_data_tlast (m_axis_data_tlast ), // output wire m_axis_data_tlast.m_axis_status_tdata ( ), // output wire [7 : 0] m_axis_status_tdata.m_axis_status_tvalid ( ), // output wire m_axis_status_tvalid.m_axis_status_tready (1b1 ), // input wire m_axis_status_tready.event_frame_started ( ), // output wire event_frame_started.event_tlast_unexpected ( ), // output wire event_tlast_unexpected.event_tlast_missing ( ), // output wire event_tlast_missing.event_status_channel_halt ( ), // output wire event_status_channel_halt.event_data_in_channel_halt ( ), // output wire event_data_in_channel_halt.event_data_out_channel_halt ( )// output wire event_data_out_channel_halt
);//
fft_shift u_fft_shift(
//.fft_data (m_axis_data_tdata ), // (input ) .fft_cnt (m_axis_data_tuser[9:0] ), // (input ) .fft_last (m_axis_data_tlast ), // (input ) .fft_data_valid (m_axis_data_tvalid ), // (input ) .fftshift_data (fftshift_data ), // (output) .fftshift_data_valid (fftshift_data_valid ), // (output) .fftshift_cnt (fftshift_cnt[9:0] ), // (output)
//system signal.sys_clk (clk ), // (input ) .rst_n (rst_n )// (input ) );//
abs_top u_abs_top(
//.plural_data (fftshift_data[31:0] ), // (input ) (input ).plural_data_valid (fftshift_data_valid ), // (input ) (input ).abs_data (abs_data[15:0] ), // (output) (output).abs_data_valid (abs_data_valid ), // (output) (output)
//system signal.clk (clk ), // (input ) (input ).rst_n (rst_n ) // (input ) (input )
);//
xfft_0 u_ifft (.aclk ( clk ), // input wire aclk.aresetn ( rst_n ), // input wire aresetn.s_axis_config_tdata (8d1 ), // input wire [7 : 0] s_axis_config_tdata.s_axis_config_tvalid (1b1 ), // input wire s_axis_config_tvalid.s_axis_config_tready ( ), // output wire s_axis_config_tready.s_axis_data_tdata (m_axis_data_tdata ), // input wire [31 : 0] s_axis_data_tdata.s_axis_data_tvalid (m_axis_data_tvalid ), // input wire s_axis_data_tvalid.s_axis_data_tready (m_axis_data_tready ), // output wire s_axis_data_tready.s_axis_data_tlast (m_axis_data_tlast ), // input wire s_axis_data_tlast.m_axis_data_tdata ( ), // output wire [31 : 0] m_axis_data_tdata.m_axis_data_tuser ( ), // output wire [23 : 0] m_axis_data_tuser.m_axis_data_tvalid ( ), // output wire m_axis_data_tvalid.m_axis_data_tready (1b1 ), // input wire m_axis_data_tready.m_axis_data_tlast ( ), // output wire m_axis_data_tlast.m_axis_status_tdata ( ), // output wire [7 : 0] m_axis_status_tdata.m_axis_status_tvalid ( ), // output wire m_axis_status_tvalid.m_axis_status_tready (1b1 ), // input wire m_axis_status_tready.event_frame_started ( ), // output wire event_frame_started.event_tlast_unexpected ( ), // output wire event_tlast_unexpected.event_tlast_missing ( ), // output wire event_tlast_missing.event_status_channel_halt ( ), // output wire event_status_channel_halt.event_data_in_channel_halt ( ), // output wire event_data_in_channel_halt.event_data_out_channel_halt ( )// output wire event_data_out_channel_halt
);//
//
initial
beginclk 0;rst_n0;data_gen 0;#100;rst_n 1;#1000;data_gen 1;#100;data_gen 0;endalways (posedge clk or negedge rst_n)
beginif(rst_n 1b0)begin data_flog 1b0;endelse if(data_gen 1b1)begindata_flog 1b1;end else if(cnt 10d1022)begindata_flog 1b0;end
endalways (posedge clk or negedge rst_n)
beginif(rst_n 1b0)begin douta_vld 1b0;endelse begindouta_vld data_flog;end endalways (posedge clk or negedge rst_n)
beginif(rst_n 1b0)begin cnt 16d0;endelse if(s_axis_data_tvalid 1b1 s_axis_data_tready 1b1)begincnt cnt 1b1;end else begincnt cnt;endend//
//always #5 clk ~clk;endmodule复信号输入。 实信号输入。 逆傅里叶变换结果