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 #ident "$Author: alliance $ $Date: 2012/05/14 14:20:25 $ $Revision: 1.7 $"
25
26 /*******************************************************************************
27 * *
28 * Tool : Spice parser / driver v 7.00 *
29 * Author(s) : Gregoire AVOT *
30 * Updates : March, 18th 1998 *
31 * *
32 *******************************************************************************/
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <math.h>
38 #include <ctype.h>
39
40 #include <mut.h>
41 #include <mlo.h>
42 #include <rcn.h>
43 #include "msl.h"
44 #include "spi_int.h"
45 #include "spi_hash.h"
46 #include "spi_parse.h"
47 #include "spi_msg.h"
48 #include "spi_global.h"
49
50 /* Fonctions dynamiques */
51 static int (*ext_handler)() = NULL;
52 static int (*cmp_handler)() = NULL;
53
54 /* Variables globales MSL */
55 lofig_list *msl_ptfig;
56 int msl_figloaded;
57 char* msl_figname;
58 char* msl_subckt;
59 int msl_line;
60
61 char SPI_SEPAR ;
62 static char *SPI_NETNAME ;
63 char SPI_ONE_NODE_NORC ;
64 char SPI_MERGE ;
65 char SPI_VERBOSE ;
66 char SPI_FILE ;
67 char SPI_CHECK_NAME ;
68 char SPI_AUTO_LOAD ;
69 char SPI_NODE_EQUI_DRIVE ;
70 char SPI_AFF_UNK ;
71
72 /******************************************************************************/
73
spiceloadlofig(ptfig,name,mode)74 void spiceloadlofig(ptfig, name, mode)
75 lofig_list *ptfig;
76 char *name;
77 char mode;
78 {
79 char *env;
80 ginterf *teteinterf;
81 ginterf *effinterf;
82 ginterf *scaninterf;
83 chain_list *scanchain;
84 char *spicename;
85
86 /* Comportement par defaut */
87
88 SPI_SEPAR = '.' ;
89 SPI_NETNAME = "NET" ;
90 SPI_MERGE = 1 ;
91 SPI_VERBOSE = 0 ;
92 SPI_FILE = 0 ;
93 SPI_ONE_NODE_NORC = 0 ;
94 SPI_CHECK_NAME = 0 ;
95 SPI_AUTO_LOAD = 0 ;
96 SPI_NODE_EQUI_DRIVE = 0 ;
97 SPI_AFF_UNK = 1 ;
98
99 spi_init_lang();
100
101 env = mbkgetenv( "MBK_SPI_NETNAME" );
102
103 if( env )
104 SPI_NETNAME = env;
105
106 env = mbkgetenv( "MBK_SPI_SEPAR" );
107
108 if( env )
109 {
110 switch( strlen( env ) )
111 {
112 case 0:
113 SPI_SEPAR = 0;
114 SPI_MERGE = 0;
115 break;
116 case 1:
117 SPI_SEPAR = *env;
118 break;
119 default :
120 fflush( stdout );
121 fprintf( stderr, "%s.\n", SPIMSG(7) );
122 EXIT(1);
123 break;
124 }
125 }
126
127 env = mbkgetenv( "MBK_SPI_CHECK_NAME" );
128
129 if( env )
130 SPI_CHECK_NAME = 1;
131
132 env = mbkgetenv( "MBK_SPI_AUTO_LOAD" );
133
134 if( env )
135 SPI_AUTO_LOAD = 1;
136
137 /* Variables d'environnement cachees */
138
139 /* MBK_SPI_MERGE. Si positionnee, on n'effectue pas
140 * de regroupement de locon sur les noms toto, toto.1, toto.2, toto.3...
141 */
142
143 env = mbkgetenv( "MBK_SPI_MERGE" );
144
145 if( env )
146 SPI_MERGE = 0;
147
148 env = mbkgetenv( "MBK_SPI_FILE" );
149
150 if( env )
151 SPI_FILE = 1;
152
153 env = mbkgetenv( "MBK_SPI_VERBOSE" );
154
155 if( env )
156 SPI_VERBOSE = 1;
157
158 env = mbkgetenv( "MBK_SPI_ONE_NODE_NORC" );
159
160 if( env )
161 SPI_ONE_NODE_NORC = 1;
162
163 env = mbkgetenv( "MBK_SPI_NODE_EQUI_DRIVE" );
164
165 if( env )
166 SPI_NODE_EQUI_DRIVE = 1;
167
168 env = mbkgetenv( "MBK_SPI_NO_AFF_UNK" );
169
170 if( env )
171 SPI_AFF_UNK = 0;
172
173 if( SPI_VERBOSE )
174 {
175 printf( "Parser Spice compile le %s a %s\n", __DATE__, __TIME__ );
176 printf( "Revision : %s\n", "$Revision: 1.7 $" );
177 printf( "Date : %s\n", "$Date: 2012/05/14 14:20:25 $" );
178
179 printf( "Separateur : '%c'\n", SPI_SEPAR );
180 printf( "Nom de noeud : %s\n", SPI_NETNAME );
181 printf( "Regroupement : %s\n", SPI_MERGE ? "Oui" : "Non" );
182 printf( "Noms : %s\n", SPI_CHECK_NAME ? "Oui" : "Non" );
183 printf(
184 "Ne cree pas les vues RC sur les reseaux ne contenant qu'un seul noeud : %s\n",
185 SPI_ONE_NODE_NORC ? "Oui" : "Non"
186 );
187 }
188
189 if( mode != 'A' )
190 {
191 fflush( stdout );
192 fprintf( stderr, "%s\n", SPIMSG(0) );
193 fprintf( stderr, "%s : '%c'\n", SPIMSG(8), mode );
194 EXIT(1);
195 }
196
197 spicename = (char*)mbkalloc( sizeof(char)*( strlen(name)+5 ));
198 sprintf( spicename, "%s.%s", name, IN_LO );
199
200 msl_figname = name;
201 msl_ptfig = NULL;
202
203 teteinterf = NULL;
204
205 teteinterf = spiceloading( ptfig, spicename, mode, teteinterf );
206
207 if( teteinterf )
208 {
209 effinterf = NULL;
210 for( scaninterf = teteinterf; scaninterf ; scaninterf = scaninterf->SUIV )
211 {
212 if( effinterf )
213 {
214 free( effinterf->NOM );
215 for( scanchain = effinterf->GINTERF ;
216 scanchain ;
217 scanchain = scanchain->NEXT )
218 mbkfree( scanchain->DATA );
219 freechain( effinterf->GINTERF );
220 mbkfree( effinterf );
221 }
222 effinterf = scaninterf;
223 }
224 if( effinterf )
225 {
226 free( effinterf->NOM );
227 for( scanchain = effinterf->GINTERF ;
228 scanchain ;
229 scanchain = scanchain->NEXT )
230 mbkfree( scanchain->DATA );
231 freechain( effinterf->GINTERF );
232 mbkfree( effinterf );
233 }
234 }
235
236 mbkfree( spicename );
237 }
238
spifileopen(name)239 spifile* spifileopen( name )
240 char *name;
241 {
242 spifile *pt;
243
244 if( SPI_FILE )
245 {
246 fflush( stdout );
247 fprintf( stderr, "%s : %s\n", SPIMSG(53), name );
248 }
249
250 pt = mbkalloc( sizeof( *pt ) );
251 pt->df = mbkfopen( name, NULL, READ_TEXT );
252 pt->decomp1 = NULL;
253 pt->decomp2 = NULL;
254 pt->filename = name;
255 pt->msl_line = -1;
256 *(pt->file_line) = '\0';
257
258
259 if( ! pt->df )
260 {
261 fflush( stdout );
262 fprintf( stderr, "%s\n", SPIMSG(0) );
263 fprintf( stderr, "%s %s.\n", SPIMSG(9), name );
264 EXIT(1);
265 }
266
267 return( pt );
268 }
269
spifileclose(pt)270 void spifileclose( pt )
271 spifile *pt;
272 {
273 fclose( pt->df );
274
275 if( pt->decomp1 || pt->decomp2 )
276 {
277 fflush( stdout );
278 fprintf( stderr, "%s\n", SPIMSG(0) );
279 fprintf( stderr, "%s.\n", SPIMSG(10) );
280 EXIT(1);
281 }
282
283 mbkfree( pt );
284 }
285
spiceloading(ptfig,name,mode,teteinterf)286 ginterf* spiceloading(ptfig, name, mode, teteinterf )
287 lofig_list *ptfig;
288 char *name;
289 char mode;
290 ginterf *teteinterf;
291 {
292 circuit *ptcir;
293 spifile *df;
294 lofig_list *newfig;
295
296 df = spifileopen( name );
297
298
299 while( ( ptcir = lirecircuit( df, &teteinterf ) ) )
300 {
301 constequi( ptcir, teteinterf );
302 teteinterf = constinterf( ptcir, teteinterf );
303
304 if( SPI_VERBOSE )
305 taillevuespice( ptcir );
306
307 if( ptfig && strcasecmp( ptcir->NOM, ptfig->NAME ) == 0 )
308 {
309 if( SPI_VERBOSE )
310 printf( "Construction figure pere.\n" );
311
312 constlofig( ptcir, ptfig, teteinterf, mode );
313 msl_ptfig = ptfig;
314 ptfig->USER = constphinterf( ptfig->USER, teteinterf );
315 }
316 else
317 {
318 lofig_list *lf;
319 const char *name = namealloc(ptcir->NOM);
320 /* Check that a model has not yet been read, otherwise (wrongly)
321 * assumes that the models having the same name are identical.
322 * I issue a warning because this suck.
323 * I should preprend a prefix and use the prefixed name, but
324 * since it is the first and probably last time that I hack this
325 * code, I'll live with this on my conscience ;-) */
326 for (lf = HEAD_LOFIG; lf ; lf = lf->NEXT) {
327 if (lf->NAME == name) {
328 fprintf(stderr, "Warning: skipping model '%s' as it has already"
329 " been loaded\n", name);
330 goto skip;
331 }
332 }
333
334 /* Si la figure est vide, on ne construit pas la lofig correspondante */
335 if( ptcir->RESI ||
336 ptcir->VALIM ||
337 ptcir->TRANS ||
338 ptcir->CAPA ||
339 ptcir->INST
340 )
341 {
342 if( SPI_VERBOSE )
343 printf( "Construction figure fille %s.\n", ptcir->NOM );
344
345 /* figure fille ou n'ayant rien a voir avec ptfig */
346 newfig = addlofig( ptcir->NOM );
347
348 constlofig( ptcir, newfig, teteinterf, mode );
349 msl_ptfig = newfig;
350 newfig->USER = constphinterf( newfig->USER, teteinterf );
351 }
352 else
353 skip: if( SPI_VERBOSE )
354 printf( "Ne construit pas la figure %s.\n", ptcir->NOM );
355 }
356
357 if( SPI_VERBOSE )
358 printf( "Taille memoire occupee par le subckt %s : %ld\n",
359 ptcir->NOM,
360 ptcir->TAILLE
361 );
362
363 liberecircuit( ptcir );
364 }
365
366 spifileclose( df );
367
368 if( cmp_handler )
369 {
370 msl_figloaded = FALSE;
371 msl_subckt = NULL;
372 msl_line = df->msl_line;
373 cmp_handler();
374 }
375
376 return( teteinterf );
377 }
378
379 /******************************************************************************/
380
constphinterf(pt,interface)381 ptype_list* constphinterf( pt, interface )
382 ptype_list *pt;
383 ginterf *interface;
384 {
385 chain_list *tete_ph_interf;
386 chain_list *scan;
387 char *nomdevec;
388
389 tete_ph_interf=NULL;
390
391 for( scan = interface->GINTERF ; scan ; scan = scan->NEXT )
392 {
393 nomdevec = spi_devect( (char*)(scan->DATA) );
394 tete_ph_interf = addchain( tete_ph_interf, namealloc( nomdevec ) );
395 mbkfree( nomdevec );
396 }
397
398 return( addptype( pt, PH_INTERF, reverse( tete_ph_interf )) );
399 }
400
401 /******************************************************************************/
402
constinterf(ptcir,teteinterf)403 ginterf* constinterf( ptcir, teteinterf )
404 circuit *ptcir;
405 ginterf *teteinterf;
406 {
407 ginterf *ninterf;
408 chain_list *scaninterf;
409 char **tabnom;
410 int i;
411 int nb;
412 noeud *ptnoeud;
413 noeud *scannoeud;
414 char nom[80];
415
416 ninterf = (ginterf*) mbkalloc( sizeof( ginterf ) );
417 ninterf->NOM = mbkstrdup( ptcir->NOM );
418
419 ninterf->SUIV = teteinterf;
420
421 /* On cree pour chaque signal de l'interface une chain_list contenant tous
422 * les noms possibles pour un signal. Pour chaque signal, le nom retenu en
423 * priorite est le premier nomm� sur l'interface */
424
425 /* Calcul du nombre d'elements */
426 nb = 0;
427 for( scaninterf = ptcir->CINTERF ;
428 scaninterf ;
429 scaninterf = scaninterf->NEXT
430 )
431 {
432 ptnoeud = (noeud*) scaninterf->DATA;
433
434 if( ptnoeud->SIGNAL > nb )
435 nb = ptnoeud->SIGNAL;
436 }
437
438 /* Creation du tableau */
439 tabnom = (char**) mbkalloc( sizeof(char*) * nb );
440 for( i = 0 ; i < nb ; i++ )
441 tabnom[ i ] = NULL;
442
443 /* Remplissage du tableau */
444 /* On regarde d'abord l'interface */
445 for( scaninterf = ptcir->CINTERF ;
446 scaninterf ;
447 scaninterf = scaninterf->NEXT
448 )
449 {
450 ptnoeud = (noeud*) scaninterf->DATA;
451 if( ptnoeud->NOM && ! tabnom[ ptnoeud->SIGNAL - 1 ] )
452 {
453 tabnom[ ptnoeud->SIGNAL - 1 ] = ptnoeud->NOM;
454 }
455 }
456 /* Puis les noeuds constituant les signaux */
457
458 for( scaninterf = ptcir->CINTERF ;
459 scaninterf ;
460 scaninterf = scaninterf->NEXT
461 )
462 {
463 ptnoeud = (noeud*) scaninterf->DATA;
464 if( ! tabnom[ ptnoeud->SIGNAL - 1 ] )
465 {
466 for( scannoeud = ptcir->NOEUD ; scannoeud ; scannoeud = scannoeud->SUIV )
467 {
468 if( scannoeud->SIGNAL == ptnoeud->SIGNAL && scannoeud->NOM )
469 {
470 /* Il est possible que le nom de signal soit deja utilise :
471 * on le verifie*/
472 for( i = 0 ; i < nb ; i++ )
473 if( tabnom[ i ] == scannoeud->NOM )
474 break;
475
476 if( i == nb )
477 {
478 tabnom[ ptnoeud->SIGNAL - 1 ] = scannoeud->NOM;
479 break;
480 }
481 }
482 }
483 }
484 }
485
486 /* finallement on cree un nom de connecteurs */
487 i=0;
488 for( scaninterf = ptcir->CINTERF ;
489 scaninterf ;
490 scaninterf = scaninterf->NEXT
491 )
492 {
493 ptnoeud = (noeud*) scaninterf->DATA;
494 if( tabnom[ ptnoeud->SIGNAL - 1 ] == NULL )
495 {
496 sprintf( nom, "SPICE_C_%d",i++);
497 tabnom[ ptnoeud->SIGNAL - 1 ] = spicenamealloc( ptcir, nom );
498 }
499 }
500
501 /* On cree la chainlist de interf */
502
503 ninterf->GINTERF = NULL;
504 for( scaninterf = ptcir->CINTERF ;
505 scaninterf ;
506 scaninterf = scaninterf->NEXT
507 )
508 {
509 ptnoeud = (noeud*) scaninterf->DATA;
510 strcpy( nom, tabnom[ ptnoeud->SIGNAL -1 ] );
511
512 if( SPI_MERGE )
513 stopchainsepar( nom );
514
515 ninterf->GINTERF = addchain( ninterf->GINTERF,
516 mbkstrdup( nom )
517 );
518 }
519
520 ninterf->GINTERF = reverse( ninterf->GINTERF );
521
522 mbkfree( tabnom );
523
524 return( ninterf );
525 }
526
527 /******************************************************************************/
528
lirecircuit(df,teteinterf)529 circuit* lirecircuit( df, teteinterf )
530 spifile *df;
531 ginterf **teteinterf;
532 {
533 char complet;
534 chain_list *ligne;
535 chain_list *elem, *elem1, *elem2;
536 float valeur;
537 circuit *ptcir;
538 noeud *ptnoeud;
539 chain_list *sc1, *sc2, *prev;
540 resi *ptresi, *scanresi;
541 capa *ptcapa, *scancapa;
542 trans *pttrans, *scantrans;
543 inst *ptinst, *scaninst;
544 valim *ptvalim, *scanvalim;
545 int nbelem;
546 int status;
547 int i;
548 int traitecomment;
549 float com_x,com_y;
550 ginterf *scaninterf;
551 char buf[1024];
552 char tt;
553
554 complet = 0;
555 ptcir = NULL;
556
557 while( !complet )
558 {
559 ligne = lireligne( df );
560 traitecomment = TRUE;
561
562 if( !ligne ) /* fin de fichier */
563 break;
564
565 com_x = 0.0;
566 com_y = 0.0;
567
568 /* On r�cup�re les param�tres non standards : $X, $Y */
569 for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
570 {
571 if( strcasecmp( (char*)(sc1->DATA), "$X" ) == 0 &&
572 sc1->NEXT &&
573 sc1->NEXT->NEXT
574 )
575 {
576 if( strcmp( (char*)(sc1->NEXT->DATA), "=" ) )
577 continue;
578 valeur = spicefloat( (char*)(sc1->NEXT->NEXT->DATA) ,&status );
579 if( status == -1 )
580 continue;
581 com_x = valeur;
582 }
583 else
584 if( strcasecmp( (char*)(sc1->DATA), "$Y" ) == 0 &&
585 sc1->NEXT &&
586 sc1->NEXT->NEXT
587 )
588 {
589 if( strcmp( (char*)(sc1->NEXT->DATA), "=" ) )
590 continue;
591 valeur = spicefloat( (char*)(sc1->NEXT->NEXT->DATA) ,&status );
592 if( status == -1 )
593 continue;
594 com_y = valeur;
595 }
596 }
597
598 prev = NULL;
599
600 for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
601 {
602 if( *((char*)(sc1->DATA)) == '$' )
603 break;
604 prev = sc1;
605 }
606
607 if( sc1 )
608 {
609 for( sc2 = sc1 ; sc2 ; sc2 = sc2->NEXT )
610 mbkfree( sc2->DATA );
611
612 if( prev )
613 prev->NEXT = NULL;
614
615 freechain( sc1 );
616 }
617
618 if( ! prev )
619 ligne = NULL;
620
621 if( !ligne )
622 {
623 }
624 else
625 if( strcasecmp( (char*)ligne->DATA, ".INCLUDE" ) == 0 )
626 {
627 if( ptcir )
628 spierror( 2, df->filename, df->msl_line );
629
630 elem = ligne->NEXT;
631
632 if( !elem )
633 spierror( 13, df->filename, df->msl_line );
634
635 if( elem->NEXT )
636 spierror( 14, df->filename, df->msl_line );
637
638 *teteinterf = traiteinclude( *teteinterf, (char*)elem->DATA );
639 }
640 else
641 if( strcasecmp( (char*)ligne->DATA, ".SUBCKT" ) == 0 )
642 {
643 if( ptcir )
644 spierror( 15, df->filename, df->msl_line );
645
646 ptcir = (circuit*)mbkalloc( sizeof( circuit ) );
647 ptcir->NOEUD = NULL;
648 ptcir->TRANS = NULL;
649 ptcir->RESI = NULL;
650 ptcir->CAPA = NULL;
651 ptcir->INST = NULL;
652 ptcir->NOM = NULL;
653 ptcir->CINTERF = NULL;
654 ptcir->FREE = NULL;
655 ptcir->VALIM = NULL;
656 ptcir->INT_NOEUD = creattableint();
657 ptcir->NOM_NOEUD = creatthash( );
658 ptcir->HASHGNAME = creatthash( );
659 ptcir->HASHCAPA = creatthash( );
660 ptcir->HASHRESI = creatthash( );
661 ptcir->HASHVALIM = creatthash( );
662 ptcir->HASHINST = creatthash( );
663 ptcir->HASHTRAN = creatthash( );
664 ptcir->TAILLE = sizeof( circuit );
665 ptcir->RESTENOM = 0;
666
667 elem = ligne->NEXT;
668
669 if( !elem )
670 spierror( 16, df->filename, df->msl_line );
671
672 ptcir->NOM = (char*)spiciralloue( ptcir,
673 sizeof(char)*( strlen( (char*)(elem->DATA) ) + 1 )
674 );
675 strcpy( ptcir->NOM, (char*)( elem->DATA ) );
676
677 /* Pour verifier qu'on a pas plusieurs fois le meme noeud, on
678 * met un 1 dans le champs RCN */
679 for( elem = elem->NEXT; elem; elem = elem->NEXT )
680 {
681 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
682
683 if( ptnoeud->RCN )
684 {
685 fflush( stdout );
686 fprintf( stderr, "%s.\n", SPIMSG(0) );
687 fprintf( stderr, "%s : %s - %d\n", SPIMSG(6),
688 ptnoeud->NOM,
689 ptnoeud->SPICE
690 );
691 fprintf( stderr, "%s : %s, %s : %d\n", SPIMSG(11), df->filename,
692 SPIMSG(12), df->msl_line
693 );
694 exit( 1 );
695 }
696 ptnoeud->RCN = 1;
697
698 ptcir->CINTERF = addchain( ptcir->CINTERF, ptnoeud );
699 }
700
701 for( sc1 = ptcir->CINTERF ; sc1 ; sc1 = sc1->NEXT )
702 ((noeud*)(sc1->DATA))->SPICE = -1;
703
704 ptcir->CINTERF = reverse( ptcir->CINTERF );
705
706 }
707 else
708 if( *( (char*)(ligne->DATA) ) == '*' )
709 {
710 traitecomment = FALSE;
711
712 elem = ligne->NEXT;
713
714 if( ptcir && elem )
715 {
716
717 if( strcasecmp( (char*)(elem->DATA), SPI_NETNAME ) == 0 )
718 {
719 traitecomment = TRUE;
720 elem = elem->NEXT;
721 sc1 = elem;
722 sc2 = NULL;
723
724 for( ; elem && strcasecmp( (char*)(elem->DATA), "=" ) != 0;
725 elem = elem->NEXT )
726 {
727 for( i=0; ((char*)(elem->DATA))[i] >= '0' &&
728 ((char*)(elem->DATA))[i] <= '9' ; i++ ) ;
729
730 if( ((char*)(elem->DATA))[i] != 0 )
731 spierror( 17, df->filename, df->msl_line );
732
733 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
734 sc2 = addchain( sc2, ptnoeud );
735 }
736
737 if( !elem )
738 spierror( 18, df->filename, df->msl_line );
739
740 if( elem == sc1 )
741 spierror( 19, df->filename, df->msl_line );
742
743 elem = elem->NEXT; /* on passe le = */
744
745 if( !elem )
746 spierror( 20, df->filename, df->msl_line );
747
748 for( sc1 = sc2; sc1; sc1 = sc1->NEXT)
749 nomenoeud( ptcir, (noeud*)(sc1->DATA), (char*)(elem->DATA), df );
750 freechain(sc2);
751
752 elem = elem->NEXT;
753 if( elem )
754 spierror( 21, df->filename, df->msl_line );
755 }
756 }
757
758 if( ext_handler && ! traitecomment )
759 {
760 msl_figloaded = ( ptcir ? TRUE : FALSE );
761 msl_subckt = ( ptcir ? ptcir->NOM : NULL );
762 msl_line = df->msl_line;
763 ext_handler( df->file_line1 );
764 }
765 }
766 else
767 if( strcasecmp( (char*)(ligne->DATA), ".ENDS" ) == 0 )
768 {
769 if( !ptcir )
770 spierror( 22, df->filename, df->msl_line );
771
772 if( !ligne->NEXT )
773 {
774 /*spierror( 23, df->filename, df->msl_line );*/
775 }
776 else
777 {
778 if( strcasecmp( (char*)(ligne->NEXT->DATA), ptcir->NOM ) != 0 )
779 spierror( 24, df->filename, df->msl_line );
780
781 if( ligne->NEXT->NEXT )
782 spierror( 14, df->filename, df->msl_line );
783 }
784 complet = 1;
785
786 /* V�rification de l'existance des mod�les pour les instances */
787 if( SPI_AUTO_LOAD )
788 {
789 for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
790 {
791 for( scaninterf = *teteinterf ;
792 scaninterf ;
793 scaninterf = scaninterf->SUIV
794 )
795 {
796 if( strcasecmp( scaninterf->NOM, scaninst->MODELE )==0 )
797 break;
798 }
799
800 if( !scaninterf )
801 {
802 sprintf( buf,"%s.%s", scaninst->MODELE, IN_LO );
803 *teteinterf = traiteinclude( *teteinterf, buf );
804 }
805 }
806 }
807 }
808 else
809 if( ( *((char*)ligne->DATA)=='M' || *((char*)ligne->DATA)=='m' ) && ptcir )
810 {
811 pttrans = (trans*) spiciralloue( ptcir, sizeof( trans ) );
812 pttrans->L = 0.0;
813 pttrans->W = 0.0;
814 pttrans->AS = 0.0;
815 pttrans->AD = 0.0;
816 pttrans->PS = 0.0;
817 pttrans->PD = 0.0;
818
819 if( *( (char*)( ligne->DATA ) + 1 ) == 0 )
820 spierror( 25, df->filename, df->msl_line );
821
822 pttrans->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1 );
823
824 scantrans = getthashelem( pttrans->NOM, ptcir->HASHTRAN, NULL );
825
826 if( scantrans )
827 {
828 if( SPI_CHECK_NAME )
829 spierror( 26, df->filename, df->msl_line );
830 }
831 else
832 addthashelem( pttrans->NOM, pttrans, ptcir->HASHTRAN );
833
834 pttrans->SUIV = ptcir->TRANS;
835 ptcir->TRANS = pttrans;
836
837 elem = ligne->NEXT; /* drain */
838
839 if( !elem )
840 spierror( 27, df->filename, df->msl_line );
841
842 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
843 pttrans->DRAIN = ptnoeud;
844
845 elem = elem->NEXT; /* grille */
846
847 if( !elem )
848 spierror( 28, df->filename, df->msl_line );
849
850 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
851 pttrans->GRILLE = ptnoeud;
852
853 elem = elem->NEXT; /* source */
854
855 if( !elem )
856 spierror( 29, df->filename, df->msl_line );
857
858 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
859 pttrans->SOURCE = ptnoeud;
860
861 elem = elem->NEXT; /* bulk ou type du transistor */
862
863 if( !elem )
864 spierror( 30, df->filename, df->msl_line );
865
866 tt = spitranstype( (char*)(elem->DATA) );
867 if( tt != SPI_UNK_TRANS_TYPE )
868 {
869 pttrans->TYPE = tt;
870 pttrans->SUBST = NULL;
871 }
872 else
873 {
874 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
875 pttrans->SUBST = ptnoeud;
876
877 elem = elem->NEXT; /* type du transistor */
878
879 if( !elem )
880 spierror( 31, df->filename, df->msl_line );
881
882 tt = spitranstype( (char*)(elem->DATA) );
883 if( tt != SPI_UNK_TRANS_TYPE )
884 pttrans->TYPE = tt;
885 else
886 spierror( 32, df->filename, df->msl_line );
887 }
888
889 /* Le reste des parametres est de la forme xxx = yyy */
890
891 while( (elem = elem->NEXT ) )
892 {
893 elem1 = elem->NEXT;
894 elem2 = ( elem1 ? elem1->NEXT : NULL );
895
896 if( !elem2 )
897 spierror( 33, df->filename, df->msl_line );
898
899 if( strcmp( (char*)(elem1->DATA), "=" ) )
900 spierror( 33, df->filename, df->msl_line );
901
902 valeur = spicefloat( (char*)(elem2->DATA) ,&status );
903 if( status == -1 )
904 spierror( 34, df->filename, df->msl_line );
905
906 if( strcasecmp( (char*)(elem->DATA), "L" ) == 0 )
907 pttrans->L = valeur;
908 else
909 if( strcasecmp( (char*)(elem->DATA), "W" ) == 0 )
910 pttrans->W = valeur;
911 else
912 if( strcasecmp( (char*)(elem->DATA), "AS" ) == 0 )
913 pttrans->AS = valeur;
914 else
915 if( strcasecmp( (char*)(elem->DATA), "AD" ) == 0 )
916 pttrans->AD = valeur;
917 else
918 if( strcasecmp( (char*)(elem->DATA), "PS" ) == 0 )
919 pttrans->PS = valeur;
920 else
921 if( strcasecmp( (char*)(elem->DATA), "PD" ) == 0 )
922 pttrans->PD = valeur;
923 else
924 {
925 fflush( stdout );
926 fprintf( stderr, "%s.\n", SPIMSG(0) );
927 fprintf( stderr, "%s. %s %s. %s %d.\n",
928 SPIMSG(1),
929 SPIMSG(11),
930 df->filename,
931 SPIMSG(12),
932 df->msl_line
933 );
934 fprintf( stderr, "%s : %s.\n", SPIMSG(35), (char*)(elem->DATA) );
935 EXIT(1);
936 }
937 elem = elem->NEXT->NEXT;
938 }
939 pttrans->X = com_x;
940 pttrans->Y = com_y;
941 }
942 else
943 if( ( *((char*)ligne->DATA)=='R' || *((char*)ligne->DATA)=='r' ) && ptcir )
944 {
945 ptresi = (resi*) spiciralloue( ptcir, sizeof(resi) );
946
947 if( *( (char*)( ligne->DATA ) +1 ) == 0 )
948 spierror( 36, df->filename, df->msl_line );
949
950 ptresi->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1 );
951
952 scanresi = getthashelem( ptresi->NOM, ptcir->HASHRESI, NULL );
953
954 if( scanresi )
955 {
956 if( SPI_CHECK_NAME )
957 spierror( 37, df->filename, df->msl_line );
958 }
959 else
960 addthashelem( ptresi->NOM, ptresi, ptcir->HASHRESI );
961
962 ptresi->SUIV = ptcir->RESI;
963 ptcir->RESI = ptresi;
964
965 elem = ligne->NEXT; /* first node */
966
967 if( !elem )
968 spierror( 13, df->filename, df->msl_line );
969
970 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
971 ptresi->N1 = ptnoeud;
972
973 elem = elem->NEXT; /* second node */
974
975 if( !elem )
976 spierror( 13, df->filename, df->msl_line );
977
978 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
979 ptresi->N2 = ptnoeud;
980
981 elem = elem->NEXT; /* R value */
982 if( !elem )
983 spierror( 13, df->filename, df->msl_line );
984
985 valeur = spicefloat( (char*)(elem->DATA) ,&status );
986 if( status == -1 )
987 spierror( 34, df->filename, df->msl_line );
988
989 ptresi->RESI = valeur;
990
991 elem = elem->NEXT; /* no more parameters */
992 if( elem )
993 spierror( 14, df->filename, df->msl_line );
994 }
995 else
996 if( ( *((char*)ligne->DATA)=='C' || *((char*)ligne->DATA)=='c' ) && ptcir )
997 {
998 ptcapa = (capa*) spiciralloue( ptcir, sizeof(capa) );
999
1000 if( *( (char*)( ligne->DATA ) +1 ) == 0 )
1001 spierror( 38, df->filename, df->msl_line );
1002
1003 ptcapa->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1 );
1004
1005 scancapa = getthashelem( ptcapa->NOM, ptcir->HASHCAPA, NULL );
1006 if( scancapa )
1007 {
1008 if( SPI_CHECK_NAME )
1009 spierror( 39, df->filename, df->msl_line );
1010 }
1011 else
1012 addthashelem( ptcapa->NOM, ptcapa, ptcir->HASHCAPA);
1013
1014
1015 ptcapa->SUIV = ptcir->CAPA;
1016 ptcir->CAPA = ptcapa;
1017
1018 elem = ligne->NEXT; /* first node */
1019
1020 if( !elem )
1021 spierror( 13, df->filename, df->msl_line );
1022
1023 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1024 ptcapa->N1 = ptnoeud;
1025
1026 elem = elem->NEXT; /* second node */
1027
1028 if( !elem )
1029 spierror( 13, df->filename, df->msl_line );
1030
1031 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1032 ptcapa->N2 = ptnoeud;
1033
1034 elem = elem->NEXT; /* C value */
1035 if( !elem )
1036 spierror( 13, df->filename, df->msl_line );
1037
1038 valeur = spicefloat( (char*)(elem->DATA) ,&status );
1039
1040 if( status == -1 )
1041 spierror( 34, df->filename, df->msl_line );
1042
1043 /* Les valeurs dans Alliance sont en pif */
1044 ptcapa->CAPA = valeur * 1e12 ;
1045
1046 elem = elem->NEXT; /* no more parameters */
1047
1048 if( elem )
1049 spierror( 14, df->filename, df->msl_line );
1050 }
1051 else
1052 if( ( *((char*)ligne->DATA)=='V' || *((char*)ligne->DATA)=='v' ) && ptcir )
1053 {
1054 ptvalim = (valim*) spiciralloue( ptcir, sizeof(valim) );
1055
1056 if( *( (char*)( ligne->DATA ) +1 ) == 0 )
1057 spierror( 36, df->filename, df->msl_line );
1058
1059 ptvalim->NOM = spicenamealloc( ptcir, (char*)(ligne->DATA) + 1 );
1060
1061 scanvalim = getthashelem( ptvalim->NOM, ptcir->HASHVALIM, NULL );
1062
1063 if( scanvalim )
1064 {
1065 if( SPI_CHECK_NAME )
1066 spierror( 37, df->filename, df->msl_line );
1067 }
1068 else
1069 addthashelem( ptvalim->NOM, ptvalim, ptcir->HASHVALIM );
1070
1071 ptvalim->SUIV = ptcir->VALIM;
1072 ptcir->VALIM = ptvalim;
1073
1074 elem = ligne->NEXT; /* first node */
1075
1076 if( !elem )
1077 spierror( 13, df->filename, df->msl_line );
1078
1079 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1080 ptvalim->N1 = ptnoeud;
1081
1082 elem = elem->NEXT; /* second node */
1083
1084 if( !elem )
1085 spierror( 13, df->filename, df->msl_line );
1086
1087 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1088 ptvalim->N2 = ptnoeud;
1089
1090 elem = elem->NEXT; /* R value */
1091 if( !elem )
1092 spierror( 13, df->filename, df->msl_line );
1093
1094 valeur = spicefloat( (char*)(elem->DATA) ,&status );
1095 if( status == -1 )
1096 spierror( 34, df->filename, df->msl_line );
1097
1098 ptvalim->TENSION = valeur;
1099
1100 elem = elem->NEXT; /* no more parameters */
1101 if( elem )
1102 spierror( 14, df->filename, df->msl_line );
1103 }
1104 else
1105 if( ( *(char*)(ligne->DATA) == 'X' || *(char*)(ligne->DATA) == 'x' ) &&
1106 ptcir )
1107 {
1108 ptinst = (inst*)spiciralloue( ptcir, sizeof(inst) );
1109 ptinst->IINTERF = NULL;
1110
1111 if( *( ((char*)(ligne->DATA)) + 1) == 0 )
1112 spierror( 40, df->filename, df->msl_line );
1113
1114 ptinst->NOM = spicenamealloc( ptcir, ((char*)(ligne->DATA)) + 1 );
1115
1116
1117 scaninst = getthashelem( ptinst->NOM, ptcir->HASHINST, NULL );
1118 if( scaninst )
1119 spierror( 41, df->filename, df->msl_line );
1120
1121 ptinst->SUIV = ptcir->INST;
1122 ptcir->INST = ptinst;
1123 addthashelem( ptinst->NOM, ptinst, ptcir->HASHINST );
1124
1125 for( nbelem=0, elem = ligne->NEXT ; elem ; elem = elem->NEXT, nbelem++ );
1126
1127 if( nbelem <= 1 )
1128 spierror( 13, df->filename, df->msl_line );
1129
1130 for( elem = ligne->NEXT; elem->NEXT; elem = elem->NEXT )
1131 {
1132 ptnoeud = ajoutenoeud( ptcir, (char*)(elem->DATA), df );
1133 ptinst->IINTERF = addchain( ptinst->IINTERF, ptnoeud );
1134 }
1135 ptinst->IINTERF = reverse( ptinst->IINTERF );
1136
1137 ptinst->MODELE = spicenamealloc( ptcir, (char*)elem->DATA );
1138 }
1139 else
1140 {
1141 if( SPI_AFF_UNK )
1142 {
1143 fflush( stdout );
1144 fprintf( stderr, "%s\n", SPIMSG(0) );
1145 fprintf( stderr, "%s. %s %s. %s %d :\n",
1146 SPIMSG(42),
1147 SPIMSG(11),
1148 df->filename,
1149 SPIMSG(12),
1150 df->msl_line
1151 );
1152 fprintf( stderr, "%s\n", (char*)ligne->DATA );
1153 }
1154 }
1155
1156 if( ligne )
1157 {
1158 for( sc1 = ligne; sc1; sc1 = sc1->NEXT )
1159 mbkfree( sc1->DATA );
1160
1161 freechain( ligne );
1162 }
1163 }
1164
1165
1166 return( ptcir );
1167 }
1168
1169 /******************************************************************************/
1170
traiteinclude(instance,nom)1171 ginterf* traiteinclude( instance, nom )
1172 ginterf *instance;
1173 char *nom;
1174 {
1175 ginterf *sci;
1176 ginterf *nouvinterf;
1177
1178 for( sci = instance ; sci ; sci = sci->SUIV )
1179 {
1180 if( strcasecmp( sci->NOM, nom ) == 0 )
1181 {
1182 fflush( stdout );
1183 fprintf( stderr, "%s\n", SPIMSG(0) );
1184 fprintf( stderr, "%s : %s.\n", SPIMSG(41), nom );
1185 EXIT( 1 );
1186 }
1187 }
1188
1189 nouvinterf = spiceloading( NULL, nom, 'A', instance );
1190
1191 return( nouvinterf );
1192 }
1193
1194 /******************************************************************************/
1195
loconinterf(ptfig,tete)1196 void loconinterf( ptfig, tete )
1197 lofig_list *ptfig;
1198 chain_list *tete;
1199 {
1200 chain_list *sc1;
1201 chain_list *sc2;
1202 char *nomdevec;
1203 /*int sigidx;
1204 losig_list *ptsig;
1205
1206 sigidx = 0;*/
1207
1208 for( sc1 = tete ; sc1 ; sc1 = sc1->NEXT )
1209 {
1210 for( sc2 = tete; sc2 != sc1 ; sc2 = sc2->NEXT )
1211 if( strcasecmp( sc1->DATA, sc2->DATA ) == 0 )
1212 break;
1213 if( sc1 == sc2 )
1214 {
1215 /*
1216 sigidx++;
1217 ptsig = addlosig( ptfig, sigidx, NULL, 'E' );
1218 */
1219 nomdevec = spi_devect( (char*)(sc1->DATA) );
1220 addlocon( ptfig, namealloc(nomdevec), /*ptsig*/ NULL, 'X' );
1221 mbkfree( nomdevec );
1222 }
1223 }
1224
1225 ptfig->LOCON = (locon_list*)reverse( (chain_list*)ptfig->LOCON );
1226 }
1227
1228 /******************************************************************************/
1229
constequi(ptcir,instances)1230 void constequi( ptcir, instances )
1231 circuit *ptcir;
1232 ginterf *instances;
1233 {
1234 inst *scaninst;
1235 chain_list *sc1, *sc2, *sc3, *sc4, *sc5 ;
1236 ptype_list *pt, *pt2;
1237 int idsig = 0 ; /* Warning a la compil */
1238 int signal;
1239 ptype_list *headsig;
1240 int nb;
1241 int t;
1242 ptype_list *spt;
1243 noeud *scannoeud;
1244 resi *scanresi;
1245 valim *scanvalim;
1246 ginterf *sci;
1247 char *vdd;
1248 char *vss;
1249 int vuevss;
1250 int vuevdd;
1251 int cirvss;
1252 int cirvdd;
1253 chain_list *scanchain;
1254 noeud *node1;
1255 noeud *node2;
1256
1257 signal = 1;
1258 headsig = NULL;
1259
1260 /* traite les instances */
1261
1262 for( scaninst = ptcir->INST; scaninst; scaninst = scaninst->SUIV )
1263 {
1264 for( sci = instances; sci; sci = sci->SUIV )
1265 {
1266 if( strcasecmp( sci->NOM, scaninst->MODELE ) == 0 )
1267 break;
1268 }
1269
1270 if( !sci )
1271 {
1272 fflush( stdout );
1273 fprintf( stderr, "%s\n", SPIMSG(0) );
1274 fprintf( stderr, "%s %s.\n", SPIMSG( 43 ), scaninst->MODELE );
1275 EXIT(1);
1276 }
1277
1278 for( sc1 = sci->GINTERF, sc2 = scaninst->IINTERF ;
1279 sc1 && sc2 ;
1280 sc1 = sc1->NEXT, sc2 = sc2->NEXT )
1281 {
1282 /* On verifie qu'on a une nouvelle equipotentielle */
1283
1284 for( sc3 = sci->GINTERF ; sc3 != sc1 ; sc3 = sc3->NEXT )
1285 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1286 break;
1287 if( sc3 != sc1 )
1288 continue;
1289
1290 nb = 0; /* nombre d'equipotentielle deja existant sur l'interface */
1291
1292 for( sc3 = sc1, sc4 = sc2 ; sc3 && sc4 ; sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1293 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 &&
1294 ( (noeud*)( sc4->DATA ) )->SIGNAL != 0 )
1295 {
1296 nb ++;
1297 idsig = ( (noeud*)( sc4->DATA ) )->SIGNAL;
1298 }
1299
1300 switch( nb )
1301 {
1302 case 0 : /* creation d'une nouvelle equi */
1303
1304 headsig = addptype( headsig, signal, NULL );
1305
1306 for( sc3 = sc1, sc4 = sc2 ;
1307 sc3 && sc4 ;
1308 sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1309 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1310 {
1311 ((noeud*)(sc4->DATA))->SIGNAL = signal;
1312 headsig->DATA = addchain( headsig->DATA, sc4->DATA );
1313 }
1314
1315 signal++;
1316
1317 break;
1318
1319 case 1: /* On reutilise l'equi existante */
1320
1321 pt = getptype( headsig, idsig );
1322
1323 for( sc3 = sc1, sc4 = sc2 ;
1324 sc3 && sc4 ;
1325 sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1326 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1327 {
1328 if( ! ((noeud*)(sc4->DATA))->SIGNAL )
1329 {
1330 ((noeud*)( sc4->DATA ))->SIGNAL = idsig;
1331 pt->DATA = addchain( pt->DATA, sc4->DATA );
1332 }
1333 }
1334
1335 break;
1336
1337 default : /* Il y a plus de deux equi existante : il faut
1338 les regrouper en une seule */
1339 pt = getptype( headsig, idsig );
1340
1341 for( sc3 = sc1, sc4 = sc2 ;
1342 sc3 && sc4 ;
1343 sc3 = sc3->NEXT, sc4 = sc4->NEXT)
1344 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
1345 {
1346 /* Pas de signal sur le noeud sc4 */
1347 if( ! ( (noeud*)( sc4->DATA ) )->SIGNAL )
1348 {
1349 ((noeud*)( sc4->DATA ))->SIGNAL = idsig;
1350 pt->DATA = addchain( pt->DATA, sc4->DATA );
1351 }
1352 else
1353 /* Si on se trouve sur un autre signal */
1354 if( ( (noeud*)( sc4->DATA ) )->SIGNAL != idsig )
1355 {
1356 /* t : index signal source */
1357 t = ( (noeud*)( sc4->DATA ) )->SIGNAL;
1358 pt2 = getptype( headsig, t );
1359
1360 /* on change ne numero de signal de tous les noeuds du signal
1361 * source */
1362 for( sc5 = pt2->DATA ; sc5 ; sc5 = sc5->NEXT )
1363 ( (noeud*)( sc5->DATA ) )->SIGNAL = idsig;
1364
1365 /* on ajoute la chain_list source a la fin de la chain_list
1366 * destination */
1367 for( sc5 = (chain_list*)( pt->DATA ) ;
1368 sc5->NEXT ;
1369 sc5 = sc5->NEXT );
1370 sc5->NEXT = (chain_list*)pt2->DATA;
1371
1372 /* On libere le signal source */
1373 headsig = delptype( headsig, t );
1374
1375 }
1376 /* Cas o� on est sur le meme signal : on ne fait rien */
1377 }
1378
1379 break;
1380 }
1381 }
1382
1383 if( sc1 || sc2 )
1384 {
1385 fflush( stdout );
1386 fprintf( stderr, "%s\n", SPIMSG(0) );
1387 fprintf( stderr, "%s :\n%s %s. %s %s. %s %s.\n", SPIMSG( 44 ),
1388 SPIMSG( 54 ),
1389 ptcir->NOM,
1390 SPIMSG( 55 ),
1391 scaninst->NOM,
1392 SPIMSG( 56 ),
1393 scaninst->MODELE
1394 );
1395 EXIT(1);
1396 }
1397 }
1398
1399 /* traite les resistances : Ca peut s'ameliorer pour aller + vite */
1400
1401 for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
1402 {
1403 if( scanresi->N1->SIGNAL == 0 && scanresi->N2->SIGNAL == 0 )
1404 {
1405 headsig = addptype( headsig, signal, NULL );
1406 scanresi->N1->SIGNAL = signal;
1407 scanresi->N2->SIGNAL = signal;
1408 headsig->DATA = addchain( headsig->DATA, scanresi->N1 );
1409 headsig->DATA = addchain( headsig->DATA, scanresi->N2 );
1410 signal++;
1411 }
1412 else
1413 if( scanresi->N1->SIGNAL != 0 && scanresi->N2->SIGNAL == 0 )
1414 {
1415 pt = getptype( headsig, scanresi->N1->SIGNAL );
1416 pt->DATA = addchain( pt->DATA, scanresi->N2 );
1417 scanresi->N2->SIGNAL = pt->TYPE;
1418 }
1419 else
1420 if( scanresi->N1->SIGNAL == 0 && scanresi->N2->SIGNAL != 0 )
1421 {
1422 pt = getptype( headsig, scanresi->N2->SIGNAL );
1423 pt->DATA = addchain( pt->DATA, scanresi->N1 );
1424 scanresi->N1->SIGNAL = pt->TYPE;
1425 }
1426 else
1427 if( scanresi->N1->SIGNAL != scanresi->N2->SIGNAL )
1428 {
1429 pt = getptype( headsig, scanresi->N1->SIGNAL );
1430 pt2 = getptype( headsig, scanresi->N2->SIGNAL );
1431
1432 for( sc1 = pt2->DATA ; sc1 ; sc1 = sc1->NEXT )
1433 ((noeud*)(sc1->DATA))->SIGNAL = pt->TYPE;
1434 for( sc1 = pt->DATA ; sc1->NEXT ; sc1 = sc1->NEXT ) ;
1435 sc1->NEXT = pt2->DATA;
1436 headsig = delptype( headsig, pt2->TYPE );
1437 }
1438 }
1439
1440 for( scanvalim = ptcir->VALIM ; scanvalim ; scanvalim = scanvalim->SUIV )
1441 {
1442 if( scanvalim->N1->SIGNAL == 0 && scanvalim->N2->SIGNAL == 0 )
1443 {
1444 headsig = addptype( headsig, signal, NULL );
1445 scanvalim->N1->SIGNAL = signal;
1446 scanvalim->N2->SIGNAL = signal;
1447 headsig->DATA = addchain( headsig->DATA, scanvalim->N1 );
1448 headsig->DATA = addchain( headsig->DATA, scanvalim->N2 );
1449 signal++;
1450 }
1451 else
1452 if( scanvalim->N1->SIGNAL != 0 && scanvalim->N2->SIGNAL == 0 )
1453 {
1454 pt = getptype( headsig, scanvalim->N1->SIGNAL );
1455 pt->DATA = addchain( pt->DATA, scanvalim->N2 );
1456 scanvalim->N2->SIGNAL = pt->TYPE;
1457 }
1458 else
1459 if( scanvalim->N1->SIGNAL == 0 && scanvalim->N2->SIGNAL != 0 )
1460 {
1461 pt = getptype( headsig, scanvalim->N2->SIGNAL );
1462 pt->DATA = addchain( pt->DATA, scanvalim->N1 );
1463 scanvalim->N1->SIGNAL = pt->TYPE;
1464 }
1465 else
1466 if( scanvalim->N1->SIGNAL != scanvalim->N2->SIGNAL )
1467 {
1468 pt = getptype( headsig, scanvalim->N1->SIGNAL );
1469 pt2 = getptype( headsig, scanvalim->N2->SIGNAL );
1470
1471 for( sc1 = pt2->DATA ; sc1 ; sc1 = sc1->NEXT )
1472 ((noeud*)(sc1->DATA))->SIGNAL = pt->TYPE;
1473 for( sc1 = pt->DATA ; sc1->NEXT ; sc1 = sc1->NEXT ) ;
1474 sc1->NEXT = pt2->DATA;
1475 headsig = delptype( headsig, pt2->TYPE );
1476 }
1477 }
1478
1479 if( SPI_MERGE == 1 )
1480 {
1481 for( sc1 = ptcir->CINTERF ; sc1 ; sc1 = sc1->NEXT )
1482 {
1483 node1 = ( noeud* )( sc1->DATA );
1484
1485 for( sc2 = ptcir->CINTERF ; sc2 != sc1 ; sc2 = sc2->NEXT )
1486 {
1487 node2 = ( noeud* )( sc2->DATA );
1488 if( nodenameisequi( node1->NOM, node2->NOM ) )
1489 break;
1490 }
1491
1492 if( sc1 != sc2 )
1493 continue;
1494
1495 for( sc2 = sc1->NEXT ; sc2 ; sc2 = sc2->NEXT )
1496 {
1497 node2 = ( noeud* )( sc2->DATA );
1498
1499 if( nodenameisequi( node1->NOM, node2->NOM ) )
1500 {
1501 if( node1->SIGNAL == 0 && node2->SIGNAL == 0 )
1502 {
1503 headsig = addptype( headsig, signal, NULL );
1504 node1->SIGNAL = signal;
1505 node2->SIGNAL = signal;
1506 headsig->DATA = addchain( headsig->DATA, node1 );
1507 headsig->DATA = addchain( headsig->DATA, node2 );
1508 signal++;
1509 }
1510 else
1511 if( node1->SIGNAL != 0 && node2->SIGNAL == 0 )
1512 {
1513 pt = getptype( headsig, node1->SIGNAL );
1514 pt->DATA = addchain( pt->DATA, node2 );
1515 node2->SIGNAL = node1->SIGNAL;
1516 }
1517 else
1518 if( node1->SIGNAL == 0 && node2->SIGNAL != 0 )
1519 {
1520 pt = getptype( headsig, node2->SIGNAL );
1521 pt->DATA = addchain( pt->DATA, node1 );
1522 node1->SIGNAL = node2->SIGNAL;
1523 }
1524 else
1525 if( node1->SIGNAL != node2->SIGNAL )
1526 {
1527 pt = getptype( headsig, node1->SIGNAL );
1528 pt2 = getptype( headsig, node2->SIGNAL );
1529
1530 for( sc3 = pt2->DATA ; sc3 ; sc3 = sc3->NEXT )
1531 ((noeud*)(sc3->DATA))->SIGNAL = node1->SIGNAL;
1532 for( sc3 = pt->DATA ; sc3->NEXT ; sc3 = sc3->NEXT ) ;
1533 sc3->NEXT = pt2->DATA;
1534 headsig = delptype( headsig, pt2->TYPE );
1535 }
1536 else
1537 {
1538 /* rien a faire : node1->SIGNAL == node2->SIGNAL */
1539 }
1540 }
1541 }
1542 }
1543 }
1544
1545 /* On s'occupe des noeuds libres */
1546
1547 for( scannoeud = ptcir->NOEUD; scannoeud; scannoeud = scannoeud->SUIV )
1548 {
1549 if( scannoeud->SIGNAL == 0 )
1550 {
1551 headsig = addptype( headsig, signal, addchain( NULL, scannoeud ) );
1552 scannoeud->SIGNAL = signal++;
1553
1554 }
1555 }
1556
1557 /* Remplie le champ RCN de chaque noeud */
1558
1559 for( spt = headsig ; spt ; spt = spt->NEXT )
1560 {
1561 sc1 = (chain_list*)(spt->DATA);
1562
1563 if( sc1->NEXT || SPI_ONE_NODE_NORC == 0 )
1564 {
1565 nb = 1;
1566 for( ; sc1 ; sc1 = sc1->NEXT )
1567 ((noeud*)(sc1->DATA))->RCN = nb++ ;
1568 }
1569 else
1570 {
1571 ((noeud*)(sc1->DATA))->RCN = 0;
1572 }
1573 }
1574
1575 /* Tous les noeuds d'un signal VSS ou VDD ont le nom VSS ou VDD */
1576
1577 vss = spicenamealloc( ptcir, VSS );
1578 vdd = spicenamealloc( ptcir, VDD );
1579 cirvss = 0;
1580 cirvdd = 0;
1581
1582 for( spt = headsig ; spt ; spt = spt->NEXT )
1583 {
1584 vuevss = vuevdd = 0;
1585
1586 for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1587 {
1588 if( ( ( noeud* )( sc1->DATA ) )->NOM == vss )
1589 vuevss = 1;
1590
1591 if( ( ( noeud* )( sc1->DATA ) )->NOM == vdd )
1592 vuevdd = 1;
1593 }
1594
1595 if( vuevss && vuevdd )
1596 {
1597 fflush( stdout );
1598 fprintf( stderr, "%s\n", SPIMSG(0) );
1599 fprintf( stderr, "%s : %s\n", SPIMSG(45), ptcir->NOM );
1600 EXIT( 1 );
1601 }
1602
1603 if( vuevss && cirvss )
1604 {
1605 fflush( stdout );
1606 fprintf( stderr, "%s\n", SPIMSG(0) );
1607 fprintf( stderr, "%s : %s\n", SPIMSG(46), ptcir->NOM );
1608 EXIT( 1 );
1609 }
1610
1611 if( vuevss )
1612 {
1613 for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1614 ( ( noeud* )( sc1->DATA ) )->NOM = vss;
1615 cirvss = 1;
1616 }
1617
1618 if( vuevdd && cirvdd )
1619 {
1620 fflush( stdout );
1621 fprintf( stderr, "%s\n", SPIMSG(0) );
1622 fprintf( stderr, "%s : %s\n", SPIMSG(47), ptcir->NOM );
1623 EXIT( 1 );
1624 }
1625
1626 if( vuevdd )
1627 {
1628 for( sc1 = spt->DATA ; sc1 ; sc1 = sc1->NEXT )
1629 ( ( noeud* )( sc1->DATA ) )->NOM = vdd;
1630 cirvdd = 1;
1631 }
1632 }
1633
1634 /*
1635 if( !cirvss || !cirvdd )
1636 {
1637 fflush( stdout );
1638 fprintf( stderr,
1639 "*** mbkspi error *** : No vdd or vss nodes in %s\n",
1640 ptcir->NOM
1641 );
1642 EXIT( 1 );
1643 }
1644 */
1645
1646 /* On renumerote les signaux en partant de 1, c'est plus propre. */
1647 idsig = 1;
1648 for(spt = headsig ; spt ; spt = spt->NEXT )
1649 {
1650 if( spt->DATA )
1651 {
1652 for( scanchain = (chain_list*)(spt->DATA) ;
1653 scanchain ;
1654 scanchain = scanchain->NEXT
1655 )
1656 {
1657 scannoeud = (noeud*)(scanchain->DATA);
1658 scannoeud->SIGNAL = idsig;
1659 }
1660 idsig++;
1661 }
1662 }
1663
1664 if( SPI_NODE_EQUI_DRIVE )
1665 spi_dump_equi( ptcir->NOM, headsig );
1666
1667 /* libere la liste des noeuds par signal */
1668
1669 for(spt = headsig; spt; spt = spt->NEXT )
1670 if( spt->DATA )
1671 freechain( (chain_list*)(spt->DATA) );
1672 freeptype( headsig );
1673
1674 }
1675
1676 /******************************************************************************/
spi_dump_equi(char * figname,ptype_list * headsig)1677 void spi_dump_equi( char *figname, ptype_list *headsig )
1678 {
1679 ptype_list *spt;
1680 chain_list *scan;
1681 FILE *ptf;
1682 noeud *node;
1683
1684 ptf = mbkfopen( figname, "equi", WRITE_TEXT );
1685 if( !ptf )
1686 return;
1687
1688 for( spt = headsig ; spt ; spt = spt->NEXT )
1689 {
1690 if( spt->DATA )
1691 {
1692 scan = (chain_list*)spt->DATA ;
1693 fprintf( ptf, "Signal %d.\n", ((noeud*)(scan->DATA))->SIGNAL );
1694 for( ; scan ; scan = scan->NEXT )
1695 {
1696 node = ((noeud*)scan->DATA );
1697 fprintf( ptf,
1698 " %5d %5d %s\n",
1699 node->SPICE,
1700 node->RCN,
1701 node->NOM ? node->NOM : "-"
1702 );
1703 }
1704 }
1705 }
1706 fclose( ptf );
1707 }
1708
1709 /******************************************************************************/
1710
nodenameisequi(name1,name2)1711 int nodenameisequi( name1, name2 )
1712 /* Renvoie 1 si les deux noms sont sur la meme equipotentielle */
1713 char *name1;
1714 char *name2;
1715 {
1716 int end1;
1717 int end2;
1718 int end1x;
1719 int end2x;
1720
1721 if( name1 == NULL || name2 == NULL )
1722 return(0);
1723
1724 /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1725 /*end1 = strlen( name1 ) - 1 ;*/
1726 end1x = end1 = strlen( name1 ) - 1 ;
1727
1728 /* on passe les chiffres */
1729
1730 while( end1 > 0 && isdigit( (int)name1[ end1 ] ) )
1731 end1--;
1732
1733 /* on passe le '.' */
1734
1735 /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1736 if( name1[ end1 ] == SPI_SEPAR )
1737 end1--;
1738 else
1739 end1 = end1x ;
1740
1741 /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1742 /*end2 = strlen( name2 ) - 1 ;*/
1743 end2x = end2 = strlen( name2 ) - 1 ;
1744
1745 /* on passe les chiffres */
1746
1747 while( end2 > 0 && isdigit( (int)name2[ end2 ] ) )
1748 end2--;
1749
1750 /* on passe le '.' */
1751
1752 /*modif karim pour passer les fichier ck1 ck1.1 ck1.2*/
1753 if( name2[ end2 ] == SPI_SEPAR )
1754 end2--;
1755 else
1756 end2 = end2x ;
1757
1758 end1++;
1759 end2++;
1760
1761 if( end1 == end2 )
1762 if( strncmp( name1, name2, end1 ) == 0 )
1763 return( 1 );
1764
1765 return( 0 );
1766 }
1767
1768 /******************************************************************************/
1769
constlofig(ptcir,ptfig,instances,mode)1770 void constlofig( ptcir, ptfig, instances, mode )
1771 circuit *ptcir;
1772 lofig_list *ptfig;
1773 ginterf *instances;
1774 char mode;
1775 {
1776 noeud *scannoeud;
1777 noeud *ptnoeud;
1778 chain_list *sc1, *sc2, *sc3, *sc4, *sc5;
1779 locon_list *scanlocon;
1780 losig_list *ptsig;
1781 int nbsig;
1782 int i;
1783 losig_list **tabsig;
1784 num_list *interf;
1785 chain_list *connec_sig;
1786 chain_list *connec_noeud;
1787 chain_list *connec_nom;
1788 chain_list *connec_con;
1789 trans *scantrans;
1790 inst *scaninst;
1791 char *nom;
1792 lotrs_list *pttrs;
1793 locon_list *scancon;
1794 capa *scancapa;
1795 loins_list *ptinst;
1796 resi *scanresi;
1797 valim *scanvalim;
1798 ginterf *sci;
1799 lofig_list *modele;
1800 lofig_list *tetemodele;
1801 loctc_list *ptctc;
1802 char *devect;
1803 ptype_list *ptnodename;
1804
1805
1806 tetemodele = NULL;
1807
1808 /* Cr�ation du tableau des signaux */
1809
1810 nbsig = 0;
1811 for( scannoeud = ptcir->NOEUD; scannoeud ; scannoeud = scannoeud->SUIV )
1812 if( scannoeud->SIGNAL > nbsig )
1813 nbsig = scannoeud->SIGNAL;
1814
1815 tabsig = (losig_list**)mbkalloc( sizeof(losig_list*)*nbsig );
1816 for( i = 0 ; i < nbsig ; i++ )
1817 tabsig[i] = NULL;
1818
1819 /* Cr�ation des signaux */
1820
1821 setsigsize( ptfig, nbsig > 1024 ? 1024 : nbsig );
1822
1823 for( scannoeud = ptcir->NOEUD; scannoeud ; scannoeud = scannoeud->SUIV )
1824 {
1825 if( !(ptsig = tabsig[ scannoeud->SIGNAL - 1 ]) )
1826 {
1827 ptsig = addlosig( ptfig, scannoeud->SIGNAL, NULL, INTERNAL );
1828 tabsig[ scannoeud->SIGNAL - 1 ] = ptsig;
1829 }
1830
1831 if( scannoeud->NOM )
1832 {
1833 devect = spi_devect( scannoeud->NOM );
1834
1835 nom = namealloc( devect );
1836 mbkfree( devect );
1837
1838 for( sc1 = ptsig->NAMECHAIN; sc1 ; sc1 = sc1->NEXT )
1839 if( sc1->DATA == nom )
1840 break;
1841
1842 if( ! sc1 )
1843 ptsig->NAMECHAIN = addchain( ptsig->NAMECHAIN, nom );
1844 }
1845 }
1846
1847 /* On construit les vues RCN et/ou CTC */
1848 /*
1849 for( ptsig = ptfig->LOSIG ; ptsig ; ptsig = ptsig->NEXT )
1850 if( ! ptsig->PRCN )
1851 addlorcnet( ptsig );
1852 */
1853
1854 triecapa( ptcir );
1855
1856 for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
1857 {
1858 if( !tabsig[ scancapa->N1->SIGNAL -1 ]->PRCN )
1859 addlorcnet( tabsig[ scancapa->N1->SIGNAL -1 ] );
1860
1861 if( !tabsig[ scancapa->N2->SIGNAL -1 ]->PRCN )
1862 addlorcnet( tabsig[ scancapa->N2->SIGNAL -1 ] );
1863
1864 tabsig[ scancapa->N1->SIGNAL -1 ]->PRCN->CAPA += scancapa->CAPA;
1865 tabsig[ scancapa->N2->SIGNAL -1 ]->PRCN->CAPA += scancapa->CAPA;
1866 }
1867
1868 for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
1869 {
1870 if( !tabsig[ scanresi->N1->SIGNAL - 1 ]->PRCN )
1871 addlorcnet( tabsig[ scanresi->N1->SIGNAL - 1 ] );
1872
1873 addlowire( tabsig[ scanresi->N1->SIGNAL - 1 ],
1874 RCN_WIRE_UNKNOW,
1875 0,
1876 scanresi->RESI,
1877 scanresi->CAPA,
1878 0l,
1879 0l,
1880 0l,
1881 0l,
1882 scanresi->N1->RCN,
1883 scanresi->N2->RCN
1884 );
1885 }
1886
1887 for( scanvalim = ptcir->VALIM ; scanvalim ; scanvalim = scanvalim->SUIV )
1888 {
1889 if( !tabsig[ scanvalim->N1->SIGNAL - 1 ]->PRCN )
1890 addlorcnet( tabsig[ scanvalim->N1->SIGNAL - 1 ] );
1891
1892 addlowire( tabsig[ scanvalim->N1->SIGNAL - 1 ],
1893 RCN_WIRE_UNKNOW,
1894 0,
1895 0.0,
1896 0.0,
1897 0l,
1898 0l,
1899 0l,
1900 0l,
1901 scanvalim->N1->RCN,
1902 scanvalim->N2->RCN
1903 );
1904 }
1905
1906 for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
1907 {
1908 if( !tabsig[ scancapa->N1->SIGNAL - 1 ]->PRCN )
1909 addlorcnet( tabsig[ scancapa->N1->SIGNAL - 1 ] );
1910
1911 if( !tabsig[ scancapa->N2->SIGNAL - 1 ]->PRCN )
1912 addlorcnet( tabsig[ scancapa->N2->SIGNAL - 1 ] );
1913
1914 if( scancapa->NOM != NULL && scancapa->N1 != scancapa->N2 )
1915 {
1916 ptctc = getloctc( tabsig[ scancapa->N1->SIGNAL - 1 ],
1917 scancapa->N1->RCN ? scancapa->N1->RCN : 1,
1918 tabsig[ scancapa->N2->SIGNAL - 1 ],
1919 scancapa->N2->RCN ? scancapa->N2->RCN : 1
1920 );
1921
1922 if( ptctc )
1923 ptctc->CAPA = ptctc->CAPA + scancapa->CAPA;
1924 else
1925 addloctc( tabsig[ scancapa->N1->SIGNAL - 1 ],
1926 scancapa->N1->RCN ? scancapa->N1->RCN : 1,
1927 tabsig[ scancapa->N2->SIGNAL - 1 ],
1928 scancapa->N2->RCN ? scancapa->N2->RCN : 1,
1929 scancapa->CAPA
1930 );
1931 }
1932 }
1933
1934 /* Connecteurs de l'interface */
1935
1936 for( sc1 = ptcir->CINTERF, sc2 = instances->GINTERF ;
1937 sc1 && sc2 ;
1938 sc1 = sc1->NEXT, sc2 = sc2->NEXT
1939 )
1940 {
1941 ptnoeud = (noeud*)(sc1->DATA);
1942
1943 for( scanlocon = ptfig->LOCON ; scanlocon ; scanlocon = scanlocon->NEXT )
1944 if( scanlocon->SIG->INDEX == ptnoeud->SIGNAL )
1945 break;
1946
1947 if( !scanlocon )
1948 {
1949 ptsig = tabsig[ ptnoeud->SIGNAL - 1 ];
1950 ptsig->TYPE = 'E';
1951
1952 devect = spi_devect( (char*)(sc2->DATA) );
1953
1954 if( SPI_MERGE == 1 )
1955 stopchainsepar( devect );
1956
1957 nom = namealloc( devect );
1958 mbkfree( devect );
1959
1960 scanlocon = addlocon( ptfig, nom, ptsig, UNKNOWN );
1961 scanlocon->USER = addptype( scanlocon->USER, PNODENAME, NULL );
1962 }
1963
1964 if( ptnoeud->RCN )
1965 {
1966 if( !scanlocon->SIG->PRCN )
1967 addlorcnet( scanlocon->SIG );
1968
1969 setloconnode( scanlocon, ptnoeud->RCN );
1970 ptnodename = getptype( scanlocon->USER, PNODENAME );
1971
1972 if( ptnoeud->NOM )
1973 ptnodename->DATA = addchain( ((chain_list*)(ptnodename->DATA)), namealloc( ptnoeud->NOM ) );
1974 else
1975 ptnodename->DATA = addchain( ((chain_list*)(ptnodename->DATA)), NULL );
1976 }
1977 }
1978
1979 if( sc1 || sc2 )
1980 {
1981 fflush( stdout );
1982 fprintf( stderr,"sc1 ou sc2.\n" );
1983 EXIT(-1);
1984 }
1985
1986 for( scanlocon = ptfig->LOCON ; scanlocon ; scanlocon = scanlocon->NEXT )
1987 {
1988 scanlocon->PNODE = (struct num *)reverse( (chain_list*)scanlocon->PNODE );
1989
1990 ptnodename = getptype( scanlocon->USER, PNODENAME );
1991 for( sc1 = (chain_list*)( ptnodename->DATA ) ; sc1 ; sc1 = sc1->NEXT )
1992 if( sc1->DATA )
1993 break;
1994 if( sc1 )
1995 ptnodename->DATA = reverse( ((chain_list*)(ptnodename->DATA)) );
1996 else
1997 {
1998 freechain( (chain_list*)ptnodename->DATA );
1999 scanlocon->USER = delptype( scanlocon->USER, PNODENAME );
2000 }
2001 }
2002
2003 ptfig->LOCON = (locon_list *)reverse( (chain_list*)ptfig->LOCON );
2004
2005 /* On cree les transistors */
2006
2007 for( scantrans = ptcir->TRANS; scantrans; scantrans = scantrans->SUIV )
2008 {
2009 pttrs = addlotrs(
2010 ptfig,
2011 scantrans->TYPE,
2012 float2long( scantrans->X ),
2013 float2long( scantrans->Y ),
2014 float2long( scantrans->W * SCALE_X * 1e6 ),
2015 float2long( scantrans->L * SCALE_X * 1e6 ),
2016 float2long( scantrans->PS * SCALE_X * 1e6 ),
2017 float2long( scantrans->PD * SCALE_X * 1e6 ),
2018 float2long( scantrans->AS * SCALE_X * 1e6 / scantrans->W ),
2019 float2long( scantrans->AD * SCALE_X * 1e6 / scantrans->W ),
2020 tabsig[ scantrans->GRILLE->SIGNAL - 1 ],
2021 tabsig[ scantrans->SOURCE->SIGNAL - 1 ],
2022 tabsig[ scantrans->DRAIN->SIGNAL - 1 ],
2023 scantrans->SUBST ?
2024 tabsig[ scantrans->SUBST->SIGNAL - 1 ] :
2025 NULL,
2026 scantrans->NOM
2027 );
2028
2029 if( scantrans->DRAIN->RCN )
2030 {
2031 if( !pttrs->DRAIN->SIG->PRCN )
2032 addlorcnet( pttrs->DRAIN->SIG );
2033 setloconnode(pttrs->DRAIN, scantrans->DRAIN->RCN );
2034 if( scantrans->DRAIN->NOM )
2035 pttrs->DRAIN->USER = addptype( pttrs->DRAIN->USER,
2036 PNODENAME,
2037 addchain( NULL,
2038 namealloc( scantrans->DRAIN->NOM)
2039 )
2040 );
2041 }
2042
2043 if( scantrans->GRILLE->RCN )
2044 {
2045 if( !pttrs->GRID->SIG->PRCN )
2046 addlorcnet( pttrs->GRID->SIG );
2047 setloconnode(pttrs->GRID, scantrans->GRILLE->RCN );
2048 if( scantrans->GRILLE->NOM )
2049 pttrs->GRID->USER = addptype( pttrs->GRID->USER,
2050 PNODENAME,
2051 addchain( NULL,
2052 namealloc( scantrans->GRILLE->NOM)
2053 )
2054 );
2055 }
2056
2057 if( scantrans->SOURCE->RCN )
2058 {
2059 if( !pttrs->SOURCE->SIG->PRCN )
2060 addlorcnet( pttrs->SOURCE->SIG );
2061 setloconnode(pttrs->SOURCE, scantrans->SOURCE->RCN );
2062 if( scantrans->SOURCE->NOM )
2063 pttrs->SOURCE->USER = addptype( pttrs->SOURCE->USER,
2064 PNODENAME,
2065 addchain( NULL,
2066 namealloc( scantrans->SOURCE->NOM)
2067 )
2068 );
2069 }
2070
2071 if( scantrans->SUBST )
2072 {
2073 if( scantrans->SUBST->RCN )
2074 {
2075 if( !pttrs->BULK->SIG->PRCN )
2076 addlorcnet( pttrs->BULK->SIG );
2077 setloconnode(pttrs->BULK, scantrans->SUBST->RCN );
2078 if( scantrans->SUBST->NOM )
2079 pttrs->BULK->USER = addptype( pttrs->BULK->USER,
2080 PNODENAME,
2081 addchain( NULL,
2082 namealloc( scantrans->SUBST->NOM)
2083 )
2084 );
2085 }
2086 }
2087 }
2088
2089 /* On cree les instances */
2090
2091
2092 for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2093 {
2094 connec_sig = NULL;
2095 connec_noeud = NULL;
2096 connec_nom = NULL;
2097 connec_con = NULL;
2098
2099 for( sci = instances ; sci ; sci = sci->SUIV )
2100 {
2101 if( strcasecmp( sci->NOM, scaninst->MODELE ) == 0 )
2102 break;
2103 }
2104
2105 if( !sci )
2106 {
2107 fflush( stdout );
2108 fprintf( stderr,
2109 "Internal error : can't find model %s.\n",
2110 scaninst->MODELE
2111 );
2112 EXIT( 1 );
2113 }
2114
2115 /* Constitue la liste des signaux */
2116 for( sc1 = sci->GINTERF, sc2 = scaninst->IINTERF ;
2117 sc1 && sc2 ;
2118 sc1 = sc1->NEXT, sc2 = sc2->NEXT
2119 )
2120 {
2121 for( sc3 = sci->GINTERF ; sc3 != sc1 ; sc3 = sc3->NEXT )
2122 if( strcasecmp( sc3->DATA, sc1->DATA ) == 0 )
2123 break;
2124
2125 if( sc3 == sc1 ) /* Creation d'un nouveau locon */
2126 {
2127 connec_sig = addchain( connec_sig,
2128 tabsig[ ((noeud*)(sc2->DATA))->SIGNAL - 1 ]
2129 );
2130 connec_noeud = addchain( connec_noeud,
2131 addnum( NULL, ((noeud*)(sc2->DATA))->RCN )
2132 );
2133 connec_nom = addchain( connec_nom,
2134 addchain( NULL,
2135 namealloc( ((noeud*)(sc2->DATA))->NOM )
2136 )
2137 );
2138 connec_con = addchain( connec_con, sc1->DATA );
2139 }
2140 else /* On complete des noeuds d'un locon */
2141 {
2142 for ( sc3 = connec_con, sc4 = connec_noeud, sc5 = connec_nom ;
2143 strcasecmp( (char*)sc3->DATA, (char*)sc1->DATA ) != 0 ;
2144 sc3 = sc3->NEXT, sc4 = sc4->NEXT, sc5 = sc5->NEXT
2145 ) ;
2146
2147 sc4->DATA = addnum( sc4->DATA, ((noeud*)(sc2->DATA))->RCN );
2148 sc5->DATA = addchain( sc5->DATA, namealloc (
2149 ((noeud*)(sc2->DATA))->NOM
2150 )
2151 );
2152 }
2153 }
2154
2155 freechain( connec_con );
2156 connec_sig = reverse( connec_sig );
2157 connec_noeud = reverse( connec_noeud );
2158 connec_nom = reverse( connec_nom );
2159
2160 nom = namealloc( sci->NOM );
2161
2162 modele = getlomodel( tetemodele, nom );
2163 if( !modele )
2164 modele = tetemodele = recuperemodele( tetemodele, nom, sci->GINTERF );
2165
2166 ptinst = addloins( ptfig, "*", modele, connec_sig );
2167 ptinst->INSNAME = namealloc( scaninst->NOM ) ;
2168
2169 ptinst->USER = constphinterf( ptinst->USER, sci );
2170
2171 for( scancon = ptinst->LOCON, sc1 = connec_noeud, sc2 = connec_nom ;
2172 scancon ;
2173 scancon = scancon->NEXT, sc1 = sc1->NEXT, sc2 = sc2->NEXT
2174 )
2175 {
2176 interf = (num_list*)sc1->DATA;
2177 scancon->USER = addptype( scancon->USER, PNODENAME, NULL );
2178 ptnodename = scancon->USER;
2179
2180 if( interf->DATA )
2181 {
2182 if( !scancon->SIG->PRCN )
2183 addlorcnet( scancon->SIG );
2184
2185 for( ; interf ; interf = interf->NEXT )
2186 setloconnode( scancon, interf->DATA );
2187
2188 sc3 = (chain_list*)sc2->DATA;
2189 for( ; sc3 ; sc3 = sc3->NEXT )
2190 ptnodename->DATA = addchain(((chain_list*)(ptnodename->DATA)),
2191 sc3->DATA
2192 );
2193
2194 }
2195 }
2196
2197 freechain( connec_sig );
2198 for( sc1 = connec_noeud ; sc1 ; sc1 = sc1->NEXT )
2199 freenum( sc1->DATA );
2200 freechain( connec_noeud );
2201 for( sc1 = connec_nom ; sc1 ; sc1 = sc1->NEXT )
2202 freechain( sc1->DATA );
2203 freechain( connec_nom );
2204
2205 for( scancon = ptinst->LOCON ; scancon ; scancon = scancon->NEXT )
2206 {
2207 ptnodename = getptype( scancon->USER, PNODENAME );
2208 for( sc1 = (chain_list*)( ptnodename->DATA ) ; sc1 ; sc1 = sc1->NEXT )
2209 if( sc1->DATA )
2210 break;
2211 if( !sc1 )
2212 {
2213 freechain( (chain_list*)ptnodename->DATA );
2214 scancon->USER = delptype( scancon->USER, PNODENAME );
2215 }
2216 }
2217 }
2218
2219 ptfig->MODE = mode;
2220 mbkfree( tabsig );
2221 freelomodel( tetemodele );
2222
2223 ptfig->LOTRS = ( lotrs_list* ) reverse( (chain_list*) ptfig->LOTRS );
2224
2225 lofigchain( ptfig );
2226 }
2227
2228 /******************************************************************************/
2229
lireligne(df)2230 chain_list* lireligne( df )
2231 spifile *df;
2232 {
2233 chain_list *sc;
2234 chain_list *eff;
2235
2236 if( df->decomp2 == NULL )
2237 {
2238 df->decomp1 = decompligne(df);
2239 strcpy( df->file_line1, df->file_line );
2240 }
2241 else
2242 {
2243 df->decomp1 = df->decomp2;
2244 strcpy( df->file_line1, df->file_line2 );
2245 }
2246
2247 if( df->decomp1 == NULL ) /* cas d'un fichier vide */
2248 return(NULL);
2249
2250 while( TRUE )
2251 {
2252 df->decomp2 = decompligne(df);
2253 strcpy( df->file_line2, df->file_line );
2254
2255 if( df->decomp2 == NULL )
2256 break;
2257
2258 /*
2259 if( strcmp( (char*)df->decomp2->DATA, "+" ) != 0 )
2260 */
2261 if( ((char*)(df->decomp2->DATA))[0] != '+' ||
2262 ((char*)(df->decomp2->DATA))[1] != 0 )
2263 break;
2264
2265 /* On reforme les lignes s�par�es par des + */
2266
2267 eff = df->decomp2;
2268 df->decomp2 = df->decomp2->NEXT;
2269 eff->NEXT = NULL;
2270 mbkfree( eff->DATA );
2271 freechain(eff);
2272
2273 for( sc = df->decomp1; sc->NEXT; sc = sc->NEXT );
2274 sc->NEXT = df->decomp2;
2275 }
2276 return( df->decomp1 );
2277 }
2278
2279 /******************************************************************************/
2280
decompligne(df)2281 chain_list* decompligne( df )
2282 spifile *df;
2283 {
2284 char mot[LONG_LIGNE];
2285 int lg;
2286 chain_list *decomp;
2287 char motencours;
2288 char *element;
2289 int i, j=0 ; /* Warning a la compilation */
2290
2291 do
2292 {
2293 df->msl_line++;
2294 decomp = NULL;
2295
2296 fgets( df->file_line, LONG_LIGNE, df->df );
2297
2298 if( feof(df->df) )
2299 return( NULL );
2300
2301 lg = strlen(df->file_line);
2302
2303 if( lg == LONG_LIGNE-1 )
2304 spierror( 48, df->filename, df->msl_line );
2305
2306 motencours = 0;
2307
2308 /* Un cas particulier : si le premier caractere de la ligne est
2309 * un '+'. Sur la suite de la ligne, le '+' sera considere comme un
2310 * caractere standard. */
2311
2312 i=0;
2313 while( df->file_line[i] == ' ' )
2314 i++;
2315
2316 if( df->file_line[i] == '+' )
2317 {
2318 element = (char*)mbkalloc( 2 * sizeof(char) );
2319 element[0] = df->file_line[i];
2320 element[1] = 0;
2321 decomp = addchain( decomp, element );
2322 i++;
2323 }
2324
2325 /* On traite le reste de la ligne */
2326
2327 for( ; i<lg; i++ )
2328 {
2329 if( ( df->file_line[i] >= 'A' && df->file_line[i] <= 'Z' ) ||
2330 ( df->file_line[i] >= 'a' && df->file_line[i] <= 'z' ) ||
2331 ( df->file_line[i] >= '0' && df->file_line[i] <= '9' ) ||
2332 strchr( ":/$<>[]._-|+@", df->file_line[i] ) )
2333 {
2334 if( !motencours )
2335 {
2336 motencours = 1;
2337 j = 0;
2338 }
2339 mot[j++] = df->file_line[i];
2340 }
2341 else
2342 {
2343 if( motencours )
2344 {
2345 mot[j++] = 0;
2346
2347 element = (char*)mbkalloc( j * sizeof(char) );
2348 memcpy( element, mot, j );
2349 decomp = addchain( decomp, element );
2350
2351 motencours = 0;
2352 }
2353
2354 if( strchr( "=*$", df->file_line[i] ) )
2355 {
2356 element = (char*)mbkalloc( 2 * sizeof(char) );
2357 element[0] = df->file_line[i];
2358 element[1] = 0;
2359 decomp = addchain( decomp, element );
2360 }
2361 }
2362 }
2363 }
2364 while(!decomp);
2365
2366 return(reverse(decomp));
2367 }
2368
2369 /******************************************************************************/
2370
liberecircuit(ptcir)2371 void liberecircuit( ptcir )
2372 circuit *ptcir;
2373 {
2374 chain_list *scanchain;
2375 inst *scaninst;
2376
2377 for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2378 freechain( scaninst->IINTERF );
2379
2380 for( scanchain = ptcir->FREE ; scanchain ; scanchain = scanchain->NEXT )
2381 mbkfree( scanchain->DATA );
2382
2383 freechain( ptcir->FREE );
2384 freechain( ptcir->CINTERF );
2385 freetableint( ptcir->INT_NOEUD );
2386 freethash( ptcir->HASHGNAME );
2387 freethash( ptcir->HASHCAPA );
2388 freethash( ptcir->HASHRESI );
2389 freethash( ptcir->HASHVALIM );
2390 freethash( ptcir->HASHINST );
2391 freethash( ptcir->HASHTRAN );
2392 freethash( ptcir->NOM_NOEUD );
2393 mbkfree( ptcir );
2394 }
2395
2396 /******************************************************************************/
2397
ajoutenoeud(ptcir,index,df)2398 noeud* ajoutenoeud( ptcir, index, df )
2399 circuit *ptcir;
2400 char *index;
2401 spifile *df;
2402 {
2403 int val;
2404 char *fin;
2405 noeud *sn;
2406 char *nom = NULL;
2407
2408 val = strtol( index, &fin, 10 );
2409
2410 if( fin != index ) /* Ca commence par un nombre */
2411 {
2412 if( *fin!=0 )
2413 {
2414 fflush( stdout );
2415 fprintf( stderr, "%s\n", SPIMSG(0) );
2416 fprintf( stderr, "%s : %s\n", SPIMSG(49), index );
2417 fprintf( stderr, "%s %s. %s %d :\n",
2418 SPIMSG(11),
2419 df->filename,
2420 SPIMSG(12),
2421 df->msl_line
2422 );
2423 EXIT( 1 );
2424 }
2425
2426 sn = (noeud*) tsttableint( ptcir->INT_NOEUD, val );
2427 if( sn )
2428 return( sn );
2429 }
2430 else
2431 {
2432 if(!(( index[0] >= 'A' && index[0] <= 'Z' ) ||
2433 ( index[0] >= 'a' && index[0] <= 'z' ) ||
2434 ( index[0] == '_' || index[0] == '@' ) ) )
2435 {
2436 fflush( stdout );
2437 fprintf( stderr, "%s\n", SPIMSG(0) );
2438 fprintf( stderr, "%s : %s\n", SPIMSG(50), index );
2439 fprintf( stderr, "%s %s. %s %d :\n",
2440 SPIMSG(11),
2441 df->filename,
2442 SPIMSG(12),
2443 df->msl_line
2444 );
2445 EXIT( 1 );
2446 }
2447
2448 nom = spicenamealloc( ptcir, index );
2449
2450 sn = getthashelem( nom, ptcir->NOM_NOEUD, NULL );
2451 if( sn )
2452 return( sn );
2453 }
2454
2455 sn = (noeud*)spiciralloue( ptcir, sizeof(noeud) );
2456 sn->SUIV = ptcir->NOEUD;
2457 ptcir->NOEUD = sn;
2458
2459 sn->NOM = nom;
2460 sn->SIGNAL = 0;
2461 sn->RCN = 0;
2462 sn->SPICE = val;
2463
2464 if( val != -1 )
2465 settableint( ptcir->INT_NOEUD, val, sn );
2466 if( nom )
2467 addthashelem( nom, sn, ptcir->NOM_NOEUD );
2468
2469 return(sn);
2470 }
2471
2472 /******************************************************************************/
2473
nomenoeud(ptcir,ptnoeud,ptnom,df)2474 void nomenoeud( ptcir, ptnoeud, ptnom, df )
2475 circuit *ptcir;
2476 noeud *ptnoeud;
2477 char *ptnom;
2478 spifile *df;
2479 {
2480 if( ptnoeud->NOM )
2481 {
2482 fflush( stdout );
2483 fprintf( stderr, "%s\n", SPIMSG(0) );
2484 fprintf( stderr, "%s : %s\n", SPIMSG(51), ptnoeud->NOM );
2485 fprintf( stderr, "%s %s. %s %d :\n",
2486 SPIMSG(11),
2487 df->filename,
2488 SPIMSG(12),
2489 df->msl_line
2490 );
2491 EXIT( 1 );
2492 }
2493
2494 ptnoeud->NOM = spicenamealloc( ptcir, ptnom );
2495 addthashelem( ptnoeud->NOM, ptnoeud, ptcir->NOM_NOEUD );
2496 }
2497
2498 /******************************************************************************/
2499
spicenamealloc(ptcir,ptnom)2500 char* spicenamealloc( ptcir, ptnom )
2501 circuit *ptcir;
2502 char *ptnom;
2503 {
2504 char *elem;
2505 char tmp[LONG_LIGNE];
2506 int l;
2507
2508 downstr( ptnom, tmp );
2509 /* Bug dans la fonction downstr : il ne recopie pas le 0 de fin de chaine */
2510 tmp[ strlen(ptnom) ] = 0;
2511
2512 elem = getthashelem( tmp, ptcir->HASHGNAME, NULL );
2513 if( elem )
2514 return( elem );
2515
2516 l = sizeof(char) * (strlen( tmp ) + 1 );
2517 if( ptcir->RESTENOM < l )
2518 {
2519 ptcir->ALLOUENOM = (char*)spiciralloue( ptcir, TAILLENOM );
2520 ptcir->RESTENOM = TAILLENOM;
2521 }
2522
2523 elem = strcpy( ptcir->ALLOUENOM + ( TAILLENOM - ptcir->RESTENOM ), tmp );
2524 ptcir->RESTENOM = ptcir->RESTENOM - l;
2525 addthashelem( elem, elem, ptcir->HASHGNAME );
2526 return( elem );
2527 }
2528
2529 /******************************************************************************/
2530
spiciralloue(cir,taille)2531 void* spiciralloue( cir, taille )
2532 circuit *cir;
2533 int taille;
2534 {
2535 void *pt;
2536
2537 if(!cir)
2538 {
2539 fflush( stdout );
2540 fprintf( stderr, "*** mbkspi internal error *** : spiciralloue()\n" );
2541 EXIT(1);
2542 }
2543
2544 pt = mbkalloc( taille );
2545 cir->FREE = addchain( cir->FREE, pt );
2546 cir->TAILLE = cir->TAILLE + taille ;
2547 return( pt );
2548 }
2549
2550 /******************************************************************************/
2551
spicefloat(nombre,status)2552 float spicefloat( nombre, status )
2553 char *nombre;
2554 int *status;
2555 {
2556 float valeur;
2557 char *fin;
2558
2559 /* Les caract�res suivant une unit� sont ignor�s */
2560
2561 *status = -1 ;
2562
2563 valeur = (float)strtod( nombre, &fin );
2564
2565 if( *fin == 0 )
2566 *status = 1;
2567 else
2568 if( strncasecmp( fin, "F", 1 ) == 0 )
2569 {
2570 *status = 1;
2571 valeur = valeur * 1e-15 ;
2572 }
2573 else
2574 if( strncasecmp( fin, "P", 1 ) == 0 )
2575 {
2576 *status = 1;
2577 valeur = valeur * 1e-12 ;
2578 }
2579 else
2580 if( strncasecmp( fin, "N", 1 ) == 0 )
2581 {
2582 *status = 1;
2583 valeur = valeur * 1e-9 ;
2584 }
2585 else
2586 if( strncasecmp( fin, "U", 1 ) == 0 )
2587 {
2588 *status = 1;
2589 valeur = valeur * 1e-6 ;
2590 }
2591 else
2592 if( strncasecmp( fin, "M", 1 ) == 0 )
2593 {
2594 *status = 1;
2595 valeur = valeur * 1e-3 ;
2596 }
2597 else
2598 if( strncasecmp( fin, "K", 1 ) == 0 )
2599 {
2600 *status = 1;
2601 valeur = valeur * 1e+3 ;
2602 }
2603 else
2604 if( strncasecmp( fin, "MEG", 3 ) == 0 )
2605 {
2606 *status = 1;
2607 valeur = valeur * 1e+6 ;
2608 }
2609 else
2610 if( strncasecmp( fin, "MI", 2 ) == 0 )
2611 {
2612 *status = 1;
2613 valeur = valeur * 25.4e+6 ;
2614 }
2615 else
2616 if( strncasecmp( fin, "G", 1 ) == 0 )
2617 {
2618 *status = 1;
2619 valeur = valeur * 1e+9 ;
2620 }
2621 else /*unit values*/
2622 if( strncasecmp( fin, "V", 1 ) == 0 )
2623 {
2624 *status = 1;
2625 valeur = valeur * 1e+9 ;
2626 }
2627
2628 return( valeur);
2629 }
2630
2631 /******************************************************************************/
2632
triecapa(ptcir)2633 void triecapa( ptcir )
2634 circuit *ptcir;
2635 {
2636 resi *scanresi;
2637 char *n1, *n2;
2638 capa *c1, *c2;
2639 noeud *tmp;
2640 char *vss;
2641
2642 vss = spicenamealloc( ptcir, VSS);
2643
2644 for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
2645 {
2646 n1 = mbkalloc( sizeof( char ) * ( strlen(scanresi->NOM) + 2 ) );
2647 n2 = mbkalloc( sizeof( char ) * ( strlen(scanresi->NOM) + 2 ) );
2648
2649 sprintf( n1 , "%s1", scanresi->NOM );
2650 sprintf( n2 , "%s2", scanresi->NOM );
2651
2652 c1 = NULL;
2653 c2 = NULL;
2654
2655 c1 = getthashelem( n1, ptcir->HASHCAPA, NULL );
2656 c2 = getthashelem( n2, ptcir->HASHCAPA, NULL );
2657
2658 if( !c1 || !c2 )
2659 {
2660 scanresi->CAPA = 0.0;
2661 mbkfree( n1 );
2662 mbkfree( n2 );
2663 continue;
2664 }
2665
2666 if( c1->N2->NOM == vss )
2667 {
2668 tmp = c1->N2;
2669 c1->N2 = c1->N1;
2670 c1->N1 = tmp;
2671 }
2672 else
2673 if( c1->N1->NOM != vss )
2674 {
2675 scanresi->CAPA = 0.0;
2676 mbkfree( n1 );
2677 mbkfree( n2 );
2678 continue;
2679 }
2680
2681 if( c2->N2->NOM == vss )
2682 {
2683 tmp = c2->N2;
2684 c2->N2 = c2->N1;
2685 c2->N1 = tmp;
2686 }
2687 else
2688 if( c2->N1->NOM != vss )
2689 {
2690 scanresi->CAPA = 0.0;
2691 mbkfree( n1 );
2692 mbkfree( n2 );
2693 continue;
2694 }
2695
2696 if( c1->CAPA != c2->CAPA )
2697 {
2698 scanresi->CAPA = 0.0;
2699 mbkfree( n1 );
2700 mbkfree( n2 );
2701 continue;
2702 }
2703
2704 if( ( c1->N2 == scanresi->N1 && c2->N2 == scanresi->N2 ) ||
2705 ( c2->N2 == scanresi->N1 && c1->N2 == scanresi->N1 ) )
2706 {
2707 /* On ne prendra plus ces capacites en compte */
2708
2709 c1->NOM = NULL;
2710 c2->NOM = NULL;
2711
2712 scanresi->CAPA = c1->CAPA+c1->CAPA;
2713 }
2714 else
2715 {
2716 scanresi->CAPA = 0.0;
2717 mbkfree( n1 );
2718 mbkfree( n2 );
2719 continue;
2720 }
2721
2722 mbkfree( n1 );
2723 mbkfree( n2 );
2724
2725 }
2726 }
2727
2728 /******************************************************************************/
2729
float2long(v)2730 long float2long( v )
2731 float v;
2732 {
2733 long i;
2734 float r;
2735
2736 i = v;
2737 r = v-i;
2738
2739 if( r >= 0.5 )
2740 return ( i+1 );
2741 return(i);
2742 }
2743
2744 /******************************************************************************/
2745
taillevuespice(ptcir)2746 void taillevuespice( ptcir )
2747 circuit *ptcir;
2748 {
2749 int nb_noeud = 0;
2750 int nb_resi = 0;
2751 int nb_capa = 0;
2752 int nb_inst = 0;
2753 int nb_alim = 0;
2754 int nb_trans = 0;
2755 int total;
2756 noeud *scannoeud;
2757 resi *scanresi;
2758 capa *scancapa;
2759 trans *scantrans;
2760 inst *scaninst;
2761 valim *scanalim;
2762
2763 for( scannoeud = ptcir->NOEUD ; scannoeud ; scannoeud = scannoeud->SUIV )
2764 nb_noeud++;
2765
2766 for( scantrans = ptcir->TRANS ; scantrans ; scantrans = scantrans->SUIV )
2767 nb_trans++;
2768
2769 for( scanresi = ptcir->RESI ; scanresi ; scanresi = scanresi->SUIV )
2770 nb_resi++;
2771
2772 for( scancapa = ptcir->CAPA ; scancapa ; scancapa = scancapa->SUIV )
2773 nb_capa++;
2774
2775 for( scaninst = ptcir->INST ; scaninst ; scaninst = scaninst->SUIV )
2776 nb_inst++;
2777
2778 for( scanalim = ptcir->VALIM ; scanalim ; scanalim = scanalim->SUIV )
2779 nb_alim++;
2780
2781 printf( "Data size structure :\n" );
2782 printf( " noeud : %7dx%3d = %9d\n",
2783 nb_noeud,
2784 sizeof( noeud ),
2785 nb_noeud * sizeof(noeud)
2786 );
2787 printf( " trans : %7dx%3d = %9d\n",
2788 nb_trans,
2789 sizeof(trans),
2790 nb_trans * sizeof(trans)
2791 );
2792 printf( " resi : %7dx%3d = %9d\n",
2793 nb_resi,
2794 sizeof(resi),
2795 nb_resi * sizeof(resi)
2796 );
2797 printf( " capa : %7dx%3d = %9d\n",
2798 nb_capa,
2799 sizeof(capa),
2800 nb_capa * sizeof(capa)
2801 );
2802 printf( " inst : %7dx%3d = %9d\n",
2803 nb_inst,
2804 sizeof(inst),
2805 nb_inst * sizeof(inst)
2806 );
2807 printf( " alim : %7dx%3d = %9d\n",
2808 nb_alim,
2809 sizeof(valim),
2810 nb_alim * sizeof(valim)
2811 );
2812
2813 total = nb_noeud * sizeof(noeud) +
2814 nb_trans * sizeof(trans) +
2815 nb_resi * sizeof(resi) +
2816 nb_capa * sizeof(capa) +
2817 nb_inst * sizeof(inst) +
2818 nb_alim * sizeof(valim);
2819
2820 printf( "Total : %d.\n", total );
2821 printf( "Real size : %ld\n", ptcir->TAILLE );
2822
2823 }
2824
2825 /******************************************************************************/
2826
affvuespice(ptcir)2827 void affvuespice( ptcir )
2828 circuit *ptcir;
2829 {
2830 chain_list *sc;
2831 inst *scaninst;
2832 trans *scantrans;
2833 resi *scanresi;
2834 capa *scancapa;
2835
2836 printf("Circuit : %s\n", ptcir->NOM );
2837
2838 printf("Interface :\n");
2839 for( sc = ptcir->CINTERF; sc; sc = sc->NEXT )
2840 printf(" %ld %4d %4d %4d %s\n",
2841 ((unsigned long)(sc->DATA)),
2842 ((noeud*)(sc->DATA))->SPICE,
2843 ((noeud*)(sc->DATA))->SIGNAL,
2844 ((noeud*)(sc->DATA))->RCN,
2845 ((noeud*)(sc->DATA))->NOM ? ((noeud*)(sc->DATA))->NOM : "" );
2846
2847 for(scantrans = ptcir->TRANS; scantrans; scantrans = scantrans->SUIV)
2848 {
2849 printf("Transitor : %s\n",scantrans->NOM);
2850 printf(" DRAIN %ld %4d %4d %4d %s\n",
2851 (unsigned long)scantrans->DRAIN,
2852 scantrans->DRAIN->SPICE,
2853 scantrans->DRAIN->SIGNAL,
2854 scantrans->DRAIN->RCN,
2855 scantrans->DRAIN->NOM ? scantrans->DRAIN->NOM : "" );
2856 printf(" GRILLE %ld %4d %4d %4d %s\n",
2857 (unsigned long)scantrans->GRILLE,
2858 scantrans->GRILLE->SPICE,
2859 scantrans->GRILLE->SIGNAL,
2860 scantrans->GRILLE->RCN,
2861 scantrans->GRILLE->NOM ? scantrans->GRILLE->NOM : "" );
2862 printf(" SOURCE %ld %4d %4d %4d %s\n",
2863 (unsigned long)scantrans->SOURCE,
2864 scantrans->SOURCE->SPICE,
2865 scantrans->SOURCE->SIGNAL,
2866 scantrans->SOURCE->RCN,
2867 scantrans->SOURCE->NOM ? scantrans->SOURCE->NOM : "" );
2868 if( scantrans->SUBST )
2869 {
2870 printf(" SUBST %ld %4d %4d %4d %s\n",
2871 (unsigned long)scantrans->SUBST,
2872 scantrans->SUBST->SPICE,
2873 scantrans->SUBST->SIGNAL,
2874 scantrans->SUBST->RCN,
2875 scantrans->SUBST->NOM ? scantrans->SUBST->NOM : "" );
2876 printf(" TYPE %c\n",scantrans->TYPE );
2877 printf(" L=%g W=%g AS=%g AD=%g PS=%g PD=%g\n",scantrans->L,
2878 scantrans->W,
2879 scantrans->AS,
2880 scantrans->AD,
2881 scantrans->PS,
2882 scantrans->PD );
2883 }
2884 }
2885
2886 for(scanresi = ptcir->RESI ; scanresi; scanresi = scanresi->SUIV )
2887 {
2888 printf("Resistance : %s\n",scanresi->NOM);
2889 printf(" N1 %ld %4d %4d %4d %s\n",
2890 (unsigned long)scanresi->N1,
2891 scanresi->N1->SPICE,
2892 scanresi->N1->SIGNAL,
2893 scanresi->N1->RCN,
2894 scanresi->N1->NOM ? scanresi->N1->NOM : "" );
2895 printf(" N2 %ld %4d %4d %4d %s\n",
2896 (unsigned long)scanresi->N2,
2897 scanresi->N2->SPICE,
2898 scanresi->N2->SIGNAL,
2899 scanresi->N2->RCN,
2900 scanresi->N2->NOM ? scanresi->N2->NOM : "" );
2901 printf(" R=%g\n",scanresi->RESI);
2902 }
2903
2904 for(scancapa = ptcir->CAPA ; scancapa; scancapa = scancapa->SUIV )
2905 {
2906 printf("Capacite : %s\n",scancapa->NOM);
2907 printf(" N1 %ld %4d %4d %4d %s\n",
2908 (unsigned long)scancapa->N1,
2909 scancapa->N1->SPICE,
2910 scancapa->N1->SIGNAL,
2911 scancapa->N1->RCN,
2912 scancapa->N1->NOM ? scancapa->N1->NOM : "" );
2913 printf(" N2 %ld %4d %4d %4d %s\n",
2914 (unsigned long)scancapa->N2,
2915 scancapa->N2->SPICE,
2916 scancapa->N2->SIGNAL,
2917 scancapa->N2->RCN,
2918 scancapa->N2->NOM ? scancapa->N2->NOM : "" );
2919 printf(" C=%g\n",scancapa->CAPA);
2920 }
2921
2922 for( scaninst = ptcir->INST; scaninst; scaninst = scaninst->SUIV)
2923 {
2924 printf("Instance %s basee sur %s\n",scaninst->NOM, scaninst->MODELE);
2925 for( sc = scaninst->IINTERF; sc; sc = sc->NEXT )
2926 printf(" %ld %4d %4d %4d %s\n",
2927 ((unsigned long)(sc->DATA)),
2928 ((noeud*)(sc->DATA))->SPICE,
2929 ((noeud*)(sc->DATA))->SIGNAL,
2930 ((noeud*)(sc->DATA))->RCN,
2931 ((noeud*)(sc->DATA))->NOM ? ((noeud*)(sc->DATA))->NOM : "" );
2932 }
2933 }
2934
2935 /******************************************************************************/
2936
retireextention(nom)2937 char* retireextention( nom )
2938 char *nom;
2939 {
2940 char *pt;
2941 int i;
2942
2943 pt = mbkstrdup( nom );
2944
2945 /* On retire l'extention du nom, c'est a dire qu'on arrete la chaine au
2946 * dernier point rencontr� */
2947 /* >0 : On laisse quand meme 1 caractere si le nom commence par un point */
2948 for( i = strlen( pt ) - 1 ; i > 0 ; i-- )
2949 if( pt[i] == '.' )
2950 {
2951 pt[i] = 0;
2952 break;
2953 }
2954
2955 return( pt );
2956 }
2957
2958 /******************************************************************************/
2959
recuperemodele(tetemodel,nom,interf)2960 lofig_list* recuperemodele( tetemodel, nom, interf )
2961 lofig_list *tetemodel;
2962 char *nom;
2963 chain_list *interf;
2964 {
2965 lofig_list *ptmod;
2966 chain_list *sc1, *sc2;
2967 char *nomdevec;
2968
2969 ptmod = addlomodel( tetemodel, nom );
2970
2971 for( sc1 = interf ; sc1 ; sc1 = sc1->NEXT )
2972 {
2973 for( sc2 = interf; sc1 != sc2 ; sc2 = sc2->NEXT )
2974 if( strcasecmp( sc1->DATA, sc2->DATA ) == 0 )
2975 break;
2976
2977 if( sc1 != sc2 )
2978 continue;
2979
2980 nomdevec = spi_devect( (char*)(sc1->DATA) );
2981 ptmod->LOCON = addlocon( ptmod, namealloc( nomdevec ), NULL, 'X' );
2982 mbkfree( nomdevec );
2983 }
2984
2985 ptmod->LOCON = (locon_list*)reverse( (chain_list*) ptmod->LOCON );
2986 return( ptmod );
2987 }
2988
2989 /******************************************************************************/
2990
2991 void mslAddExtension(mslExtHandler)
2992 int (*mslExtHandler)();
2993 {
2994 ext_handler = mslExtHandler;
2995 }
2996
2997 /******************************************************************************/
2998
mslRmvExtension()2999 void mslRmvExtension()
3000 {
3001 ext_handler = NULL;
3002 }
3003
3004 /******************************************************************************/
3005
3006 void mslAddCompletion(mslCmpHandler)
3007 int (*mslCmpHandler)();
3008 {
3009 cmp_handler = mslCmpHandler;
3010 }
3011
3012 /******************************************************************************/
3013
mslRmvCompletion()3014 void mslRmvCompletion()
3015 {
3016 cmp_handler = NULL;
3017 }
3018
3019 /******************************************************************************/
3020
spi_devect(nom)3021 char* spi_devect( nom )
3022 char *nom;
3023 {
3024 int taille;
3025 int i;
3026 int j;
3027 char *nouv;
3028 int fin;
3029 int modif;
3030
3031 taille = strlen( nom );
3032 if( taille == 0 )
3033 {
3034 /* message */
3035 EXIT(1);
3036 }
3037
3038 nouv = (char*)mbkalloc( sizeof(char) * (taille+1) );
3039 fin = taille - 1 ;
3040 modif = 0;
3041
3042 if( nom[fin] == ']' )
3043 {
3044 /* Retrouve le crochet ouvrant */
3045 for( i = fin-1 ; i >= 0 && isdigit( (int)nom[i] ) ; i-- );
3046
3047 if( nom[i] == '[' )
3048 {
3049 if( i == 0 || i == fin - 1 )
3050 {
3051 /* nom de variable bizare, de la forme [43] ou toto[] */
3052 fflush( stdout );
3053 fprintf( stderr, "%s : \"%s\"\n", SPIMSG(52), nom );
3054 EXIT(1);
3055 }
3056 else
3057 {
3058 /* bon vecteur : toto[32] */
3059 for( j = 0 ; j < fin ; j++ )
3060 if( i != j )
3061 nouv[j] = nom[j];
3062 else
3063 nouv[i] = ' ';
3064 nouv[j] = 0;
3065
3066 modif = 1;
3067 }
3068 }
3069 else
3070 {
3071 /* Nom de variable bizarre, de la forme toto32], toto] ou 32] */
3072 fflush( stdout );
3073 fprintf( stderr, "%s : \"%s\"\n", SPIMSG(52), nom );
3074 EXIT(1);
3075 }
3076 }
3077
3078 if( ! modif )
3079 strcpy( nouv, nom );
3080
3081 return(nouv);
3082 }
3083
3084 /******************************************************************************/
3085
spierror(mesg,file,line)3086 void spierror( mesg, file, line )
3087 int mesg;
3088 char *file;
3089 int line;
3090 {
3091 fflush( stdout );
3092 fprintf( stderr, "%s.\n", SPIMSG(0) );
3093 fprintf( stderr, "%s. %s %s. %s %d.\n",
3094 SPIMSG(1),
3095 SPIMSG(11),
3096 file,
3097 SPIMSG(12),
3098 line
3099 );
3100 fprintf( stderr, "%s.\n",SPIMSG(mesg));
3101 EXIT(1);
3102 }
3103
3104 /******************************************************************************/
3105
stopchainsepar(chaine)3106 void stopchainsepar( chaine )
3107 char *chaine;
3108 {
3109 int i;
3110
3111 /* On retire le nombre en fin de nom et le SPI_SEPAR */
3112 for( i = strlen( chaine ) - 1 ; i >= 0 ; i-- )
3113 if( ! isdigit( (int)chaine[i] ) )
3114 break;
3115
3116 if( i > 0 )
3117 if( chaine[i] == SPI_SEPAR )
3118 chaine[i] = '\0' ;
3119 }
3120