本文测试直接I型的IIr低通滤波器在matlab中和在fpga实现中有什么不同。。
为了看的清楚写的简略,可以参考后面贴的代码
第一步:产生两个信号源,采样率fs =1000hz,单频信号fc1 = 50hz,单频信号fc2 = 300hz,其中肯定是想滤掉fc2的。
原始数据频谱:
第二步:在matlab中用函数设计和fpga一样的8阶滤波器,来进行滤波。其中分两种情况滤波,一种是直接用filter函数,另一种是用自己写的有实现过程的滤波,模拟fpga中动作,看效果如何
matlab设计的8阶参数频谱:
matlab调用自带滤波函数filter处理数据后的频谱图:
matlab中自己写IIr滤波器的滤波效果图:
田耕上的8阶直接型IIr滤波器幅频图:
利用田耕数上滤波参数,直接I型IIR滤波器滤波效果图:
第三步,当然是把产生的数据导到modesim中进行仿真,然后把modesim生成的滤波数据在matlab读取,观察滤波效果
这是通过modesim仿真经过滤波后产生的数据频谱图:
疑问:
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
用户1715035 2015-4-24 10:39
用户1605975 2015-4-20 21:38
自做自受 2013-11-18 13:01
用户1719731 2013-11-16 11:26
自做自受 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
今天把被迫“夭折”了的高科技热水器包装好,存放着,等待起死回生。
这个纸箱就是新热水器的包装物一次循环再用。