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
仿真结果:
转置结构滤波器
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
直接型的设计报告:
Minimum period: 19.082ns (Maximum Frequency: 52.405MHz)
Minimum input arrival time before clock: 1.946ns
Maximum output required time after clock: 4.283ns
转置结构的设计报告:
Minimum period: 11.119ns (Maximum Frequency: 89.936MHz)
Minimum input arrival time before clock: 2.057ns
Maximum output required time after clock: 4.283ns
转置转置结构的实现方式将关键路径从1个乘法器7个加法器减小到1个乘法器1个加法器,少了6个加法器。
OPTIMISM, PASSION & HARDWORK