首页 > 编程知识 正文

什么叫做ip核,fft ip

时间:2023-05-05 00:16:07 阅读:120993 作者:3760

xilinix的IP核心FFT功能强大

设定IP核心Vivado的FFT IP核心支持“多通道输入”(Number of Channels )和“实时更改FFT点数”(runtimeconfigurabletransformlength )。 在Configuration标签下设定“FFT点数”(“Transform Length”和“工作时钟频率”(Target Clock Frequency ) ),然后输入管线流、基4 Burst、基2 Burst、基2 Burst和轻量级数据输入个数错误或输入未完成时,FFT不输出结果。 此外,输入的数据类型是带符号数,模拟数据可以在matlab中生成,matlab代码是本人的另一篇文章https://blog.csdn.net/Baidu _ 25816669/article/dedeab

在Implementation标签卡下将FFT数据格式设置为固定点固定点或浮点浮动点; 设定输入数据的位宽和相位系数的位宽。 这相当于旋转系数。 也有可选的追加信号。 输出排序将FFT计算结果设置为按自然顺序(Nature Order )或按位/数字逆序)输出。

在名为Detailed Implementation的Tab中,设定有与优化方式、存储器的类型、是否使用DSP单元等的整合、实现相关的信息,例如可以选择复数乘法器和蝶形运算单元的实现结构。

在IP核心的右侧,如下图所示,可以看到安装后占用的资源、各接口的功能、延迟。

在此需要注意S_AXIS_CONFIG_TDATDA。

S_AXIS_CONFIG_TDATDA中包含下图的数据内容。 S_AXIS_CONFIG_TDATDA,的位宽核心内容取决于为IP核心设置的选项。 下图为完整的数据内容,实线框内始终有内容,其他内容根据IP核心设定而增减。

如果在配置aa接口设置中禁用了运行时间……,则S_AXIS_CONFIG_TDATDA位宽为8,内部D_INV,只需设置运算类型为FFT还是IFFT即可。

选中Run Time .后,S_AXIS_CONFIG_TDATDA位宽为16,在implement detial中可以看到与下图的设定位宽相对应的内容

下图为NFFT的设定内容,与运算点数有关。

最麻烦的设定是关于是否切尾、是否压缩的设定。 在implement接口中选择unscaled时,不需要设置末尾,但资源消耗大,输出数据位宽,实际工程中选择scaled。 在这种情况下,可以在实施详细信息中找到S_AXIS_CONFIG_TDATDA

关于截距压缩的设定,参考下图的内容有点复杂。

有关FFT的具体配置,请参阅https://blog.csdn.net/gslscyx/article/details/107073799进行详细介绍。

完整的模拟工程代码如下。

模块FFT _ TB (; reg clk; reg rst_n; reg signed [ 15:0 ] time _ data _ I [ 127:0 ]; wire fft_s_config_tready; reg signed [ 31:0 ] FFT _ s _ data _ tdata; reg fft_s_data_tvalid; wire fft_s_data_tready; reg fft_s_data_tlast; wiresigned [ 47:0 ] FFT _ m _ data _ tdata; //wiresigned [ 31:0 ] FFT _ m _ data _ tdata; wiresigned [ 7:0 ] FFT _ m _ data _ tuser; wire fft_m_data_tvalid; reg fft_m_data_tready; wire fft_m_data_tlast; 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; reg [7:0] count; // reg signed [15:0] fft_i_out;// reg signed [15:0] fft_q_out; reg signed [23:0] fft_i_out; reg signed [23:0] fft_q_out; reg signed [47:0] fft_abs; integer fid1; integer i; integer s; initial begin clk = 1'b1; rst_n = 1'b1; #5 rst_n = 1'b0;// #5 rst_n = 1'b1; fft_m_data_tready = 1'b1;// $readmemh("C:/Users/HP/Desktop/sin_data1.txt",Time_data_I);//无符号数导入 fid1 = $fopen("C:/Users/HP/Desktop/sin_data.txt","r");//这里的斜杠与计算机里面的斜杠不一样 //有符号数导入 for(i=0;i<=127;i=i+1) begin s= $fscanf(fid1,"%d",Time_data_I[i]); end $fclose(fid1); #50 rst_n = 1'b1;; end always #5 clk = ~clk; reg [3:0] state; //发送时域数据到FFT IP核,主->从 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin fft_s_data_tvalid <= 1'b0; fft_s_data_tdata <= 32'd0; fft_s_data_tlast <= 1'b0; count <= 8'd0; state<=0; end else case(state) 4'b0:begin if (fft_s_data_tready) begin//FFT IP核(从设备)已经准备好接收数据,主设备开始发送有效数据 if(count == 8'd127)begin fft_s_data_tvalid <= 1'b1; fft_s_data_tlast<=1'b1;//tlast置1 fft_s_data_tdata <= {16'd0,Time_data_I[count]}; count <= 8'd0; state<=4'b1; end else begin fft_s_data_tvalid <= 1'b1; fft_s_data_tlast<=1'b0;//tlast置0 fft_s_data_tdata <= {16'd0,Time_data_I[count]}; count <= count + 1'b1; end end else begin fft_s_data_tvalid <= 1'b0; fft_s_data_tlast <= 1'b0; fft_s_data_tdata <= fft_s_data_tdata; end end 4'b1:begin fft_s_data_tvalid <= 1'b0; fft_s_data_tlast <= 1'b0; if(fft_m_data_tlast) state<=4'b0; end endcase end //取频谱数据出来 always @(posedge clk) begin if (fft_m_data_tvalid) begin fft_i_out<=fft_m_data_tdata[23:0]; fft_q_out<=fft_m_data_tdata[47:24]; // fft_i_out<=fft_m_data_tdata[15:0];// fft_q_out<=fft_m_data_tdata[31:16]; end end always @(posedge clk) begin fft_abs<=$signed(fft_i_out)* $signed(fft_i_out)+ $signed(fft_q_out)* $signed(fft_q_out); end //fft ip核例化 xfft_0 u_fft( .aclk(clk), // 时钟信号(input) .aresetn(rst_n), // 复位信号,低有效(input) .s_axis_config_tdata(16'b1_0000_0111), // ip核设置参数内容,为1时做FFT运算,为0时做IFFT运算(input) .s_axis_config_tvalid(1'b1), // ip核配置输入有效,可直接设置为1(input) .s_axis_config_tready(fft_s_config_tready), // output wire s_axis_config_tready //作为接收时域数据时是从设备 .s_axis_data_tdata(fft_s_data_tdata), // 把时域信号往FFT IP核传输的数据通道,[31:16]为虚部,[15:0]为实部(input,主->从) .s_axis_data_tvalid(fft_s_data_tvalid), // 表示主设备正在驱动一个有效的传输(input,主->从) .s_axis_data_tready(fft_s_data_tready), // 表示从设备已经准备好接收一次数据传输(output,从->主),当tvalid和tready同时为高时,启动数据传输 .s_axis_data_tlast(fft_s_data_tlast), // 主设备向从设备发送传输结束信号(input,主->从,拉高为结束) //作为发送频谱数据时是主设备 .m_axis_data_tdata(fft_m_data_tdata), // FFT输出的频谱数据,[47:24]对应的是虚部数据,[23:0]对应的是实部数据(output,主->从)。 .m_axis_data_tuser(fft_m_data_tuser), // 输出频谱的索引(output,主->从),该值*fs/N即为对应频点; .m_axis_data_tvalid(fft_m_data_tvalid), // 表示主设备正在驱动一个有效的传输(output,主->从) .m_axis_data_tready(fft_m_data_tready), // 表示从设备已经准备好接收一次数据传输(input,从->主),当tvalid和tready同时为高时,启动数据传输 .m_axis_data_tlast(fft_m_data_tlast), // 主设备向从设备发送传输结束信号(output,主->从,拉高为结束) //其他输出数据 .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 );

仿真图形如下,注意有符号和无符号显示的模拟波形不同,应选用有符号显示。下图的频率是镜像的显示。

 另外,如果给虚部的最高位写入1,则显示的频谱出现直流分量。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。