MATLAB代做|FPGA代做|simulink代做——分布式算法FIR滤波器 
            发布时间:2021/6/4  浏览数:1689 
           目前FIR滤波器的实现方法有三种:利用单片通用数字滤波器集成电路、DSP器件和可编程逻辑器件实现。单片通用数字滤波器使用方便,但由于字长和阶数的规格较少,不能完全满足实际需要。使用DSP器件实现虽然简单,但由于程序顺序执行,执行速度必然不快。FPGA有着规整的内部逻辑阵列和丰富的连线资源,特别适合于数字信号处理任务,相对于串行运算为主导的通用DSP芯片来说,其并行性和可扩展性更好。但长期以来,FPGA一直被用于系统逻辑或时序控制上,很少有信号处理方面的应用,其原因主要是因为在FPGA中缺乏实现乘法运算的有效结构。现在这个问题得到了解决,使FPGA在数字信号处理方面有了长足的发展。
分布式算法(Distributed Arithmetic,DA)是一种已实现乘加运算为目的的运算方法。它与传统实现乘加运算算法的不同之处在于:执行部分积运算的先后顺序不同。简单地说,分布式算法在完成乘加功能时是通过将各输入数据每一对应位产生的部分积预先进行相加形成相应部分积,然后再对各部分积进行累加形成最终结果;而传统算法是等到所有乘积产生之后再进行相加来完成乘加运算的。与传统算法相比,分布式算法可极大地减少硬件电路规模,很容易实现流水线处理,提高电路的执行速度。
在实际中,不仅是对于滤波器方面,在卷积、相关、DFT等有乘累加运算的地方,都可以使用这种方法实现。DA设计的先决条件是滤波器的系数h[i]可以通过运算得到,那么在技术部分乘积项h[i]*x[n-1]就变成了一个常数乘法(也就是缩放)。DA算法的主要特点是,巧妙地利用查找表将固定系数的MAC运算转化为查表操作,其运算速度不随系数和输入数据位数的增加而降低,而且相对直接实现乘法器而言,在硬件规模上得到了极大的改善。
————————————————
module fir1(clk,reset,fir_in,fir_in_reg,fir_out,divfre_count_4b,divfre13_clk);
 
parameter S0=1'd0;      //初始状态
parameter S1=1'd1;      //处理状态
 
input clk;
input reset;
input[11:0]fir_in;
 
output[12:0]fir_out;
output[11:0]fir_in_reg;
output[3:0]divfre_count_4b;
output divfre13_clk;
 
reg[12:0]fir_out;
 
reg[11:0]fir_in_reg;
reg[12:0]shift_buf[7:0];
reg[12:0]add_buf[3:0];
 
//reg[12:0]state_shift_buf[4-1:0]; 
reg[12:0]state_shift_buf0;
reg[12:0]state_shift_buf1;
reg[12:0]state_shift_buf2;
reg[12:0]state_shift_buf3;
 
wire[3:0]table_4b;
 
wire[11:0]table_out_12b;
 
reg[12:0]sum;
reg STATE;
 
reg[3:0]divfre_count_4b;
reg divfre13_clk;
 
integer i,j,k,l,m,n,p;
 
 
always@(posedge clk or negedge reset)
begin
  if(!reset)
    begin
      divfre13_clk<=1'b0;
      divfre_count_4b<=4'b0000;          //14分频
    end
  else
    begin
      if(divfre_count_4b==13)
         begin
            divfre_count_4b<=4'b0000;
            divfre13_clk<=1'b1;
         end
      else
         begin
            divfre_count_4b<=divfre_count_4b+1'b1;   //计数
            divfre13_clk<=1'b0;                 
         end
     end
end
 
always @(posedge clk or negedge reset)     //数据输入
begin
    if(!reset)
       fir_in_reg<=12'b0000_0000_0000;
    else
       if(divfre13_clk)
          fir_in_reg<=fir_in;
end
 
 
always @(posedge clk or negedge reset)
begin
    if(!reset)
        for(i=0;i<=7;i=i+1)
            shift_buf[i]<=13'b0000_0000_00000;
    else if(divfre13_clk)
       begin
                     for(j=0;j<8-1;j=j+1)
                            shift_buf[j+1]<= shift_buf[j];
                            shift_buf[0]<={fir_in_reg[11],fir_in_reg}; 
              end
end
always @(posedge clk or negedge reset)
begin
    if(!reset)
       for(k=0;k<=4-1;k=k+1)
           add_buf[k]<=13'b0000_0000_00000;
    else
       if(divfre13_clk)
           for(l=0;l<=3;l=l+1) 
                add_buf[l]<=shift_buf[l]+shift_buf[7-1];
end
 
 
always @(posedge clk or negedge reset)    //有限状态机初始化,比特移位
begin
    if(!reset)
        begin
           //for(m=0;m<=4-1;m=m+1)  
              //state_shift_buf[m]<=13'b0000_0000_00000;
                            state_shift_buf0<=13'b0000_0000_00000;
                            state_shift_buf1<=13'b0000_0000_00000;
                            state_shift_buf2<=13'b0000_0000_00000;
                            state_shift_buf3<=13'b0000_0000_00000; 
           STATE<=S0;
        end
    else
        case(STATE)
            S0:begin      //初始状态
                  // for(n=0;n<=4-1;n=n+1) 
                      //state_shift_buf[n]<= add_buf[n];
                                          state_shift_buf0<=add_buf[0];
                                          state_shift_buf1<=add_buf[1];
                                          state_shift_buf2<=add_buf[2];
                                          state_shift_buf3<=add_buf[3];      
                   STATE<=S1;
               end
            S1:begin       //处理状态
                   if(divfre_count_4b==4'b1101)
                       STATE<=S0;
                   else
                      begin
                          for(p=0;p<=11;p=p+1) 
                              begin
                                 state_shift_buf0[p]<=state_shift_buf0[p+1];  
                                 state_shift_buf1[p]<=state_shift_buf1[p+1];
                                 state_shift_buf2[p]<=state_shift_buf2[p+1];
                                 state_shift_buf3[p]<=state_shift_buf3[p+1];
                              end
                          STATE<=S1;
                      end
                 end
        endcase
end
        
assign table_4b[0]=state_shift_buf0[0];
assign table_4b[1]=state_shift_buf1[0];
assign table_4b[2]=state_shift_buf2[0];
assign table_4b[3]=state_shift_buf3[0];
 
DA_table U_DA(
              .table_in_4b(table_4b),
              .table_out_12b(table_out_12b)
              );
                             
wire[26:0]sign_ex={table_out_12b[11],table_out_12b[11],table_out_12b[11],
                   table_out_12b[11],table_out_12b[11],table_out_12b[11],
                   table_out_12b[11],table_out_12b[11],table_out_12b[11],
                   table_out_12b[11],table_out_12b[11],table_out_12b[11],
                   table_out_12b[11],table_out_12b[11],table_out_12b[11],
                   table_out_12b};
                                           
always @(posedge clk or negedge reset)
begin
  if(!reset)
     sum<=27'b0;
  else
     if(divfre_count_4b==4'b0000)
       sum<=27'b0;
     else
       if(divfre_count_4b==4'b1101) 
         sum<=sum-delta(sign_ex,divfre_count_4b-4'b0001); 
     else
         sum<=sum+delta(sign_ex,divfre_count_4b-4'b0001);  
end
 
 
always @(posedge clk or negedge reset)
begin
  if(!reset)
    fir_out<=27'b0;
  else
     if(divfre_count_4b==4'b0000)
         fir_out<=sum;      //滤波器输出
end
 
function[13-1:0]delta;   //定义移位寄存器左移
   input[13-1:0]IQ;
   input[3:0]pipe;
 
   begin
       case(pipe)
         4'b0000:delta=IQ;
         4'b0001:delta={IQ[13-2:0],1'b0};
         4'b0010:delta={IQ[13-3:0],2'b00};
         4'b0011:delta={IQ[13-4:0],3'b000};
         4'b0100:delta={IQ[13-5:0],4'b0000};
         4'b0101:delta={IQ[13-6:0],5'b00000};
         4'b0110:delta={IQ[13-7:0],6'b000000};
         4'b0111:delta={IQ[13-8:0],7'b0000000};
         4'b1000:delta={IQ[13-9:0],8'b00000000};
         4'b1001:delta={IQ[13-10:0],9'b000000000};
         4'b1010:delta={IQ[13-11:0],10'b0000000000};
         4'b1011:delta={IQ[13-12:0],11'b00000000000};
         4'b1100:delta={IQ[13-13:0],12'b000000000000};
         //4'b1101:delta={IQ[13-14:0],13'b0000000000000};
         //4'b1110:delta={IQ[13-15:0],14'b00000000000000};
         //4'b1111:delta={IQ[13-16:0],15'b000000000000000};
         default:delta=IQ;
       endcase
     end
endfunction
 
endmodule
 
module DA_table(table_in_4b,table_out_12b);
 
input [3:0] table_in_4b;
output [11:0] table_out_12b;
reg[11:0] table_out_12b;
 
 
always @(table_in_4b)
      begin
         case(table_in_4b)
              4'b0000:table_out_12b=0;
              4'b0001:table_out_12b=41;
              4'b0010:table_out_12b=132;
              4'b0011:table_out_12b=173;
              4'b0100:table_out_12b=341;
              4'b0101:table_out_12b=382;
              4'b0110:table_out_12b=473;
              4'b0111:table_out_12b=514;
              4'b1000:table_out_12b=510;
              4'b1001:table_out_12b=551;
              4'b1010:table_out_12b=642;
              4'b0011:table_out_12b=683;
              4'b1100:table_out_12b=851;
              4'b1101:table_out_12b=892;
              4'b1110:table_out_12b=983;
              4'b1111:table_out_12b=1024;
              default:table_out_12b=0;
           endcase
              end
endmodule
 
  为了可以方便的判断程序输出结果的正确性,我们在仿真时采用了几个简单的数据作为采样后的数据输入。分别采用:1,2,3作为输入,则经过三次计算对应的输出应为41,241,728,十六进制数为29h,D6h,28Dh。与乘累加方式FIR滤波算法得出的结果完全一致。
————————————————