热度 6
2015-4-19 00:29
2238 次阅读|
2 个评论
本文测试直接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 = ; 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; % %可以选择不同的函数的估计参数 = butter(n,Wp,'low'); % = cheby1(n,rp,Wp); % = 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 = ; % 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 = *(b1)'; % data_feedback = sum(out(1,i-1:-1:i-order+1) .*(a1(2:end))); % end % %画频谱图 % figure % pwelch(out) %按直接I型iir滤波器滤波 data_new = ; 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 = ; a2 = ; figure freqz(b2,a2,512,1000) title('田耕书上的8阶iir频谱图'); data_new2 = ; 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 Data_out; input Data_in; input clock,reset; reg Samples_in ; reg Samples_out ; wire Data_feedforward; wire Data_feedback; integer k; assign Data_feedforward = b0*Data_in + b1*Samples_in + b2*Samples_in + b3*Samples_in + b4*Samples_in + b5*Samples_in +b6*Samples_in +b7*Samples_in ; //assign Data_feedback = a1*Samples_out + a2*Samples_out + a3*Samples_out +a4*Samples_out + // a5*Samples_out + a6*Samples_out +a7*Samples_out +a8*Samples_out ; //assign Data_out = Data_feedforward + Data_feedback; // by me assign Data_feedback = a2*Samples_out + a3*Samples_out + a4*Samples_out +a5*Samples_out + a6*Samples_out + a7*Samples_out +a8*Samples_out ; assign Data_out = Data_feedforward - Data_feedback; always @(posedge clock) if(reset==1) for(k=1;k=order;k=k+1) begin Samples_in = 0; Samples_out =0; end else begin Samples_in = Data_in; Samples_out = Data_out; for(k=2;k=order;k=k+1) begin Samples_in = Samples_in ; Samples_out = Samples_out ; 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 Data_out; reg 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 data_mem ; 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