基于 FPGAFIR 滤波器 IP 仿真实例
 
AT7_Xilinx 开发板(USB3.0+LVDS)资料共享
 
腾讯链接:https://share.weiyun.com/5GQyKKc
 
百度网盘链接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 
 
提取码:qr0t
 
 
1 FIR 滤波器简介
FIR(Finite Impulse Response)滤波器,即有限脉冲响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR 滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。
 
Vivado 集成的 FIR IP 核可以实现如下公式所示的 N 级卷积运算。
 
 
FIR IP 核可以根据配置实现复用的乘累加单元,以实现面积最优化的设计;当然了,在速度性能要求极高的应用中,也可以配置并行的乘累加单元,以达到最大的 FIR 数据吞吐量。
 
 
2 FIR IP 核配置
FIRIP 配置主页面如图所示。此页面可以配置基本的滤波参数。 
 
 
通道配置页面如下。 
 
 
输入输出的数据位宽可在 Implementation 页面配置。 
 

 

 
实现的资源利用情况,如优化选项、存储器选项和 DSP Slice 选项等,可以在 Detailed Implementation 页面配置。 
 
 
额外的控制接口,可以在 Interface 页面配置。 
 
 
左侧的 Freq.Response 页面可以参考所使用的 FIR 滤波参数最终实现的滤波特性(低通、高通、低阻、高阻或带通、带阻等),这里我们使用的是一组 IP 默认的参数,低通滤波器。
 
 
而左侧的 Implementation Details 页面,则可以自由利用以及接口等信息。如图所示的 ufix16_0 表示输入数据为 16 位的无符号整数,而 fix25_0 则表示输出结果是 25 位的有符号整数。
 
 
详细配置可参看 pg149-fir-compiler.pdf(at7_img_ex07/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_tvalid 和 s_axis_data_tready 信号同时拉高时,s_axis_data_tdata 被 FIR IP 核接收,进行处理。当 m_axis_data_tvalid 拉高时,表示输出 FIR 滤波结果 m_axis_data_tdata 有效。 
 
 
4 FIR IP 仿真
使用 at7_img_ex07/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-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 工程 at7_img_ex07 的顶层是一个测试脚本,at7_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 中打开 at7_img_ex07 工程,在 Project Manager à Simulation Sources à sim_1 下,看到 top module 为高亮的 at7_fir_sim.v 模块,点击 Flow Navigator à Simulation à Run Simulation 可以启动仿真。
 
运行仿真如图。
 
 
 
仿真的结果将写入生成的 fir_result.txt 文本(位于 at7_img_ex07\at7.sim 文件夹的子文件夹中),将该文本放置到 matlab 文件夹中,运行 matlab 脚本 draw_wave_from_txt.m,可以查看正弦数据 FIR 滤波前后的波形比对。在时域看来,峰或谷的位置是高频,因此都被 FIR 滤波处理了。 
 
 
AT7_Xilinx 开发板(USB3.0+LVDS)资料共享
 
腾讯链接:https://share.weiyun.com/5GQyKKc
 
百度网盘链接:https://pan.baidu.com/s/1M7PLzRs-yMJv7NFJE8GVAw 
 
提取码:qr0t