X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Focs-0.1.3%2Fprs%2Fprs_iff.m;fp=octave_packages%2Focs-0.1.3%2Fprs%2Fprs_iff.m;h=1d3df5de383dc48f8e2ae40a1f80ef0d7ac74431;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/ocs-0.1.3/prs/prs_iff.m b/octave_packages/ocs-0.1.3/prs/prs_iff.m new file mode 100644 index 0000000..1d3df5d --- /dev/null +++ b/octave_packages/ocs-0.1.3/prs/prs_iff.m @@ -0,0 +1,312 @@ +## Copyright (C) 2006,2007,2008 Carlo de Falco +## +## This file is part of: +## OCS - A Circuit Simulator for Octave +## +## OCS is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with OCS; If not, see . +## +## author: Carlo de Falco +## author: Massimiliano Culpo + +## -*- texinfo -*- +## @deftypefn{Function File} @var{outstruct} = prs_iff(@var{name}) +## Parse a netlist in IFF format and produce the system description +## structure @var{outstruct}. +## +## @var{name} is the basename of the CIR and NMS files to +## be parsed. +## +## See the @cite{IFF file format specifications} (distributed together +## with the OCS package) for more details on the file format. +## +## @var{outstruct} has the following fields: +## +## @example +## outstruct = +## @{ +## LCR: struct % the fields of LCR are shown below +## NLC: struct % NLC has the same fields as LCR +## namesn: matrix % numbers of vars named in .nms file +## namess: cell % the names corresponding to the vars above +## totextvar: scalar % the total number of external variables +## totintvar: scalar % the total number of internal variables +## @} +## +## outstruct.LCR = +## outstruct.NLC = +## @{ +## struct array containing the fields: % array has one element per block +## +## func % name of the sbn file corresponding to each block +## section % string parameter to be passed to the sbn files +## nextvar % number of external variables for each element of the block +## vnmatrix % numbers of the external variables of each element +## nintvar % number of internal variables for each element of the block +## osintvar % number of the first internal variable +## npar % number of parameters +## nparnames% number of parameter names +## nrows % number of rows in the block +## parnames % list of parameter names +## pvmatrix % list of parameter values for each element +## +## @} +## @end example +## +## See the @cite{IFF file format specifications} for details about +## the output structures. +## @seealso{prs_spice} +## @end deftypefn + +function outstruct = prs_iff(name) + + ## Check input + if (nargin != 1 || !ischar(name)) + error("prs_iff: wrong input.") + endif + + ## Initialization + version ="0.1b1"; + outstruct = struct("NLC",[],\ + "LCR",[],\ + "totextvar",0); + + ## Open cir file + filename = [name ".cir"]; + if isempty(file_in_path(".",filename)) + error(["prs_iff: .cir file not found:" filename]); + endif + fid = fopen(filename,"r"); + + ## Check version + ## FIXME: this part can be improved a lot!! + line = fgetl(fid); + + if line(1)!="%" + error(["prs_iff: missing version number in file " filename]); + endif + + if ~strcmp(version,sscanf(line(2:end),"%s")); + error(["prs_iff: conflicting version number in file " filename]); + endif + + ndsvec = []; # Vector of circuit nodes + intvar = 0; # Number of internal variables + + ## NLC section + NLCcount = 0; + while !strcmp(line,"END") + + ## Skip comments + while line(1)=="%" + line = fgetl(fid); + endwhile + + if strcmp(line,"END") + break + else + NLCcount++; + endif + + ## parse NLC block + [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar); + + ndsvec = [ndsvec ; \ + outstruct.NLC(NLCcount).vnmatrix(:)]; + + ## skip the newline char after the matrix + line = fgetl(fid); + + ## proceed to next line + line = fgetl(fid); + + endwhile + + ## LCR section + LCRcount = 0; + line = fgetl(fid); + + while (!strcmp(line,"END")) + + ## Skip comments + while line(1)=="%" + line = fgetl(fid); + endwhile + + if strcmp(line,"END") + break + else + LCRcount++; + endif + + ## parse block header + [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar); + + ndsvec = [ndsvec ; \ + outstruct.LCR(LCRcount).vnmatrix(:)]; + + ## skip the newline char after the matrix + line = fgetl(fid); + + ## proceed to next line + line = fgetl(fid); + + endwhile + + ## Set the number of internal and external variables + outstruct.totintvar = intvar; + nnodes = length(unique(ndsvec)); + maxidx = max(ndsvec); + + if nnodes <= (maxidx+1) + ## If the valid file is a subcircuit it may happen + ## that nnodes == maxidx, otherwise nnodes == (maxidx+1) + outstruct.totextvar = max(ndsvec); + else + error("prs_iff: hanging nodes in circuit %s",name); + endif + ## fclose cir file + fclose(fid); + + ## Open nms file + filename = [name ".nms"]; + if isempty(file_in_path(".",filename)) + error(["prs_iff: .nms file not found:" filename]); + endif + fid = fopen(filename,"r"); + + ## Check version + line = fgetl(fid); + + if line(1)~="%" + error(["prs_iff: missing version number in file " filename]); + endif + + if ~strcmp(version,sscanf(line(2:end),"%s")); + error(["prs_iff: conflicting version number in file " filename]); + endif + + ## Initialization + cnt = 1; + outstruct.namesn = []; + outstruct.namess = {}; + nnames = 0; + + while cnt + [nn,cnt] = fscanf(fid,"%d","C"); + [ns,cnt] = fscanf(fid,"%s","C"); + + if cnt + outstruct.namesn(++nnames)=nn; + outstruct.namess{nnames}=ns; + endif + endwhile + + ## fclose nms file + fclose(fid); + +endfunction + + +############################################## +function [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar); + + ## Parse first line of the header and retrieve: + ## 1 - SBN function name + ## 2 - Section + ## 3 - Number of external variables + ## 4 - Number of parameters + [func,section,nextvar,npar] = sscanf(line,"%s %s %g %g","C"); + outstruct.NLC(NLCcount).func = func; + outstruct.NLC(NLCcount).section = section; + outstruct.NLC(NLCcount).nextvar = nextvar; + outstruct.NLC(NLCcount).npar = npar; + ## Parse second line of the header and retrieve: + ## 1 - Number of elements of this type + ## 2 - Number of parameter names to be parsed + [nrows,nparnames] = fscanf(fid,"%g %g","C"); + outstruct.NLC(NLCcount).nrows = nrows; + outstruct.NLC(NLCcount).nparnames = nparnames; + outstruct.NLC(NLCcount).parnames = {}; + for ii=1:nparnames + outstruct.NLC(NLCcount).parnames{ii} = fscanf(fid,"%s","C"); + endfor + + ## Parse the matrix containing the values of parameters + [outstruct.NLC(NLCcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])'; + + ## Parse the connectivity matrix + [outstruct.NLC(NLCcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])'; + + ## Compute internal variables cycling over each + ## element in the section + for iel = 1:nrows + [a,b,c] = feval(func,section,outstruct.NLC(NLCcount).pvmatrix(iel,:),\ + outstruct.NLC(NLCcount).parnames,zeros(nextvar,1),[],0); + + ## FIXME: if all the element in the same section share the + ## same number of internal variables, the for cycle can be + ## substituted by only one call + outstruct.NLC(NLCcount).nintvar(iel) = columns(a) - outstruct.NLC(NLCcount).nextvar; + outstruct.NLC(NLCcount).osintvar(iel) = intvar; + + intvar += outstruct.NLC(NLCcount).nintvar(iel); + endfor + +endfunction + +############################################## +function [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar); + + ## Parse first line of the header and retrieve: + ## 1 - SBN function name + ## 2 - Section + ## 3 - Number of external variables + ## 4 - Number of parameters + [func,section,nextvar,npar] = sscanf(line,"%s %s %g %g","C"); + outstruct.LCR(LCRcount).func = func; + outstruct.LCR(LCRcount).section = section; + outstruct.LCR(LCRcount).nextvar = nextvar; + outstruct.LCR(LCRcount).npar = npar; + ## Parse second line of the header and retrieve: + ## 1 - Number of elements of this type + ## 2 - Number of parameter names to be parsed + [nrows,nparnames] = fscanf(fid,"%g %g","C"); + outstruct.LCR(LCRcount).nrows = nrows; + outstruct.LCR(LCRcount).nparnames = nparnames; + outstruct.LCR(LCRcount).parnames = {}; + for ii=1:nparnames + outstruct.LCR(LCRcount).parnames{ii} = fscanf(fid,"%s","C"); + endfor + + ## Parse the matrix containing the values of parameters + [outstruct.LCR(LCRcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])'; + + ## Parse the connectivity matrix + [outstruct.LCR(LCRcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])'; + + ## Compute internal variables cycling over each + ## element in the section + for iel = 1:nrows + [a,b,c] = feval(func,section,outstruct.LCR(LCRcount).pvmatrix(iel,:),\ + outstruct.LCR(LCRcount).parnames,zeros(nextvar,1),[],0); + + ## FIXME: if all the element in the same section share the + ## same number of internal variables, the for cycle can be + ## substituted by only one call + outstruct.LCR(LCRcount).nintvar(iel) = columns(a) - outstruct.LCR(LCRcount).nextvar; + outstruct.LCR(LCRcount).osintvar(iel) = intvar; + + intvar += outstruct.LCR(LCRcount).nintvar(iel); + endfor + +endfunction \ No newline at end of file