1 ## Copyright (C) 2006,2007,2008 Carlo de Falco
3 ## This file is part of:
4 ## OCS - A Circuit Simulator for Octave
6 ## OCS is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation.
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with OCS; If not, see <http://www.gnu.org/licenses/>.
18 ## author: Carlo de Falco <cdf _AT_ users.sourceforge.net>
19 ## author: Massimiliano Culpo <culpo _AT_ users.sourceforge.net>
22 ## @deftypefn{Function File} @var{outstruct} = prs_iff(@var{name})
23 ## Parse a netlist in IFF format and produce the system description
24 ## structure @var{outstruct}.
26 ## @var{name} is the basename of the CIR and NMS files to
29 ## See the @cite{IFF file format specifications} (distributed together
30 ## with the OCS package) for more details on the file format.
32 ## @var{outstruct} has the following fields:
37 ## LCR: struct % the fields of LCR are shown below
38 ## NLC: struct % NLC has the same fields as LCR
39 ## namesn: matrix % numbers of vars named in .nms file
40 ## namess: cell % the names corresponding to the vars above
41 ## totextvar: scalar % the total number of external variables
42 ## totintvar: scalar % the total number of internal variables
48 ## struct array containing the fields: % array has one element per block
50 ## func % name of the sbn file corresponding to each block
51 ## section % string parameter to be passed to the sbn files
52 ## nextvar % number of external variables for each element of the block
53 ## vnmatrix % numbers of the external variables of each element
54 ## nintvar % number of internal variables for each element of the block
55 ## osintvar % number of the first internal variable
56 ## npar % number of parameters
57 ## nparnames% number of parameter names
58 ## nrows % number of rows in the block
59 ## parnames % list of parameter names
60 ## pvmatrix % list of parameter values for each element
65 ## See the @cite{IFF file format specifications} for details about
66 ## the output structures.
67 ## @seealso{prs_spice}
70 function outstruct = prs_iff(name)
73 if (nargin != 1 || !ischar(name))
74 error("prs_iff: wrong input.")
79 outstruct = struct("NLC",[],\
84 filename = [name ".cir"];
85 if isempty(file_in_path(".",filename))
86 error(["prs_iff: .cir file not found:" filename]);
88 fid = fopen(filename,"r");
91 ## FIXME: this part can be improved a lot!!
95 error(["prs_iff: missing version number in file " filename]);
98 if ~strcmp(version,sscanf(line(2:end),"%s"));
99 error(["prs_iff: conflicting version number in file " filename]);
102 ndsvec = []; # Vector of circuit nodes
103 intvar = 0; # Number of internal variables
107 while !strcmp(line,"END")
114 if strcmp(line,"END")
121 [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar);
124 outstruct.NLC(NLCcount).vnmatrix(:)];
126 ## skip the newline char after the matrix
129 ## proceed to next line
138 while (!strcmp(line,"END"))
145 if strcmp(line,"END")
151 ## parse block header
152 [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar);
155 outstruct.LCR(LCRcount).vnmatrix(:)];
157 ## skip the newline char after the matrix
160 ## proceed to next line
165 ## Set the number of internal and external variables
166 outstruct.totintvar = intvar;
167 nnodes = length(unique(ndsvec));
168 maxidx = max(ndsvec);
170 if nnodes <= (maxidx+1)
171 ## If the valid file is a subcircuit it may happen
172 ## that nnodes == maxidx, otherwise nnodes == (maxidx+1)
173 outstruct.totextvar = max(ndsvec);
175 error("prs_iff: hanging nodes in circuit %s",name);
181 filename = [name ".nms"];
182 if isempty(file_in_path(".",filename))
183 error(["prs_iff: .nms file not found:" filename]);
185 fid = fopen(filename,"r");
191 error(["prs_iff: missing version number in file " filename]);
194 if ~strcmp(version,sscanf(line(2:end),"%s"));
195 error(["prs_iff: conflicting version number in file " filename]);
200 outstruct.namesn = [];
201 outstruct.namess = {};
205 [nn,cnt] = fscanf(fid,"%d","C");
206 [ns,cnt] = fscanf(fid,"%s","C");
209 outstruct.namesn(++nnames)=nn;
210 outstruct.namess{nnames}=ns;
220 ##############################################
221 function [outstruct,intvar] = parseNLCblock(fid,line,outstruct,NLCcount,intvar);
223 ## Parse first line of the header and retrieve:
224 ## 1 - SBN function name
226 ## 3 - Number of external variables
227 ## 4 - Number of parameters
228 [func,section,nextvar,npar] = sscanf(line,"%s %s %g %g","C");
229 outstruct.NLC(NLCcount).func = func;
230 outstruct.NLC(NLCcount).section = section;
231 outstruct.NLC(NLCcount).nextvar = nextvar;
232 outstruct.NLC(NLCcount).npar = npar;
233 ## Parse second line of the header and retrieve:
234 ## 1 - Number of elements of this type
235 ## 2 - Number of parameter names to be parsed
236 [nrows,nparnames] = fscanf(fid,"%g %g","C");
237 outstruct.NLC(NLCcount).nrows = nrows;
238 outstruct.NLC(NLCcount).nparnames = nparnames;
239 outstruct.NLC(NLCcount).parnames = {};
241 outstruct.NLC(NLCcount).parnames{ii} = fscanf(fid,"%s","C");
244 ## Parse the matrix containing the values of parameters
245 [outstruct.NLC(NLCcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])';
247 ## Parse the connectivity matrix
248 [outstruct.NLC(NLCcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])';
250 ## Compute internal variables cycling over each
251 ## element in the section
253 [a,b,c] = feval(func,section,outstruct.NLC(NLCcount).pvmatrix(iel,:),\
254 outstruct.NLC(NLCcount).parnames,zeros(nextvar,1),[],0);
256 ## FIXME: if all the element in the same section share the
257 ## same number of internal variables, the for cycle can be
258 ## substituted by only one call
259 outstruct.NLC(NLCcount).nintvar(iel) = columns(a) - outstruct.NLC(NLCcount).nextvar;
260 outstruct.NLC(NLCcount).osintvar(iel) = intvar;
262 intvar += outstruct.NLC(NLCcount).nintvar(iel);
267 ##############################################
268 function [outstruct,intvar] = parseLCRblock(fid,line,outstruct,LCRcount,intvar);
270 ## Parse first line of the header and retrieve:
271 ## 1 - SBN function name
273 ## 3 - Number of external variables
274 ## 4 - Number of parameters
275 [func,section,nextvar,npar] = sscanf(line,"%s %s %g %g","C");
276 outstruct.LCR(LCRcount).func = func;
277 outstruct.LCR(LCRcount).section = section;
278 outstruct.LCR(LCRcount).nextvar = nextvar;
279 outstruct.LCR(LCRcount).npar = npar;
280 ## Parse second line of the header and retrieve:
281 ## 1 - Number of elements of this type
282 ## 2 - Number of parameter names to be parsed
283 [nrows,nparnames] = fscanf(fid,"%g %g","C");
284 outstruct.LCR(LCRcount).nrows = nrows;
285 outstruct.LCR(LCRcount).nparnames = nparnames;
286 outstruct.LCR(LCRcount).parnames = {};
288 outstruct.LCR(LCRcount).parnames{ii} = fscanf(fid,"%s","C");
291 ## Parse the matrix containing the values of parameters
292 [outstruct.LCR(LCRcount).pvmatrix] = fscanf(fid,"%g",[npar,nrows])';
294 ## Parse the connectivity matrix
295 [outstruct.LCR(LCRcount).vnmatrix] = fscanf(fid,"%g",[nextvar,nrows])';
297 ## Compute internal variables cycling over each
298 ## element in the section
300 [a,b,c] = feval(func,section,outstruct.LCR(LCRcount).pvmatrix(iel,:),\
301 outstruct.LCR(LCRcount).parnames,zeros(nextvar,1),[],0);
303 ## FIXME: if all the element in the same section share the
304 ## same number of internal variables, the for cycle can be
305 ## substituted by only one call
306 outstruct.LCR(LCRcount).nintvar(iel) = columns(a) - outstruct.LCR(LCRcount).nextvar;
307 outstruct.LCR(LCRcount).osintvar(iel) = intvar;
309 intvar += outstruct.LCR(LCRcount).nintvar(iel);