1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail : mailto:alliance-users@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 /*******************************************************************************
25 * mbk : vti parser netlist view : hns & fne formats v4r11 *
26 * *
27 * Based upon material provided by Alain Greiner in 1990, in lex and yacc *
28 * *
29 * version 0.0 written by Hichang Li in june 1991 under the supervision of *
30 * Frederic Petrot *
31 * version n.x is a rewitting and update of version 0.0 written by Frederic *
32 * Petrot on september 1991 *
33 * *
34 * New versions are mostly bug corrections, or standardization matters and are *
35 * done by Frederic Petrot, since middle 1990. *
36 * *
37 * Rc nets support done by Gregoire Avot on April 1997. *
38 * *
39 * *
40 * version : 4.12 *
41 * date : 12/06/1998 *
42 * *
43 * $Log: parse_vti_l.c,v $
44 * Revision 1.5 2012/05/14 14:20:26 alliance
45 * Updated GNU/FSF address (patch from Thibault North).
46 *
47 * Revision 1.4 2006/03/29 17:10:46 xtof
48 * * gcc4 compatible : no cast like (Foo*)bar=foo; use bar=(Bar*)foo;
49 *
50 * * ALLIANCE_CFLAGS not added anymore to CFLAGS or CXXFLAGS
51 * by alliance.m4 -> must be added explicitely in each
52 * Makefile.am
53 *
54 * * remove configure.in (generated by autostuff)
55 *
56 * Revision 1.3 2002/09/30 16:21:00 czo
57 * support/users
58 *
59 * Revision 1.2 2002/03/14 12:34:30 fred
60 * Using new headers
61 * *
62 * *
63 *******************************************************************************/
64
65 #ident "@(#)vti logical views parser version 4.04"
66
67 #include <ctype.h>
68 #include <string.h>
69 #include <stdlib.h>
70 #include <math.h>
71 #include <mut.h>
72 #include <mlo.h>
73 #include <mlu.h>
74 #include <rcn.h>
75
76 #define LSIZE 16384 /* max line size for vfgets */
77
78 enum {SYNTAX_ERROR, NET_ERROR, OPEN_ERROR, PARSE_ERROR, CLOSE_ERROR,
79 NAME_ERROR, CON_SIGDIF, BAD_JOIN};
80
81 /* rcnet support */
82 struct hns_X {
83 struct hns_X *NEXT;
84 long idx;
85 long rcn;
86 } ;
87
88 struct hns_I {
89 struct hns_I *NEXT;
90 long idx;
91 loins_list *ins;
92 long rcn;
93 } ;
94
95 struct hns_P {
96 struct hns_P *NEXT;
97 long idx;
98 losig_list *sig;
99 long rcn;
100 } ;
101
102 /* flag :
103 1 : node1 = hns_X
104 2 : node1 = hns_I
105 4 : node1 = hns_P
106 8 : node2 = hns_X
107 16 : node2 = hns_I
108 32 : node2 = hns_P
109 */
110 struct hns_W {
111 struct hns_W *NEXT;
112 long flag;
113 void *node1;
114 void *node2;
115 float r;
116 float c;
117 } ;
118
119 struct hns_X *HNS_X=NULL;
120 struct hns_I *HNS_I=NULL;
121 struct hns_P *HNS_P=NULL;
122 struct hns_W *HNS_W=NULL;
123 chain_list *FREE_HNS=NULL;
124
125 #define HNSRCN 53432
126 #define HNSRCNIDX 53433
127 #define HNSPHCON 53434
128 #define HNSRCNX 53435
129 #define HNSRCNI 53436
130
131 static void buildrcn __P(( lofig_list* ));
132 static struct hns_I* givehnsi __P(( lofig_list*, int, loins_list* ));
133 static struct hns_X* givehnsx __P(( lofig_list*, int ));
134 static struct hns_P* givehnsp __P(( losig_list*, int ));
135 static struct hns_I* add_hns_I __P(( void ));
136 static struct hns_X* add_hns_X __P(( void ));
137 static struct hns_P* add_hns_P __P(( void ));
138 static struct hns_W* add_hns_W __P(( void ));
139 static void del_hns_X __P(( struct hns_X* ));
140 /* static void del_hns_P __P(( struct hns_P* )); */
141 static void del_hns_I __P(( struct hns_I* ));
142 static void del_hns_W __P(( struct hns_W* ));
143 /* static void movehnsw __P(( losig_list*, losig_list* )); */
144 static float stof __P(( char* ));
145 static losig_list* givelosigalias __P(( lofig_list*, chain_list*, int ));
146 static int compare_alias_join __P(( lofig_list*, chain_list*, chain_list** ));
147 static int traite_join __P(( lofig_list*, chain_list* ));
148 static void msg_err __P(( lofig_list*, chain_list* ));
149 /* static void debug __P(( lofig_list* )); */
150
151
152 /*******************************************************************************
153 * hns_error : generic error routine for vtiloadlofig function *
154 *******************************************************************************/
hns_error(type,name,line,string,parameter)155 static void hns_error(type, name, line, string, parameter)
156 int type;
157 long line, parameter;
158 char *name, *string;
159 {
160 (void)fflush(stdout);
161 (void)fprintf(stderr, "*** mbk error ***\n");
162 switch (type) {
163 case SYNTAX_ERROR :
164 (void)fprintf(stderr, "syntax error");
165 break;
166 case NET_ERROR :
167 (void)fprintf(stderr, "external connector %s on signal %ld",
168 string, parameter);
169 (void)fprintf(stderr, " is internally joined with an other");
170 (void)fprintf(stderr, " external connector with an other name");
171 break;
172 case OPEN_ERROR :
173 (void)fprintf(stderr, "can't open file : %s", name);
174 break;
175 case PARSE_ERROR :
176 (void)fprintf(stderr, "abnormal parsing for : %s", name);
177 break;
178 case CLOSE_ERROR :
179 (void)fprintf(stderr, "can't close file : %s", name);
180 break;
181 case NAME_ERROR :
182 (void)fprintf(stderr, "name syntax error");
183 break;
184 case CON_SIGDIF :
185 (void)fprintf(stderr, "two connectors with the same name on two different signals");
186 break;
187 case BAD_JOIN :
188 (void)fprintf(stderr, "join of signal %ld connected on two different external connectors %s",parameter,string);
189 break;
190 }
191 if (line)
192 (void)fprintf(stderr, "\nvtiloadlofig : parsing file %s.%s line %ld\n",
193 name, IN_LO, line);
194 else
195 (void)fprintf(stderr, "\nvtiloadlofig : parsing file %s.%s\n",
196 name, IN_LO);
197 EXIT(1);
198 }
199
200 /*******************************************************************************
201 * vfgets: read a line of a file to a buffer, the line beeing size max or end *
202 * with a \n. In order to properly treat vti line breaks, the -\n pattern is *
203 * recognized and ignored *
204 *******************************************************************************/
vfgets(str,size,iob)205 static char *vfgets(str, size, iob)
206 char *str;
207 int size;
208 FILE *iob;
209 {
210 register char *cs;
211 register int c;
212
213 cs = str;
214 while (--size > 0 && (c = getc(iob)) != EOF) {
215 if ((*(cs++) = c) == '-') {
216 if ((c = getc(iob)) == '\n') {
217 /* avant : *cs-- */
218 cs--;
219 } else
220 (void)ungetc(c ,iob);
221 } else if (c == '\n')
222 break;
223 }
224 *cs = '\0';
225 return (c == EOF && cs == str) ? (char *)NULL : str;
226 }
227
228 /*******************************************************************************
229 * shift : shift a float 3 times to give a long in ascii *
230 *******************************************************************************/
231 #define shift(pt) \
232 if (*(pt + 1) == '\0') { \
233 *pt = '0'; \
234 *(pt + 1) = '0'; \
235 *(pt + 2) = '0'; \
236 *(pt + 3) = '\0'; \
237 } else if (*(pt + 2) == '\0') { \
238 *pt = *(pt + 1); \
239 *(pt + 1) = '0'; \
240 *(pt + 2) = '0'; \
241 *(pt + 3) = '\0'; \
242 } else if (*(pt + 3) == '\0') { \
243 *pt = *(pt + 1); \
244 *(pt + 1) = *(pt + 2); \
245 *(pt + 2) = '0'; \
246 *(pt + 3) = '\0'; \
247 } else { \
248 *pt = *(pt + 1); \
249 *(pt + 1) = *(pt + 2); \
250 *(pt + 2) = *(pt + 3); \
251 *(pt + 3) = '\0'; \
252 }
253
254 /*******************************************************************************
255 * stol : convert a string to a long *
256 *******************************************************************************/
stol(token)257 static long stol(token)
258 char *token;
259 {
260 register char *pt;
261
262 if ((pt = strchr(token, '.')) == (char *)NULL)
263 return (long)(SCALE_X * atol(token));
264 else {
265 shift(pt);
266 return (long)(SCALE_X * atol(token) / 1000);
267 }
268 }
269
270 /*******************************************************************************
271 * stof : convert a string to a float *
272 *******************************************************************************/
stof(token)273 static float stof(token)
274 char *token;
275 {
276 char *end;
277 double f;
278 f = strtod( token, &end );
279 if( end == token )
280 hns_error((int)SYNTAX_ERROR, NULL, (long)0, (char *)NULL, 0L);
281 return( (float)(f) );
282 }
283
284
285 /*******************************************************************************
286 * checkname : check for busses *
287 *******************************************************************************/
checkname(name)288 static char *checkname(name)
289 char *name;
290 {
291 char *s, *t;
292
293 s = t = name;
294 while (*t) {
295 if (*t == '[')
296 *t = ' ';
297 else if (*t == ']')
298 {
299 if (*(++t) == '\0') /* ok, it's finished */
300 goto end;
301 else if (*t == '[') /* multiple array */
302 continue;
303 }
304 *s++ = *t++;
305 }
306 end:
307 *s = '\0';
308 return name;
309 }
310
311 /*******************************************************************************
312 * function env() *
313 *******************************************************************************/
env(tn,tp)314 static void env(tn, tp)
315 char *tn, *tp;
316 {
317 char *s, *mbkgetenv();
318
319 s = mbkgetenv("MBK_VTI_TN");
320 *tn = s ? *s : 'e';
321 if (islower((int)*tn))
322 *tn = toupper(*tn);
323 s = mbkgetenv("MBK_VTI_TP");
324 *tp = s ? *s : 'p';
325 if (islower((int)*tp))
326 *tp = toupper(*tp);
327 }
328
329
330 /*******************************************************************************
331 * logical parser : vti2mbk *
332 *******************************************************************************/
parse(fig,mode,in,fname)333 static int parse(fig, mode, in, fname)
334 lofig_list *fig;
335 char mode;
336 FILE *in;
337 char *fname;
338 {
339 char line[LSIZE+1];
340 char *t1, *t2, *t3, *t4, *t5; /* pointers to token on a line */
341 char *t6, *t7, *t8, *t9, *t10, *t11; /* of vti file */
342 char s[100]; /* intermediate string to process tokens */
343 long l1, l2, l3, l4; /* results from strtol */
344 float f; /* only used for capacitances */
345 lofig_list *model = (lofig_list *)NULL; /* must be initialized */
346 num_list *ylist = (num_list *)NULL; /* must be initialized */
347 long i = 1L; /* line number */
348 static char tn, tp;
349 losig_list *cursig = NULL; /* current signal for wire */
350 ptype_list *ptl;
351 chain_list *head_join;
352 chain_list *head_sigalias;
353 losig_list *sigct1,*sigct2;
354
355 head_join = head_sigalias = NULL;
356
357 if (!tn) /* or tp, who cares? */
358 env(&tn, &tp);
359
360 while (1) {
361 i++;
362 if (vfgets(line, LSIZE, in) == (char *)NULL)
363 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
364 switch (line[0]) {
365 case '#' : /* comment */
366 case '\{' : /* comment */
367 case ' ' : /* empty line in vti file */
368 case ';' : /* empty line in vti file */
369 case 'A' :
370 case 'B' :
371 break;
372 case 'C' : /* C INT NOP NOP cap INT INT ; */
373 if (mode != 'P') {
374 loctc_list *ptctc;
375
376 t1 = strtok(line + 2, " \n\t\"");
377 l1 = atol(t1);
378 t2 = strtok((char *)NULL, " \n\t\"");
379 t3 = strtok((char *)NULL, " \n\t\"");
380 t4 = strtok((char *)NULL, " \n\t\"");
381 (void)strcpy(s, t4);
382 f = atof(s);
383 t5 = strtok((char *)NULL, " \n\t\"");
384 l3 = atol(t5);
385 t6 = strtok((char *)NULL, " \n\t\"");
386 l4 = atol(t6);
387 /* capacitance :
388 units are picofarads inside vti logical formats.
389 add capacitance on both signals.
390 0 is a linear, wire, capacitance,
391 1 is a grid capacitance,
392 2-5 are sidewall and surface diffusion capacitances
393 6 is diaphonic capacitances. */
394 if (l1 != 1) {
395
396 sigct1 = givelosigalias(fig, head_sigalias, (long)l3);
397 sigct2 = givelosigalias(fig, head_sigalias, (long)l4);
398
399 if( !sigct1->PRCN )
400 addlorcnet( sigct1 );
401
402 if( !sigct2->PRCN )
403 addlorcnet( sigct2 );
404
405 if( ( ptctc = getloctc( sigct1, 0, sigct2, 0 ) ) )
406 ptctc->CAPA = ptctc->CAPA + f;
407 else
408 addloctc( sigct1, 0, sigct2, 0, f );
409
410 addcapa( sigct1, f );
411 addcapa( sigct2, f );
412 }
413 }
414 break;
415 case 'E': /* E ; */
416 {
417 locon_list *c1;
418 ptype_list *ptl;
419 num_list *pn;
420 lofig_list *ptmodel;
421 struct hns_X *effx;
422 struct hns_X *effscanx;
423 chain_list *scan_head_join;
424 losig_list *ptsig;
425 locon_list *ptcon;
426
427 lofigchain( fig );
428
429 for (c1 = fig->LOCON; c1; c1 = c1->NEXT) {
430 ptl = getptype(c1->USER,HNSRCN);
431 ptl->DATA = reverse( ptl->DATA );
432 }
433
434 if( !compare_alias_join( fig, head_sigalias, &head_join ) ) {
435 hns_error((int)CON_SIGDIF, fname, (long)i, (char *)NULL, 0L);
436 }
437
438 if( !traite_join( fig, head_join ) ) {
439 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
440 }
441
442 /* Comme la fonction traite_join peut avoir deplacer des connecteurs ( passe d'un signal a un autre ), on refait un lofigchain
443 pour tout remettre a jour. Le lofigchain fait un nettoyage prealable, donc pas de problemes... */
444
445 lofigchain(fig);
446
447 /* On nettoie les join */
448 for( scan_head_join = head_join; scan_head_join; scan_head_join = scan_head_join->NEXT ) {
449 freechain( (chain_list*)(scan_head_join->DATA) );
450 }
451 freechain( head_join );
452
453 /* destroy the trhu routes connectors and signals */
454 for (pn = ylist; pn; pn = pn->NEXT)
455 {
456 ptsig = getlosig( fig, pn->DATA );
457 ptl = getptype( ptsig->USER, LOFIGCHAIN );
458 if( !ptl->DATA )
459 dellosig( fig, pn->DATA );
460 else
461 {
462 ptcon = (locon_list*)(((chain_list*)(ptl->DATA))->DATA);
463 if( !((chain_list*)(ptl->DATA))->NEXT && ptcon->ROOT == fig )
464 {
465 if( (ptl = getptype( ptcon->USER, HNSRCN )) )
466 {
467 freechain( (chain_list*)(ptl->DATA) );
468 ptcon->USER = delptype( ptcon->USER, HNSRCN );
469 }
470 dellocon( fig, ptcon->NAME );
471 /*
472 for (delete = &fig->LOCON; *delete != NULL; )
473 if ((*delete)->SIG->INDEX == pn->DATA)
474 {
475 c1 = (*delete)->NEXT;
476 if( (ptl = getptype( (*delete)->USER,HNSRCN )))
477 {
478 freechain( (chain_list*)(ptl->DATA));
479 (*delete)->USER = delptype( (*delete)->USER, HNSRCN );
480 }
481 mbkfree((void *)*delete);
482 *delete = c1;
483 }
484 else
485 delete = &(*delete)->NEXT;
486 */
487
488 dellosig( fig, pn->DATA );
489 }
490 else
491 {
492 fprintf( stderr, "*** mbkvti warning : Can't delete thru routes %ld.\n", ptsig->INDEX );
493 }
494 }
495 }
496
497 freenum(ylist);
498
499 buildrcn(fig);
500
501 for( ptmodel = model ; ptmodel; ptmodel = ptmodel->NEXT ) {
502 freechain( (chain_list*)( getptype(ptmodel->USER, HNSPHCON)->DATA ) );
503 for(c1 = ptmodel->LOCON; c1; c1 = c1->NEXT ) {
504 effx = NULL;
505 for( effscanx = (struct hns_X*)( getptype( c1->USER,HNSRCN )->DATA );
506 effscanx; effscanx = effscanx->NEXT ) {
507 if( effx )
508 del_hns_X(effx);
509 effx = effscanx;
510 }
511 if( effx )
512 del_hns_X(effx);
513 c1->USER = delptype(c1->USER, HNSRCN);
514 }
515 }
516 freelomodel(model);
517
518 /* successfull exit */
519 return 0;
520 }
521 case 'G' : /* G INT name ; */
522 if (mode != 'P') {
523 losig_list *ptsig;
524 t1 = strtok(line + 2, " \n\t\"@");
525 l1 = atol(t1);
526 t2 = strtok((char *)NULL, " \n\t\"@;");
527 for (ptsig = fig->LOSIG; ptsig; ptsig = ptsig->NEXT)
528 if (ptsig->INDEX == (long)l1) {
529 ptsig->NAMECHAIN = addchain(ptsig->NAMECHAIN,(void *)namealloc(checkname(t2)));
530 break;
531 }
532 if (ptsig == (losig_list *)NULL)
533 (void)addlosig(fig, (long)l1, addchain((chain_list *)NULL,
534 (void *)t2), INTERNAL);
535 }
536 break;
537 case 'H' : /* H INT ; */
538 break;
539 case 'I' : /* I name name name | numlist | numlist ; */
540 if (mode != 'P') {
541 num_list *pnlist1 = (num_list *)NULL, *pnlist2 = (num_list *)NULL;
542 char s2[100];
543 char s3[100];
544
545 if (strchr(line + 2, ';') != (char *)NULL) {
546 t1 = strtok(line + 2, " \n\t\"@");
547 t2 = strtok((char *)NULL, " \n\t\"@");
548 (void)strcpy(s2, t2);
549 t3 = strtok((char *)NULL, " \n\t\"@");
550 (void)strcpy(s3, t3);
551 t4 = strtok((char *)NULL, " \n\t\"@");
552 t5 = strtok((char *)NULL, " \n\t\"@");
553 if (*t5 == '|')
554 pnlist1 = (num_list *)NULL;
555 else {
556 if (*t5 == '*')
557 pnlist1 = addnum((num_list *)NULL, 0L);
558 else
559 pnlist1 = addnum((num_list *)NULL, atol(t5));
560 while (*(t5 = strtok((char *)NULL, " \n\t\"@")) != '|') {
561 if (*t5 == '*')
562 pnlist1 = addnum(pnlist1, 0L);
563 else
564 pnlist1 = addnum(pnlist1, atol(t5));
565 }
566 }
567 t6 = strtok((char *)NULL, " \n\t\"@;");
568 if (t6 == (char *)NULL)
569 pnlist2 = (num_list *)NULL;
570 else {
571 if (*t6 == '*')
572 pnlist2 = addnum((num_list *)NULL, 0L);
573 else
574 pnlist2 = addnum((num_list *)NULL, atol(t6));
575 while ((t6 = strtok((char *)NULL, " \n\t\"@;"))
576 != (char *)NULL) {
577 if (*t6 == '*')
578 pnlist2 = addnum(pnlist2, 0L);
579 else
580 pnlist2 = addnum(pnlist2, atol(t6));
581 }
582 }
583 } else
584 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
585
586 {
587 lofig_list *ptmodel;
588 chain_list *phcon,*ch1,*ch2,*chainsig;
589 num_list *n1,*n2;
590 losig_list *ptsig;
591 locon_list *cm, *ci;
592 loins_list *ptins;
593 struct hns_X *scanx;
594 struct hns_I *newi;
595 chain_list *headi;
596
597 ptmodel = getlomodel(model,s2);
598 phcon = (chain_list*)( (getptype(ptmodel->USER,HNSPHCON))->DATA );
599 pnlist2 = (num_list*)reverse((chain_list*)pnlist2);
600 chainsig = NULL;
601
602 for(ch1 = phcon, n1 = pnlist2; ch1 && n1; ch1 = ch1->NEXT, n1 = n1->NEXT ) {
603 /* Verify all signals on locon are the same */
604 for(ch2 = ch1->NEXT, n2 = n1->NEXT ; ch2 && n2 ; ch2 = ch2->NEXT, n2 = n2->NEXT ) {
605 if( (ch1->DATA == ch2->DATA) && (n1->DATA != n2->DATA) )
606 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char*)NULL, 0L);
607 }
608 /* Get one signal per locon */
609 for(ch2 = phcon; ch2!=ch1; ch2 = ch2->NEXT ) {
610 if(ch2->DATA == ch1->DATA)
611 break;
612 }
613 if(ch1 == ch2) {
614 ptsig = givelosigalias( fig, head_sigalias, n1->DATA );
615 chainsig = addchain(chainsig,(void*)ptsig);
616 }
617 }
618 /* On recupere la liste des signaux dans l'ordre inverse ou ils apparaissent dans le
619 fichier, mais dans l'ordre des connecteurs du modele */
620 ptins = addloins(fig,s3,ptmodel,chainsig);
621 freenum(pnlist2);
622 freenum(pnlist1); /* no more parameters */
623
624 for( cm = ptmodel->LOCON; cm; cm = cm->NEXT) {
625 for( ci = ptins->LOCON; ci; ci = ci->NEXT ) {
626 if( ci->NAME == cm->NAME )
627 break;
628 }
629 headi = NULL;
630 for(scanx=(struct hns_X*)( getptype(cm->USER,HNSRCN)->DATA );
631 scanx;
632 scanx = scanx->NEXT) {
633 newi = givehnsi(fig, scanx->idx,ptins);
634 headi = addchain(headi,newi);
635 }
636 ci->USER = addptype(ci->USER,HNSRCN,headi);
637 }
638 }
639 }
640 break;
641 case 'J' : /* J INT INT ; */
642 {
643 losig_list *s1, *s2;
644 chain_list *scan_head_join1;
645 chain_list *scan_head_join2;
646 chain_list *scan_join;
647
648 t1 = strtok( line + 2, " \n\t\"@" );
649 s1 = givelosig( fig, atol(t1) );
650
651 for( scan_head_join1 = head_join; scan_head_join1 ; scan_head_join1 = scan_head_join1->NEXT ) {
652 for( scan_join = (chain_list*)(scan_head_join1->DATA); scan_join; scan_join = scan_join->NEXT ) {
653 if( s1 == scan_join->DATA )
654 break;
655 }
656 if( scan_join )
657 break;
658 }
659
660 if( ! scan_head_join1 ) {
661 head_join = addchain( head_join, addchain( NULL, s1 ) );
662 scan_head_join1 = head_join;
663 }
664 /* scan_head_join1 est la liste qui contient le premier signal rencontre */
665
666 while( (t1 = strtok( NULL, " \n\t\"@" ) ) )
667 {
668 if( strcmp(t1,";")==0 )
669 break;
670 s2 = givelosig( fig, atol(t1) );
671
672 for( scan_head_join2 = head_join; scan_head_join2 ; scan_head_join2 = scan_head_join2->NEXT ) {
673 for( scan_join = (chain_list*)(scan_head_join2->DATA); scan_join; scan_join = scan_join->NEXT ) {
674 if( s2 == scan_join->DATA )
675 break;
676 }
677 if( scan_join )
678 break;
679 }
680
681 if( !scan_head_join2 ) {
682 scan_head_join1->DATA = addchain( (chain_list*)(scan_head_join1->DATA), s2 );
683 }
684 else
685 if( scan_head_join1 != scan_head_join2 ) {
686 for( scan_join = (chain_list*)(scan_head_join2->DATA); scan_join; scan_join = scan_join->NEXT ) {
687 scan_head_join1->DATA = addchain( (chain_list*)(scan_head_join1->DATA), scan_join->DATA );
688 }
689 freechain( (chain_list*)(scan_head_join2->DATA) );
690 head_join = delchain( head_join, scan_head_join2 );
691 }
692 }
693 }
694 break;
695 case 'M' : /* M name name | strlist | strlist | numlist ; */
696 if (mode != 'P') {
697 chain_list *slist2 = (chain_list *)NULL, *pt;
698 num_list *llist3 = NULL, *ptn;
699 chain_list *ptv;
700 locon_list *ptcon;
701 struct hns_X *headX;
702
703 t1 = strtok(line + 2, " \n\t\"@");
704 t2 = strtok((char *)NULL, " \n\t\"@");
705 (void)strcpy(s, t2);
706 t3 = strtok((char *)NULL, " \n\t\"@"); /* the seperator | */
707
708 if (*t3 != '|')
709 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
710
711 /* the first strlist is to be skipped */
712 do {
713 t4 = strtok((char *)NULL, " \n\t\"@");
714 if (t4 == (char *)NULL)
715 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
716 } while(*t4 != '|');
717
718 /* the second one contains the connectors name and order */
719 t4 = strtok((char *)NULL, " \n\t\"@");
720 while(*t4 != '|') {
721 if (t4 == (char *)NULL)
722 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
723 slist2 = addchain(slist2, (void *)namealloc(checkname(t4)));
724 t4 = strtok((char *)NULL, " \n\t\"@");
725 }
726
727 /* the third one contains the connectors ident */
728 t4 = strtok((char *)NULL, " \n\t\"@");
729 while(*t4 != ';') {
730 if (t4 == (char *)NULL)
731 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
732 llist3 = addnum(llist3,atol(t4));
733 t4 = strtok((char *)NULL, " \n\t\"@");
734 }
735
736 model = addlomodel(model, s);
737 llist3 = (num_list*)reverse((chain_list*)llist3);
738 slist2 = reverse(slist2);
739
740 for (pt = slist2, ptn = llist3; pt && ptn ; pt = pt->NEXT, ptn = ptn->NEXT) {
741
742 headX = add_hns_X();
743 headX->NEXT = NULL;
744 headX->idx = ptn->DATA;
745 headX->rcn = 0;
746
747 for(ptv = slist2; ptv != pt; ptv = ptv->NEXT) {
748 if( pt->DATA == ptv->DATA )
749 break;
750 }
751 if(pt == ptv) {
752 ptcon = addlocon(model, (char *)pt->DATA,(losig_list *)NULL, 'X');
753 ptcon->USER = addptype(ptcon->USER, HNSRCN, headX);
754 }
755 else {
756 ptcon = getlocon(model,(char*)(pt->DATA));
757 ptl = getptype(ptcon->USER,HNSRCN);
758 headX->NEXT = (struct hns_X*)( ptl->DATA );
759 ptl->DATA = headX;
760 }
761 }
762
763 if( pt || ptn )
764 hns_error((int)PARSE_ERROR, fname, (long)i, (char *)NULL, 0L);
765
766 freenum(llist3);
767 model->USER = addptype(model->USER,HNSPHCON,slist2);
768 }
769 break;
770 case 'N' : /* N INT name ; */
771 if (mode != 'P') {
772 losig_list *ptsig;
773 t1 = strtok(line + 2, " \n\t\"@");
774 l1 = atol(t1);
775 t2 = strtok((char *)NULL, " \n\t\"@;");
776 ptsig = givelosigalias(fig, head_sigalias, (long)l1);
777 ptsig->NAMECHAIN = addchain(ptsig->NAMECHAIN,(void *)namealloc(checkname(t2)));
778 cursig = givelosig( fig, (long)l1 );
779 }
780 break;
781 case 'P' : /* P INT name num ; */
782 if (mode != 'C') {
783 t1 = strtok(line + 2, " \n\t\"@");
784 t2 = strtok((char *)NULL, " \n\t\"@");
785 t3 = strtok((char *)NULL, " \n\t\"@;");
786 /* let's keep it, just in case ... */
787 }
788 break;
789
790 case 'T' : /* T name name name num num cap INT INT INT INT ; */
791 if (mode != 'P') {
792 char type;
793 t1 = strtok(line + 2, " \n\t\"@");
794 t2 = strtok((char *)NULL, " \n\t\"@[");
795 t3 = strtok((char *)NULL, " \n\t\"@[,");
796 t4 = strtok((char *)NULL, " \n\t\"@,]");
797 t5 = strtok((char *)NULL, " \n\t\"@]");
798 t6 = strtok((char *)NULL, " \n\t\"@");
799 t7 = strtok((char *)NULL, " \n\t\"@");
800 t8 = strtok((char *)NULL, " \n\t\"@");
801 t9 = strtok((char *)NULL, " \n\t\"@");
802 if (islower((int)*t1))
803 *t1 = toupper(*t1);
804 type = (*t1 == tn) ? TRANSN : TRANSP;
805 (void)strcpy(s, t3);
806 l1 = stol(s);
807 (void)strcpy(s, t4);
808 l2 = stol(s);
809 if ((t10 = strtok((char *)NULL, " \n\t\"@;")) == (char *)NULL) {
810 losig_list *ptgrid;
811 ptgrid = givelosigalias(fig, head_sigalias, atol(t6));
812 (void)addlotrs(fig, type, 0L, 0L,
813 (unsigned short)l1, (unsigned short)l2,
814 0, 0, 0, 0,
815 ptgrid, givelosigalias(fig, head_sigalias, atol(t7)),
816 givelosigalias(fig, head_sigalias, atol(t8)), givelosigalias(fig, head_sigalias, atol(t9) ), NULL);
817 /* do not add grid capacatance anymore
818 (void)addcapa(ptgrid, atof(t5));
819 */
820 }
821 else { /* T name name [num,num] num num cap INT INT INT INT; */
822 losig_list *ptgrid;
823 t11 = strtok((char *)NULL, " \n\t\"@;");
824 ptgrid = givelosigalias(fig, head_sigalias, atol(t8));
825 (void)strcpy(s, t5);
826 l3 = stol(s);
827 (void)strcpy(s, t6);
828 l4 = stol(s);
829 (void)addlotrs(fig, type, l1, l2,
830 (unsigned short)l3, (unsigned short)l4,
831 0, 0, 0, 0,
832 ptgrid, givelosigalias(fig, head_sigalias, atol(t9)),
833 givelosigalias(fig, head_sigalias, atol(t10)), givelosigalias(fig, head_sigalias, atol(t11) ), NULL);
834 /* do not add grid capacatance anymore
835 (void)addcapa(ptgrid, atof(t7));
836 */
837 }
838 }
839 break;
840
841 case 'W' : /* W node1 node2 R C */
842 if (mode != 'P') {
843 char *separ;
844 struct hns_X *pt_X;
845 struct hns_P *pt_P;
846 struct hns_I *pt_I;
847 struct hns_W *pt_W;
848 struct hns_W *head_W;
849
850 separ=" \n\t\"@";
851 ptl = getptype(cursig->USER,HNSRCN);
852 if(!ptl) {
853 cursig->USER = addptype(cursig->USER,HNSRCN,NULL);
854 ptl = cursig->USER;
855 }
856 head_W = ( struct hns_W* )( ptl->DATA );
857
858 pt_W = add_hns_W();
859
860 t1 = strtok(line + 2, separ);
861 if( strcasecmp(t1,"P")==0 ) {
862 t2 = strtok((char*)NULL,separ);
863 l1 = atol(t2);
864 pt_P = givehnsp(cursig, l1);
865 pt_W->flag = pt_W->flag | 4;
866 pt_W->node1 = pt_P;
867 }
868 else
869 if( strcasecmp(t1,"I")==0 ) {
870 t2 = strtok((char*)NULL,separ);
871 t3 = strtok((char*)NULL,separ);
872 l1 = atol(t3);
873
874 pt_I = givehnsi(fig, l1,getloins(fig,t2));
875 pt_W->flag = pt_W->flag | 2;
876 pt_W->node1 = pt_I;
877 }
878 else
879 if( strcasecmp(t1,"X")==0 ) {
880 t2 = strtok((char*)NULL,separ);
881 l1 = atol(t2);
882
883 pt_X = givehnsx(fig, l1);
884 pt_W->flag = pt_W->flag | 1;
885 pt_W->node1 = pt_X;
886 }
887 else {
888 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
889 }
890 t1 = strtok((char*)NULL, separ);
891 if( strcasecmp(t1,"P")==0 ) {
892 t2 = strtok((char*)NULL,separ);
893 l1 = atol(t2);
894
895 pt_P = givehnsp(cursig, l1);
896 pt_W->flag = pt_W->flag | 32;
897 pt_W->node2 = pt_P;
898 }
899 else
900 if( strcasecmp(t1,"I")==0 ) {
901 t2 = strtok((char*)NULL,separ);
902 t3 = strtok((char*)NULL,separ);
903 l1 = atol(t3);
904
905 pt_I = givehnsi(fig, l1,getloins(fig,t2));
906 pt_W->flag = pt_W->flag | 16;
907 pt_W->node2 = pt_I;
908 }
909 else
910 if( strcasecmp(t1,"X")==0 ) {
911 t2 = strtok((char*)NULL,separ);
912 l1 = atol(t2);
913
914 pt_X = givehnsx(fig, l1);
915 pt_W->flag = pt_W->flag | 8;
916 pt_W->node2 = pt_X;
917 }
918 else {
919 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
920 }
921
922 t1 = strtok( NULL, separ);
923 pt_W->r = stof(t1);
924 t1 = strtok( NULL, separ);
925 pt_W->c = stof(t1);
926 pt_W->NEXT = head_W;
927 head_W = pt_W;
928 ptl->DATA = head_W;
929 }
930 break;
931
932 case 'X' : /* X INT bof name ; */
933 {
934 locon_list *ptcon;
935 losig_list *ptsig;
936 losig_list *sig2;
937 char *conname;
938 struct hns_X *headX;
939 ptype_list *ptl;
940 chain_list *scan_head_sigalias, *scan_sigalias;
941
942 t1 = strtok(line + 2, " \n\t\"@");
943 l1 = atol(t1);
944 t2 = strtok((char *)NULL, " \n\t\"@");
945 t3 = strtok((char *)NULL, " \n\t\"@;");
946
947 headX= givehnsx(fig, atol(t2));
948
949 conname = namealloc(checkname(t3));
950
951 /* Chaque locon possede un nom unique */
952
953 for(ptcon = fig->LOCON; ptcon; ptcon = ptcon->NEXT) {
954 if( ptcon->NAME == conname )
955 break;
956 }
957
958 if( ptcon ) {
959 if ( ptcon->SIG->INDEX != l1 ) {
960 sig2 = givelosig(fig, l1);
961 sig2->TYPE = EXTERNAL;
962 for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias = scan_head_sigalias->NEXT ) {
963 for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
964 if( (losig_list*)( scan_sigalias->DATA ) == ptcon->SIG )
965 break;
966 }
967 if( scan_sigalias )
968 break;
969 }
970 if( !scan_head_sigalias ) {
971 /* Attention : l'ordre est important : le signal qui existait avant doit etre
972 en fin de liste */
973 head_sigalias = addchain( head_sigalias, addchain( addchain(NULL,ptcon->SIG), sig2 ));
974 }
975 else {
976 for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
977 if( (losig_list*)( scan_sigalias->DATA ) == sig2 )
978 break;
979 }
980 if( !scan_sigalias ) {
981 scan_head_sigalias->DATA = addchain( (chain_list*)(scan_head_sigalias->DATA), sig2);
982 }
983 }
984 }
985
986 /* Si on est en mode 'C', on peut se retrouver ici sans avoir de ptype */
987 if( mode == 'C' )
988 {
989 ptl = getptype(ptcon->USER,HNSRCN);
990 if( !ptl )
991 {
992 /* C'est la 1ere fois qu'on tombe sur ce locon, on lui enleve tous les connecteurs physiques
993 * qu'il avait */
994 while(ptcon->PNODE)
995 delloconnode( ptcon, ptcon->PNODE->DATA);
996 ptl = ptcon->USER = addptype( ptcon->USER, HNSRCN, NULL );
997 }
998 }
999 else
1000 ptl = getptype(ptcon->USER,HNSRCN);
1001
1002 ptl->DATA = addchain( (chain_list*)(ptl->DATA),headX);
1003 }
1004 else {
1005 /* Si c'est il existe deja un connecteur sur ce signal, le addlosig terminera le programme. */
1006 ptsig = addlosig(fig, (long)l1, addchain((chain_list *)NULL,
1007 (void *)conname), EXTERNAL);
1008 ptcon = addlocon( fig, conname, ptsig, 'X');
1009 ptcon->USER = addptype( ptcon->USER, HNSRCN, addchain(NULL,headX) );
1010 }
1011 }
1012
1013 break;
1014 case 'Y' : /* Y INT INT [ num , num ] [ num , num ] ; */
1015 break;
1016 /* t1 = strtok(line + 2, " \n\t\"@"); */
1017 /* t2 = strtok((char *)NULL, " \n\t\"@;"); */
1018 /* l2 = atol(t2); */
1019 /* ylist = addnum(ylist, l2); /\* create a list of thru routes *\/ */
1020 /* break; */
1021 case 'Z' : /* Z INT name INT cap INT num num ; */
1022 break;
1023 default :
1024 hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
1025 break;
1026 }
1027 }
1028 }
1029
1030 /*******************************************************************************
1031 * unique function accesible from this file *
1032 *******************************************************************************/
vtiloadlofig(ptfig,figname,mode)1033 void vtiloadlofig(ptfig, figname, mode)
1034 lofig_list *ptfig;
1035 char *figname;
1036 char mode;
1037 {
1038 FILE *in;
1039
1040 /* opening file */
1041 if ((in = mbkfopen(figname, IN_LO, READ_TEXT)) == (FILE *)NULL)
1042 hns_error((int)OPEN_ERROR, figname, 0L, (char *)NULL, 0L);
1043
1044 if (TRACE_MODE == 'Y')
1045 (void)printf("\n--- mbk --- parsing file : %s.%s in mode %c\n",
1046 figname, IN_LO, mode);
1047
1048 /* parsing */
1049 if (parse(ptfig, mode, in, figname))
1050 hns_error((int)PARSE_ERROR, figname, 0L, (char *)NULL, 0L);
1051
1052 if (fclose(in))
1053 hns_error((int)CLOSE_ERROR, figname, 0L, (char *)NULL, 0L);
1054
1055 (void)strcpy(PARSER_INFO, "@(#)vti logical views parser version 4.04");
1056 }
1057
add_hns_X()1058 static struct hns_X* add_hns_X()
1059 {
1060 struct hns_X *head;
1061 int i;
1062
1063 if(!HNS_X)
1064 {
1065 HNS_X = (struct hns_X*)mbkalloc(sizeof(struct hns_X)*64);
1066 FREE_HNS = addchain(FREE_HNS,HNS_X);
1067
1068 for(i=0;i<=62;i++)
1069 HNS_X[i].NEXT=&(HNS_X[i+1]);
1070 HNS_X[63].NEXT=NULL;
1071 }
1072 head = HNS_X;
1073 HNS_X = HNS_X->NEXT;
1074
1075 head->NEXT = NULL;
1076 head->idx = 0;
1077 head->rcn = 0;
1078
1079 return(head);
1080 }
1081
del_hns_X(ptx)1082 static void del_hns_X( ptx )
1083 struct hns_X *ptx;
1084 {
1085 ptx->NEXT = HNS_X;
1086 HNS_X = ptx;
1087 }
1088
add_hns_I()1089 static struct hns_I* add_hns_I()
1090 {
1091 struct hns_I *head;
1092 int i;
1093
1094 if(!HNS_I)
1095 {
1096 HNS_I = (struct hns_I*)mbkalloc(sizeof(struct hns_I)*64);
1097 FREE_HNS = addchain(FREE_HNS,HNS_I);
1098
1099 for(i=0;i<=62;i++)
1100 HNS_I[i].NEXT=&(HNS_I[i+1]);
1101 HNS_I[63].NEXT=NULL;
1102 }
1103 head = HNS_I;
1104 HNS_I = HNS_I->NEXT;
1105
1106 head->NEXT = NULL;
1107 head->idx = 0;
1108 head->rcn = 0;
1109 head->ins = NULL;
1110
1111 return(head);
1112 }
1113
del_hns_I(pti)1114 static void del_hns_I( pti )
1115 struct hns_I *pti;
1116 {
1117 pti->NEXT = HNS_I;
1118 HNS_I = pti;
1119 }
1120
add_hns_P()1121 static struct hns_P* add_hns_P()
1122 {
1123 struct hns_P *head;
1124 int i;
1125
1126 if(!HNS_P)
1127 {
1128 HNS_P = (struct hns_P*)mbkalloc(sizeof(struct hns_P)*64);
1129 FREE_HNS = addchain(FREE_HNS,HNS_P);
1130
1131 for(i=0;i<=62;i++)
1132 HNS_P[i].NEXT=&(HNS_P[i+1]);
1133 HNS_P[63].NEXT=NULL;
1134 }
1135 head = HNS_P;
1136 HNS_P = HNS_P->NEXT;
1137
1138 head->NEXT = NULL;
1139 head->idx = 0;
1140 head->sig = NULL;
1141 head->rcn = 0;
1142
1143 return(head);
1144 }
1145
1146 /*
1147 static void del_hns_P( ptp )
1148 struct hns_P *ptp;
1149 {
1150 ptp->NEXT = HNS_P;
1151 HNS_P = ptp;
1152 }
1153 */
1154
add_hns_W()1155 static struct hns_W* add_hns_W()
1156 {
1157 struct hns_W *head;
1158 int i;
1159
1160 if(!HNS_W)
1161 {
1162 HNS_W = (struct hns_W*)mbkalloc(sizeof(struct hns_W)*64);
1163 FREE_HNS = addchain(FREE_HNS,HNS_W);
1164
1165 for(i=0;i<=62;i++)
1166 HNS_W[i].NEXT=&(HNS_W[i+1]);
1167 HNS_W[63].NEXT=NULL;
1168 }
1169 head = HNS_W;
1170 HNS_W = HNS_W->NEXT;
1171
1172 head->NEXT = NULL;
1173 head->flag = 0;
1174 head->node1 = NULL;
1175 head->node2 = NULL;
1176 head->r = 0.0;
1177 head->c = 0.0;
1178
1179 return(head);
1180 }
1181
del_hns_W(ptw)1182 static void del_hns_W( ptw )
1183 struct hns_W *ptw;
1184 {
1185 ptw->NEXT = HNS_W;
1186 HNS_W = ptw;
1187 }
1188
givehnsp(ptsig,index)1189 static struct hns_P* givehnsp( ptsig, index )
1190 losig_list *ptsig;
1191 int index;
1192 {
1193 ptype_list *ptl;
1194 struct hns_P *ptp;
1195 struct hns_W *scanw;
1196
1197 ptl = getptype(ptsig->USER, HNSRCN);
1198 if( !ptl ) {
1199 ptp = add_hns_P();
1200 ptp->idx = index;
1201 ptp->sig = ptsig;
1202 ptp->rcn = 0;
1203 return(ptp);
1204 }
1205
1206 for(scanw = (struct hns_W*)( getptype( ptsig->USER, HNSRCN )->DATA ); scanw; scanw = scanw->NEXT ) {
1207 if(scanw->flag & 4) {
1208 ptp = (struct hns_P*)(scanw->node1);
1209 if( ptp->idx == index && ptp->sig == ptsig )
1210 return(ptp);
1211 }
1212 if(scanw->flag & 32) {
1213 ptp = (struct hns_P*)(scanw->node2);
1214 if( ptp->idx == index && ptp->sig == ptsig )
1215 return(ptp);
1216 }
1217 }
1218 ptp = add_hns_P();
1219 ptp->idx = index;
1220 ptp->sig = ptsig;
1221 ptp->rcn = 0;
1222 return(ptp);
1223 }
1224
givehnsx(ptfig,index)1225 static struct hns_X* givehnsx(ptfig, index)
1226 lofig_list *ptfig;
1227 int index;
1228 {
1229 ptype_list *ptl;
1230 struct hns_X *headx, *scanx;
1231
1232 ptl = getptype( ptfig->USER, HNSRCNX );
1233 if( !ptl ) {
1234 ptfig->USER = addptype( ptfig->USER, HNSRCNX, NULL );
1235 ptl = ptfig->USER;
1236 }
1237 headx = (struct hns_X*)(ptl->DATA);
1238
1239 for( scanx = headx; scanx; scanx = scanx->NEXT ) {
1240 if (scanx->idx == index )
1241 break;
1242 }
1243
1244 if(!scanx) {
1245 scanx = add_hns_X();
1246 scanx->idx = index;
1247 scanx->NEXT = headx;
1248 scanx->rcn = 0;
1249 headx = scanx;
1250 ptl->DATA = headx;
1251 }
1252
1253 return(scanx);
1254 }
1255
givehnsi(ptfig,index,ptins)1256 static struct hns_I* givehnsi(ptfig, index, ptins)
1257 lofig_list *ptfig;
1258 int index;
1259 loins_list *ptins;
1260 {
1261 ptype_list *ptl;
1262 struct hns_I *headi, *scani;
1263
1264 ptl = getptype( ptfig->USER, HNSRCNI );
1265 if( !ptl ) {
1266 ptfig->USER = addptype( ptfig->USER, HNSRCNI, NULL );
1267 ptl = ptfig->USER;
1268 }
1269 headi = (struct hns_I*)(ptl->DATA);
1270
1271 for( scani = headi; scani; scani = scani->NEXT ) {
1272 if (scani->idx == index && scani->ins == ptins)
1273 break;
1274 }
1275
1276 if(!scani) {
1277 scani = add_hns_I();
1278 scani->idx = index;
1279 scani->NEXT = headi;
1280 scani->ins = ptins;
1281 scani->rcn = 0;
1282 headi = scani;
1283 ptl->DATA = headi;
1284 }
1285
1286 return(scani);
1287
1288 }
1289
buildrcn(ptfig)1290 static void buildrcn( ptfig )
1291 lofig_list *ptfig;
1292 {
1293 int index;
1294 losig_list *scanlosig;
1295 ptype_list *ptl;
1296 struct hns_W *headw;
1297 struct hns_W *scanw;
1298 struct hns_W *elem_w;
1299 struct hns_X *elem_x;
1300 struct hns_X *headx;
1301 struct hns_X *scanx;
1302 struct hns_I *elem_i;
1303 struct hns_I *scani;
1304 struct hns_I *headi;
1305 struct hns_P *elem_p;
1306 int n1=0,n2=0;
1307 locon_list *ptcon;
1308 chain_list *scan;
1309 chain_list *head;
1310 chain_list *scanchain;
1311 locon_list *scanlocon;
1312 loins_list *scanloins;
1313 ptype_list *ptl_head;
1314
1315
1316 /* On commence par remplir le champ RCN des structures */
1317 for( scanlosig = ptfig->LOSIG; scanlosig; scanlosig = scanlosig->NEXT ) {
1318
1319 index = 1;
1320 ptl = getptype( scanlosig->USER, HNSRCN );
1321
1322 /* Si on est en mode 'C', il se peut que certains signaux aient herites d'une vue
1323 * RC dans les signaux cree pour les connecteurs */
1324
1325 headw = NULL;
1326
1327 if( ptl ) {
1328
1329 headw = (struct hns_W*)( ptl->DATA );
1330
1331 /* On ne cree les vues RC que si on a des resistances. Tant pis pour les noeuds sur les locons */
1332 if( !scanlosig->PRCN && headw )
1333 addlorcnet(scanlosig);
1334
1335 for( scanw = headw; scanw; scanw = scanw->NEXT ) {
1336
1337 if( scanw->flag & 1 ) {
1338 elem_x = (struct hns_X*)( scanw->node1 );
1339 if( elem_x->rcn == 0 )
1340 elem_x->rcn = index++;
1341 n1 = elem_x->rcn;
1342 }
1343 else if( scanw->flag & 2 ) {
1344 elem_i = (struct hns_I*)( scanw->node1 );
1345 if( elem_i->rcn == 0 )
1346 elem_i->rcn = index++;
1347 n1 = elem_i->rcn;
1348 }
1349 else if( scanw->flag & 4 ) {
1350 elem_p = (struct hns_P*)( scanw->node1 );
1351 if( elem_p->rcn == 0 )
1352 elem_p->rcn = index++;
1353 n1 = elem_p->rcn;
1354 }
1355
1356 if( scanw->flag & 8 ) {
1357 elem_x = (struct hns_X*)( scanw->node2 );
1358 if( elem_x->rcn == 0 )
1359 elem_x->rcn = index++;
1360 n2 = elem_x->rcn;
1361 }
1362 else if( scanw->flag & 16 ) {
1363 elem_i = (struct hns_I*)( scanw->node2 );
1364 if( elem_i->rcn == 0 )
1365 elem_i->rcn = index++;
1366 n2 = elem_i->rcn;
1367 }
1368 else if( scanw->flag & 32 ) {
1369 elem_p = (struct hns_P*)( scanw->node2 );
1370 if( elem_p->rcn == 0 )
1371 elem_p->rcn = index++;
1372 n2 = elem_p->rcn;
1373 }
1374
1375 addlowire( scanlosig, RCN_WIRE_UNKNOW, 0, scanw->r, scanw->c, 0l, 0l, 0l, 0l, n1, n2 );
1376 addcapa( scanlosig, scanw->c );
1377 }
1378 }
1379
1380 ptl = getptype( scanlosig->USER, LOFIGCHAIN );
1381
1382 if( ptl && headw ) {
1383
1384 for( scanchain = (chain_list*)( ptl->DATA ); scanchain; scanchain = scanchain->NEXT ) {
1385
1386 ptcon = (locon_list*)( scanchain->DATA );
1387 ptl_head = getptype( ptcon->USER, HNSRCN );
1388 if( !ptl_head )
1389 continue;
1390
1391 head = (chain_list*)( ptl_head->DATA );
1392 head = reverse(head);
1393
1394 if( ptcon->ROOT == ptfig ) {
1395 for(scan = head; scan; scan = scan->NEXT ) {
1396 elem_x = (struct hns_X*)(scan->DATA);
1397 if( elem_x->rcn == 0 )
1398 elem_x->rcn = index++;
1399 setloconnode( ptcon, elem_x->rcn );
1400 }
1401 }
1402 else {
1403 for(scan = head; scan; scan = scan->NEXT ) {
1404 elem_i = (struct hns_I*)(scan->DATA);
1405 if( elem_i->rcn == 0 )
1406 elem_i->rcn = index++;
1407 setloconnode( ptcon, elem_i->rcn );
1408 }
1409 }
1410 head = reverse(head);
1411 }
1412 }
1413 }
1414
1415 /* Technicien de surface */
1416
1417 for(scanlosig = ptfig->LOSIG; scanlosig; scanlosig = scanlosig->NEXT ) {
1418 ptl = getptype( scanlosig->USER, HNSRCN );
1419 if( ptl ) {
1420 headw = (struct hns_W*)( ptl->DATA );
1421 elem_w = NULL;
1422 for( scanw = headw; scanw; scanw = scanw->NEXT ) {
1423 if( elem_w )
1424 del_hns_W( elem_w );
1425 }
1426 if( elem_w )
1427 del_hns_W( elem_w );
1428 scanlosig->USER = delptype( scanlosig->USER, HNSRCN );
1429 }
1430 }
1431
1432 for(scanlocon = ptfig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1433 freechain( (chain_list*)( getptype(scanlocon->USER,HNSRCN)->DATA ) );
1434 scanlocon->USER = delptype( scanlocon->USER, HNSRCN );
1435 }
1436
1437 for(scanloins = ptfig->LOINS; scanloins; scanloins = scanloins->NEXT ) {
1438 for(scanlocon = scanloins->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1439 freechain( (chain_list*)( getptype(scanlocon->USER,HNSRCN)->DATA ) );
1440 scanlocon->USER = delptype( scanlocon->USER, HNSRCN );
1441 }
1442 }
1443
1444 ptl = getptype( ptfig->USER, HNSRCNX );
1445 if(ptl) {
1446 headx = (struct hns_X*)( ptl->DATA );
1447 elem_x = NULL;
1448 for( scanx = headx; scanx; scanx = scanx->NEXT ) {
1449 if( elem_x )
1450 del_hns_X( elem_x );
1451 elem_x = scanx;
1452 }
1453 if( elem_x )
1454 del_hns_X( elem_x );
1455
1456 ptfig->USER = delptype( ptfig->USER, HNSRCNX );
1457 }
1458
1459 ptl = getptype( ptfig->USER, HNSRCNI );
1460 if(ptl) {
1461 headi = (struct hns_I*)( ptl->DATA );
1462 elem_i = NULL;
1463 for( scani = headi; scani; scani = scani->NEXT ) {
1464 if( elem_i )
1465 del_hns_I( elem_i );
1466 elem_i = scani;
1467 }
1468 if( elem_i )
1469 del_hns_I( elem_i );
1470
1471 ptfig->USER = delptype( ptfig->USER, HNSRCNI );
1472 }
1473 }
1474
1475 /*
1476 static void movehnsw( sig1, sig2)
1477 losig_list *sig1;
1478 losig_list *sig2;
1479 {
1480 ptype_list *ptl;
1481 struct hns_W *headw1;
1482 struct hns_W *headw2;
1483
1484 ptl = getptype( sig1->USER,HNSRCN );
1485 if (!ptl )
1486 headw1 = NULL;
1487 else
1488 headw1 = ( struct hns_W* )( ptl->DATA );
1489
1490 ptl = getptype( sig2->USER,HNSRCN );
1491 if (!ptl )
1492 headw2 = NULL;
1493 else
1494 headw2 = ( struct hns_W* )( ptl->DATA );
1495
1496 if( !headw2 )
1497 return;
1498
1499 if( !headw1 ) {
1500 sig1->USER = addptype( sig1->USER, HNSRCN, headw2 );
1501 }
1502 else {
1503 for( ; headw1->NEXT; headw1 = headw1->NEXT ) ;
1504 headw1->NEXT = headw2;
1505 }
1506 sig2->USER = delptype( sig2->USER, HNSRCN );
1507 }
1508 */
1509 /*
1510 void debug(ptfig)
1511 lofig_list *ptfig;
1512 {
1513 locon_list *scanlocon;
1514 ptype_list *ptl;
1515 chain_list *scanchain;
1516 struct hns_X *elem_x;
1517
1518 printf("##############################################################################################\n");
1519 for( scanlocon = ptfig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1520 printf("Connecteur %s :",scanlocon->NAME);
1521 ptl = getptype(scanlocon->USER,HNSRCN);
1522 if( ptl )
1523 {
1524 for(scanchain = (chain_list*)(ptl->DATA); scanchain; scanchain = scanchain->NEXT ) {
1525 elem_x = (struct hns_X*)(scanchain->DATA);
1526 printf("%ld ", elem_x->idx);
1527 }
1528 }
1529 printf("\n");
1530 }
1531 printf("##############################################################################################\n");
1532 }
1533 */
1534
givelosigalias(ptfig,head_sigalias,n)1535 static losig_list* givelosigalias( ptfig, head_sigalias, n )
1536 lofig_list *ptfig;
1537 chain_list *head_sigalias;
1538 int n;
1539 {
1540 chain_list *scan_head_sigalias;
1541 chain_list *scan_sigalias;
1542 losig_list *ptsig;
1543 losig_list *grpsig;
1544
1545 for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias = scan_head_sigalias->NEXT ) {
1546
1547 for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
1548
1549 ptsig = (losig_list*)( scan_sigalias->DATA );
1550
1551 if( ptsig->INDEX == n ) {
1552 for( ; scan_sigalias->NEXT ; scan_sigalias = scan_sigalias->NEXT );
1553 grpsig = (losig_list*)( scan_sigalias->DATA );
1554 return( grpsig );
1555 }
1556 }
1557 }
1558
1559 return( givelosig( ptfig, n ) );
1560 }
1561
compare_alias_join(fig,head_sigalias,ext_join)1562 static int compare_alias_join( fig, head_sigalias, ext_join )
1563 lofig_list *fig;
1564 chain_list *head_sigalias;
1565 chain_list **ext_join;
1566 {
1567 chain_list *scan_head_sigalias;
1568 chain_list *scan_sigalias;
1569 chain_list *scan_head_join;
1570 chain_list *scan_join;
1571 chain_list *scan_chain;
1572 chain_list *head_new_join;
1573 chain_list *add_to_head_join;
1574 chain_list *head_join;
1575 int manque;
1576 int me;
1577
1578 head_join = *ext_join;
1579
1580 add_to_head_join = NULL;
1581
1582 for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias=scan_head_sigalias->NEXT) {
1583
1584 manque = 0;
1585 me=0;
1586
1587 scan_sigalias = (chain_list*)( scan_head_sigalias ->DATA );
1588
1589 for( scan_head_join = head_join; scan_head_join ; scan_head_join = scan_head_join->NEXT ) {
1590 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1591 if( scan_join->DATA == scan_sigalias->DATA ) {
1592 break;
1593 }
1594 }
1595 if( scan_join )
1596 break;
1597 }
1598
1599 if( !scan_head_join ) {
1600 msg_err( fig, scan_head_sigalias->DATA );
1601 manque = 1;
1602 me = 1;
1603 /*
1604 return(0);
1605 */
1606 }
1607 else {
1608
1609 for( scan_sigalias = scan_sigalias->NEXT; scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
1610 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1611 if ( scan_join->DATA == scan_sigalias->DATA )
1612 break;
1613 }
1614 if( !scan_join )
1615 {
1616 if( me )
1617 msg_err( fig, scan_head_sigalias->DATA );
1618 manque = 1;
1619 me = 1;
1620 /*
1621 return(0);
1622 */
1623 }
1624 }
1625 }
1626
1627 if( manque ) {
1628 /* Il manque un join pour regrouper des signaux */
1629
1630 head_new_join = NULL;
1631
1632 for( scan_sigalias = ((chain_list*)(scan_head_sigalias->DATA));
1633 scan_sigalias;
1634 scan_sigalias = scan_sigalias->NEXT ) {
1635 head_new_join = addchain( head_new_join, scan_sigalias->DATA );
1636 }
1637
1638 for( scan_head_join = head_join; scan_head_join ; scan_head_join = scan_head_join->NEXT ) {
1639 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1640 for( scan_sigalias = ((chain_list*)(scan_head_sigalias->DATA)); scan_sigalias;
1641 scan_sigalias = scan_sigalias->NEXT) {
1642 if( scan_join->DATA == scan_sigalias->DATA ) {
1643 break;
1644 }
1645 }
1646 if( scan_sigalias )
1647 break;
1648 }
1649
1650 /* Si on a trouve au moins un element dans la liste join, on transfert toute la liste join vers la
1651 nouvelle et on supprime l'originale */
1652
1653 if( scan_join ) {
1654 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1655 for( scan_chain = head_new_join; scan_chain; scan_chain = scan_chain->NEXT ) {
1656 if( scan_chain->DATA == scan_join->DATA )
1657 break;
1658 }
1659 if(!scan_chain)
1660 head_new_join = addchain( head_new_join, scan_join->DATA );
1661 }
1662
1663 freechain( (chain_list*)(scan_head_join->DATA) );
1664 scan_head_join->DATA = NULL;
1665 }
1666 }
1667
1668 /* En creant le head_new_join, on a utilise addchain, ce qui inverse l'ordre des signaux */
1669
1670 add_to_head_join = addchain( add_to_head_join, head_new_join );
1671 }
1672 }
1673
1674 if( head_join ) {
1675 for( scan_head_join = head_join; scan_head_join->NEXT ; scan_head_join = scan_head_join->NEXT );
1676 scan_head_join->NEXT = add_to_head_join;
1677 }
1678 else {
1679 head_join = add_to_head_join;
1680 }
1681
1682 *ext_join = head_join;
1683 return( 1 );
1684 }
1685
msg_err(fig,head)1686 static void msg_err(fig, head)
1687 lofig_list *fig;
1688 chain_list *head;
1689 {
1690 locon_list *ptcon = NULL;
1691 losig_list *ptsig;
1692 chain_list *scan,*slf;
1693 ptype_list *ptl;
1694
1695 for( scan = head; scan; scan = scan->NEXT ) {
1696
1697 ptcon = NULL;
1698
1699 ptsig = (losig_list*)(scan->DATA);
1700 ptl = getptype( ptsig->USER, LOFIGCHAIN );
1701
1702 for( slf = (chain_list*)(ptl->DATA) ; slf; slf = slf->NEXT ) {
1703 ptcon = (locon_list*)( slf->DATA );
1704 if(ptcon->ROOT == fig ) {
1705 break;
1706 }
1707 }
1708
1709 if(ptcon)
1710 break;
1711 }
1712
1713 (void)fprintf(stderr,"\n*** mbk warning ***\n");
1714 (void)fprintf(stderr,"no join for signals connected on the connector %s\n\n",ptcon->NAME);
1715 }
1716
1717
traite_join(fig,head_join)1718 static int traite_join( fig, head_join )
1719 lofig_list *fig;
1720 chain_list *head_join;
1721 {
1722 chain_list *scan_head_join, *scan_join;
1723 int trouve;
1724 losig_list *ptsig;
1725 losig_list *grpsig = NULL;
1726 loins_list *scanloins;
1727 lotrs_list *scanlotrs;
1728 locon_list *scanlocon;
1729 locon_list *oldlocon=NULL;
1730 chain_list *scanchain;
1731 ptype_list *ptlsrc;
1732 ptype_list *ptldst;
1733 ptype_list *ptl;
1734 struct hns_W *scanw;
1735 char errmes[256] ;
1736 int externe;
1737 chain_list *nom,*scnom;
1738 loctc_list *ptctc;
1739 losig_list *s1, *s2;
1740 float f;
1741
1742 for( scan_head_join = head_join; scan_head_join; scan_head_join = scan_head_join->NEXT ) {
1743 if( !scan_head_join->DATA )
1744 continue;
1745
1746 /* On commence par verifier qu'il n'y a seulement qu'un signal qui possede des connecteurs.
1747 On en profite egalement pour retrouver le signal qui regroupera les autres ( le dernier
1748 dans la liste des join ) */
1749
1750 trouve = 0;
1751 externe = 0;
1752 nom = NULL;
1753
1754 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1755
1756 ptsig = (losig_list*)(scan_join->DATA);
1757 ptl = getptype( ptsig->USER, LOFIGCHAIN );
1758
1759 if( ptsig->TYPE == EXTERNAL )
1760 externe = 1;
1761
1762 for( scanchain = (chain_list*)(ptl->DATA); scanchain; scanchain = scanchain->NEXT ) {
1763
1764 scanlocon = (locon_list*)( scanchain->DATA );
1765
1766 if( scanlocon->ROOT==fig ) {
1767 if( trouve ) {
1768 sprintf(errmes,"%s and %s",oldlocon->NAME,scanlocon->NAME) ;
1769 hns_error((int)BAD_JOIN, fig->NAME, (long)0,errmes,ptsig->INDEX);
1770 }
1771 trouve = 1;
1772 oldlocon = scanlocon ;
1773 }
1774 }
1775
1776 if( !scan_join->NEXT )
1777 grpsig = ptsig;
1778 }
1779
1780 /* On fait remplace par ptsig tous les signaux de la figure qui apparaissent dans le join */
1781
1782 /* Les connecteurs sur les instances */
1783
1784 for( scanloins = fig->LOINS ; scanloins; scanloins = scanloins->NEXT ) {
1785
1786 for( scanlocon = scanloins->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1787
1788 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1789
1790 if( scan_join->DATA == scanlocon->SIG ) {
1791 scanlocon->SIG = grpsig;
1792 break;
1793 }
1794 }
1795 }
1796 }
1797
1798 /* Les connecteurs de la figure */
1799
1800 for( scanlocon = fig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1801
1802 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1803
1804 if( scan_join->DATA == scanlocon->SIG ) {
1805
1806 scanlocon->SIG = grpsig;
1807 break;
1808 }
1809 }
1810 }
1811
1812 /* Les connecteurs sur les transistors */
1813
1814 for( scanlotrs = fig->LOTRS; scanlotrs; scanlotrs = scanlotrs->NEXT ) {
1815
1816 for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1817
1818 if( scan_join->DATA == scanlotrs->GRID->SIG )
1819 scanlotrs->GRID->SIG = grpsig;
1820
1821 if( scan_join->DATA == scanlotrs->SOURCE->SIG )
1822 scanlotrs->SOURCE->SIG = grpsig;
1823
1824 if( scan_join->DATA == scanlotrs->DRAIN->SIG )
1825 scanlotrs->DRAIN->SIG = grpsig;
1826
1827 if( scan_join->DATA == scanlotrs->BULK->SIG )
1828 scanlotrs->BULK->SIG = grpsig;
1829 }
1830
1831 }
1832
1833 /* On efface les signaux devenus inutiles en transferant les vues RC */
1834
1835 for( scan_join = ((chain_list*)(scan_head_join->DATA)); scan_join; scan_join = scan_join->NEXT ) {
1836 ptsig = (losig_list*)(scan_join->DATA);
1837 if( ptsig != grpsig ) {
1838 if ( ptsig->PRCN )
1839 {
1840 if( !grpsig->PRCN )
1841 addlorcnet( grpsig );
1842 addcapa( grpsig, ptsig->PRCN->CAPA );
1843 }
1844
1845 if( nom ) {
1846 for( scnom = nom ; scnom->NEXT; scnom = scnom->NEXT ) ;
1847 scnom->NEXT = ptsig->NAMECHAIN;
1848 ptsig->NAMECHAIN = NULL;
1849 }
1850 else {
1851 nom = ptsig->NAMECHAIN;
1852 ptsig->NAMECHAIN = NULL;
1853 }
1854
1855 ptlsrc = getptype( ptsig->USER, HNSRCN );
1856 if( ptlsrc ) {
1857 ptldst = getptype( grpsig->USER, HNSRCN );
1858 if( !ptldst ) {
1859 grpsig->USER = addptype( grpsig->USER, HNSRCN, ptlsrc->DATA );
1860 }
1861 else {
1862 for( scanw= (struct hns_W*)( ptlsrc->DATA ); scanw->NEXT; scanw = scanw->NEXT );
1863 scanw->NEXT = (struct hns_W*)( ptldst->DATA );
1864 ptldst->DATA = ptlsrc->DATA;
1865 }
1866 ptsig->USER = delptype( ptsig->USER, HNSRCN );
1867 }
1868
1869 if( ptsig->PRCN )
1870 while( ptsig->PRCN->PCTC )
1871 {
1872 ptctc = (loctc_list*)(ptsig->PRCN->PCTC->DATA);
1873 s1 = ptctc->SIG1 ;
1874 s2 = ptctc->SIG2 ;
1875 f = ptctc->CAPA ;
1876 delloctc( s1, 0, s2, 0 );
1877 if( s1 == ptsig )
1878 s1 = grpsig;
1879 if( s2 == ptsig )
1880 s2 = grpsig;
1881
1882 if( s1 != s2 )
1883 {
1884 ptctc = getloctc( s1, 0, s2, 0 );
1885 if( ptctc )
1886 ptctc->CAPA = ptctc->CAPA + f;
1887 else
1888 addloctc( s1, 0, s2, 0, f );
1889 }
1890 }
1891 dellosig( fig, ptsig->INDEX );
1892 }
1893 }
1894
1895 if( externe )
1896 grpsig->TYPE = EXTERNAL;
1897 else
1898 grpsig->TYPE = INTERNAL;
1899
1900 if( grpsig->NAMECHAIN ) {
1901 for( scnom = grpsig->NAMECHAIN ; scnom->NEXT; scnom = scnom->NEXT ) ;
1902 scnom->NEXT = nom;
1903 }
1904 else {
1905 grpsig->NAMECHAIN = nom;
1906 }
1907 }
1908
1909 return( 1 );
1910 }
1911