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

[H,L0,ABCD,k]=LCparam2tf(param,k)
function [H,L0,ABCD,k]=LCparam2tf(param,k)
%[H,L0,ABCD,k]=LCparam2tf(param,k=1)
%Compute the transfer functions (and the Q. gain, k) of an LC modulator.
%
%Arguments
% param	A struct containing the following fields (all normalized):
%   l   The inductances in each tank.
%   c	The capacitances in each tank.
%   gu	The transconductance from the u input to each of the tanks.
%	The final term is the voltage gain to the comparator input.
%	Default = [1 0 .. ]. (1 by n+1)
%   gv	The transconductance from the v output to each of the tanks.
%	(1 by n+1).
%   gw	The inter-stage transconductances. 
%	Default = [1 1 .. ]. (1 by n-1)
%   gx	The gains from the top of each tank resistor to the comparator.
%	Default = [0 0 .. 1]. (1 by n)
%   rx	The resistances inserted between the output of each interstage 
%	transconductance and the top of each tank.
%	Default = [0 ..]. (1 by n)  Note that rx(1) is not used.
%   t	A two-element vector containing the start and end times of the feedback
%	waveform.
%	Default = [0 1].
%   rl	The series resistance of each inductor. 
%	Default = [0 ..]. (1 by n)
%   gc	The parallel conductances of each tank. 
%	Default = [0 ..]. (1 by n)
%
% k	The value to assume for the quantizer gain. If k is omitted or if
%	k is defaulted, k is taken to be 1.
%	If k is 0, a value is computed by the formula 
%	k = mean(abs(y))/mean(y.^2), where y is the quantizer input
%	sequence when the modulator is fed with a small input at f0.
%
%Output
% H	The closed-loop noise transfer function (in z).
% L0	The open-loop tf (in s) from u to v.  G  may be evaluated
%	using evalContSTF(L0,H,f).
% k	The value of the quantizer gain used to compute the above tfs.
% ABCD  The state-space description of the discrete-time system
%
%For the conversion from continuous to discrete time, corrections to the
%standard MATLAB formulae need to be applied in order for the sampled-data
%value to be taken at the END of the time interval.
%This effectively makes t1>0 and requires corrections if t2>=1 and gv(n+1)~=0.
%More complex formulae are needed for t2>=1, so for the moment this code
%requires t2<1.

l = param.l; 
c = param.c;
f0 = mean(1 ./ sqrt(l.*c)) / (2*pi);
n = length(l);
%Handle the input arguments and their defaults
% !! isempty() must be first because when k=[] isnan returns [] and this 
% !! makes the whole expression []
if nargin<2 | isempty(k) | isnan(k) 
    k = 1;
end
if any(strcmp(fieldnames(param),'gu')) & ~isempty(param.gu) & ~isnan(param.gu)	
    gu = param.gu;
else
    gu = [1 zeros(1,n)];
end
gu = padr(gu,n+1,0);	% Pad out with zeros, if needed.
gv = padr(param.gv,n+1,0);	% Pad out with zeros, if needed.
if any(strcmp(fieldnames(param),'gw')) & ~isempty(param.gw) & ~isnan(param.gw)	
    gw = param.gw;
else
    gw = ones(1,n-1);
end
if any(strcmp(fieldnames(param),'gx')) & ~isempty(param.gx) & ~isnan(param.gx)	
    gx = param.gx;
else
    gx = [zeros(1,n-1) 1];
end
if any(strcmp(fieldnames(param),'rx')) & ~isempty(param.rx) & ~isnan(param.rx)	
    rx = param.rx;
    if length(rx)==1;	
	rx = rx(ones(1,n));
    end
else
    rx = [zeros(1,n)];
end
if any(strcmp(fieldnames(param),'t')) & ~isempty(param.t) & ~isnan(param.t)	
    t = param.t;
else
    t = [0 1];
end
if any(strcmp(fieldnames(param),'rl')) & ~isempty(param.rl) & ~isnan(param.rl)	
    rl = param.rl;
    if length(rl)==1;	
	rl = rl(ones(1,n));
    end
else
    rl = [zeros(1,n)];
end
if any(strcmp(fieldnames(param),'gc')) & ~isempty(param.gc) & ~isnan(param.gc)	
    gc = param.gc;
    if length(gc)==1;	
	gc = gc(ones(1,n));
    end
else
    gc = [zeros(1,n)];
end

% Form the state-space description of the modulator
% The states are ordered v1, i1, v2, i2 ...
n2 = 2*n;
ABc = zeros(n2,n2+2); CDc = zeros(1,n2+2);
for i = 1:n
    i2 = 2*i-1;
    % y represents the voltage at the top of the resistor stacked on the tank.
    if i == 1
	y = [ 1 zeros(1,n2+1) ];
    else
	ABc(i2,:) = gw(i-1)*y;
	y = rx(i)*gw(i-1)*y; y(i2) = 1;
    end
    ABc(i2,n2+1:n2+2) = [gu(i) -gv(i)]; 
    ABc(i2:i2+1,i2:i2+1) = [-gc(i) -1; 1 -rl(i)];
    ABc(i2,:) = ABc(i2,:)/c(i); 
    ABc(i2+1,:) = ABc(i2+1,:)/l(i); 
    CDc = CDc + gx(i)*y;
end
CDc = CDc + [zeros(1,n2) gu(n+1) -gv(n+1)];

% THIS IS THE NEW CODE !!
[Ac,Bc,Cc,Dc] = partitionABCD([ABc;CDc], 2);
sys_c = ss( Ac, Bc(:,2), Cc, Dc(2) );
sys = mapCtoD(sys_c,t,f0);
% Augment the input matrix. 
A=sys.a;
B=[padb(Bc(:,1),size(sys.b,1)) sys.b];
C=sys.c;
D=[Dc(1) sys.d];

% Compute L0; use the LC parameters to compute the poles and thereby
% ensure exact agreement with the zeros in H.
%!! THIS IS GOING TO NEED FIXING
s_poles = zeros(1,2*n);
for i=1:n
    s_poles(2*i-1:2*i) = roots([ l(i)*c(i) ( rl(i)*c(i) + gc(i)*l(i) ) 1+rl(i)*gc(i) ]);
end
LF0 = ss(Ac,Bc(:,1),Cc,Dc(1));
L0 = zpk( LF0 );
L0.p =  s_poles;

% Compute H. Use the poles in L0 to compute the zeros in H.
ABCD =[A B; C D];
if k==0		% Estimate k by simulatiing the modulator with a small input
    w0 = mean(1./sqrt(l.*c));
    H = calculateTF(ABCD);
    H.z = exp(s_poles);
    stf0 = abs(evalTFP(L0,H,w0/(2*pi)));
    u = 0.1/stf0*sin(w0*[0:10000]);
    [tmp1,tmp2,tmp3,y] = simulateDSM(u,[A B; C D]);
    k = mean(abs(y))/mean(y.^2);
end
H = calculateTF(ABCD,k);
H.z = exp(s_poles);

% Correct L0k to include the quantizer gain
L0.k = L0.k*k;

Contact us