Multi_phase_filter

通过将近一周的时间,初步掌握了利用FPGA完成一个简单项目的开发流程,具体包括算法的设计,程序的编写,程序的仿真,结果对比。


目标是利用FPGA生成一个多向滤波器,实现降采样的过程。首先利用MATLAB生成ISE FIR compiler 所需的滤波器的参数。下面是代码。这段代码是根据《利用赛灵思FGPA 实现降采样FIR 滤波器》这篇文章参考而写。然后通过MATLAB生成的.COE的文件以后就可以利用ISE IP核来生成所需的滤波器,方法也是参考上篇文章。

clc;
close all;
clear;
%% 设计一个2倍抽取的降采样滤波器
Fs_in=400e6;%原始信号采样率400m
Fs_out=200e6;%降采样之后成为200m采样率
M=Fs_in/Fs_out%抽取倍数
%低通FIR滤波器设计
Fp = 0.4*Fs_out%通带截至频率
Fst = 0.5*Fs_out%阻带截至频率
Ap = 0.1;%通带衰减幅度(dB)
Ast = 100;%阻带衰减频率(dB)
%调用FDA toolj进行滤波器设计
h1=fdesign.decimator(M,'Lowpass','Fp,Fst,Ap,Ast',Fp,Fst,Ap,Ast,Fs_in);
Href = design(h1);
info(Href)%显示滤波器信息
fvtool(Href);
title('Lowpass single stage filter');
legend('Lowpass single stage filter');
axis([0 200 -120 5])
%生成COE文件
ref_filter = Href.Numerator;
% gen_coe_rad10(Href.Numerator,'Low_pass_down_2.coe');
%% 设计多相滤波器
ph1=ref_filter(1:M:end);
ph2=ref_filter(2:M:end);
%生成COE文件
gen_coe_rad10(ph1,'Low_pass_down_first.coe');
gen_coe_rad10(ph2,'Low_pass_down_second.coe');

配置好IP CORE以后就是调用问题,参考的《基于IPCore的FIR数字滤波器的FPGA实现_许金生》来调用信号。具体内容如下:

各管脚功能如下:
DIN(15:0): 数据输入管脚, 在 ND 有效 (高电平)时, 滤波器从 DIN端口读入数据。
CLK: 时钟信号输入管脚。
ND: 输入数据有效信号输入管脚, 高电平有效。
RST: 复位信号输入管脚, 高电平有效。
DOUT(32:0): 数据输出管脚, 在 RDY 信号有效时, 输出滤波后的数值。文中设计的 FIR 滤波器的各抽头系数在 (- 1, 1) 区间, 且和为 1, 量化时, 采用 Q15 (15 位小数位) 的方式, 去除低位小数位和高位多余的符号位, 将 DOUT(32:0)中的(30:15)作为有效数据输出信号。
RDY: 输出数据有效信号输出管脚, 高电平表示 DOUT端口输出数据有效。
RFD: 新数据输入允许信号输出管脚,高电平表示可以输入新数据, 当且仅当 RESET信号为高时, RFD才为低电平。


在完成滤波器的设计以后需要进行ISE和MATLAB的联合仿真,需要的操作是:

1.ISE读取相关数据从txt中(注意:路径中“/“的使用)

reg [15:0] sin_input[0:2047];

initial begin// 读出MATLAB产生的波形数据信号
        $readmemh("E:/matlab_wave_data.txt", sin_input); //将 matlab_wave_data.txt中的数据读入x_in    
    end

2.ISE写出相关数据到txt中

integer write_out_file;//定义一个文件指针
initial write_out_file = $fopen("E:/PROGECT/FIR/LPF_DESIGN/write_out_file.txt");   
    always @ (posedge rdy1) begin
        if(data_out1 != 1'b0) begin
            $fdisplay(write_out_file,"%h", data_out1);// 33bitif(j == 11'd2048)begin    //共写入2048个数据
            $stop;
            end
        end
    end

3.MATLAB写入数据到txt中(在此过程中需要把数据转换成补码进行计算)

 fid = fopen('E:\PROGECT\FIR\LPF_DESIGN\matlab_wave_data.txt', 'wt');
 fprintf(fid, '%x\n', x); % 在写文件时量化为16bit的定点实数
 fclose(fid);
 for k=1:1:2048   % 转化为补码总共的次数
         if(x(k)>=0)
             x(k)=x(k);
         else
             x(k)=65536+x(k);  %需要加上2的16次方,因为数据是16bit
         end
 end

4.MATLAB读取数据从txt中

fid = fopen('E:\matlab_wave_data.txt','r');
for i = 1 : 2048;%一共有2048个数据
num(i) = fscanf(fid, '%x', 1);%从fid所指的文件中,以16进制的方式读出一个数据
end
fclose(fid);

然后剩余ISE中的程序我是从《MATLAB设计FPGA实现联合ISE和Modelsim仿真的FIR滤波器设计》中参考而写成的。


在我写代码的这段时时间,师兄进行了好几次耐心的指导:

FPGA(ISE+MODELSIM):
1.定点数和浮点数、round(四舍五入去整)
2.波形与matlab对比:频域和时域、modelsim不好画图的话需要生成波形数据然后导入到matlab中通过仿真对比

MATLAB:
1.生成的图形怎么看、频点
2.生成数据需要转化、转成补码、
3.参考滤波器(信号没有经过分离直接滤波)和多向滤波器(信号经过处理以后滤波)是做对比作用,图形一致说明设计的多向滤波器的方法正确
4.仿真文件和源文件的变量在modelsim下看是不相同的。
5.输入数据和输出数据产生的时钟速率可以不相同的,可以多设置几个时钟来满足需求。

补充:
FPGA:
1.在给变量赋值的时候注意标明位宽和进制
2.在使用$readmemh来进行给memory赋值的时候:(1)应该使数据的类型和大小一致 (2)文件的路径应当使用“/”来表示,否则会读不进去数据

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页