利用Vivado和MATLAB分别设计FIR滤波器并滤除高频正弦波

一、利用MATLAB实现滤波

1.设计要求

(1)在MATLAB中,调用Filter Design & Analysis Tools工具,产生一个低通滤波器,以16bits定点量化滤波器系数,并产生XILINX的COE文件。
(2)在MATLAB中,产生两个正弦信号,数据位宽16bits,频率分别为3MHz和19MHz,数据长度为4096点。两个正弦信号合路(相加),送入该低通滤波器中,观察其输出信号。

2.任务一:设计滤波器

(1)在MATLAB中选择APP-滤波器设计工具,滤波器参数设置如下:

图1-1 MATLAB中滤波器参数设置图
由于两路正弦波分别为3MHz和19MHz,所以将滤波器的通带截止频率设置为8MHz,将阻带开始频率设置为15MHz。
滤波器的采样频率应该大于信号最高频率的两倍,即38MHz,本文中取200MHz。注意:在Vivado中,FIR ip核的采样频率也要设置为200MHz,两处需要统一。
一般来说,数字滤波器的阶数越高,其复杂度越高,滤波器带内越平滑,具体取值取多少应在工程中取舍,本文中取15。

(2)点击左侧第三个小图标:设置量化参数,将滤波器算法指定为定点,将字长设置为16(由设计要求可知)。

图1-2 MATLAB中滤波器参数设置图
点击输入/输出,可以看到该滤波器的输入范围是[-1,1],输出小数长度是33。在后续输入时要注意信号的范围,如果不在要求的范围内会出错。
图1-3 MATLAB中滤波器参数设置图

(3)点击任务栏目标-XILINX系数(.COE)文件,保存至相应目录下,后续在Vivoda中设置ip核时需要导入。

图1-4 导出COE文件

2.任务二

(1)代码

clc
clear all
close all
%% 生成两个正弦信号
depth = 4096;   % 存储器的单元数4096
widths = 16;    % 数据宽度为16位
Fs = 200e6;     % 采样频率为200MHz
t = 0:1/Fs:(4096-1)/Fs; % 时间向量
f1 = 3e6;       % 第一个正弦信号频率为3MHz
f2 = 19e6;      % 第二个正弦信号频率为19MHz
signal1 = sin(2*pi*f1*t)+1;  
signal2 = sin(2*pi*f2*t)+1; 
%% 合并两个信号
combined_signal = (signal1 + signal2)/4;
%% 调用低通滤波器设计函数
Hd = lowpass_filter;
%% 对合并信号进行滤波
filtered_signal = filter(Hd, combined_signal);
%% 绘制所有信号
figure;
subplot(4,1,1);
plot(t, double(signal1));
title('第一个正弦信号','Fontname','SimSun');
xlabel('时间 (秒)','Fontname','SimSun');
ylabel('幅度','Fontname','SimSun');

subplot(4,1,2);
plot(t, double(signal2));
title('第二个正弦信号','Fontname','SimSun');
xlabel('时间 (秒)','Fontname','SimSun');
ylabel('幅度','Fontname','SimSun');

subplot(4,1,3);
plot(t, double(combined_signal));
title('合并后信号','Fontname','SimSun');
xlabel('时间 (秒)','Fontname','SimSun');
ylabel('幅度','Fontname','SimSun');

subplot(4,1,4);
plot(t, double(filtered_signal));
title('滤波后信号','Fontname','SimSun');
xlabel('时间 (秒)','Fontname','SimSun');
ylabel('幅度','Fontname','SimSun');

上文中提到,滤波器的输入范围为[-1,1],所以需要将合路信号变换到[-1,1],这里选择先给两路信号加上幅值为1的直流分量,此时合路信号的范围为[0,4],再除以4,即[0,1],符合滤波器输入要求。这样做的原因在于:后续需要通过MATLAB产生正弦波数据表ROM,为了后续在Vivado中计算方便,产生时将信号扩大,并且添加了直流分量将信号搬移为正值,为了统一输入,此处做同样处理,即添加直流分量。

(2)结果

由图1-5可知,滤波后的信号频率与3MHz信号频率基本相同,但是幅值发生了变化,这是因为滤波器的幅度响应不是常数,所以3MHz的信号也有所衰减。
图1-5 滤波前后信号时域波形图

二、利用Vivado实现滤波

1.设计要求

(1)在Vivado软件中,采用FIR Compiler进行配置,并输入MATLAB产生的滤波器系数,产生一个低通滤波器。
(2)在Vivado软件中,产生一个正弦信号表:一个完整的正弦信号周期,共4096个点,精度为16bits,以ROM方式存放。
(3)例化两个正弦信号ROM,通过控制地址的步进量的方式,产生两个正弦信号输出,频率近似为3MHz和19MHz。
(4)两个正弦信号相加后,输入低通滤波器中,在Modelsim软件中,以HDL仿真方式观察其输出信号。

2.任务三:设计FIR

(1)IP核设置

①选择IP Catalog-FIR Compile

图2-1 FIR IP核设置

②在Filter Options中将Select Source设置为COE File,点击Cofficient File右侧的第一个框上传刚才MATLAB产生的.coe文件。

图2-2 FIR IP核设置

其他参数设置如下:

图2-3 FIR IP核设置
在MATLAB中设置的滤波器的采样频率为200MHz,在此要保持一致,即Input Sampling Frequency设置为200MHz。时钟频率Clock Frequency设置为200MHz,这里时钟频率和开发板保持一致即可,也应该和测试文件中的clk频率一致。输入数据位宽为16位,输出数据位宽为35位。

下图中输出数据为m_axis_data_tdata[39:0],是40位,和Summary中Output Width不符。原因应该是这里设置成40位防止数据溢出,实际上是35位。
图2-4 FIR IP核设置

(2)代码

程序中认为输入的采样数据始终有效,因此将s_axis_data_tvalid永远置1。

`timescale 1ns / 1ps
module LowBandPassFilter(
    input clk,
    input [15:0] wave_in,
    output [39:0] wave_out,
    output m_tvalid,
    output s_tready
    );

fir_compiler_0 fir1 (
  .aclk(clk),                      
  .s_axis_data_tvalid(1'b1),       
  .s_axis_data_tdata(wave_in),    
  .s_axis_data_tready(s_tready),
  .m_axis_data_tvalid(m_tvalid),
  .m_axis_data_tdata(wave_out)   
);
endmodule

3.任务四:设计ROM

(1)MATLAB产生正弦波格式的COE文件

ROM的地址数为4096,数据位宽为16位,产生的信号幅值为10进制数。产生正弦信号表时,采用初始相位为0,周期为4096的波形,并且将正弦信号乘次方并乘( 2 15 2^{15} <

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值