【DA算法】基于DA算法的FIR滤波器的FPGA实现
1.軟件版本
quartusii
2.本算法理論知識
? ? ? DA算法的主要特點是,巧妙地利用查找表將固定系數(shù)的MAC運算轉(zhuǎn)化為查表操作,其運算速度不隨系數(shù)和輸入數(shù)據(jù)位數(shù)的增加而降低,而且相對直接實現(xiàn)乘法器而言,在硬件規(guī)模上得到了極大的改善。對于FIR(有限長單位沖激響應(yīng))濾波器,其基本結(jié)構(gòu)是一個分節(jié)的延時線,每一節(jié)的輸出加權(quán)累加,得到濾波器的輸出。其輸出y就是輸入x和系數(shù)h的內(nèi)積:
? ? ??
?將式(3)中的第二部分展開,重新分別求和,這也是“分布式算法”名稱的由來,可以得到:
?這樣就可以將式(3)化簡為
?計算h[n]xb[n],就是用查找表實現(xiàn)一個映射,然后再將此映射經(jīng)過相應(yīng)的二次冪加權(quán),最后即可得到濾波器的輸出。
分布式FIR的實現(xiàn)結(jié)構(gòu)
??? 圖1給出了分布式FIR濾波器最直接的實現(xiàn)結(jié)構(gòu),虛線為流水線寄存器。對于小位寬的數(shù)據(jù)來講,Da算法不僅速度快,而且所占用的芯片資源也很少。
?
對于式(4)括號中的每一個乘積項都代表了輸入變量的某一位與常量的二進制“與”操作,加號代表了算術(shù)和操作,指數(shù)因子對括號中的值加權(quán)。如果事先構(gòu)造一個查找表,該表儲存了括號中所有可能的組合值,就可以通過所有輸入變量相對應(yīng)的組合向量(xb[N-1], xb[N-2], … ,xb[0])對該表進行尋址。該表結(jié)構(gòu)如表1所示。
表1 構(gòu)造規(guī)則
? ? ? ?在LUT實現(xiàn)分布式算法是,由于LUT的規(guī)模隨著N的增加而呈指數(shù)增加,如果濾波器系數(shù)N過多,則查表的規(guī)模十分龐大。為了減小規(guī)模,可以利用部分表計算。由于FIR濾波器是線性濾波器,因此低階濾波器輸出可以相加,由此定義一個高階濾波器的輸出。例如,可以把16輸入的查找表分割成4個并行的查找表,如圖2所示。依次類推,可以將更大的LUT分割成多個小LUT。如果加上流水線,這一結(jié)構(gòu)的改變并不會降低速度,卻可以大大減小設(shè)計規(guī)模。
?下面開始在FPGA中進行設(shè)計與實現(xiàn)。
??? 考慮到,基于DA算的程序,其查找表的復(fù)雜度會隨著輸入的位寬和濾波器的階數(shù)的增加而大大增加,這里,我們在滿足設(shè)計指標的前提下,將濾波器的輸入位寬改為12位,階數(shù)為16階。
3.核心代碼
module firfilter_da( CLK,Reset,DIN,Dout); //----------------------- // port declaration //-----------------------input CLK;input Reset;input [7:0] DIN;output [15:0] Dout;//輸入信號寄存器 reg [7:0] DIN_8b_0;reg [7:0] DIN_8b_1;reg [7:0] DIN_8b_2;reg [7:0] DIN_8b_3;reg [7:0] DIN_8b_4;reg [7:0] DIN_8b_5;reg [7:0] DIN_8b_6;reg [7:0] DIN_8b_7;reg [7:0] DIN_8b_8;reg [7:0] DIN_8b_9;reg [7:0] DIN_8b_10;reg [7:0] DIN_8b_11;reg [7:0] DIN_8b_12;reg [7:0] DIN_8b_13;reg [7:0] DIN_8b_14;//加法結(jié)果暫存器 reg [25:0] temp_1_1,temp_1_2,temp_1_3,temp_1_4;reg [25:0] temp_2_1,temp_2_2;reg [25:0] temp_3; assign Dout = temp_3[25:10]; //查找表函數(shù),將與A3,A2,A1,A0對應(yīng)相乘的各個位進行查找 function[15:0] look_A3_A0;input [3:0] DIN;begincase(DIN)4'b0000: look_A3_A0=16'h0;4'b0001: look_A3_A0=16'h0;4'b0010: look_A3_A0=16'h65;4'b0011: look_A3_A0=16'h65;4'b0100: look_A3_A0=16'h18f;4'b0101: look_A3_A0=16'h18f;4'b0110: look_A3_A0=16'h1f4;4'b0111: look_A3_A0=16'h1f4;4'b1000: look_A3_A0=16'h35a;4'b1001: look_A3_A0=16'h35a;4'b1010: look_A3_A0=16'h3bf;4'b1011: look_A3_A0=16'h3bf;4'b1100: look_A3_A0=16'h4e9;4'b1101: look_A3_A0=16'h4e9;4'b1110: look_A3_A0=16'h54e;4'b1111: look_A3_A0=16'h54e;endcaseendendfunction//查找表函數(shù),將與A7,A6,A5,A4對應(yīng)相乘的各個位進行查找function[15:0] look_A7_A4;input [3:0] DIN;begincase(DIN) 4'b0000: look_A7_A4=16'h0;4'b0001: look_A7_A4=16'h579;4'b0010: look_A7_A4=16'h78e;4'b0011: look_A7_A4=16'hd07;4'b0100: look_A7_A4=16'h935;4'b0101: look_A7_A4=16'heae;4'b0110: look_A7_A4=16'h10c3;4'b0111: look_A7_A4=16'h163c;4'b1000: look_A7_A4=16'h0a1f;4'b1001: look_A7_A4=16'h0f98;4'b1010: look_A7_A4=16'h11ad;4'b1011: look_A7_A4=16'h1726;4'b1100: look_A7_A4=16'h1354;4'b1101: look_A7_A4=16'h18cd;4'b1110: look_A7_A4=16'h1ae2;4'b1111: look_A7_A4=16'h205b;endcaseendendfunction //查找表查找結(jié)果寄存器 reg [16:0] lookup0_1,lookup0_2,lookup0_3,lookup0_4,lookup1_1,lookup1_2,lookup1_3,lookup1_4,lookup2_1,lookup2_2,lookup2_3,lookup2_4,lookup3_1,lookup3_2,lookup3_3,lookup3_4,lookup4_1,lookup4_2,lookup4_3,lookup4_4,lookup5_1,lookup5_2,lookup5_3,lookup5_4,lookup6_1,lookup6_2,lookup6_3,lookup6_4,lookup7_1,lookup7_2,lookup7_3,lookup7_4;reg [17:0] sum0_1,sum0_2,sum1_1,sum1_2,sum2_1,sum2_2,sum3_1,sum3_2,sum4_1,sum4_2,sum5_1,sum5_2,sum6_1,sum6_2,sum7_1,sum7_2;reg [18:0] sum0,sum1,sum2,sum3,sum4,sum5,sum6,sum7;reg [3:0] count_4b;// 輸入信號的初始化 always @(posedge CLK or posedge Reset) beginif(Reset)begincount_4b<=0;DIN_8b_0<=0;DIN_8b_1<=0;DIN_8b_2<=0;DIN_8b_3<=0;DIN_8b_4<=0;DIN_8b_5<=0;DIN_8b_6<=0;DIN_8b_7<=0;DIN_8b_8<=0;DIN_8b_9<=0;DIN_8b_10<=0;DIN_8b_11<=0;DIN_8b_12<=0;DIN_8b_13<=0;DIN_8b_14<=0;endelsebeginif(count_4b==15)beginDIN_8b_0<=DIN_8b_1;DIN_8b_1<=DIN_8b_2;DIN_8b_2<=DIN_8b_3;DIN_8b_3<=DIN_8b_4;DIN_8b_4<=DIN_8b_5;DIN_8b_5<=DIN_8b_6;DIN_8b_6<=DIN_8b_7;DIN_8b_7<=DIN_8b_8;DIN_8b_8<=DIN_8b_9;DIN_8b_9<=DIN_8b_10;DIN_8b_10<=DIN_8b_11;DIN_8b_11<=DIN_8b_12;DIN_8b_12<=DIN_8b_13;DIN_8b_13<=DIN_8b_14;DIN_8b_14<=DIN;endelse begincase(count_4b)'d0: DIN_8b_0=DIN;'d1: DIN_8b_1=DIN;'d2: DIN_8b_2=DIN;'d3: DIN_8b_3=DIN; 'd4: DIN_8b_4=DIN;'d5: DIN_8b_5=DIN;'d6: DIN_8b_6=DIN;'d7: DIN_8b_7=DIN;'d8: DIN_8b_8=DIN;'d9: DIN_8b_9=DIN;'d10: DIN_8b_10=DIN;'d11: DIN_8b_11=DIN;'d12: DIN_8b_12=DIN;'d13: DIN_8b_13=DIN;'d14: DIN_8b_14=DIN;default:;endcasecount_4b=count_4b+1; endend end//利用查找表對輸入的信號進行結(jié)果的查找,等到七個結(jié)果 always @(posedge CLK or posedge Reset) beginif(Reset)begin//0lookup0_1 <= 0;lookup0_2 <= 0;lookup0_3 <= 0;lookup0_4 <= 0;sum0_1 <= 0;sum0_2 <= 0;sum0 <= 0;//1lookup1_1 <= 0;lookup1_2 <= 0;lookup1_3 <= 0;lookup1_4 <= 0;sum1_1 <= 0;sum1_2 <= 0;sum1 <= 0;//2lookup2_1 <= 0;lookup2_2 <= 0;lookup2_3 <= 0;lookup2_4 <= 0;sum2_1 <= 0;sum2_2 <= 0;sum2 <= 0;//3lookup3_1 <= 0;lookup3_2 <= 0;lookup3_3 <= 0;lookup3_4 <= 0;sum3_1 <= 0;sum3_2 <= 0;sum3 <= 0;//4lookup4_1 <= 0;lookup4_2 <= 0;lookup4_3 <= 0;lookup4_4 <= 0;sum4_1 <= 0;sum4_2 <= 0;sum4 <= 0;//5lookup5_1 <= 0;lookup5_2 <= 0;lookup5_3 <= 0;lookup5_4 <= 0;sum5_1 <= 0;sum5_2 <= 0;sum5 <= 0;//6lookup6_1 <= 0;lookup6_2 <= 0;lookup6_3 <= 0;lookup6_4 <= 0;sum6_1 <= 0;sum6_2 <= 0;sum6 <= 0;//7lookup7_1 <= 0;lookup7_2 <= 0;lookup7_3 <= 0;lookup7_4 <= 0;sum7_1 <= 0;sum7_2 <= 0;sum7 <= 0;endelseif(count_4b==15)begin//0lookup0_1 <= look_A3_A0({DIN_8b_12[0],DIN_8b_13[0],DIN_8b_14[0],DIN[0]});lookup0_2 <= look_A7_A4({DIN_8b_8[0],DIN_8b_9[0],DIN_8b_10[0],DIN_8b_11[0]});lookup0_3 <= look_A7_A4({DIN_8b_7[0],DIN_8b_6[0],DIN_8b_5[0],DIN_8b_4[0]});lookup0_4 <= look_A3_A0({DIN_8b_3[0],DIN_8b_2[0],DIN_8b_1[0],DIN_8b_0[0]});sum0_1 <= lookup0_1 + lookup0_2;sum0_2 <= lookup0_3 + lookup0_4;sum0 <= sum0_1 + sum0_2;//1lookup1_1 <= look_A3_A0({DIN_8b_12[1],DIN_8b_13[1],DIN_8b_14[1],DIN[1]});lookup1_2 <= look_A7_A4({DIN_8b_8[1],DIN_8b_9[1],DIN_8b_10[1],DIN_8b_11[1]});lookup1_3 <= look_A7_A4({DIN_8b_7[1],DIN_8b_6[1],DIN_8b_5[1],DIN_8b_4[1]});lookup1_4 <= look_A3_A0({DIN_8b_3[1],DIN_8b_2[1],DIN_8b_1[1],DIN_8b_0[1]});sum1_1 <= lookup1_1 + lookup1_2;sum1_2 <= lookup1_3 + lookup1_4;sum1 <= sum1_1 + sum1_2;//2lookup2_1 <= look_A3_A0({DIN_8b_12[2],DIN_8b_13[2],DIN_8b_14[2],DIN[2]});lookup2_2 <= look_A7_A4({DIN_8b_8[2],DIN_8b_9[2],DIN_8b_10[2],DIN_8b_11[2]});lookup2_3 <= look_A7_A4({DIN_8b_7[2],DIN_8b_6[2],DIN_8b_5[2],DIN_8b_4[2]});lookup2_4 <= look_A3_A0({DIN_8b_3[2],DIN_8b_2[2],DIN_8b_1[2],DIN_8b_0[2]});sum2_1 <= lookup2_1 + lookup2_2;sum2_2 <= lookup2_3 + lookup2_4;sum2 <= sum2_1 + sum2_2;//3lookup3_1 <= look_A3_A0({DIN_8b_12[3],DIN_8b_13[3],DIN_8b_14[3],DIN[3]});lookup3_2 <= look_A7_A4({DIN_8b_8[3],DIN_8b_9[3],DIN_8b_10[3],DIN_8b_11[3]});lookup3_3 <= look_A7_A4({DIN_8b_7[3],DIN_8b_6[3],DIN_8b_5[3],DIN_8b_4[3]});lookup3_4 <= look_A3_A0({DIN_8b_3[3],DIN_8b_2[3],DIN_8b_1[3],DIN_8b_0[3]});sum3_1 <= lookup3_1 + lookup3_2;sum3_2 <= lookup3_3 + lookup3_4;sum3 <= sum3_1 + sum3_2;//4lookup4_1 <= look_A3_A0({DIN_8b_12[4],DIN_8b_13[4],DIN_8b_14[4],DIN[4]});lookup4_2 <= look_A7_A4({DIN_8b_8[4],DIN_8b_9[4],DIN_8b_10[4],DIN_8b_11[4]});lookup4_3 <= look_A7_A4({DIN_8b_7[4],DIN_8b_6[4],DIN_8b_5[4],DIN_8b_4[4]});lookup4_4 <= look_A3_A0({DIN_8b_3[4],DIN_8b_2[4],DIN_8b_1[4],DIN_8b_0[4]});sum4_1 <= lookup4_1 + lookup4_2;sum4_2 <= lookup4_3 + lookup4_4;sum4 <= sum4_1 + sum4_2;//5lookup5_1 <= look_A3_A0({DIN_8b_12[5],DIN_8b_13[5],DIN_8b_14[5],DIN[5]});lookup5_2 <= look_A7_A4({DIN_8b_8[5],DIN_8b_9[5],DIN_8b_10[5],DIN_8b_11[5]});lookup5_3 <= look_A7_A4({DIN_8b_7[5],DIN_8b_6[5],DIN_8b_5[5],DIN_8b_4[5]});lookup5_4 <= look_A3_A0({DIN_8b_3[5],DIN_8b_2[5],DIN_8b_1[5],DIN_8b_0[5]});sum5_1 <= lookup5_1 + lookup5_2;sum5_2 <= lookup5_3 + lookup5_4;sum5 <= sum5_1 + sum5_2;//6lookup6_1 <= look_A3_A0({DIN_8b_12[6],DIN_8b_13[6],DIN_8b_14[6],DIN[6]});lookup6_2 <= look_A7_A4({DIN_8b_8[6],DIN_8b_9[6],DIN_8b_10[6],DIN_8b_11[6]});lookup6_3 <= look_A7_A4({DIN_8b_7[6],DIN_8b_6[6],DIN_8b_5[6],DIN_8b_4[6]});lookup6_4 <= look_A3_A0({DIN_8b_3[6],DIN_8b_2[6],DIN_8b_1[6],DIN_8b_0[6]});sum6_1 <= lookup6_1 + lookup6_2;sum6_2 <= lookup6_3 + lookup6_4;sum6 <= sum6_1 + sum6_2;//7lookup7_1 <= look_A3_A0({DIN_8b_12[7],DIN_8b_13[7],DIN_8b_14[7],DIN[7]});lookup7_2 <= look_A7_A4({DIN_8b_8[7],DIN_8b_9[7],DIN_8b_10[7],DIN_8b_11[7]});lookup7_3 <= look_A7_A4({DIN_8b_7[7],DIN_8b_6[7],DIN_8b_5[7],DIN_8b_4[7]});lookup7_4 <= look_A3_A0({DIN_8b_3[7],DIN_8b_2[7],DIN_8b_1[7],DIN_8b_0[7]});sum7_1 <= lookup7_1 + lookup7_2;sum7_2 <= lookup7_3 + lookup7_4;sum7 <= sum7_1 + sum7_2;endelse; end//對得到的七個結(jié)果進行移位和相加 always @(posedge CLK or posedge Reset) beginif (Reset)begintemp_1_1 <= 0;temp_1_2 <= 0;temp_1_3 <= 0;temp_1_4 <= 0;temp_2_1 <= 0;temp_2_2 <= 0;temp_3 <= 0;end elseif(count_4b==15)begintemp_1_1 <= {{7{sum0[18]}},sum0} + {{6{sum1[18]}},sum1,1'b0};temp_1_2 <= {{5{sum2[18]}},sum2,2'b0} + {{4{sum3[18]}},sum3,3'b0};temp_1_3 <= {{3{sum4[18]}},sum4,4'b0} + {{2{sum5[18]}},sum5,5'b0};temp_1_4 <= {sum6[18],sum6,6'b0}- {sum7,7'b0}; temp_2_1 <= temp_1_1 + temp_1_2;temp_2_2 <= temp_1_3 + temp_1_4;temp_3 <= temp_2_1 + temp_2_2 ;end else; end endmodule?4.操作步驟與仿真結(jié)論
濾波器系數(shù)結(jié)果如下所示:
綜合結(jié)果如下所示:
其仿真結(jié)果如下所示:
5.參考文獻
[1]朱濤玉,余志勇. 高效實現(xiàn)FPGA數(shù)字下變頻的多類濾波器分組級聯(lián)技術(shù)[J]. 現(xiàn)代電子技術(shù), 2008, 31(23):4.
A01-115
6.完整源碼獲得方式
方式1:微信或者QQ聯(lián)系博主
方式2:訂閱MATLAB/FPGA教程,免費獲得教程案例以及任意2份完整源碼
總結(jié)
以上是生活随笔為你收集整理的【DA算法】基于DA算法的FIR滤波器的FPGA实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【GPS信号】GPS信号的读取以及kal
- 下一篇: 【MATLAB教程案例2】GPS信号捕获