📄 gsm_duc_cic_filters.m
字号:
function [ hcic, hcfir, hpfir ] = gsm_duc_cic_filters(...
fclk,n_ch,...
fs_cic,m_cic,...
use_cfir,fs_cfir,m_cfir,...
use_pfir,fs_pfir,m_pfir,...
ShowPlots)
%% Filter design parameters
fpass = 80e3; % Upper frequency limit of GSM band of interest
fstop = 100e3; % Transition point of GSM mask
apass = 0.01; % Passband ripple (dB)
scale_tweak = [ 1.0 1.1 ]; % PFIR and CFIR coefficient scaling factors
%% Create CIC
ast_cic = 120; % Stopband attenuation of CIC first lobe
dd = 1; % Differential delay of CIC - 1 or 2
hcic = design(fdesign.interpolator(m_cic,'cic',dd,fpass,ast_cic,fs_cic));
set(hcic, 'Arithmetic','fixed','InputWordLength',18,'InputFracLength',17);
info(hcic)
if ShowPlots>=3
fvtool(cascade(hcic,dfilt.scalar(1/(gain(hcic)*m_cic))),'Fs',[fs_cic]);
axis([0 10 -200 10]);
title(sprintf('CIC Magnitude Response (dB), R=%d, gain=%d',m_cic,gain(hcic)));
end
%% Create CIC compensator (CFIR)
cfir_use_firceqrip = 1; % Specify method, firceqrip or Matlab CIC comp
%k_cfir = 0.912; % Scaling factor for CFIR, to prevent overflows
% due to additional passband gain
for macs=2:-1:1
% Determine the available taps using the selected number of MAC units
cfir_os = fclk/fs_cfir/n_ch;
taps_cfir = (macs*cfir_os*4-1);
n_cfir = taps_cfir-1;
display(sprintf('CFIR tap count is %d, using %d MACs',taps_cfir,macs));
if n_cfir <15
error(sprintf('CFIR tap count of %d is too low, using %d MAC units!',taps_cfir,macs));
end
% Set stop-band attenuation of Compensation FIR; if using firceqrip with a
% slope, start with a low basic stop-band attentuation, else go for higher
% stop-band
if cfir_use_firceqrip == 1
ast_cfir = 50;
else
ast_cfir = 85; % Stopband attenuation of Compensation FIR
end
for i=1:4
if use_cfir == 1
if cfir_use_firceqrip==1
% Use fircerip method of CFIR generation using a fixed
% filter order, determined by the FIR hardware capabilities
w = 0.5; % Sinc frequency factor
ripple = 10^(apass/20); % Maximum value of ripple
err_pass = (ripple-1)/2; % Ripple error
ast = 10^(-1*ast_cfir/20); % Convert stop-band attenuation to weight
slope = 80; % Slope in stop-band, db/rad/sample
wpass = fpass/(fs_cfir/2); % Normalized frequency pass-band edge
cfir = firceqrip(...
n_cfir,wpass,[err_pass, ast],'passedge',...
'slope',slope,...
'invsinc',[w,hcic.numberofsections]);
%cfir_gain(i) = m_cfir*scale_tweak(2);
%cfir_scaled = cfir*cfir_gain(i);
[ cfir_scaled cfir_gain(i) ] = scale_coeffs(cfir,m_cfir);
cfir_scaled = cfir_scaled*scale_tweak(2);
cfir_gain(i) = cfir_gain(i)*scale_tweak(2);
if m_cfir>1
%hcfir(i) = mfilt.firinterp(m_cfir,cfir*m_cfir);
hcfir(i) = mfilt.firinterp(m_cfir,cfir_scaled);
%hcfir(i).Numerator
else
hcfir(i) = dfilt.dffir(cfir);
%hcfir(i).Numerator
end
else
% Allow built-in Matlab function to generate the CIC compensation response
% Specification formats
% fpass,fstop,apass,ast_cfir, ... % Too loose, not tied to max order
% 'n,fp,ap,ast',ord,fpass,apass,ast_cfir, ... % Better for fixed order
if m_cfir>1
hcfir(i) = design( ...
fdesign.interpolator(m_cfir,'ciccomp', ...
hcic.differentialdelay, ...
hcic.numberofsections, ...
'n,fp,ap,ast',n_cfir,fpass,apass,ast_cfir, ...
fs_cfir ));
else
hcfir(i) = design( ...
fdesign.ciccomp( ...
hcic.differentialdelay, ...
hcic.numberofsections, ...
'n,fp,ap,ast',n_cfir,fpass,apass,ast_cfir, ...
fs_cfir ));
end
cfir_gain(i) = scale_tweak(2)*m_cfir;
hcfir(i).Numerator = hcfir(i).Numerator*scale_tweak(2);
end
% Quantize filter coefficients
set(hcfir(i),...
'Arithmetic','fixed',...
'CoeffWordLength',18,...
'FilterInternals','SpecifyPrecision','RoundMode','floor');
if ShowPlots>=4
fvtool(cascade(hcfir(i),dfilt.scalar(1/cfir_gain(i))),'Fs',[ fs_cfir ])
title(sprintf('CFIR Magnitude Response (dB) with N=%d, Ast=%d, firceqrip=%d',n_cfir,ast_cfir,cfir_use_firceqrip));
end
% Next loop adjustments
ast_cfir=ast_cfir+10;
else
% Bypass PFIR
hcfir(i) = dfilt.scalar(1);
end
end
end
% Display the loop results in an overlay
if ShowPlots>=4 && use_cfir==1
% fvtool(hcfir,'Fs',[ fs_cfir ]);
for i=1:4
htemp(i)=cascade(hcfir(i),dfilt.scalar(1/cfir_gain(i)));
end
fvtool(htemp(:),'Fs',[ fs_cfir ],'ShowReference','off');
title('Overlay of CFIR Magnitude Responses (dB)');
end
% Choose an option from the loop, cascade and analyze response (including
% passband zoom)
hcfir = hcfir(3);
cfir_gain = cfir_gain(3)
if ShowPlots>=3 && use_cfir==1
fvtool(cascade(hcfir,hcic,dfilt.scalar(1/(gain(hcic)*m_cic*cfir_gain))),...
'Fs',[ fs_cic ]); axis([0 5 -200 +10]);
title('CFIR-CIC Cascaded Magnitude Response (dB)');
fvtool(cascade(hcic,dfilt.scalar(1/(gain(hcic)*m_cic))),...
cascade(hcfir,dfilt.scalar(1/cfir_gain)),...
cascade(hcfir,hcic,dfilt.scalar(1/(gain(hcic)*m_cic*cfir_gain))),...
'Fs',[ fs_cic fs_cfir fs_cic ],...
'Legend','off',...
'ShowReference','off');
axis([0 0.12 -0.1 +0.1]); % Focus in on passband
legend('CIC','CFIR','CIC-CFIR Cascade');
title('Passband Zoom Overlay of CIC, CFIR and cascaded CFIR-CIC Magnitude Responses (dB)');
end
%% Create the PFIR
% PFIR response should further attenuate the CIC lobe and sharpen
% up the pass-band to stopband transition edge
pfir_use_firceqrip = 1;
% Set stop-band attenuation of Pulse-Shaping FIR; if using firceqrip with a
% slope, start with a low basic stop-band attentuation, else go for higher
% stop-band
if cfir_use_firceqrip == 1
ast_pfir = 60;
else
ast_pfir = 85; % Stopband attenuation of Compensation FIR
end
for macs=1
% Determine the available taps using the selected number of MAC units
pfir_os = fclk/fs_pfir/n_ch;
taps_pfir = (macs*pfir_os*4-1);
n_pfir = taps_pfir-1;
display(sprintf('PFIR tap count is %d, using %d MACs',taps_pfir,macs));
if n_pfir < 30, error(sprintf('PFIR tap count of %d is too low, using %d MAC units!',taps_pfir,macs)); end
for i=1:4
if use_pfir==1
if pfir_use_firceqrip==1
ripple = 10^(apass/20); % Maximum value of ripple
err_pass = (ripple-1)/2; % Ripple error
ast = 10^(-1*ast_pfir/20); % Convert stop-band attenuation to weight
slope = 40; % Slope in stop-band, db/rad/sample
wpass = fpass/(fs_pfir/2); % Normalized frequency pass-band edge
pfir = firceqrip(...
n_pfir,wpass,[err_pass, ast],'passedge',...
'slope',slope);
%pfir_gain(i) = m_pfir*scale_tweak(1);
%pfir_scaled = pfir*pfir_gain(i)
[ pfir_scaled pfir_gain(i) ] = scale_coeffs(pfir,m_pfir);
pfir_scaled = pfir_scaled*scale_tweak(1);
pfir_gain(i) = pfir_gain(i)*scale_tweak(1);
if m_pfir>1
hpfir(i) = mfilt.firinterp(m_pfir,pfir_scaled);
else
hpfir(i) = dfilt.dffir(pfir_scaled);
end
else
% Parks McLellan / Generalized Remez algorithm
F = [0 fpass fstop 2*fstop 2*fstop fs_pfir/2]/(fs_pfir/2);
A = [scale_tweak(1) scale_tweak(1) 0 0 0 0];
W = [10 1 10];
pfir= gremez(n_pfir,F,A,W);
pfir_gain(i) = m_pfir*scale_tweak(1);
pfir_scaled = pfir*pfir_gain(i);
%[ pfir_scaled pfir_gain(i) ] = scale_coeffs(pfir,m_pfir);
%pfir_scaled = pfir_scaled*scale_tweak(1);
%pfir_gain(i) = pfir_gain(i)*scale_tweak(1);
if m_pfir>1
hpfir(i) = mfilt.firinterp(m_pfir,pfir_scaled);
else
hpfir(i) = dfilt.dffir(pfir_scaled);
end
end
set(hpfir(i),...
'Arithmetic','fixed',...
'CoeffWordLength',18,...
'FilterInternals','SpecifyPrecision','RoundMode','floor');
if ShowPlots>=4
fvtool(cascade(hpfir(i),dfilt.scalar(1/pfir_gain(i))),'Fs',[ fs_pfir ]);
title(sprintf('PFIR Magnitude Response (dB) with N=%d, Ast=%d, firceqrip=%d',n_pfir,ast_pfir,pfir_use_firceqrip));
end
else
hpfir(i) = dfilt.scalar(1); % Bypass PFIR
pfir_gain(i) = 1;
end
% Next loop adjustments
ast_pfir=ast_pfir+10;
end
end
% Display the loop results in an overlay
if ShowPlots>=4 && use_pfir==1
% fvtool(pfir,'Fs',[ fs_pfir ]);
for i=1:4
htemp(i)=cascade(hpfir(i),dfilt.scalar(1/pfir_gain(i)));
end
fvtool(htemp(:),'Fs',[ fs_pfir ],'ShowReference','off');
title('Overlay of PFIR Magnitude Responses (dB)');
end
% Choose an option from the loop and display selected response
hpfir = hpfir(3); pfir_gain = pfir_gain(3);
if ShowPlots>=3 && use_pfir==1
fvtool(cascade(hpfir,dfilt.scalar(1/pfir_gain)),'Fs',[ fs_pfir ]);
title('Selected PFIR Magnitude Response (dB)');
end
%% Filter cascade and overlay visualization
full_chain = cascade(hpfir,hcfir,hcic,dfilt.scalar(1/(gain(hcic)*m_cic*cfir_gain*pfir_gain)));
if ShowPlots>=1
fvtool(full_chain,'Fs',[fs_cic]); axis([0 5 -200 10]);
title('Final Cascaded Magnitude Response (dB)')
fvtool(cascade(hcic,dfilt.scalar(1/(gain(hcic)*m_cic))),...
cascade(hcfir,dfilt.scalar(1/cfir_gain)),...
cascade(hpfir,dfilt.scalar(1/pfir_gain)),...
full_chain,...
'Fs',[fs_cic fs_cfir fs_pfir fs_cic],...
'Legend','off',...
'ShowReference','off');
axis([0 10 -200 10]);
legend('CIC','CFIR','PFIR','Full Cascade');
title('Final Overlaid Magnitude Responses (dB)')
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -