本测试主要是为了测试fir滤波器在matlab和modesim中有什么不同。。
用的fir滤波器都是8阶直接,而且信号处理过程也是一模一样。
第一步:以matlab为原型,现在matla中产生双单点频信号然后用matlab中的自己写的滤波器看滤波效果如何
第二步:以matlab为原型,在quartus中写相同处理过程的fir滤波器,,然后导入matlab输出的源数据,通过fir后导出数据,将fpga滤波后的数据交由matlab处理,画出频谱图对比第一步中的matlab处理后的滤波数据,看效果如何
原始数据频谱图:
Matlab的fir滤波后频谱图:
Fpga的fir滤波器频谱图:
分析问题疑问:
1,下面matlab代码中为什么有符号数转化为无符号数频谱就变了,还没想通??
2、为什么fpga中fir和matlab中fir都是针对定点数滤波,效果却不同。。。。
这个作为一个bug改天修改,今天太晚l。。应当是一个地方数据没衔接起来。。
源代码如下:
Matlab:
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
文章评论(0条评论)
登录后参与讨论