天天看點

FIR濾波器FPGA實作

假設一個信号中混合200KHz和15MHz的信号 ,設計一個低通濾波器濾波高頻分量。

MATLAB仿真

采樣率為50Mhz,使用Matlab設計濾波器

Fs = 50;  % Sampling Frequency

Fpass = 3;               % Passband Frequency
Fstop = 10;              % Stopband Frequency
Dpass = 0.057501127785;  % Passband Ripple
Dstop = 0.031622776602;  % Stopband Attenuation
dens  = 20;              % Density Factor

% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs/2), [1 0], [Dpass, Dstop]);

% Calculate the coefficients using the FIRPM function.
b  = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);
Hd.Numerator=round(Hd.Numerator*255);      

這個7階的濾波器得其8位量化的系數:

4    28    46    61    61    46    28     4。

Matlab仿真檔案:

1驗證上面得到的濾波器

fs= 50e6;
N=1024;
t=0:1/fs:(N-1)/fs;
f0=2e5;f1=15e6;
x_in= fix(63*(cos(2*pi*f0*t) + cos(2*pi*f1*t)));
figure(1);
subplot(1,2,1)
plot(t,x_in);
title('輸入信号');
xlabel('時間');
ylabel('幅度');
SpectrumX= fft(x_in,N);
subplot(1,2,2);
n=0:1:N-1;
stem(n,abs(SpectrumX));

%lpf
%function Hd = lpf_5_10_50m
%LPF_5_10_50M Returns a discrete-time filter object.
Fs = 50;  % Sampling Frequency

Fpass = 3;               % Passband Frequency
Fstop = 10;              % Stopband Frequency
Dpass = 0.057501127785;  % Passband Ripple
Dstop = 0.031622776602;  % Stopband Attenuation
dens  = 20;              % Density Factor

% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs/2), [1 0], [Dpass, Dstop]);

% Calculate the coefficients using the FIRPM function.
b  = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);
Hd.Numerator=round(Hd.Numerator*255);
% [EOF]
format short;
y_out=conv(Hd.Numerator,x_in);
len_of_y = length(y_out);
t=0:1/fs:(len_of_y-1)/fs;
figure(2);
 subplot(1,2,1);
plot(t,y_out);
SpectrumY= fft(y_out,len_of_y);
 subplot(1,2,2);
n=0:1:len_of_y-1;
 stem(n,abs(SpectrumY));      

2量化後的濾波器仿真

fs= 50e6;
N=1024;
t=0:1/fs:(N-1)/fs;
f0=2e5;f1=15e6;
x_in= fix(63*(cos(2*pi*f0*t) + cos(2*pi*f1*t)));
figure(1);
subplot(1,2,1)
plot(t,x_in);
title('輸入信号');
xlabel('時間');
ylabel('幅度');
SpectrumX= fft(x_in,N);
subplot(1,2,2);
n=0:1:N-1;
stem(n,abs(SpectrumX));
y=zeros(1,N);
lastr0=0;
lastr1=0;
lastr2=0;
lastr3=0;
lastr4=0;
lastr5=0;
lastr6=0;
lastr7=0;

for i=1:1:N
     newr0  = x_in(i)*4;
     newr1  = lastr0 + x_in(i)*28;
     newr2  = lastr1 + x_in(i)*46;
     newr3  = lastr2 + x_in(i)*61;
     newr4  = lastr3 + x_in(i)*61;
     newr5  = lastr4 + x_in(i)*46;
     newr6  = lastr5 + x_in(i)*28;
     newr7  = lastr6 + x_in(i)*4;
     lastr0  = newr0 ;
     lastr1  = newr1 ;
     lastr2  = newr2 ;
     lastr3  = newr3 ;
     lastr4  = newr4 ;
     lastr5  = newr5 ;
     lastr6  = newr6 ;
     y(i)=newr7;
    
end
figure(2);
 subplot(1,2,1);
plot(t,y );
len_of_y=length(y);
SpectrumY= fft(y ,len_of_y);
 subplot(1,2,2);
n=0:1:len_of_y-1;
 stem(n,abs(SpectrumY));      
仿真結果      

直接型實作

module lpf_direct(
   input wire clk, reset,
   input wire signed [7:0] x_in,
   output reg signed [24:0]y_out
    );
integer i;
reg signed [7:0] xr0, xr1 ,xr2, xr3, xr4, xr5, xr6, xr7 ;
reg signed [24:0] r0, r1, r2, r3, r4, r5, r6, r7;
reg signed [24:0] x0m4, x1m28, x2m46, x3m61,x4m61, x5m46, x6m28, x7m4;
always @(posedge clk or posedge reset)
   if(reset)
       begin
            
               xr0 <= 8'h00;
                xr1 <= 8'h00;
                xr2 <= 8'h00;
                xr3 <= 8'h00;
                xr4 <= 8'h00;
                xr5 <= 8'h00;
                xr6 <= 8'h00;
                xr7 <= 8'h00;
        end
     else
         begin
            
              xr0 <= x_in;
              xr1 <= xr0;
              xr2 <= xr1;
              xr3 <= xr2;
              xr4 <= xr3;
              xr5 <= xr4;
              xr6 <= xr5;
              xr7 <= xr6;
               
        end
        
        
always @ *
     begin
     x0m4 = xr0 <<< 2;
      x1m28 =(xr1 <<< 5 )- (xr1 <<< 2);
      x2m46 = (xr2 <<< 6) - (xr2 <<< 4)-(xr2 <<< 1);
     x3m61 = (xr3 <<< 6)- (xr3 <<<1) -( xr3);
      x4m61 = (xr4 <<< 6)- (xr4 <<<1) -( xr4);
      x5m46 = (xr5 <<< 6) - (xr5 <<< 4)-(xr5 <<< 1);
      x6m28 =(xr6 <<< 5 )- (xr6 <<< 2);
      x7m4 = xr7 <<< 2;
      end        
      
always  @*
    begin  r0  = x0m4;
     r1  = r0 + x1m28;
     r2  = r1 + x2m46;
     r3  = r2 + x3m61;
     r4  = r3 + x4m61;
     r5  = r4 + x5m46;
     r6  = r5 + x6m28;
     r7  = r6 + x7m4;
     end  
always @(posedge clk)     
      y_out = r7;
      
endmodule      

仿真結果:

FIR濾波器FPGA實作

轉置結構濾波器

module lpf_transpose
  (
  input wire clk, reset,
  input wire signed [7:0] x_in,
  output wire signed [24:0]y_out
    );
 
  reg signed [7:0] x_reg;
  reg signed [24:0] r0, r1, r2, r3, r4, r5, r6, r7;
  reg signed [24:0] x4, x28, x46, x61;
  always @(posedge clk or posedge reset)
    if(reset)
       x_reg <= 0;
     else
        
     x_reg <= x_in;
      
      
  always @(x_reg)
     begin
     x4 = x_reg <<< 2;
      x28 =(x_reg <<< 5 )- (x_reg <<< 2);
      x46 = (x_reg <<< 6) - (x_reg <<< 4)-(x_reg <<< 1);
     x61 = (x_reg <<< 6)- (x_reg <<<1) -( x_reg);
      end
      
  always @(posedge clk or posedge reset)
    if(reset)
     begin
     r0 <= 25'b0;
     r1 <= 25'b0;
     r2 <= 25'b0;
     r3 <= 25'b0;
     r4 <= 25'b0;
     r5 <= 25'b0;
     r6 <= 25'b0;
     r7 <= 25'b0;
     end
     else
    begin
     r0 <= x4;
     r1 <= r0 + x28;
     r2 <= r1 + x46;
     r3 <= r2 + x61;
     r4 <= r3 + x61;
     r5 <= r4 + x46;
     r6 <= r5 + x28;
     r7 <= r6 + x4;
     end
  assign y_out = r7;
endmodule      

FIR濾波器FPGA實作

直接型的設計報告:

Minimum period: 19.082ns (Maximum Frequency: 52.405MHz)

   Minimum input arrival time before clock: 1.946ns

   Maximum output required time after clock: 4.283ns