用MATLAB生成的滤波器系数是可以控制增益的,一般归一化的目的是控制增益为1。滤波器的阶数由数据速率,过渡带宽、通带波纹和阴带波纹来决定,
在下图中FS,Apass,Astop固定之后,只要Fpass与Fstop两者差值一定,滤波器的阶数就是一定的。
在ALTERA的FPGA,滤波器ip支持多系数就是一组阶数相同的系数。
用MATLAB生成的滤波器系数是可以控制增益的,一般归一化的目的是控制增益为1。滤波器的阶数由数据速率,过渡带宽、通带波纹和阴带波纹来决定,
在下图中FS,Apass,Astop固定之后,只要Fpass与Fstop两者差值一定,滤波器的阶数就是一定的。
在ALTERA的FPGA,滤波器ip支持多系数就是一组阶数相同的系数。
转载于:https://www.cnblogs.com/zhongguo135/p/9149033.html
本文借鉴 小墨学FPGA 的文章 《零基础学FPGA( 三十二) 写在京城,多级FIR半带滤波器的FPGA实现 》
地址是: http://bbs.elecfans.com/forum.php?mod=viewthread&tid=509022
假设我们的合成信号是由100,300和600hz的正弦波相加而成的信号,并将其进行8bit量化,初始采样频率为6400hz,现在我需要将采样信号降为800hz,并要求获得100hz有用信号,要求滤波器的通阻带容限为0.1,设计这样一个FIR半带滤波器。
clear all
clc
close all%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 通带截止频率近似3KHz,阻带截止频率近似5KHz
fp = 100; % 要求最后一级滤波器的通带截止频率
fc = 300; % 要求最后一级滤波器的阻带截止频率
fs = 6400; %原始采样频率
fs_out = 800; % 要求降频后的采样频率
dev=0.1; %要求的滤波器通阻带容限
D=fs/fs_out; %求总抽取倍数
N=log2(D) ; %求滤波器级数
devi=dev/N; % 求每级滤波器通阻带容限% 设计前2级半带滤波器
hin1 = firhalfband('minorder',fp/(fs/2),dev); %designs a lowpass minimum-order filter,
% with passband edge fp. The peak ripple is constrained by the scalar dev.
% This design uses the equiripple method.hin2 = firhalfband('minorder',fp/(fs/4),dev);
fid=fopen('E:\WORK\DRS6000_Q\MATLAB CODE\hin1.txt','wt');
fprintf(fid, '%d\n', hin1);
fclose(fid);fid=fopen('E:\WORK\DRS6000_Q\MATLAB CODE\hin2.txt','wt');
fprintf(fid, '%d\n', hin2);
fclose(fid);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 设计最后一级最优低通滤波器
f = [fp,fc]; % 最优低通滤波器带宽
a = [1 0]; % 最优低通滤波器幅频特性,低通滤波器
devk = [devi,dev] ; % 要求的滤波器通阻带容限
mag = [1 1 0 0]; %最优滤波器幅度特性
fpm = [0 fp/((fs_out*2)/2) fc/((fs_out*2)/2) 1];
[n,wn,beta,firtype] = kaiserord(f,a,devk,fs_out*2); %调用函数求滤波器最小阶数
hin3 =firpm(n,fpm,mag); %调用函数设计最优滤波器
% freqz(hin3);
fid=fopen('E:\WORK\DRS6000_Q\MATLAB CODE\hin3.txt','wt');
fprintf(fid, '%d\n', hin3);
fclose(fid);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
f1 = 100; % 信号频率
f2 = 300; % 信号频率
f3 = 600; % 信号频率
lengthy = 1024;
n = 0:1:lengthy-1;
t = n/fs;
si = sin(2*pi*f1*t)+sin(2*pi*f2*t)+sin(2*pi*f3*t);
figure
plot(t,si);
freq=linspace(-fs/2,fs/2,lengthy);
figure
plot(freq,fftshift( abs(fft(si)) ));
xlim( [ 0, 1000 ] ); %设置横轴范围0~1000
xlabel('Frequency ');
title('Magnitude spectrum of chirp signal');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%滤波与抽取过程
F1_out = filter (hin1,1,si); %第一级半带滤波器
s1 = F1_out (1:2:length(F1_out)); %2倍抽取
F1_max = max (abs(F1_out));F2_out = filter (hin2,1,s1); %第二级半带滤波器
s2 = F2_out (1:2:length(F2_out)); %2倍抽取F3_out = filter (hin3,1,s2); %第二级半带滤波器
sout = F3_out (1:2:length(F3_out)); %2倍抽取
sout = sout/max(sout);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
lengths = lengthy/8;
n1 = 0:1:lengths-1;
t1=n1/fs;
figure
plot(t1,sout);
freq=linspace(-fs/16,fs/16,lengths);
figure
plot(freq,fftshift( abs(fft(sout)) ));
xlim( [ 0, 1000 ] ); %设置横轴范围0~1000
xlabel('Frequency ');
title('Magnitude spectrum of chirp signal');
figure
subplot(211)
stem(si);
subplot(212)
stem(sout);% % 前2级半带滤波器的幅频相应
% figure
% impz(hin1);
% figure
% impz(hin2);
%
% h1 = mfilt.firdecim(2,hin1); % Create a polyphase decimator
% h2 = mfilt.firdecim(2,hin2); % Create a polyphase decimator
% freqz(h1);
% freqz(h2);转载于:https://www.cnblogs.com/chuanchuan304/p/5888790.html
使用MATLAB生成滤波器有很多学问,这里只是作为初步的探索,和FPGA的更多结合,也正在探索中,相关博文例如:【 FPGA 】FIR滤波器目录,该专题目录正在记录我学习FIR滤波器的过程。
MATLAB生成30阶低通1MHz海明窗函数设计步骤:
(1)在MATLAB命令窗口中输入“fdatool”出现如下对话框:
注意,在MATLAB2018以后的版本中输入:filterDesigner,即可打开上述界面。
(2)设定为低通滤波器。
(3)选择FIR滤波器的设计类型为窗函数。
设置FIR滤波器为30阶滤波器,选择窗函数的类型为海明窗函数,海明窗函数可以得到旁瓣更小的效果,能量更加集中在主瓣中,主瓣的能量约占99.963%,第一旁瓣的峰值比主瓣小40dB,但主瓣宽度与海明窗相同。它定义为:
(4)输入抽样频率和截止频率,分别是16MHz和1MHz。
(5)点击Design Filter 得到结果,如下图:
(6)量化输入输出,点击工作栏左边的量化选项,即“set quantization parameters”选项,选择定点,设置输入字长为8,其他选择默认,如下图示:
设置完成后,点击Targets中Generate HDL,选择生成Verilog 代码,设置路径,MATLAB即可生成设计好的滤波器Verilog HDL 代码以及测试文件:
仿真结果如下图:
![]()
如上图所示,当输入为线性,或者输入频率较低时,输出幅度不会被抑制,当输入频率较高,输出幅度会受到大幅度抑制,而当输入为白噪声或者混频信号时,滤波器会过滤掉高频信号。
这里分出来一小部分空间,引用点别人的内容来简单介绍下上述几个参数的意思:
Response Type:选择FIR滤波器的类型:低通、高通、带通和带阻等。在DDC/DUC模块设计中,抽取和内插需要使用Halfband Lowpass类型,而channel filter需要使用Raised-cosine类型。
Design Method:FIR滤波器设计方法有多种,最常用的是窗函数设计法(Window)、等波纹设计法(Equiripple)和最小二乘法(Least-Squares)等。其中窗函数设计法在学校课堂中是重点讲解的,提到FIR滤波器肯定会想到hamming、kaiser窗,但是实际应用中却很少使用,因为如果采用窗函数设计法,达到所期望的频率响应,与其它方法相比往往阶数会更多;而且窗函数设计法一般只参照通频带wp、抑制频带ws和理想增益来设计滤波器,但是实际应用中通频带和抑制带的波纹也是需要考虑的,那在这种情况下,采用等波纹设计法就非常适用了。
Filter Order:设置滤波器的阶数,这个选项直接影响滤波器的性能,阶数越高,性能越好,但是相应在FPGA实现耗用的资源需要增多。在这个设置中提供2个选项:Specify order和Minimum order,Specify order是工程师自己确定滤波器的阶数,Minimum order是让工具自动确定达到期望的频率相应所需要的最小阶数,因此具体选择哪个选项得视实际情况而定了。
density factor:这个参数控制了频率网的密度。提高这个参数的值可以使设计出的滤波器更加接近理想的频率响应,但这样会增加滤波的计算量。因为滤波器设计要求频率网上每个频点都要满足理想滤波器的指标规格,频率网越密,设计出的滤波器公式越复杂。
Frequency Specification:设置频率响应的参数,包括采样频率Fs、通带频率Fpass和阻带频率Fstop。
magnitude specifications:定义幅值衰减,单位是db,分贝。Apass表示通带衰减,Astop表示阻带衰减。Apass/Astop = 20*log10(输出/输入)。
用等波纹最佳逼近法设计的滤波器,其通带和阻带均为等波纹特性,且通带最大衰减和阻带最小衰减可以分别控制,所以其指标均匀分布,没有资源浪费,所以阶数低得多。
http://www.elecfans.com/d/700098.html
当然,如果仅仅直接给出上述仿真结果,略显没有诚意,因为一般教科书上的风格就是这样的,不告诉你怎么仿真成这个样子,(例如这里的模拟波形是如何产生的等),那这里不是教科书,这里是更随意、更接地气的分享知识以及经验的地方,我就给出仿真的过程。
预备1:
首先,你的电脑上必须要有Modelsim这个仿真软件:
我曾经写过modelsim安装以及破解的博文,可以参考!
modelsim-win64-10.4-se 破解(win7实验成功)(其他操作系统也可参考,大同小异)
预备2:通过上述的方法生成Verilog HDL代码以及testbench文件:
正式开始:
打开Modelsim,新建一个工程文件:
添加Verilog HDL文件以及测试文件:
如下图,选中并编译:
之后开始仿真:
选中tb文件,并取消优化选项:
之后,如下图:选中目标并右击添加到wave;
如下图:仿真时间改为1ms
运行:
选中下面的两项:
右击,format,analog(automatic);
右击,radix,decimal;
这两个步骤完成之后,就出现如下图的效果:
从中,最直观的感受就是我们设计的这个滤波器对低频分量给予通过,对高频分量则出现抑制现象,和我们的预期一样,因为我们设计的就是低通滤波器。
更多内容的你可以仔细去阅读tb文件,看看人家输入的信号是什么样的。
好了,这篇博文就到这里了。
路漫漫其修远兮,吾将上下而求索!
参考博文:https://www.cnblogs.com/xiaomeige/p/8846786.html
参考文献:Verilog HDL数字集成电路高级电路设计