[原创] 玩转Zynq连载50——[ex69] FIR滤波器IP仿真实例

ove学习使我快乐   2020-3-3 09:12 楼主

00.jpg

 

 

 

 

 

 

 

1 FIR滤波器简介

 

 

 

 

FIRFinite Impulse Response)滤波器,即有限脉冲响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。

 

 

 

 

         Vivado集成的FIR IP核可以实现如下公式所示的N级卷积运算。

 

 

 

 

50-1.png

 

 

 

 

         FIR IP核可以根据配置实现复用的乘累加单元,以实现面积最优化的设计;当然了,在速度性能要求极高的应用中,也可以配置并行的乘累加单元,以达到最大的FIR数据吞吐量。

 

 

 

 

50-2.png

 

 

 

 

 

 

 

 

 

2 FIR IP核配置

 

 

 

 

         FIRIP配置主页面如图所示。此页面可以配置基本的滤波参数。

 

 

 

 

50-3.png

 

 

 

 

         通道配置页面如下。

 

 

 

 

50-4.png

 

 

 

 

         输入输出的数据位宽可在Implementation页面配置。

 

 

 

 

50-5.png

 

 

 

 

         实现的资源利用情况,如优化选项、存储器选项和DSP Slice选项等,可以在Detailed Implementation页面配置。

 

 

 

 

50-6.png

 

 

 

 

         额外的控制接口,可以在Interface页面配置。

 

 

 

 

50-7.png

 

 

 

 

         左侧的Freq.Response页面可以参考所使用的FIR滤波参数最终实现的滤波特性(低通、高通、低阻、高阻或带通、带阻等),这里我们使用的是一组IP默认的参数,低通滤波器。

 

 

 

 

50-8.png

 

 

 

 

         而左侧的Implementation Details页面,则可以自由利用以及接口等信息。如图所示的ufix16_0表示输入数据为16位的无符号整数,而fix25_0则表示输出结果是25位的有符号整数。

 

 

 

 

50-9.png

 

 

 

 

         详细配置可参看pg149-fir-compiler.pdf/project/zstar_ex69/matlab文件夹下)。

 

 

 

 

 

 

 

 

 

3 FIR IP核接口时序

 

 

 

 

         我们例化的FIR IP核,有如下的接口,其功能和端口方向定义如下。

 

 

 

 

inputaclk;          //时钟信号

 

 

 

 

 

 

 

 

 

input [15 : 0] s_axis_data_tdata;    //unsigned(16.0),输入数据

 

 

 

 

inputs_axis_data_tvalid;                   //输入数据有效信号,高电平有效

 

 

 

 

outputs_axis_data_tready;              //准备好接收输入数据,高电平有效

 

 

 

 

 

 

 

 

 

output [24 : 0] m_axis_data_tdata;         //signed(25.0)FIR滤波结果输出

 

 

 

 

outputm_axis_data_tvalid;                        //FIR滤波结果输出有效,高电平有效

 

 

 

 

         接口时序控制如图所示。图中很多信号本实例不涉及,可以忽略。s_axis_data_tvalids_axis_data_tready信号同时拉高时,s_axis_data_tdataFIR IP核接收,进行处理。当m_axis_data_tvalid拉高时,表示输出FIR滤波结果m_axis_data_tdata有效。

 

 

 

 

50-10.png

 

 

 

 

 

 

 

 

 

4 FIR IP仿真

 

 

 

 

         使用/project/zstar_ex69/matlab文件夹下的test_data_generate_for_fir.m脚本,可以产生一组1000个点的余弦数据,存放在time_domain_cos.txt文件中,这组数据将作为FPGA的仿真输入激励,经过FIR滤波器进行滤波处理。

 

 

 

 

clc;clear `all;close all;

 

 

 

 

 

 

 

 

 

format long g

 

 

 

 

 

 

 

 

 

Fs = 1000;                    % Sampling frequency

 

 

 

 

T = 1/Fs;                     % Sampling period

 

 

 

 

L = 1000;                     % Length of signal

 

 

 

 

t = (0:L-1)*T;                % Time vector

 

 

 

 

 

 

 

 

 

x1 = cos(2*pi*50*t)*(2^13);          % First row wave

 

 

 

 

 

 

 

 

 

%output time domain data

 

 

 

 

x1_fix = round(x1,0);    %convert to fixed signed(3.13)

 

 

 

 

x1_fix(find(x1_fix<0)) = x1_fix(find(x1_fix<0))+(2^16);

 

 

 

 

fid0 = fopen('time_domain_cos.txt', 'wt');

 

 

 

 

fprintf(fid0, '%16x\n', x1_fix);

 

 

 

 

fid0 = fclose(fid0);

 

 

 

 

         FPGA工程zstar_ex69的顶层是一个测试脚本,zstar_fir_sim.v文件。该测试脚本将time_domain_cos.txt文件的1000个数据读入,然后依次送入FIR滤波器IP核进行处理,输出结果写入fir_result.txt文本中。

 

 

 

 

`timescale 1ns/1ps

 

 

 

 

module zstar_fir_sim(

 

 

 

 

    );

 

 

 

 

        

 

 

 

 

reg clk;    

 

 

 

 

 

 

 

 

 

reg [15 : 0] s_axis_data_tdata;       //unsigned(16.0)

 

 

 

 

reg s_axis_data_tvalid;

 

 

 

 

wire s_axis_data_tready;

 

 

 

 

 

 

 

 

 

wire [31 : 25] null;

 

 

 

 

wire [24 : 0] m_axis_data_tdata;    //signed(25.0)

 

 

 

 

wire m_axis_data_tvalid;

 

 

 

 

 

 

 

 

 

parameter DATA_NUM = 1000;

 

 

 

 

        

 

 

 

 

////////////////////////////////////////////////////

 

 

 

 

//FIR IP Core   

 

 

 

 

 

 

 

 

 

fir_compiler_0  uut_fir_compiler_0 (

 

 

 

 

.aclk(clk),                              // input wire aclk

 

 

 

 

.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_tdata(s_axis_data_tdata),    // input wire [15 : 0] s_axis_data_tdata

 

 

 

 

  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid

 

 

 

 

  .m_axis_data_tdata({null,m_axis_data_tdata})    // output wire [31 : 0] m_axis_data_tdata

 

 

 

 

);

 

 

 

 

        

 

 

 

 

////////////////////////////////////////////////////      

 

 

 

 

integer i;

 

 

 

 

 

 

 

 

 

reg[15:0] data_mem [DATA_NUM-1:0];

 

 

 

 

 

 

 

 

 

initial #500 $readmemh("../../time_domain_cos.txt",  data_mem);           

 

 

 

 

 

 

 

 

 

 

 

 

 

 

initial begin

 

 

 

 

         clk = 0;

 

 

 

 

        

 

 

 

 

         s_axis_data_tdata<= 16'd0;

 

 

 

 

         s_axis_data_tvalid<= 1'b0;

 

 

 

 

        

 

 

 

 

        

 

 

 

 

         #1000;

 

 

 

 

         @(posedgeclk);

 

 

 

 

 

 

 

 

 

         i<= 1;

 

 

 

 

         #10000;

 

 

 

 

 

 

 

 

 

         @(posedgeclk);                

 

 

 

 

        

 

 

 

 

         #100_000;

 

 

 

 

        

 

 

 

 

         $fclose(w1_file);

 

 

 

 

         #1000;

 

 

 

 

         $stop;

 

 

 

 

end 

 

 

 

 

 

 

 

 

 

always @(*) begin

 

 

 

 

         if((i>0) && (i<DATA_NUM+1)) s_axis_data_tdata<= data_mem[i-1];

 

 

 

 

         else s_axis_data_tdata<= 16'd0;

 

 

 

 

end 

 

 

 

 

 

 

 

 

 

always @(posedgeclk) begin

 

 

 

 

         if(i == 0) i<= 0;

 

 

 

 

         else if(i<= DATA_NUM) begin 

 

 

 

 

                   if(s_axis_data_tready&&s_axis_data_tvalid) i<= i+1;

 

 

 

 

                   else ;

 

 

 

 

         end

 

 

 

 

         else if(i< DATA_NUM+26) i<= i+1;

 

 

 

 

         else ;

 

 

 

 

end

 

 

 

 

 

 

 

 

 

always @(posedgeclk) begin

 

 

 

 

         if((i>=1) && (i<=DATA_NUM-1)) s_axis_data_tvalid<= 1'b1; 

 

 

 

 

         else s_axis_data_tvalid<= 1'b0;

 

 

 

 

end

 

 

 

 

 

 

 

 

 

 

 

 

 

 

always #10 clk = ~clk;               

 

 

 

 

 

 

 

 

 

 

 

 

 

 

integer w1_file;

 

 

 

 

 

 

 

 

 

initial w1_file = $fopen("./fir_result.txt","w");      

 

 

 

 

                  

 

 

 

 

always @(posedgeclk) begin

 

 

 

 

         if(m_axis_data_tvalid) begin

 

 

 

 

                   $fwrite(w1_file, "%x\n", m_axis_data_tdata);      

 

 

 

 

         end 

 

 

 

 

end 

 

 

 

 

        

 

 

 

 

endmodule

 

 

 

 

         如图所示,Vivado中打开zstar_ex69工程,在Project Manager à Simulation Sources à sim_1下,看到top module为高亮的zstar_fir_sim.v模块,点击Flow Navigator à Simulation à Run Simulation可以启动仿真。

 

 

 

 

50-11.png

 

 

 

 

         运行仿真如图。

 

 

 

 

50-12.png

 

 

 

 

仿真的结果将写入生成的fir_result.txt文本(位于zstar_ex69\zstar.sim文件夹的子文件夹中),将该文本放置到matlab文件夹中,运行matlab脚本draw_wave_from_txt.m,可以查看正弦数据FIR滤波前后的波形比对。在时域看来,峰或谷的位置是高频,因此都被FIR滤波处理了。

50-13.png



此内容由EEWORLD论坛网友ove学习使我快乐原创,如需转载或用于商业用途需征得作者同意并注明出处

 

 

本帖最后由 ove学习使我快乐 于 2020-3-3 09:13 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复