原创 fir 滤波器的matlab实现和modesim实现仿真对比

2015-4-20 16:20 1786 5 5 分类: FPGA/CPLD 文集: matlab

本测试主要是为了测试fir滤波器在matlab和modesim中有什么不同。。

用的fir滤波器都是8阶直接,而且信号处理过程也是一模一样。

第一步:以matlab为原型,现在matla中产生双单点频信号然后用matlab中的自己写的滤波器看滤波效果如何

第二步:以matlab为原型,在quartus中写相同处理过程的fir滤波器,,然后导入matlab输出的源数据,通过fir后导出数据,将fpga滤波后的数据交由matlab处理,画出频谱图对比第一步中的matlab处理后的滤波数据,看效果如何

 

原始数据频谱图:

111111.jpg

 

Matlab的fir滤波后频谱图:

22222222222.jpg
 

Fpga的fir滤波器频谱图:

333333.jpg
 
 

分析问题疑问:

1,下面matlab代码中为什么有符号数转化为无符号数频谱就变了,还没想通??

2、为什么fpga中fir和matlab中fir都是针对定点数滤波,效果却不同。。。。

这个作为一个bug改天修改,今天太晚l。。应当是一个地方数据没衔接起来。。

 

 

源代码如下:

Matlab:

  1. 信号产生源代码:

close all;clc;clear all;

fidout =fopen('data_out.txt','w');

 

fs = 10e2;

fc = 1e2;

 

ts =1/fs;

n = fs;

nn = [1:n];

 

data_in = cos(2*pi*fc*ts*nn);

figure

 pwelch(data_in)

 data = data_in

save fir_data1.mat data

%write for modesim

 

%8bit adc

lianghua_bit = 8;

data_max = max(data_in);

data_adc = fix(data_in/data_max*(2^(lianghua_bit-1)-1));

figure

pwelch(data_adc-mean(data_adc))

% length(data_adc)

%8bit有符号数转化为无符号数??为什么有符号数转化为无符号数后频谱变了??

for i = 1:length(data_adc)

    if(data_adc(i) <0)

        data(i) = data_adc(i)+2^lianghua_bit;

    else

        data(i) = data_adc(i);

    end

end

figure

pwelch(data-mean(data))

% max(data)

 

for i = 1:length(data)

    data1(i,1:8) = dec2bin(data(i),8);

end

save fir_data.mat data

for i =1:length(data1)  

    fprintf(fidout,'%c%c%c%c%c%c%c%c\n',data1(i,1),data1(i,2),data1(i,3),...

    data1(i,4),data1(i,5),data1(i,6),data1(i,7),data1(i,8));  

end

 

(2) matlab的fir滤波测试程序:

close all;clc;clear all;

load fir_data.mat data

figure

 pwelch(data)

order = 8;%滤波器的阶数

fir_para = [7 17 32 46 52 46 32 17 7];

%为模仿fpga仿真,前后都补order个0

data_new = [zeros(1,order) data zeros(1,order)];

len = length(data_new);

 

kk= 1;

for i = 1:len-8

   out(kk) = data_new(i:i+8) * (fir_para');

   kk = kk + 1;

end

figure

 pwelch(out)

aa= 1;

 

(3)读取modesim仿真fir数据放入matlab测试程序:

close all;clc;clear all;

load fir_data.mat data

figure

 pwelch(data)

 

 fid = fopen('out.txt','r');

mm = 1;

while ~feof(fid)

    data_modesim(mm) =str2num(fgets(fid));

    mm = mm +1;

end

figure

 pwelch(data_modesim)

 

FPGA代码:

(1)FIR_Lowpass_tb:

module FIR_Lowpass_tb();

parameter word_size_in = 8;

parameter word_size_out= 2*word_size_in + 1;

reg clock;

reg reset;

reg  [word_size_in-1:0] Data_in;

wire  [word_size_out -1:0] Data_out;

 

FIR_Lowpass FIR_Lowpass_d1(

      .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 [7:0] read_data [0:1008];

initial

begin

   $readmemb("data_out.txt",read_data);

end

 

integer i;

always @(posedge clock)

begin

   if(reset ==1)

      begin

        Data_in <= 8'd0;

        i <= 32'd0;

      end

   else

      begin

        i <= i + 1;

        Data_in <= read_data;

      end

end

//滤波后写数据

integer out;

initial

begin

   out = $fopen("out.txt");

end

 

always @(i)

begin

   $fwrite(out,"%d\n",Data_out);

   if(i == 32'd1008 )

      $stop;

end

endmodule

 

 

(2)FIR_Lowpass:

 

module FIR_Lowpass(

           Data_out,Data_in,clock,reset

           );

 

 

parameter order = 8;

parameter word_size_in = 8;

parameter word_size_out= 2*word_size_in + 1;

 

//滤波器系数

parameter b0 = 8'd7;

parameter b1 = 8'd17;

parameter b2 = 8'd32;

parameter b3 = 8'd46;

parameter b4 = 8'd52;

parameter b5 = 8'd46;

parameter b6 = 8'd32;

parameter b7 = 8'd17;

parameter b8 = 8'd7;

 

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[1:order];

integer k;

 

assign  Data_out = b0*Data_in + b1*Samples[1]+b2*Samples[2] + b3*Samples[3]+b4*Samples[4]+b5*Samples[5]

                                  + b6*Samples[6]+ b7*Samples[7]+b8*Samples[7];                              

//完成移位的功能

always @(posedge clock)

      if(reset ==1)

           begin

                 for(k=1;k<=order;k =k+1)

                      Samples[k] <=0;

           end

      else

           begin

                 Samples[1] <= Data_in;

                 for(k=2;k<=order;k=k+1)

                      Samples[k] <= Samples[k-1];

           end

endmodule

 
 
fir
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条