发帖 回复
返回列表  提醒:不能用迅雷等P2P下载,否则下载失败标(二级)的板块,需二级才能下载,没二级不要购买,下载不了
  • 43阅读
  • 4回复

[资料贡献]利用FPGA的IP核实现FIR滤波器 [复制链接]

上一主题 下一主题
 

性别:
人妖
发帖
242
金币
0
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看楼主 倒序阅读 使用道具 0楼 发表于: 08-01
一、首先是设计指标: FTVV+9.l:  
采用最优化设计方法(firpm),设计一个阶数为16阶(长度为17)的线性相位低通FIR滤波器,截止频率为500hz,fs=2000hz。,系数量化位数为12bit,输入数据位宽为12bit,输出数据位宽为25Bit,系统时钟为2khz。 Ol%KXq[  
/2%646  
二、设计流程: w"A.*8Iu  
(1)利用MATLAB设计滤波器系数,浮点数类型。 ~AqFLv/%  
(2)Matlab测试滤波器性能,输入观察输出。 i?{cB!7  
(3)利用FPGA的FIR滤波器IP核设计滤波器。 z( 00"ei  
(4)编写testbench,测试滤波器性能。输入Matlab产生的激励文本文件, F(!9;O5J]  
             输出硬件处理后的信号,写入文本文件中。 /0.m|Th'm  
(5)Matlab分析硬件处理后保存在文本文件中的信号。 n(#|  
三、设计步骤: 3FD6.X>x  
1,利用MATLAB设计滤波器系数。代码如下: r |H 1Yy  
function hn=Fir_Coefficient_Design ]~YY#I":  
N=17;      %滤波器长度 ?@*hU2MTC  
Sample_Freq=2000;   %采样频率 yYdow.b!  
fc=500;    %低通滤波器的通带截止频率 e7n[NVrX  
B=12;      %量化位数 8@$`'h^6  
Cut_Off_Freq=[0 500 700 Sample_Freq/2]; z CS.P.$  
Cut_Off_Freq=Cut_Off_Freq./(Sample_Freq/2); %归一化 #N?VbDK9_  
Fir_Amplitude=[1 1 0 0]; | e? :Uq  
Fir_Coefficient=firpm(N-1,Cut_Off_Freq,Fir_Amplitude); ,Y) 7M3I  
hn=Fir_Coefficient; 3PLYC}Jq  
freqz(Fir_Coefficient,1,1024,Sample_Freq); >cTSX  
>/BMA;`  
注意MATLAB中频率归一化是针对fs/2,即采样率的一半。 0~/'c0Ho  
n+'gVEBA  
接下来将滤波器系数写入文本文件中, tL>c@w#Pv  
fid=fopen('Fir_Coefficient.txt','w'); 3qlY=5Y  
for k=1:length(Fir_Coefficient)     IonphTcU!  
      fprintf(fid,'%.14f',Fir_Coefficient(k)); Z,jR:_ p  
      if(k~=length(Fir_Coefficient) )           X[e:fW[e)  
       fprintf(fid,'\r\n'); fTq/9=Rq4  
      end )z" .lw  
end rf ?\s/#OY  
fclose(fid); ZC99/NWN  
由于采用FIR Complier13.0,其中的用户手册有这么一句: {^z>uRZ3  
H Q_IQ+  
;4:[kv@  
v@&UTU  
需要注意的就是最后一个系数后面不能有回车,否则导入系数文件的时候又会被FIR Complier识别为一个新的系数。这样,系数就被写进了文本文件Fir_Coefficient.txt QC,LHt?6  
(2)Matlab测试滤波器性能,输入观察输出。 GJ9'i-\*\  
    思路就是生成两个信号,一个在通带内,一个在阻带内,然后调用filter函数进行滤波处理,观察输出信号的频谱。代码如下:     dvW2X  
f1=200;       %信号1频率为200Hz ^uV=|1<%  
f2=800;       %信号2频率为800Hz }wIF$v?M  
Fs=2000;      %采样频率为2KHz ^oLMgz  
N=12;         %量化位数 "hbCP4  
t=0:1/Fs:1; X21k7 Ls  
c1=2*pi*f1*t; p.ks jD  
c2=2*pi*f2*t; S/2lK*F  
s1=sin(c1);%产生正弦波 ~WW!P_wI,  
s2=sin(c2);%产生正弦波 A)5;ae  
s=s1+s2;   %产生两个单载波合成后的信号 83i;:cn  
s=s/max(abs(s));%归一化处理 ]4X08Cm^  
Q_s=round(s*(2^(N-1)-1));%12比特量化 @'> Ul!.]  
%调用自已设计的滤波器函数对信号进行滤波 aA6m5  
hn=Fir_Coefficient_Design; >53Hqzm&  
Filter_s=filter(hn,1,Q_s); "n, %Hh  
然后观察输入输出频谱:可以看到800hz处的信号被衰减在-40db一下,符 JeXA*U#  
合要求。 .',d*H))E7  
r+W;}nyf  
EJid@  
接下来将测试信号以二进制数据格式写入Excitation_Signal_Bin.txt文件中,供给第四步仿真FPGA时testbench调用。 !^x;4@Ejm  
    fid=fopen('Excitation_Signal_Bin.txt','w'); cHAq[Ebp2!  
for i=1:length(Q_s) ]=%oBxWAP  
   B_s=dec2bin(Q_s(i)+(Q_s(i)<0)*2^N,N) :#zVF[Y(2  
   for j=1:N ]}Jb'(gMO4  
      if B_s(j)=='1' \gW6E^  
          tb=1; O4g2s8k  
      else )4;$;a1  
          tb=0; $fhR1A  
      end u$Wv*;TT%  
      fprintf(fid,'%d',tb);   dsG:DS`q  
   end Ywo=w:'  
   fprintf(fid,'\r\n'); !CUy{nV  
end }? :T*CJ  
fprintf(fid,';'); X EL~y  
fclose(fid); .P(A x:g  
tE$oV  
(3)利用FPGA的FIR滤波器IP核设计滤波器。 *JA0Vs 5  
G@4n]c_  
    这个Altera提供的FIR Compiler v13.0有些老了,现在有FIR Compiler II v13.0,也就是2.0版本的FIR的IP核。这里还是用FIR Compiler v13.0吧,2.0版本日后再研究研究。 L$3{L"/   
    打开MegaWizard Plug-In Manager,选择FIR Compiler v13.0,特别需要注意的是文件保存位置!只能保存在当前的工程目录下,不能放在别的文件夹里面!如果不放在工程目录下,后一步的modeisim仿真就会出错! jV.9d@EC  
]^6r7nfR6|  
     ai]KH7  
接下来就是参数设置,单击上方的"Edit Coefficient",跳出"Coefficient Generator Dialog"对话框,选择下方的"Imported Coefficient Set",导入之前设计的滤波器系数"Fir_Coefficient.txt"。 iI$;%uY3g  
    输入输出声明如下,输入一路,有符号二进制数,输入位宽12bit,输出选择基于"实际的系数","全精度"。输出位宽这里计算出是25bit。 _x]q`[Dih  
     [2.;gZj  
系数量化单位选择12bit,滤波器结构选择"分布式算法,全并行结构",流水级数选择1,数据和滤波器系数的存储都选择"Logic Cells"。这里 有什么不懂的,就要多看用户手册,写的比较清楚。 p_EWpSOt7  
m0,TH[HWGF  
     x4CSUcKb  
EG J/r  
接下来选择step 2,生成仿真文件,选择"Verilog HDL",还可以生成.m文件供MATLAB进行仿真分析,最后,Step3: Generate,这样整个滤波器便设计完成了。 9zNMv-  
接下来编写.v文件例化,即可。其输入输出信号参见IP核用户手册即可。这里给出代码参考: YfUo=ku  
    module Fir_FPGA ( ``,q[|  
    reset_n,clk,Xin, _X~xfmU  
    Yout);     c{{RP6o/j=  
    input        reset_n;   //复位信号,低电平有效 fD#!0^  
    input        clk;       //FPGA系统时钟/数据速率:2kHz \y0]BH  
    input     signed [11:0]    Xin;  //数据输入频率为2kHZ o9+fA H`D  
    output signed [24:0]    Yout; //滤波后的输出数据 'p&q}IO  
    wire ast_sink_valid,ast_source_ready,ast_source_valid; Is(ZVI  
    wire [1:0] ast_source_error; 4Jk[X>I~  
    wire [1:0] ast_sink_error; V`_)H  
    assign ast_sink_valid=1'b1; l}XnCOIT,  
    assign ast_source_ready=1'b1; eEX*\1Gg  
    assign ast_sink_error=2'd0; IQyw>_~]  
    fir    u_fir( Id?2(Tg  
        .clk(clk), 1$nuh@-ys  
        .reset_n(reset_n), i{}Q5iy  
        .ast_sink_data(Xin), |5(un/-C  
        .ast_sink_valid(ast_sink_valid), O6b.oS '-  
        .ast_source_ready(ast_source_ready), UW],9r/PD@  
        .ast_sink_error(ast_sink_error), 8S@"6TG`  
        .ast_source_data(Yout), bI:cYn1  
        .ast_sink_ready(ast_sink_ready), Og:aflS  
        .ast_source_valid(ast_source_valid), . sv uXB  
        .ast_source_error(ast_source_error)); (BZd%!  
(4)编写testbench,测试滤波器性能。     XSktb k  
主要就是将第二步MATLAB生成的激励信号输入module,然后将输出写入文本文件,供下一步MATLAB进行分析。 |D~#9  
    这里采用Quartus II 软件的"processing->start->start Test Bench Template Writer"选项自动生成模块测试文件(Fir_FPGA.vt),该目录自动存储在"工程目录\simulation\modelsim"下,然后打开文件,编写文件即可。主要是时钟,复位信号,按照时钟节拍输入和输出数据。这里给出输入和输出: psAr>:\3  
    //从外部TX文件(SinIn.txt)读入数据作为测试激励 '&F Pk T:5  
integer Pattern; ?1]h5Uh[b  
reg [11:0] stimulus[1:data_num]; tWI %P&b  
initial +|.6xC7U  
begin g]PC6xr38  
  //文件必须放置在"工程目录\simulation\modelsim"路径下     nzl3<Ar  
    $readmemb("Excitation_Signal_Bin.txt",stimulus); zxy/V^mu  
    Pattern=0; Ht7v+lY90^  
    repeat(data_num) L r9z~T:ED  
        begin Ta)6ly7'  
            Pattern=Pattern+1; gjPbhY=C[  
            Xin=stimulus[Pattern]; RO.bh#A$  
            #clk_period;//采用并行结构,数据周期等于时钟周期 10ZL-7D#m  
        end AfJ.SNE  
end ;s w3MRJ  
F=V_ACU  
//将仿真数据dout写入外部TXT文件中(Response_Signal.txt)  m8z414o  
integer file_out; [OwrIL  
initial  4FcY NJq  
begin W-ol*S  
  //文件放置在"工程目录\simulation\modelsim"路径下                                                   V w5@)l*f  
    file_out = $fopen("Response_Signal.txt"); M%N_4j.  
    if(!file_out) r&O:Bt}x  
        begin H  2UR  
            $display("could not open file!"); 1l+j^Dt'[  
            $finish; kg()C%#u  
        end "xE;IpO[  
end G-G\l?R(  
wire rst_write; J85Kgd1 \a  
wire signed [24:0] dout_s; Vf` 9[*j  
assign dout_s = Yout;                   //将dout转换成有符号数据 (!dwUB  
assign rst_write = clk& (reset_n);//产生写入时钟信号,复位状态时不写入数据 rtk1 8U-  
always @(posedge rst_write ) o;J_"' kP  
    $fdisplay(file_out,"%d",dout_s); r]O8|#P,Z$  
    然后在quartus ii中设置"Assignment->Settings"选择"EDA Tool Setting",设 J7$JW3O  
置如下:主要就是选择modelsim。 XV0t 8#T2  
'sN (=CQ  
R\>=}7  
    再选择下边的"Simulation",设置仿真工具名称(Modelsin-Altera),下面的NativeLink setting,选中第二项"Compile test bench",选择上面编辑的Fir_FPGA.vt,设置好名称之类的选项后,选择quartus ii 中的"Tool->Run simulation tool->RT Simulation",就可以启动Modelsim进行仿真。仿真完成后,处理后数据自动保存在Response_Signal.txt中。 Jk=d5B  
Fhbp,CX4p  
(5)Matlab分析硬件处理后保存在文本文件中的信号。 ?KXgG'!!  
/r mm@  
    最后,用MATLAB分析Response_Signal.txt中的数据,主要就是输入输出的频谱情况。分析结果如下:     YhJ*(oWL  
o3xfif  
可以看到,800hz处信号被衰减,达到预期效果。 QTuj v<|  
四、总结 ^*+-0b;[G  
(1)Fir滤波器阶数=抽头数目减去1。 6ZwFU5)QE/  
(2)firpm函数使用偶数阶系数,偶对称,总是在奈奎斯特频率处不为0。 4P$#m<;t  
(3).m文件返回值,可以在函数中指出。例如 *Q:EICDE7  
function hn=Fir_Coefficient_Design O{44GB3  
代码…… 2ZZF hj  
Fir_Coefficient=firpm(N-1,Cut_Off_Freq,Fir_Amplitude); CsW*E,|xyP  
hn=Fir_Coefficient; o_DZ  


评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

一般

差劲
离线yangxf0120

性别:
帅哥
发帖
4218
金币
2834
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 1楼 发表于: 08-01
谢谢分享利用FPGA的IP核实现FIR滤波器


离线hbjsss

性别:
人妖
发帖
1632
金币
1258
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 2楼 发表于: 08-01


离线zzl123

性别:
人妖
发帖
241
金币
830
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 3楼 发表于: 08-02
FPGA不好学啊


离线mj8abcd

性别:
帅哥
发帖
5844
金币
1360
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 4楼 发表于: 08-02
  


快速回复
限150 字节
 
上一个 下一个