tag 标签: matlab,fpga,iir滤波器仿真

相关博文
  • 热度 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