Code covered by the BSD License  

Highlights from
Delta Sigma Toolbox

image thumbnail

Delta Sigma Toolbox

by

 

14 Jan 2000 (Updated )

High-level design and simulation of delta-sigma modulators

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

synthesizeQNTF(order,OSR,f0,NG,ING,n_im)
function ntf = synthesizeQNTF(order,OSR,f0,NG,ING,n_im)
%ntf = synthesizeQNTF(order=3,OSR=64,f0=0,NG=-60,ING=-20,n_im=floor(order/3))
%Synthesize a noise transfer function for a quadrature delta-sigma modulator.
%  order  order of the modulator
%  OSR    oversampling ratio
%  f0     center frequency (1->fs)
%  NG     in-band noise gain (dB)
%  ING    image-band noise gain (dB)
%  n_im   number of in-band image zeros
%
%ntf is a zpk object containing the zeros and poles of the NTF. See zpk.m
%
% ALPHA VERSION
% This function uses an experimental ad hoc method that is
% neither optimal nor robust.

% Handle the input arguments
parameters = {'order','OSR','f0','NG','ING','n_im'};
defaults = { 4 64 0 -60 -20 []};
for arg_i=1:length(defaults)
    parameter = char(parameters(arg_i));
    if arg_i>nargin | ( eval(['isnumeric(' parameter ') '])  &  ...
     eval(['any(isnan(' parameter ')) | isempty(' parameter ') ']) )
        eval([parameter '=defaults{arg_i};'])
    end
end
if isempty(n_im)
    n_im = floor(order/3);
end
debug_it = 0;

if n_im==0
    % Use synthesizeNTF to get an NTF with the specified NG; ignore ING
    f1 = 0.5/OSR;
    x = 1.5;
    lowest_f = Inf;
    dfdx = NaN;
    for itn = 1:20
	ntf = synthesizeNTF(order,OSR,1,x);
	f = dbv(rmsGain(ntf,0,f1)) - NG;
	if debug_it
	    fprintf(1,'x=%.2f f=%.2f\n', x, f);
	end
	if abs(f) < 0.01
	    break;
	end
	if isnan(dfdx)
	    dx = 0.1*sign(f);
	    dfdx = 0;
	else
	    dfdx = (f-f_old)/dx;
	    dx_old = dx;
	    dx = -f/dfdx;
	    if abs(dx) > max(1,2*abs(dx_old))
		dx = sign(dx)*max(1,2*abs(dx_old));
	    end
	    if x+dx <=1	% Hinf must be at least 1
		dx = dx/2;
	    end
	end
	f_old = f;
	x = x + dx;
    end
    if itn==20
	fprintf(1,'Warning: Iteration limit reached. NTF may be poor\n');
    end
    % Rotate the NTF
    z0 = exp(2i*pi*f0);
    ntf = zpk(z0*ntf.z{1}, z0*ntf.p{1}, ntf.k, 1);
else
    n_in = order-n_im;
    f1 = f0-0.5/OSR;
    f2 = f0+0.5/OSR;
    z0 = exp(2i*pi*f0);
    x = [20 20];	% "R" parameters for cheby2()
    lowest_f = Inf;
    dfdx = [NaN NaN];
    for itn = 1:20
	if debug_it
	    fprintf(1,'x=[%.2f %.2f], ', x(1), x(2) );
	end
	[b1 a1] = cheby2(n_in,x(1),1/OSR,'high');
	[b2 a2] = cheby2(n_im,x(2),1/OSR,'high');
	warning('off');
	ntf0 = zpk( [roots(b1)*z0; roots(b2)*conj(z0)], ...
		    [roots(a1)*z0; roots(a2)*conj(z0)],1,1);
	freq = linspace(-0.5,0.5,200);
	m = evalTF(ntf0,exp(2i*pi*freq));
	NG0 = dbv(rmsGain(ntf0,f1,f2));
	ING0 = dbv(rmsGain(ntf0,-f1,-f2));
	if debug_it
	    clf;
	    subplot(121);
	    plotPZ(ntf0);
	    subplot(122);
	    fprintf(1,'NG=%.1f, ING=%.1f\n', NG0, ING0);
	    plot(freq,dbv(m));
	    figureMagic([-0.5,0.5],0.05,2, [-100 30],10,2)
	    hold on;
	    plot([f1 f2],[1 1]*NG0,'k');
	    text(mean([f1 f2]), NG0, sprintf('NG=%.1fdB',NG0),'vert','bot');
	    plot([-f1 -f2],[1 1]*ING0,'k');
	    text(mean(-[f1 f2]), ING0, sprintf('ING=%.1fdB',ING0),'vert','bot');
	    drawnow;
	end
	f = [NG0 ING0] - [NG ING];
	if abs(f) < 0.01
	    break;
	end
	if norm(f)<lowest_f
	    lowest_f = norm(f);
	    best = ntf0;
	end
	if abs(f(1)) > abs(f(2))
	    i=1;	% adjust x(1)
	else
	    i=2;	% adjust x(2)
	end
	if isnan(dfdx(i))
	    dx = sign(f(i));
	    dfdx(i) = 0;
	    dfdx(3-i) = NaN;
	else
	    dfdx(i) = (f(i)-f_old(i))/dx;
	    dfdx(3-i) = NaN;
	    dx = -f(i)/dfdx(i);
	    xnew = x(i) + dx;
	    if xnew < 0.5*x(i)
		dx = -0.5*x(i);
	    elseif xnew > 2*x(i)
		dx = x(i);
	    end
	end
	f_old = f;
	x(i) = x(i) + dx;
    end
    if itn==20
	fprintf(1,'Warning: Iteration limit reached. NTF may be poor\n');
    end
    ntf = best;
end

Contact us