原创 直接型iir滤波器的matlab实现和modesim仿真对比

2015-4-19 00:29 2238 4 6 分类: FPGA/CPLD 文集: matlab

本文测试直接I型的IIr低通滤波器在matlab中和在fpga实现中有什么不同。。

为了看的清楚写的简略,可以参考后面贴的代码

第一步:产生两个信号源,采样率fs =1000hz,单频信号fc1 = 50hz,单频信号fc2 = 300hz,其中肯定是想滤掉fc2的。

原始数据频谱:

111111111.jpg

第二步:在matlab中用函数设计和fpga一样的8阶滤波器,来进行滤波。其中分两种情况滤波,一种是直接用filter函数,另一种是用自己写的有实现过程的滤波,模拟fpga中动作,看效果如何

matlab设计的8阶参数频谱:

222222.jpg

matlab调用自带滤波函数filter处理数据后的频谱图:

33333333.jpg
 
matlab中自己写IIr滤波器的滤波效果图:
 
4444444.jpg
 
田耕上的8阶直接型IIr滤波器幅频图:
 
55555555.jpg
 
利用田耕数上滤波参数,直接I型IIR滤波器滤波效果图:
 
6666666666666.jpg

第三步,当然是把产生的数据导到modesim中进行仿真,然后把modesim生成的滤波数据在matlab读取,观察滤波效果

这是通过modesim仿真经过滤波后产生的数据频谱图:

777777777777.jpg
 
 
疑问:
1,modesim仿真iir仿真的频谱图应该差不多啊,都是数字信号,虽然在fpga中有截短,但是误差不应该这么大啊。。fpga滤波程序看综合的RTL都没有错的啊,为什么呢?反而相对变好??
 
 
代码:
 
matlab: Part1
close all;clc;clear all;
fid = fopen('data_out.txt','w');
fs = 1000;  %采样率1000hz
fc1 = 50;
fc2 = 300;  %产生两个单频信号,设计一个低通iir,滤掉其中的fc2
 
T = 1/fs;
nn = [1:fs];
 
data = cos(2*pi*fc1*nn*T)+cos(2*pi*fc2*nn*T);% 产生的数据
figure 
pwelch(data)
 
 
%将数据量化后,然后生成二进制数给modesim读
lianghua_bit = 8;
data =round( data/max(data)*(2^(lianghua_bit-1)-1) + 128);
figure 
pwelch(data)
save iir_data.mat data
for i =  1:length(data)
    data_bin = dec2bin(data(i),8);
    fprintf(fid,'%c%c%c%c%c%c%c%c\n',data_bin(1),data_bin(2),data_bin(3),...
        data_bin(4),data_bin(5),data_bin(6),data_bin(7),data_bin(8));
end
 
matlab: Part2
close all;clc;clear all;
format long g
%读取产生的数据源
load iir_data.mat data
figure 
pwelch(data)
title('原始数据频谱');
%用cheby1来进行iir滤波
order = 8;
n = order-1;%8阶
rp = 20;%带内纹波
Wp = 200/500;
%
 
%可以选择不同的函数的估计参数
[b1,a1] = butter(n,Wp,'low');
% [b1,a1] = cheby1(n,rp,Wp);
% [b1,a1] = cheby2(n,20,200/500,'low');
figure 
freqz(b1,a1,512,1000)
title('matlab设计8阶参数频谱');
 
%利用matlab函数直接滤波
y = filter(b1,a1,data);
figure 
pwelch(y)
title('matlab调用函数直接滤波');
 
 
% %FPGA里面直接型iir滤波器滤波
% data_new = [zeros(1,2*order-1) data zeros(1,order-1)];
% out(1,1:order) = zeros(1,order);
% data_feedback=0;
% data_feedforward=0;
% for i = 9:length(data_new) - order
%     out(1,i) = data_feedforward - data_feedback;
%     data_feedforward = sum(data_new(1,i:i+order-1 ) .* (fliplr(b1))); 
% %     data_feedback = [out(1,i) out(1,i-1) out(1,i-2) out(1,i-3) out(1,i-4)...
% %         out(1,i-5) out(1,i-6) out(1,i-7)] *(b1)';
%     data_feedback = sum(out(1,i-1:-1:i-order+1)  .*(a1(2:end)));
% end
% %画频谱图
% figure
% pwelch(out)
 
%按直接I型iir滤波器滤波
data_new = [zeros(1,order-1) data ];
out(1,1:order) = zeros(1,order);
data_feedforward=0;
data_feedback=0;
for i =8:length(data_new);
    data_feedforward = sum(data_new(i:-1:i-order+1) .* b1);
    data_feedback = sum(out(i-1:-1:i-order+1) .* a1(2:end));
    out(1,i) = data_feedforward - data_feedback;
end
figure 
pwelch(out)
title('自己写直接I型iir滤波器滤波效果');
 
%调用函数和自己写iir型滤波器效果差距观察
kk = out(8:1007) - y;
max(kk)
 
 
%田耕书上滤波器系数滤波
b2 = [4 22 65 110 110 65 22 6];
a2 = [25 -70 99 -85 47 -16 4 1];
figure 
freqz(b2,a2,512,1000)
title('田耕书上的8阶iir频谱图');
 
data_new2 = [zeros(1,order-1) data ];
out2(1,1:order) = zeros(1,order);
data_feedforward=0;
data_feedback=0;
for i =8:length(data_new);
    data_feedforward = sum(data_new(i:-1:i-order+1) .* b2);
    %???貌似下面两种反馈写都对结果没有影响
%     data_feedback = sum(out(i-1:-1:i-order+1) .* a2(2:end));
    data_feedback = sum(out(i-1:-1:i-order+1) .* fliplr(a2(1:end-1)));
    out2(1,i) = data_feedforward - data_feedback;
end
figure
pwelch(out2)
title('自己写直接I型iir滤波器滤波效果,滤波参数用田耕书');
 
matlab: Part3
close all;clc;clear all;
load iir_data.mat data
figure
 pwelch(data)
title('原始数据频谱')
 
 fid = fopen('data_from_modesim3.txt','r');
mm = 1;
while ~feof(fid)
    data_modesim(mm) =str2num(fgets(fid));
    mm = mm +1;
end
figure
 pwelch(data_modesim)
 title('田耕书上直接I型iir滤波器滤波后结果')
 
aa =1; 
 
fpga part1:
module IIR_Filter_8(Data_out,Data_in,clock,reset);
 
parameter order = 8;
parameter word_size_in = 8;
parameter word_size_out = 2*word_size_in + 2;
 
parameter b0 = 4;
parameter b1 =22;
parameter b2 =65;
parameter b3 = 110;
parameter b4 = 110;
parameter b5 = 65;
parameter b6 = 22;
parameter b7 = 6;
 
parameter a1 = 25;
parameter a2 = -70;
parameter a3 = 99;
parameter a4 = -85;
parameter a5 = 47;
parameter a6 = -16;
parameter a7 = 4;
parameter a8 = 1;
 
output [word_size_out-1:0] Data_out;
input [word_size_in -1:0] Data_in;
input clock,reset;
 
reg [word_size_in-1:0] Samples_in[1:order];
reg [word_size_in-1:0] Samples_out[1:order];
wire [word_size_out-1:0] Data_feedforward;
wire [word_size_out-1:0] Data_feedback;
integer k;
 
assign Data_feedforward = b0*Data_in + b1*Samples_in[1] + b2*Samples_in[2] +
b3*Samples_in[3] + b4*Samples_in[4] + b5*Samples_in[5]+b6*Samples_in[6]+b7*Samples_in[7];
 
//assign Data_feedback = a1*Samples_out[1] + a2*Samples_out[2] + a3*Samples_out[3] +a4*Samples_out[4]+
// a5*Samples_out[5] + a6*Samples_out[6] +a7*Samples_out[7] +a8*Samples_out[8];
//assign Data_out = Data_feedforward + Data_feedback;
 
 
// by me
assign Data_feedback = a2*Samples_out[1] + a3*Samples_out[2] +                          a4*Samples_out[3] +a5*Samples_out[4]+
a6*Samples_out[5] + a7*Samples_out[6] +a8*Samples_out[7] ;
assign Data_out = Data_feedforward - Data_feedback;
 
always @(posedge clock)
if(reset==1)
for(k=1;k<=order;k=k+1) begin
    Samples_in[k] <= 0;
    Samples_out[k] <=0;
end
else begin
    Samples_in[1] <= Data_in;
    Samples_out[1] <= Data_out;
    for(k=2;k<=order;k=k+1) begin
        Samples_in[k] <= Samples_in[k-1];
       Samples_out[k] <= Samples_out[k-1];
    end
end
 
endmodule
 
fpga part2:
module IIR_Filter_8_tb();
 
parameter order = 8;
parameter word_size_in = 8;
parameter word_size_out = 2*word_size_in + 2;
 
wire [word_size_out-1:0] Data_out;
reg [word_size_in -1:0] Data_in;
reg clock,reset;
 
 
IIR_Filter_8  U1(
.Data_out(Data_out),
.Data_in(Data_in),
.clock(clock),
.reset(reset));
 
 
 
initial  begin
clock = 0;
reset = 1;
 
#10 reset = 0;
end
 
always #4 clock<= ~clock;
 
 
reg [word_size_out-1:0] data_mem[0:999];
 
initial 
  $readmemb("data_out.txt",data_mem);
 
 integer i; 
 
always @(posedge clock or posedge reset)
begin
    if(reset)
    begin
         Data_in <= 8'd0;
         i <= 32'd0;
     end
   else  
        begin
          i = i + 1;
          Data_in <= data_mem;
     end
end
 
integer file_out;
 
initial
   file_out = $fopen("data_from_modesim.txt");
 
always @(i)
begin
   if(i == 1000)
       $stop;
   else
       $fwrite(file_out,"%d\n",Data_out);
end
 
 
endmodule
 
PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1715035 2015-4-24 10:39

不好意思,我对这个现在也把握不准。还在学习中

用户1605975 2015-4-20 21:38

wire [word_size_out-1:0] Data_feedforward; wire [word_size_out-1:0] Data_feedback; 博主你好,我想请教下,你这两个变量为什么取这个位宽,有什么依据,我对IIR实现的中间运算过程中的位宽控制一直没有弄明白。

自做自受 2013-11-18 13:01

“坑”,这个字用的到位!如今消费电子电器产品在盲目追求多功能、智能化,使这个“坑”越来越深、深不可测。可人人都是消费者也是制造者,怎么办?

用户1719731 2013-11-16 11:26

感觉热水器这行很坑,所谓的智能温控,成本应该也就要不了20块吧,如果不算开发的话,到厂家手上,就要身家直升,加个七八百一两千了。

自做自受 2013-11-10 18:22

多谢支持和鼓励!个人理念和行为,探索和尝试,更希望能参与,如何在电子设计环节促进减少电子垃圾泛滥。

用户403664 2013-10-31 11:39

哈哈,真不错呢

自做自受 2013-10-31 10:03

特别报告:第十天了,可乐饮料罐,面不改色,体健在。<br/>注:水温控制在了40=45度,寒冬或许在提高一点,再观察。

自做自受 2013-10-23 09:48

对不起,电脑打字,拼音输入法,本人常常有错别字,还望见谅,谢谢!
呵呵,倒也是,也带来一点儿猜谜的智力游戏,脑筋即转弯儿!哈,开个玩笑。

自做自受 2013-10-22 20:08

今天把被迫“夭折”了的高科技热水器包装好,存放着,等待起死回生。

这个纸箱就是新热水器的包装物一次循环再用。

img_999_12.jpg
相关推荐阅读
用户1715035 2015-05-18 10:41
The art of counting in fpga(2)
接前面,居然一篇放不下--------------------------------------------------------------------------------- Cus...
用户1715035 2015-05-18 10:40
The art of counting in fpga(1)
转载至fpga4fun,觉得对重新理解fpga很好,而且从来没有在中文网站上看到这种东西,而且讲的通俗易懂,以后多看点英文网站。先转下来备忘,从以前的一个自己的博客上转载过来的。。 (1)Bi...
用户1715035 2015-04-25 18:13
多相抽取fir滤波器的fpga仿真实现
今天仿真了下多相抽取滤波器的仿真实现,其原理其实很简单就是根据抽取的原则,将fir滤波器的系统函数分解,称之为多相,所以又叫多相抽取滤波器。 一、原理如下图:   系统实现函数为...
用户1715035 2015-04-20 16:20
fir 滤波器的matlab实现和modesim实现仿真对比
本测试主要是为了测试fir滤波器在matlab和modesim中有什么不同。。 用的fir滤波器都是8阶直接,而且信号处理过程也是一模一样。 第一步:以matlab为原型,现在matla中...
用户1715035 2015-04-09 23:03
matlab和modesim的一种读写交互方式(通过txt文件)
在进行modesim仿真时,由于matlab强大的数据处理能力,时常需要比较复杂的激励或者需要把仿真结果保存下来用matlab来处理。利用matlab工具来辅助modesim仿真显得十分重要。。 ...
EE直播间
更多
我要评论
2
4
关闭 站长推荐上一条 /3 下一条