FPGA学习笔记(六): FIR IP核的使用

笔记六是简单介绍FIR IP核的使用,它是借助MATLAB工具可以生成自己想要的FIR滤波器。此笔记同时介绍Multiplier IP核。

设计思路:用两个DDS产生两个正弦波信号,然后使用乘法器进行混频,再使用FIR滤波器进行滤波得到最后的滤波信号,同时使用MATLAB对滤波前后信号进行时频分析,验证结果。

1. 打开VIVADO,点击IP Catalog 

FPGA学习笔记(六): FIR IP核的使用_第1张图片

 2.搜索DDS,选择DDS Compiler,按照上节配置频率为3MHz和4MHz的DDS IP核。

FPGA学习笔记(六): FIR IP核的使用_第2张图片

FPGA学习笔记(六): FIR IP核的使用_第3张图片 FPGA学习笔记(六): FIR IP核的使用_第4张图片

 这里注意不勾选Has Phase Out

FPGA学习笔记(六): FIR IP核的使用_第5张图片

这里注意不勾选Output TREADY 

 FPGA学习笔记(六): FIR IP核的使用_第6张图片

 输出频率为3MHz

FPGA学习笔记(六): FIR IP核的使用_第7张图片

按照上述步骤,配置4MHz的DDS,同样不勾选Has Phase Out以及不勾选Output TREADY。

FPGA学习笔记(六): FIR IP核的使用_第8张图片

3. 点击IP Catalog,搜索mult,选择Multiplier

 FPGA学习笔记(六): FIR IP核的使用_第9张图片

 4. 配置Multiplier

位宽为8bit,因为DDS的输出位宽为8bit.

 FPGA学习笔记(六): FIR IP核的使用_第10张图片

 5. 点击IP Catalog,搜索fir,选择FIR Complier.

FPGA学习笔记(六): FIR IP核的使用_第11张图片

6. 配置FIR

(1) 选择COE File,加载filter的coe文件 

FPGA学习笔记(六): FIR IP核的使用_第12张图片

(2) 配置系统时钟和采样频率,均为50MHz(据实际情况而定)

 FPGA学习笔记(六): FIR IP核的使用_第13张图片

 (3) 第一个16是fir滤波器的抽头系数,第二个16是filter的输入位宽为16bit,混频器的输出位宽为16bit,选择symmetric,

FPGA学习笔记(六): FIR IP核的使用_第14张图片

7. filter的coe文件生成

(1) 打开MATLAB,输入fdatool 

FPGA学习笔记(六): FIR IP核的使用_第15张图片

(2) 选择低通滤波器,阶数设置15阶,采样频率为50MHz,通带截止频率为2MHz,阻带截止频率为3MHz,点击Design Filter.

FPGA学习笔记(六): FIR IP核的使用_第16张图片

(3) 选择左边窗口第三个,Set quantization parameters,选择定点数 Fixed-point,输入16,15阶的滤波器有16个抽头系数,然后点击Apply

FPGA学习笔记(六): FIR IP核的使用_第17张图片

(4) 点击上方Targets,选择coe文件,保存,就生成了filter的coe文件

FPGA学习笔记(六): FIR IP核的使用_第18张图片

; XILINX CORE Generator(tm)Distributed Arithmetic FIR filter coefficient (.COE) File
; Generated by MATLAB(R) 9.4 and DSP System Toolbox 9.6.
; Generated on: 14-Nov-2022 19:07:41
Radix = 16; 
Coefficient_Width = 16; 
CoefData = ec8b,
4785,
2a2b,
27c6,
2af7,
2ea0,
3175,
32f4,
32f4,
3175,
2ea0,
2af7,
27c6,
2a2b,
4785,
ec8b;

8. 顶层文件

文件的最后几段是将混频信号和滤波信号用text文件保存下来,文件的保存地址需要根据自己的路径进行更改,注意用斜杠隔开。

module dds_filter(
    input clk,					// 输入clk
    output sig1,				// 输出信号1
    output sig2,				// 输出信号2
    output sig3,				// 输出混频信号
    output filter_sig			// 输出滤波后信号
    );
    wire clk;					
    wire [7:0] sig1;
    wire [7:0] sig2;
    wire [15:0] sig3;
    wire [39:0] filter_sig;
// 例化DDS
dds_compiler_0 dds0 (
  .aclk(clk),                              // input wire aclk
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(sig1)    // output wire [7 : 0] m_axis_data_tdata
);
//  例化DDS
dds_compiler_1 dds1 (
  .aclk(clk),                              // input wire aclk
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(sig2)    // output wire [7 : 0] m_axis_data_tdata
);

//  例化MULT,输入为sig1和sig2,输出sig3
mult_gen_0 multi0 (
  .CLK(clk),  // input wire CLK
  .A(sig1),      // input wire [7 : 0] A
  .B(sig2),      // input wire [7 : 0] B
  .P(sig3)      // output wire [15 : 0] P
);

// fir例化,输入为sig3,输出filter_sig
fir_compiler_0 fir_filter (
  .aclk(clk),                              // input wire aclk
  .s_axis_data_tvalid(1'b1),  // input wire s_axis_data_tvalid
  .s_axis_data_tready(s_axis_data_tready),  // output wire s_axis_data_tready
  .s_axis_data_tdata(sig3),    // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(m_axis_data_tvalid1),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(filter_sig)    // output wire [39 : 0] m_axis_data_tdata
);

// 创建文件夹,注意地址
integer dout_file1;
initial begin
    dout_file1=$fopen("F:/shiyan/lab/lab3/project_2_firfilter_sample/after_filter_data.txt");    //打开所创建的文件
      if(dout_file1 == 0)begin 
                $display ("can not open the file!");    //创建文件失败,显示can not open the file!
                $stop;
       end
end
// 以有符号数将filter_sig信号写入文件保存
always @(posedge clk)
     if(m_axis_data_tvalid1)        
       $fdisplay(dout_file1,"%d",$signed(filter_sig));    //保存有符号数据

// 创建文件夹,注意地址
integer dout_file2;
initial begin
    dout_file2=$fopen("F:/shiyan/lab/lab3/project_2_firfilter_sample/before_filter_data.txt");    //打开所创建的文件
      if(dout_file2 == 0)begin 
                $display ("can not open the file!");    //创建文件失败,显示can not open the file!
                $stop;
       end
end
// 以有符号数将sig3信号写入文件保存
always @(posedge clk)
     if(m_axis_data_tvalid1)        
       $fdisplay(dout_file2,"%d",$signed(sig3));    //保存有符号数据
endmodule

9.测试文件

module tb_dds_filter();
    reg clk;					// 输入时钟
    wire [7:0] sig1;			// 输出信号1
    wire [7:0] sig2;			// 输出信号2
    wire [15:0] sig3;			// 输出混频信号
    wire [39:0] filter_sig;		// 输出滤波信号
	// 例化
    dds_filter dds_tb(
     .clk(clk),
     .sig1(sig1),
     .sig2(sig2),
     .sig3(sig3),
     .filter_sig(filter_sig)
    );
	// 初始化
    initial 
    begin
    clk = 1;					//  clk为高电平
    end
    always #10 clk = ~clk;		//  clk周期为20ns
        
       

endmodule

 10. 结果展示

FPGA学习笔记(六): FIR IP核的使用_第19张图片

 11. MATLAB 分析,将保存的文件加载到MATLAB中做FFT分析。

        注意:MATLAB文件要和两个保存的text文件在同一文件里;len,len2的长度和具体运行之后的保存结果有关,需要根据自己的运行结果进行更改。

%% 对混频信号和滤波信号做时频域分析
clc                                 % 清屏
clear all;                          % 清除变量
close all;                          % 关闭所有窗口
% 加载文件
load before_filter_data.txt
load after_filter_data.txt
% 给文件命名
before=before_filter_data;
after=after_filter_data;
%% 绘图
figure(1);
plot(before);                       % 绘制混频信号
axis([0 200 -20000 20000])          % 坐标轴范围设置
title('滤波前混频信号时域波形');    % 标题
figure(2);
plot(after);                        % 绘制滤波后信号
axis([0 200 -2*10e8 2*10e8])        % 坐标轴范围设置
title('滤波后信号时域波形');        % 标题
%% FFT分析
fs=50e6;                            % 采样频率                    
len=55751;                          % 滤波信号长度
len2=55751;                         % 混频信号长度 
ff=fs/len;                          % 滤波信号频谱分辨率
ff2=fs/len2;                        % 混频信号频谱分辨率
f=-fs/2:ff:fs/2-ff;                  % 滤波信号频谱范围
f2=-fs/2:ff2:fs/2-ff2;               % 混频信号频谱范围
% FFT
bfft=fft(before);                   % 混频信号做FFT
afft=fft(after);                    % 滤波信号做FFT
figure(3);
plot(f2,abs(fftshift(bfft)));       % 绘制混频信号频谱
axis([-8e6,8e6,-inf,inf]);          % 坐标轴范围设置
title('滤波前混频信号频谱');        % 标题
figure(4);
plot(f,abs(fftshift(afft)));        % 绘制滤波信号频谱
axis([-2e6,2e6,-inf,inf]);          % 坐标轴范围设置
title('滤波后单频信号频谱');        % 标题

12.MATLAB时频分析结果 

FPGA学习笔记(六): FIR IP核的使用_第20张图片  FPGA学习笔记(六): FIR IP核的使用_第21张图片

 FPGA学习笔记(六): FIR IP核的使用_第22张图片

FPGA学习笔记(六): FIR IP核的使用_第23张图片

你可能感兴趣的:(FPGA学习笔记,fpga开发,学习)