www.gusucode.com > signal 工具箱matlab源码程序 > signal/@dfilt/@filterquantizer/firdecimdggen.m
function DGDF = firdecimdggen(q,Hd,coeffnames,doMapCoeffsToPorts,states) %FIRDECIM Directed Graph generator for Firdecim multirate filter % Author(s): Honglei Chen % Copyright 1988-2005 The MathWorks, Inc. narginchk(5,5); coefs = coefficients(reffilter(Hd)); num=coefs{1}; % Get filter states and coefficient names info.states = states; info.coeffnames = coeffnames; info.doMapCoeffsToPorts = doMapCoeffsToPorts; info.decimorder = Hd.DecimationFactor; % Represent the filter in terms of DG_Dfilt DGDF = gen_DG_firdecim_stages(q,num,info,Hd); % ------------------------------------------------------------------------- % % gen_DG_firdecim_stages: Generates the DG_DFILT representation % by constructing each "Stage" of the filter. % % ------------------------------------------------------------------------- function DGDF = gen_DG_firdecim_stages(q,num,info,H) decim_order = info.decimorder; % Remove trailing zero-coefficients in polynomials: num = num(1:max(find(num~=0))); %determine the number of layers required to construct the filter max_order = floor((length(num)-1)/decim_order)+3; info.nstages = max_order; % Create the header, body and the footer. if max_order > 4 Stg(1) = inputer(num,decim_order,H,info,q); Stg(2) = header(num,decim_order,H,info,q); Stg(3) = body(num,decim_order,H,info,q); Stg(4) = footer(num,decim_order,H,info,q); Stg(5) = outputer(num,decim_order,H,info,q); elseif max_order > 3 Stg(1) = inputer(num,decim_order,H,info,q); Stg(2) = header(num,decim_order,H,info,q); Stg(3) = footer(num,decim_order,H,info,q); Stg(4) = outputer(num,decim_order,H,info,q); else Stg(1) = inputer(num,decim_order,H,info,q); % Stg(2) = firdecimheader_order0(num,decim_order,H,info,q); Stg(2) = firdecimheader_order0(q,num,decim_order,H,info); Stg(3) = outputer(num,decim_order,H,info,q); end % create demux if info.doMapCoeffsToPorts norder = decim_order + (floor((length(num)-1)/decim_order)*decim_order); Stg(length(Stg)+1) = demux(q,H,norder,info.coeffnames{1}); end % make a DG_DFILT out of it. % dg_dfilt is the bridge between the dfilt representation % and directed graph representation DGDF = filtgraph.dg_dfilt(Stg,'firdecim','lr'); DGDF.gridGrowingFactor = [0.5 ceil(decim_order)]; % ------------------------------------ % % input stage % % ------------------------------------ function Inp = inputer(num,decim_order,H,info,q) NL=filtgraph.nodelist(2); % Nodelist NL.setnode(filtgraph.node('input'),1); NL.setnode(filtgraph.node('decimcommutator'),2); % label set(NL.nodes(1).block,'label','Input'); set(NL.nodes(2).block,'label','DecimSys'); % relative position set(NL.nodes(1),'position',[0 0.5 0 0.5]); set(NL.nodes(2),'position',[0.5 0.5 0.5 0.5]); % orientation set(NL.nodes(1).block,'orientation','right'); set(NL.nodes(2).block,'orientation','right'); % obtain parameter for the decim commutator % Ndecim_str=num2str(decim_order); mainparams(1)=filtgraph.indexparam(1,{}); mainparams(2)=filtgraph.indexparam(2,num2str(decim_order)); NL.nodes(2).block.setnumoutports(decim_order); [NL, NextIPorts, NextOPorts, mainparams]=firdeciminputconnect(q,NL,H,mainparams,decim_order); Inp = filtgraph.stage(NL,[],[],NextIPorts,NextOPorts,mainparams); % -------------------------------------------------------------- % % head: Generate the conceptual header stage for Discrete FIR architecture % % Returns a filtgraph.stage, % -------------------------------------------------------------- function Head = header(num,decim_order,H,info,q) % Construct the first layer, structure specific NL=filtgraph.nodelist(3*decim_order-1); vlocfactor = 1/(4*decim_order+1); % to fit everything into one grid. The grid is enlarged using gridGrowingFactor vlocoffset = 4*vlocfactor; % Specify coefficient names nglbl = cell(1,decim_order); if info.doMapCoeffsToPorts for m=1:decim_order nglbl{m} = sprintf('%s%d',info.coeffnames{1},m); end end % connectors & gains for m=1:decim_order NL.setnode(filtgraph.node('connector'),m); set(NL.nodes(m),'position',[0 (m-1)*vlocoffset 0 (m-1)*vlocoffset]); mainparams(m)=filtgraph.indexparam(m,{}); %gain gainidx = decim_order + m; %calculate the node index in the node list NL.setnode(filtgraph.node('gain'),gainidx); set(NL.nodes(gainidx).block,'label',['headgain' num2str(m)]); set(NL.nodes(gainidx),'position',[0.5 (m-1)*vlocoffset+vlocfactor 0.5 (m-1)*vlocoffset+vlocfactor]); %gain aligned backwards set(NL.nodes(gainidx).block,'orientation','down'); ng = {'0'}; ng = NL.coeff2str(num,m); mainparams(gainidx)=filtgraph.indexparam(gainidx,ng,nglbl{m}); end % sums for m=1:decim_order-1 sumidx = 2*decim_order + m; NL.setnode(filtgraph.node('sum'),sumidx); set(NL.nodes(sumidx).block,'label',['headsum' num2str(m)]); set(NL.nodes(sumidx),'position',[0.5 (m-1)*vlocoffset+3*vlocfactor 0.5 (m-1)*vlocoffset+3*vlocfactor]); set(NL.nodes(sumidx).block,'orientation','right'); mainparams(sumidx)=filtgraph.indexparam(sumidx,'++|'); end [NL, PrevIPorts, PrevOPorts, NextIPorts, NextOPorts, mainparams]=firdecimheadconnect(q,NL,H,mainparams,decim_order); % Generate the stage. Head = filtgraph.stage(NL,PrevIPorts,PrevOPorts,NextIPorts,NextOPorts,mainparams); % -------------------------------------------------------------- % % body: Generate the conceptual repeating body stage for the % Direct Form I architecture % Returns a filtgraph.stage, % -------------------------------------------------------------- function Body = body(num,decim_order,H,info,q) % Construct the first layer, structure specific NL=filtgraph.nodelist(4*decim_order-1); vlocfactor = 1/(4*decim_order+1); % to fit everything into one grid. The grid is enlarged using gridGrowingFactor vlocoffset = 4*vlocfactor; repnum = info.nstages-4; % repetitive stage numbers % Main parameters of sum blocks for stage = 1:repnum sum_str{stage}='++|'; end % Specify coefficient names nglbl = cell(decim_order,repnum); if info.doMapCoeffsToPorts for m=1:decim_order for stage = 1:repnum nglbl{m,stage} = sprintf('%s%d',info.coeffnames{1},stage*decim_order+m); end end end % connectors & gains for m=1:decim_order %gain gainidx = m; %calculate the node index in the node list NL.setnode(filtgraph.node('gain'),gainidx); set(NL.nodes(gainidx).block,'label',['bodygain' num2str(m)]); set(NL.nodes(gainidx),'position',[0.5 (m-1)*vlocoffset+vlocfactor 0.5 (m-1)*vlocoffset+vlocfactor]); %gain aligned backwards set(NL.nodes(gainidx).block,'orientation','down'); ng = {'0'}; for stage = 1:repnum ng{stage} = NL.coeff2str(num,stage*decim_order+m); %delay state information stateidx = stage*decim_order - m+1; delay_str{stage} = ['1,' mat2str(info.states(stateidx,:))]; end mainparams(gainidx)=filtgraph.indexparam(gainidx,ng,nglbl(m,:)); %sum sumidx = decim_order + m; NL.setnode(filtgraph.node('sum'),sumidx); set(NL.nodes(sumidx).block,'label',['bodysum(' num2str(m) ')']); set(NL.nodes(sumidx),'position',[0.5 (m-1)*vlocoffset+3*vlocfactor 0.5 (m-1)*vlocoffset+3*vlocfactor]); set(NL.nodes(sumidx).block,'orientation','right'); mainparams(sumidx)=filtgraph.indexparam(sumidx,sum_str); %delay delayidx = 2*decim_order+m; NL.setnode(filtgraph.node('delay'),delayidx); set(NL.nodes(delayidx).block,'label',['bodydelay(' num2str(m) ')']); set(NL.nodes(delayidx),'position',[0.2 (m-1)*vlocoffset 0.2 (m-1)*vlocoffset]); set(NL.nodes(delayidx).block,'orientation','right'); mainparams(delayidx)=filtgraph.indexparam(delayidx,delay_str); %connectors if m < decim_order connidx = 3*decim_order + m; NL.setnode(filtgraph.node('connector'),connidx); set(NL.nodes(connidx),'position',[0.2 m*vlocoffset-vlocfactor 0.2 m*vlocoffset-vlocfactor]); mainparams(connidx)=filtgraph.indexparam(connidx,{}); end end % Set extra parameters like fixed point attributes. Also defines the extra % blocks needed for fixed point model. Connection among nodes will be % generated in this function. The interstage connection is also specified % here. [NL, PrevIPorts, PrevOPorts, NextIPorts, NextOPorts, mainparams]=firdecimbodyconnect(q,NL,H,mainparams,decim_order); % The number of repetitions bstages = info.nstages - 4; Body = filtgraph.stage(NL, PrevIPorts, PrevOPorts,... NextIPorts, NextOPorts, mainparams, [], bstages); % -------------------------------------------------------------- % % footer: Generate the conceptual footer stage for Direct Form I % architecture % % Returns a filtgraph.stage, % -------------------------------------------------------------- function Foot = footer(num,decim_order,H,info,q) % Generate the last layer of the structure. % Construct the first layer, structure specific NL=filtgraph.nodelist(3*decim_order); % calculate the appropriate gain coefficients gainstartidx = floor((length(num)-1)/decim_order)*decim_order ; % the start index of gain in this layer vlocfactor = 1/(4*decim_order+1); % to fit everything into one grid. The grid is enlarged using gridGrowingFactor vlocoffset = 4*vlocfactor; % Specify coefficient names nglbl = cell(1,decim_order); if info.doMapCoeffsToPorts for m=1:decim_order nglbl{m} = sprintf('%s%d',info.coeffnames{1},gainstartidx+m); end end repnum = info.nstages-4; % repetitive stage numbers % blocks for m=1:decim_order %gain gainidx = m; %calculate the node index in the node list NL.setnode(filtgraph.node('gain'),gainidx); set(NL.nodes(gainidx).block,'label',['footgain' num2str(m)]); set(NL.nodes(gainidx),'position',[0.5 (m-1)*vlocoffset+vlocfactor 0.5 (m-1)*vlocoffset+vlocfactor]); %gain aligned backwards set(NL.nodes(gainidx).block,'orientation','down'); ng = {'0'}; ng = NL.coeff2str(num,gainstartidx+m); mainparams(gainidx)=filtgraph.indexparam(gainidx,ng,nglbl{m}); %sum sumidx = decim_order + m; NL.setnode(filtgraph.node('sum'),sumidx); set(NL.nodes(sumidx).block,'label',['footsum(' num2str(m) ')']); set(NL.nodes(sumidx),'position',[0.5 (m-1)*vlocoffset+3*vlocfactor 0.5 (m-1)*vlocoffset+3*vlocfactor]); set(NL.nodes(sumidx).block,'orientation','right'); mainparams(sumidx)=filtgraph.indexparam(sumidx,'++|'); %delay state information stateidx = decim_order*(repnum+1) - m+1; delay_str = ['1,' mat2str(info.states(stateidx,:))]; %delay delayidx = 2*decim_order + m; NL.setnode(filtgraph.node('delay'),delayidx); set(NL.nodes(delayidx).block,'label',['footdelay(' num2str(m) ')']); set(NL.nodes(delayidx),'position',[0.2 (m-1)*vlocoffset 0.2 (m-1)*vlocoffset]); set(NL.nodes(delayidx).block,'orientation','right'); mainparams(delayidx)=filtgraph.indexparam(delayidx,delay_str); end [NL, PrevIPorts, PrevOPorts, NextIPorts, NextOPorts, mainparams]=firdecimfootconnect(q,NL,H,mainparams,decim_order); Foot = filtgraph.stage(NL,PrevIPorts,PrevOPorts,NextIPorts,NextOPorts,mainparams); % ------------------------------------ % % output stage % % ------------------------------------ function Outp = outputer(num,decim_order,H,info,q) NL=filtgraph.nodelist(1); % Nodelist NL.setnode(filtgraph.node('output'),1); % label set(NL.nodes(1).block,'label','Output'); % relative position set(NL.nodes(1),'position',[0.5 0.5 0.5 0.5]); % orientation set(NL.nodes(1).block,'orientation','right'); % obtain parameter for the decim commutator mainparams(1)=filtgraph.indexparam(1,{}); [NL, PrevIPorts, PrevOPorts, mainparams]=firdecimoutputconnect(q,NL,H,mainparams,decim_order); Outp = filtgraph.stage(NL,PrevIPorts,PrevOPorts,[],[],mainparams); %--------------------------------------------------------------------------