Vivado 利用FIR滤波器设计低通滤波器

0 系统功能

假设输入信号为cos(2*pi*f1*t)+cos(2*pi*f2*t) 。其中f1=5MHz,f2=15MHz。
然后利用FIR滤波器滤掉f2频率分量。

1 FIR IP 核

1.1 参数设置

在IP Catalog中打开FIR Compiler,主界面如下。
配置界面一:
1、IP核支持两种FIR系数输入方式,以“Vector”的形式直接写入;或者以“COE File”的形式导入coe文件;
2、2处默认为1,表示有几路滤波通道,此处选择 1 路;
3、3处的数据是61,无法更改,表示的是从刚刚加载的 .coe 文件中读取到 61个滤波器系数;
4、Xilinx的FIR IP核支持多种滤波器结构,可以在“Filter Type”设置,本文选择传统的“Single Rate”结构。该IP核同样也支持系数重载。

除了单速率(Single Rate,即数据输出与输入速率相同)外,FIR Compiler还支持抽取(Decimation)和插值(Interpolation)应用于多速率信号处理系统。此外还支持希尔伯特变换(Hilbert)模式,可以在“Filter Type”中设置。
在这里插入图片描述

配置界面二:
IP核支持多通道数据输入,可以在Channel Specification这个Tab中设置输入数据的通道数。还可以在Hardware Oversampling Specification中设置过采样模式,即输入数据的频率可以高出FIR系统时钟的频率。
该页面还需要配置系统时钟和数据采样时钟,在上一讲中设置 matlab 滤波器参数时是125MHz采样频率,所以此处选择输入采样时钟为125MHz,为了方便起见,此处设置系统时钟为125MHz
在这里插入图片描述

配置界面三:
设置FIR系数的类型、量化方式、量化位宽(此值应该与MATLAB中的设置一致,否则频率响应是错的)和结构。本文由于是设计线性相位FIR,滤波器系数是对称的,因此选择为“Symmetric”,也可以选择为“Inferred”,软件会自动判断系数的结构。
在这里插入图片描述
在这里插入图片描述

其他配置界面保持默认。

1.2 例化模板

lowpass_fir your_instance_name (
  .aclk(aclk),                              // 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(m_axis_data_tdata)    // output wire [31 : 0] m_axis_data_tdata
);

参数解释说明:
在这里插入图片描述
注意点:
输入的数据是16位,输出的数据却为32位。但是工程要其求输出数据的位宽为16位,所以我们保留输出数据的高16位。

2 功能实现

2.1 MATLAB实现

2.1.1 程序

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%           参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ADC_bit=16;      % 采样位数  
N=1024;          % 采样点数  
yinzi=10;        % 缩减因子,避免出现  D 必须为小于 flintmax 的非负整数。

c=3e8;           % 光速
f1=5e6;          % 信号频率 5M 
f2=15e6;         
fs=125e6;         % 采样频率 
t=0:1/fs:(N-1)/fs;



st=cos(2*pi*f1*t)+cos(2*pi*f2*t);      % 空间窄带远场平面波到达原点的解析信号

% ----幅度谱
P_st=fftshift(fft(st));         
P_st=abs(P_st)/N;
f=(0:N-1)*fs/N-fs/2; 


figure(1)
subplot(211);
plot(t,st);hold on;
subplot(212);
plot(f/1e6,P_st);grid on;        % 在f和fs-f出现频点
title('FFT变换');            
xlabel('频率/MHz');ylabel('幅度');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%             导出波形数据
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 阵元1
fid=fopen('data_in.coe','w');  % 实部
[u_x1_real,x1_real]= coe_generate(fid,ADC_bit,N,yinzi,real(st) );
fprintf('x1_real信号的幅度值为%g\n',u_x1_real);

figure(2)
% plot(t,st);hold on;
plot(t,x1_real);hold on;



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%          低通滤波器(10M以下的通过)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LOW_PASS_FILTER Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 9.5 and Signal Processing Toolbox 8.1.
% Generated on: 26-Nov-2021 15:34:34
% Equiripple Lowpass filter designed using the FIRPM function.
% All frequency values are in MHz.
Fs = 125;  % Sampling Frequency
N     = 60;  % Order
Fpass = 5;   % Passband Frequency
Fstop = 10;  % Stopband Frequency
Wpass = 1;   % Passband Weight
Wstop = 1;   % Stopband Weight
dens  = 20;  % Density Factor
% Calculate the coefficients using the FIRPM function.
b  = firpm(N, [0 Fpass Fstop Fs/2]/(Fs/2), [1 1 0 0], [Wpass Wstop], ...
           {dens});
       
       
y=conv(b,st);
L_filter=length(b);
delay_filter1=(L_filter-1)/2;
y1=y(delay_filter1+1:end-delay_filter1);

% ----幅度谱
P_y1=fftshift(fft(y1));         
P_y1=abs(P_y1)/N;



figure(3)
subplot(211);
plot(t,y1);hold on;
subplot(212);
plot(f/1e6,P_y1);grid on;                
xlabel('频率/MHz');ylabel('幅度');

子函数

function [u_yt,yt] = coe_generate(fid,ADC_bit,L,yinzi,st)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            MATLAB生成coe文件
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%.coe文件中
% 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
% 从第 3 行开始到第最后一行,是这个  L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。
% 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。

% y=st/max(abs(st));                 % 归一化   
 % 千万不能归一化

y=st/yinzi;
yt=round(y*(2^(ADC_bit-1)-1));     % 12bit量化  round()表示取整
YT_FFT=fft(yt,L);   % 傅里叶变换
P_YT=abs(YT_FFT)/L; % 幅度谱
u_yt=max(P_YT);     % 得到波束1接收到的信号的幅度值


% fid=fopen('data0.coe','w');
fprintf(fid,'Memory_Initialization_Radix = 2;\r\n'); % 二进制
fprintf(fid,'Memory_Initialization_Vector = \r\n');
for p=1:L
    B_s=dec2bin(yt(p)+(yt(p)<0)*2^ADC_bit,ADC_bit);
    for q=1:ADC_bit  % 12位,依次判断这12位的数值
        if B_s(q)=='1'
            data=1;
        else
            data=0;
        end
        fprintf(fid,'%d',data);
    end
    
    %  下面if语句的目的
    %  每行数字后面用逗号(,),最后一行数字结束用分号(;)
    if (p<L)
        fprintf(fid,',\r\n'); 
    else
        fprintf(fid,';\r\n');    % 分号(;)  结束标志位
    end
   
end
fclose(fid);
end


2.1.2 仿真结果

在这里插入图片描述

2.2 FPGA实现

2.2.1 程序结构

在这里插入图片描述

2.2.2 FIR IP的系数生成

我们利用MATLAB来生成滤波器的系数,也就是利用MATLAB来设计一个低通滤波器。
在输入框输入fdatool,按照以下参数进行设计
在这里插入图片描述
然后导出为函数,如下所示:

function Hd = low_pass_filter
%LOW_PASS_FILTER Returns a discrete-time filter object.

% MATLAB Code
% Generated by MATLAB(R) 9.5 and Signal Processing Toolbox 8.1.
% Generated on: 26-Nov-2021 17:23:51

% Equiripple Lowpass filter designed using the FIRPM function.

% All frequency values are in MHz.
Fs = 125;  % Sampling Frequency

N     = 60;  % Order
Fpass = 5;   % Passband Frequency
Fstop = 10;  % Stopband Frequency
Wpass = 1;   % Passband Weight
Wstop = 1;   % Stopband Weight
dens  = 20;  % Density Factor

% Calculate the coefficients using the FIRPM function.
b  = firpm(N, [0 Fpass Fstop Fs/2]/(Fs/2), [1 1 0 0], [Wpass Wstop], ...
           {dens});
Hd = dfilt.dffir(b);

% [EOF]

生成FIR滤波器的系数的程序

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%           参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Quantify_bit=16;   % 希尔伯特滤波器量化位数 16位
fs=65e6;           % 采样频率


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%          低通滤波器(10M以下的通过)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%LOW_PASS_FILTER Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 9.5 and Signal Processing Toolbox 8.1.
% Generated on: 26-Nov-2021 15:34:34
% Equiripple Lowpass filter designed using the FIRPM function.
% All frequency values are in MHz.
Fs = 125;       % Sampling Frequency
N     = 60;  % Order
Fpass = 5;   % Passband Frequency
Fstop = 10;  % Stopband Frequency
Wpass = 1;   % Passband Weight
Wstop = 1;   % Stopband Weight
dens  = 20;  % Density Factor
% Calculate the coefficients using the FIRPM function.
b  = firpm(N, [0 Fpass Fstop Fs/2]/(Fs/2), [1 1 0 0], [Wpass Wstop], ...
           {dens});


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            MATLAB生成coe文件
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%.coe文件中
% 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
% 从第 3 行开始yong到第最后一行,是这个  L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。
% 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。

yt=round(b*(2^(Quantify_bit-1)-1));     % 12bit量化


fid=fopen('lowpass_filter.coe','w');  % w表示write
fprintf(fid,'Radix = 10;\r\n'); % 二进制
fprintf(fid,'coefdata = \r\n');
L=length(b);
for p=1:L
    fprintf(fid,'%d',yt(p));  % 写入数据
    
   
    %  下面if语句的目的
    %  每行数字后面用逗号(,),最后一行数字结束用分号(;)
    if (p<L)
        fprintf(fid,' \r\n'); 
    else
        fprintf(fid,';\r\n');    % 分号(;)  结束标志位
    end
   
end
fclose(fid);


figure(1)
plot(b);

figure(2)
plot(yt);

figure(3)
plot(yt./b );

2.2.3 verilog程序

(1)top模块

`timescale 1ns / 1ps
// 程序功能:
//假设输入信号为cos(2*pi*f1*t)+cos(2*pi*f2*t) 。其中f1=5MHz,f2=15MHz。
//然后利用FIR滤波器滤掉f2频率分量。

module top(
    input           clk             ,
    input           rst_n           ,
    
    output [31:0]   data_out        ,
    output [15:0]   data_out_16bit
    );
  
  
  

//-----       1、产生长度为1024的正弦波
//--- cos(2*pi*f1*t)+cos(2*pi*f2*t) .f1=5MHz,f2=15MHz

wire [15:0] rom_data; //ROM读出数据  每个数据有16bit
reg  [9:0]  rom_addr; //ROM输入地址  1024个数据,需要2^10个地址
  
//产生ROM地址读取数据
always @ (posedge clk or negedge rst_n)
begin
    if(!rst_n)
        rom_addr <= 10'd0;
    else
        rom_addr <= rom_addr+1'b1;
end
//实例化ROM
rom_data_in rom_data_in_inst
(
    .clka  (clk         ),   //inoput clka
    .addra (rom_addr    ), //input [9:0] addra  1024个数据,需要2^10个地址
    .douta (rom_data    )  //output [15:0] douta    
);





//---------2、低通滤波器  (滤掉f2,保留f1)   

v_fir_filter v_fir_filter_inst(
    // input
    .clk     (clk       ),
    .data_in (rom_data  ),
    
    //output 
    .data_out(data_out  )
);

assign data_out_16bit=data_out[31:16];        
    
    
    
        
endmodule

(2)v_fir_filter模块

`timescale 1ns / 1ps
//
// Company:   低通滤波器的设计
//


module v_fir_filter(
    input           clk     ,
    input [15:0]    data_in ,
    
    output [31:0]   data_out
    );
 
 
lowpass_fir lowpass_fir_inst (
      .aclk(clk),                              // input wire aclk
      .s_axis_data_tvalid(1'b1),                // input wire s_axis_data_tvalid
      .s_axis_data_tready(),                    // output wire s_axis_data_tready
      .s_axis_data_tdata(data_in),              // input wire [15 : 0] s_axis_data_tdata
      
      .m_axis_data_tvalid(),                    // output wire m_axis_data_tvalid
      .m_axis_data_tdata(data_out)              // output wire [31 : 0] m_axis_data_tdata
    ); 
    
    
endmodule

(3)testbench

`timescale 1ns / 1ps
//


module sim_mytop;


//input
reg             clk;
reg             rst_n;

//output
wire  [31:0]    data_out;
wire  [15:0]    data_out_16bit;



//-----------例化top模块----------//
top top_inst(
    //input
    .clk            (clk            ),
    .rst_n          (rst_n          ),

    //output
    .data_out       (data_out       ),
    .data_out_16bit (data_out_16bit )
);


   initial  
    begin
        clk=0;
        rst_n=0;

    #5
        rst_n=1;
    end

always #5  clk=~clk;//10ns  100M


endmodule
  


2.2.4 结果

在这里插入图片描述

  • 12
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Vivado设计FIR滤波器的步骤如下: 1. 使用MATLABfirpm函数设计FIR低通滤波器,根据设计要求设置好对应参数,并导出coe文件。\[1\] 2. 在Vivado中创建一个新的工程,并添加FIR滤波器设计文件。 3. 在设计中添加DDS信号发生器模块,用于产生输入信号。 4. 将DDS信号和输入信号进行混频,得到混频后的信号。 5. 将混频后的信号输入到FIR滤波器模块中。 6. 在FIR滤波器模块中使用之前在MATLAB设计FIR滤波器的系数。 7. 将滤波器输出连接到需要的输出端口。 8. 运行综合和实现步骤,生成比特流文件。 9. 将比特流文件下载到目标设备中进行验证。 通过以上步骤,你可以在Vivado设计并实现FIR滤波器。\[2\]\[3\] #### 引用[.reference_title] - *1* [VivadoFIR IP核实现低通滤波器](https://blog.csdn.net/QDchenxr/article/details/122659624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [VIVADO 实现一个滤波器(使用FIR\DDS软核)](https://blog.csdn.net/weixin_44441263/article/details/119446921)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [FPGA—FIR滤波器vivado平台)](https://blog.csdn.net/weixin_44586889/article/details/116207811)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值