Chapter 13 Analysis of finite wordlength effects in fixed-point DSP systems function ADCNoiseGain=ADCNoise(b,a,n,FM) [B,A] = sos2tf([b a]); %form A(z) and B(z) [h,t] = impz(B,A,n); ADCNoiseGain = sum(h.^2)/12.0; %Output the results fprintf('ADC noise gain is %f\n\n',ADCNoiseGain); if FM~=1 fprintf('ADC noise is %g^2*%g*q^2\n',[FM ADCNoiseGain]); else fprintf('ADC noise is %g*q^2\n',ADCNoiseGain); end ========================================== function CoeffQuantizeErr(b,a,maxbits,ftype,f,Fs) %COEFFICIENT QUANTIZATION ERROR ANALYSIS n=256; for nbits=2:maxbits [B,A]=QuantizeCoeff(b,a,nbits); % quantize all coeffs [B,A] = sos2tf([B A]); %form A(z) and B(z) [h,w] = freqz(B,A,n); amag = abs(h); % obtain the amplitude response amag = amag/max(amag); % normalized amplitude response dev(nbits-1,:) = RippleAtten(ftype,f,amag,n,Fs); % obtain the pass and stopband deviations end fprintf('nbits\tband1\t\tband2\t\tband3\n'); fprintf('%d\t%f\t%f\t%f\n',reshape([(2:maxbits)' dev]',maxbits-1,4)); fprintf('\nfrequency response with quantization noise for desired wordlength:\n'); nbits=input(' wordlength (32 for unquantized coefficients): '); [B,A] = sos2tf([b a]); %form A(z) and B(z) freqz(B,A,n); %compute and plot the frequency response with unquantized coefficients hold on; [B,A] = QuantizeCoeff(b,a,nbits); % compute response of nbit filter [B,A] = sos2tf([B A]); %form A(z) and B(z) freqz(B,A,n); %compute and plot the frequency response with quantized coefficients title('Frequency Response for Desired Wordlength'); ================================================== function Stability(b,a,maxbits) %function Stability computes the pole radius and angle of each second %order section of the transfer function before(r1,angle1) and after %(r2,angle2) the coefficient quantization for different wordlengthes 1 format long; fprintf('\n\nnbits\tstage\tA1\tA2\tradius1\tangle1\tradius2\tangle2\n '); for nbits=2:maxbits [B,A]=QuantizeCoeff(b,a,nbits); for i=1:size(b,1) r1 = sqrt(abs(A(i,3))); angle1 = 180/pi*acos(A(i,2)/(-2.0*r1)); r2 = sqrt(abs(a(i,3))); angle2 = 180/pi*acos(a(i,2)/(-2.0*r2)); fprintf('%d\t%d\t%-7.4f\t%-7.4f\t%-7.4f\t%-7.2f\t%7.4f\t%-7.2f\n',nbits,i,A(i,2),A(i,3),r1,angle1,r2,angle2); end end format; ===================================== function ScaleFactor(b,a,nstep,size,structure) % Obtain scale factors, using L and cheb norms, for transfer function % either of canonic or of direct structure with single or multiple sections if structure norm0 = DirectScale(b,a,0,nstep); % obtain L1 norms norm1 = DirectScale(b,a,1,nstep); % obtain L2 norms norm2 = DirectScale(b,a,2,size); % obtain Loo norms else norm0 = CanonicScale(b,a,0,nstep); % obtain L1 norms norm1 = CanonicScale(b,a,1,nstep); % obtain L2 norms norm2 = CanonicScale(b,a,2,size); % obtain Loo norms end disp('L1-norms of the second order sections:'); disp(norm0); disp('L2-norms of the second order sections:'); disp(norm1); disp('Loo-norms of the second order sections:');disp(norm2); ============================================== function s = DirectScale(b,a,iopt,n) % function DirectScale computes the scale factors for a transfer % function realized by cascaded second order sections in direct structure if(iopt>=3) % scaling not required s = ones(1,size(b,1)); return; else A = 1; B = 1; for i=1:size(b,1) %loop for each stage A = conv(A,a(i,:)); B = conv(B,b(i,:)); s(i) = GetScaleFactor(B,A,iopt,n); end end ============================= 2 function s = CanonicScale(b,a,iopt,n) % function CanonicScale computes the scale factors of a transfer % function realized by cascaded second order canonic sections if(iopt>=3) % scaling not required s = ones(1,size(b,1)); return; else A = 1; B = 1; for i=1:size(b,1) %loop for each stage A = conv(A,a(i,:)); if i>1 B = conv(B,b(i-1,:)); end s(i) = GetScaleFactor(B,A,iopt,n); end end ==================================== function FWA % Program for a limited finite IIR % filters in cascade, parallel % Analysis performed are for: % (1) ADC quantization noise % (2) Coefficient quantization % (3) Product Roundoff noise % (4) Scaling % % For details see: % Digital Signal Processing: A % E C Ifeachor and B W Jervis, wordlength analysis on user-specified or direct form noise Practical Approach Addison Wesley, 1993 clear all; isel=3; %0 for ADC noise analysis %1 for coefficient quantization error analysis %2 for product roundoff noise analysis %3 for scale factors computations FM = 1 ; %filter multiplier (set to 1 if there is none) b1 = [1 0.0339 1]; %numerators of the second order sections b2 = [1 -0.7563 1]; b3 = [1 0.5331 1]; b4 = [1 -1.1489 1]; a1 = [1 -0.1743 0.9662]; %denominators of the second order sections a2 = [1 -0.5588 0.9675]; a3 = [1 -0.2711 0.9028]; a4 = [1 -0.4441 0.9045]; b = [b1; b2; b3; b4]; a = [a1; a2; a3; a4]; %above coeff are for example 7.16 (quantization error analysis) b=[1.2916 -0.08407 0];a=[1 -0.131 0.3355]; b=[7.5268 0 0];a=[1 -0.049 0]; %above coeff are for example 7.19 (scaling factor) b1 = [1 0.2189 1]; %numerators of the second order sections b2 = [1 -0.5291 1]; b3 = [1 1.5947 1]; a1 = [1 -0.0127 0.9443]; %denominators of the second order sections a2 = [1 -0.1731 0.7252]; 3 a3 = [1 -0.6152 0.2581]; b = [b1; b2; b3]; a = [a1; a2; a3]; %above coeff are for example 7.18 (scaling factor) b1=[1 -2 1]; b2=[1 -0.707 1]; a1=[1 0.777 0.3434]; a2=[1 0.01877 0.801]; b=[b1 ; b2]; a = [a1 ; a2]; %above coeff are in user guide: example 7.21 b=[0.1436 0.2872 0.1436];a=[1 -1.8353 0.9747]; %above coeff are for example 7.20 (scaling factor) b1 = [1 0.2189 1]; %numerators of the second order sections b2 = [1 -0.5291 1]; b3 = [1 1.5947 1]; a1 = [1 -0.0127 0.9443]; %denominators of the second order sections a2 = [1 -0.1731 0.7252]; a3 = [1 -0.6152 0.2581]; b = [b1; b2; b3]; a = [a1; a2; a3]; %b=[1 2 1];a=[1 -1.0581359 0.338544]; isel = 3; if isel==0 n=300; % length of impulse response FM = 1; ADCNoise(b,a,n,FM); elseif isel==1 Fs = 1000; %sampling frequency in Hz maxbits = 8; %maximum wordlength ftype = 2; %filter type: 0 - LPF, 1 - HPF, 2 - BPF, 3 - BSF f = [0 100 120 300 320 500]; %bandedge frequencies(Hz) (4 or 6) of filters CoeffQuantizeErr(b,a,maxbits,ftype,f,Fs); %coefficient quantization error analysis Stability(b,a,maxbits); elseif isel==2 iopt= 2; % scaling type: 0 - L1, 1 - L2, 2 - Loo, 3 - no scaling n = 300; % time points(300) for L1 and L2, frequency points(256) for Loo nbits = 30; % word length of the coefficients RoundoffNoise(b,a,n,nbits,iopt); else structure = 0 ; % 0 - canonic, 1 - direct nstep = 256; size = 300; ScaleFactor(b,a,nstep,size,structure); end =========================================== function s = GetScaleFactor(b,a,iopt,n) % function GetScaleFactor computes the scale factors for L1, L2, and % Loo forms from a transfer function described by coefficients a and b if (iopt==0|iopt==1) [h,t] = impz(b,a,n); %impulse response if (iopt) s = sqrt(sum(h.^2)); else s = sum(abs(h)); end elseif (iopt==2) 4 [h,w] = freqz(b,a,n); % frequency response s = max(abs(h)); else s = 1; end % otherwise no scale ======================================= function [B,A]=QuantizeCoeff(b,a,nbits) if(nbits==32) B = b; A = a; return; end ip2=2^(nbits-1); B = floor(sign(b).*(abs(b)*ip2+0.5))/ip2; A = floor(sign(a).*(abs(a)*ip2+0.5))/ip2; ================================== function RoundoffNoise(b,a,n,nbits,iopt) % function RoundoffNoise computes the scale factors and roundoff % noise of the transfer function realized by the cascaded second % order canonic sections if(nbits<2) nbits=2; elseif(nbits>28) nbits=32; end norm = CanonicScale(b,a,iopt,n); % obtain scale factors temp = norm./[norm(2:size(b,1)) 1]; for i=1:size(b,1) % scale the coefficients B(i,:)=b(i,:)*temp(i); end [B,A] = QuantizeCoeff(B,a,nbits); norm_square = NormSquare(B,A); % norm_square(i)=||Hi(z)||2 squared roundoff_noise_gain = 3*norm_square(1); for i=2:size(b,1) roundoff_noise_gain = roundoff_noise_gain+5*norm_square(i); end roundoff_noise_gain = (roundoff_noise_gain + 3)/12; fprintf('Scale factors: '); disp(norm); fprintf('Norm squared values for Fi(z): '); disp(norm_square); ================================================ function norm_square = NormSquare(b,a) % function NormSquare computes the scale norm squares of a transfer % function realized by cascaded second order canonic sections A = 1; B = 1; for i=1:size(b,1) %loop for each stage A = conv(A,a(i,:)); B = conv(B,b(i,:)); end for i=1:size(b,1) %loop for each stage if i>1 A = deconv(A,a(i-1,:)); 5 B = deconv(B,b(i-1,:)); end s(i) = GetScaleFactor(B,A,1,300); % get L2 norm from 300 points end norm_square = s.*s; ================================== function dev = RippleAtten(ftype,f,amag,n,Fs) m=floor(2*n*f/Fs); if ftype==0 % LPF: obtain passband ripple and stopband attenuation dev(1)=20.0*log10(1.0+max(amag(m(1)+2:m(2)))min(amag(m(1)+2:m(2)))); dev(2)=-20.0*log10(max(amag(m(3)+2:m(4)))); dev(3)=0.0; elseif ftype==1 % HPF: obtain passband and stopband attenuation dev(1)=-20.0*log10(max(amag(m(1)+2:m(2)))); dev(2)=20.0*log10(1.0+max(amag(m(3)+2:m(4)))min(amag(m(3)+2:m(4)))); dev3=0.0; elseif ftype==2 % bandpass filter dev(1)=-20.0*log10(max(amag(m(1)+2:m(2)))); dev(2)=20.0*log10(1.0+max(amag(m(3)+2:m(4)))min(amag(m(3)+2:m(4)))); dev(3)=-20.0*log10(max(amag(m(5)+2:m(6)))); elseif ftype==3 %BSF: obtain passband and stopband attenuation dev(1)=20.0*log10(1.0+max(amag(m(1)+2:m(2)))min(amag(m(1)+2:m(2)))); dev(2)=-20.0*log10(max(amag(m(3)+2:m(4)))); dev(3)=20.0*log10(1.0+max(amag(m(5)+2:m(6)))min(amag(m(5)+2:m(6)))); end ============================================== 6 7