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 /*******************************************************************************
26 * *
27 * Tool : Spice parser / driver v 7.00 *
28 * Author(s) : Gregoire AVOT *
29 * Updates : August, 17th 1998 *
30 * *
31 *******************************************************************************/
32
33 #define SPI_MAX_COL 80
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <unistd.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <stdarg.h>
42 #include <time.h>
43 #include <ctype.h>
44 #include <string.h>
45 #include <mut.h>
46 #include <mlo.h>
47 #include <rcn.h>
48
49 #include "msl.h"
50 #include "spi_drive.h"
51 #include "spi_int.h"
52 #include "spi_msg.h"
53 #include "spi_global.h"
54
55
56
57 void sort_locap(lofig_list *ptfig,FILE *df) ;
58 void sort_lores(lofig_list *ptfig,FILE *df) ;
59 void sort_loself(lofig_list *ptfig,FILE *df) ;
60
61
62
63
64
65 static char *TNMOS,
66 *TPMOS;
67 static char *SPI_NETNAME;
68 char SPI_NAMEDNODES;
69
70 #define SPI_NONODES (-1l)
71 #define SPI_MAXSTATICNAME 16
72
spivecname(char * name)73 char *spivecname( char *name )
74 {
75 char *new_name;
76 char *blank;
77 unsigned int length;
78 unsigned int pos_blank;
79
80 if ( name != (char *)0 )
81 {
82 blank = strchr( name, ' ' );
83 if ( blank != (char *)0 )
84 {
85 length = strlen( name );
86 pos_blank = blank - name;
87 new_name = (char *)mbkalloc( (length + 2) * sizeof(char) );
88 strcpy(new_name, name);
89 new_name[ pos_blank ] = '[';
90 new_name[ length ] = ']';
91 new_name[ length + 1] = '\0';
92
93 name = namealloc( new_name );
94 mbkfree( new_name );
95 }
96 }
97
98 return( name );
99 }
100
spinamednode(losig,node)101 char* spinamednode( losig, node )
102 losig_list *losig;
103 long node;
104 {
105 static char names[SPI_MAXSTATICNAME][255];
106 static int curnames = 0;
107
108 ptype_list *ptptype;
109 convindex *cvx;
110
111 curnames++;
112 if( curnames == SPI_MAXSTATICNAME )
113 curnames=0;
114
115 if( SPI_NAMEDNODES == TRUE ) {
116 if( node == SPI_NONODES ) {
117 if( losig->NAMECHAIN )
118 sprintf( names[curnames], "%s", spivecname( (char*)(losig->NAMECHAIN->DATA)));
119 else
120 sprintf( names[curnames], "sig%ld", losig->INDEX );
121 }
122 else {
123 if( losig->NAMECHAIN ) {
124 sprintf( names[curnames], "%s%c%ld", spivecname((char*)(losig->NAMECHAIN->DATA)),
125 SEPAR,
126 node
127 );
128 }
129 else {
130 sprintf( names[curnames], "sig%ld%c%ld", losig->INDEX,
131 SEPAR,
132 node
133 );
134 }
135 }
136 }
137 else {
138 ptptype = getptype( losig->USER, SPI_DRIVER_PTYPE );
139 cvx = (convindex*)(ptptype->DATA);
140 if( node == SPI_NONODES )
141 sprintf( names[curnames], "%d", cvx->premier );
142 else
143 sprintf( names[curnames], "%ld", cvx->premier + node - 1 );
144 }
145
146 return( names[curnames] );
147 }
148
cherche_alim(ptfig,vdd,vss)149 void cherche_alim( ptfig, vdd, vss )
150 lofig_list *ptfig;
151 char **vdd;
152 char **vss;
153 {
154 locon_list *scancon;
155 losig_list *signal;
156 static char stvss[255], stvdd[255];
157
158 *vdd = 0;
159 *vss = 0;
160
161 for( scancon = ptfig->LOCON ;
162 scancon && !(*vdd && *vss) ;
163 scancon = scancon->NEXT
164 )
165 {
166 if( isvdd( scancon->NAME ) )
167 {
168 signal = scancon->SIG;
169 if( scancon->PNODE )
170 strcpy( stvdd, spinamednode( signal, scancon->PNODE->DATA ) );
171 else
172 strcpy( stvdd, spinamednode( signal, SPI_NONODES ) );
173
174 *vdd = stvdd;
175 }
176
177 if( isvss( scancon->NAME ) )
178 {
179 signal = scancon->SIG;
180 if( scancon->PNODE )
181 strcpy( stvss, spinamednode( signal, scancon->PNODE->DATA ) );
182 else
183 strcpy( stvss, spinamednode( signal, SPI_NONODES ) );
184
185 *vss = stvss;
186 }
187 }
188 }
189
sortrcn(ptfig,df,vss)190 void sortrcn( ptfig, df, vss )
191 lofig_list *ptfig;
192 FILE *df;
193 char *vss;
194 {
195 losig_list *scanlosig;
196 int nbr;
197 lowire_list *scanlowire;
198 int nbctc;
199 chain_list *scanchain;
200 chain_list *headctc;
201 loctc_list *ptctc;
202
203 nbctc = 0;
204
205 for( scanlosig = ptfig->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
206 {
207 if( !scanlosig->PRCN )
208 continue;
209
210 if( scanlosig->PRCN->PWIRE || scanlosig->PRCN->PCTC )
211 {
212 nbr = 1;
213
214
215 for( scanlowire = scanlosig->PRCN->PWIRE ;
216 scanlowire ;
217 scanlowire = scanlowire->NEXT )
218 {
219 tooutput( df,
220 "R%d_%d %s %s %g\n",
221 scanlosig->INDEX,
222 nbr,
223 spinamednode( scanlosig, scanlowire->NODE1 ),
224 spinamednode( scanlosig, scanlowire->NODE2 ),
225 scanlowire->RESI < RESIMINI ? RESIMINI : scanlowire->RESI
226 );
227
228 /* HSpice ne supporte pas 1e-6P : Il ne prendra pas en compte le P, et
229 * on aura 1 micron au lieu de 1e-18. */
230
231 if( scanlowire->CAPA / 2.0 >= CAPAMINI )
232 {
233 tooutput( df,
234 "C%d_%d1 %s %s %g\n",
235 scanlosig->INDEX,
236 nbr,
237 spinamednode( scanlosig, scanlowire->NODE1 ),
238 vss,
239 scanlowire->CAPA / 2.0 * 1e-12
240 );
241
242 tooutput( df,
243 "C%d_%d2 %s %s %g\n",
244 scanlosig->INDEX,
245 nbr,
246 spinamednode( scanlosig, scanlowire->NODE2 ),
247 vss,
248 scanlowire->CAPA / 2.0 * 1e-12
249 );
250 }
251
252 nbr++;
253 }
254 }
255
256 /* On ne sort la capa totale que si on a ni RCN, ni CTC */
257
258 if( !scanlosig->PRCN->PWIRE && !scanlosig->PRCN->PCTC )
259 {
260 if( scanlosig->PRCN->CAPA >= CAPAMINI )
261 {
262 tooutput( df,
263 "C%d %s %s %g\n",
264 scanlosig->INDEX,
265 spinamednode( scanlosig, SPI_NONODES ),
266 vss,
267 scanlosig->PRCN->CAPA * 1e-12
268 );
269 }
270 }
271 }
272
273 headctc = getallctc( ptfig );
274
275 for( scanchain = headctc ; scanchain ; scanchain = scanchain->NEXT )
276 {
277 ptctc = (loctc_list*)scanchain->DATA ;
278
279 if( ptctc->CAPA >= CAPAMINI )
280 {
281 tooutput( df,
282 "C_ctc_%d %s %s %g\n",
283 nbctc,
284 spinamednode( ptctc->SIG1, ptctc->NODE1 > 0 ? ptctc->NODE1 :
285 SPI_NONODES ),
286 spinamednode( ptctc->SIG2, ptctc->NODE2 > 0 ? ptctc->NODE2 :
287 SPI_NONODES ),
288 ptctc->CAPA * 1e-12
289 );
290 }
291
292 nbctc++;
293 }
294
295 freechain( headctc );
296 }
297
signalnoeud(ptfig)298 void signalnoeud( ptfig )
299 lofig_list *ptfig;
300 {
301 losig_list *scanlosig;
302 convindex *nouveau;
303 int dernier;
304
305 dernier = 1;
306
307 for( scanlosig = ptfig -> LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
308 {
309 nouveau = ( convindex* ) mbkalloc( sizeof( convindex ) );
310 nouveau->sig = scanlosig;
311 nouveau->premier = dernier;
312
313 if( scanlosig->PRCN && scanlosig->PRCN->NBNODE > 0 )
314 dernier += scanlosig->PRCN->NBNODE ;
315 else
316 dernier++;
317
318 scanlosig->USER = addptype( scanlosig->USER, SPI_DRIVER_PTYPE, nouveau );
319 }
320 }
321
sortconnecteur(df,c,position)322 int sortconnecteur( df, c, position )
323 FILE *df;
324 locon_list *c;
325 int position;
326 {
327 losig_list *signal;
328 num_list *tetenum,*scannum;
329 char v[1024] = "";
330 int lgmot;
331
332 signal = c->SIG;
333
334 if( c->PNODE )
335 {
336 tetenum = c->PNODE;
337 for( scannum = tetenum ; scannum ; scannum = scannum->NEXT )
338 {
339 sprintf( v,"%s ", spinamednode( signal, scannum->DATA) );
340 lgmot = strlen(v);
341 if( lgmot + position >= SPI_MAX_COL - 2 )
342 {
343 tooutput( df, "\n+ " );
344 position = lgmot+2;
345 }
346 else
347 position = position + lgmot;
348
349 tooutput( df, v );
350 }
351 }
352 else
353 {
354 lgmot = strlen(v);
355 if( lgmot + position >= SPI_MAX_COL - 2 )
356 {
357 tooutput( df, "\n+ " );
358 position = lgmot+2;
359 }
360 else
361 position = position + lgmot;
362 sprintf( v, "%s ", spinamednode( signal, SPI_NONODES ) );
363 tooutput( df, v );
364 }
365
366 return( position );
367 }
368
sortconnecteur_ordre(df,ordre,liste,position)369 int sortconnecteur_ordre( df, ordre, liste, position )
370 FILE *df;
371 chain_list *ordre;
372 locon_list *liste;
373 int position;
374 {
375 chain_list *scanordre;
376 locon_list *scanlocon;
377 int num;
378 int n;
379 chain_list *cpteordre;
380 losig_list *signal;
381 num_list *scannum;
382 num_list *tetenum;
383 char v[1024];
384 int lgmot;
385
386 for( scanordre = ordre ; scanordre ; scanordre = scanordre->NEXT )
387 {
388 for( scanlocon = liste ; scanlocon ; scanlocon = scanlocon->NEXT )
389 if( scanlocon->NAME == ((char*)(scanordre->DATA)) )
390 break;
391
392 if( !scanlocon )
393 {
394 fflush( stdout );
395 fprintf( stderr, "%s.\n", SPIMSG(5) );
396 EXIT(1);
397 }
398
399 num = 0;
400 for( cpteordre = ordre ;
401 cpteordre != scanordre ;
402 cpteordre = cpteordre->NEXT
403 )
404 if( ((char*)(cpteordre->DATA)) == scanlocon->NAME )
405 num++;
406
407 signal = scanlocon->SIG;
408
409 if( scanlocon->PNODE )
410 {
411 tetenum = scanlocon->PNODE;
412 for( scannum = tetenum, n=0 ; n<num ; scannum = scannum->NEXT, n++ );
413 sprintf( v, "%s ", spinamednode( signal, scannum->DATA ) );
414 }
415 else
416 sprintf( v, "%s ", spinamednode( signal, SPI_NONODES ) );
417
418 lgmot = strlen(v);
419 if( lgmot + position >= SPI_MAX_COL )
420 {
421 tooutput( df, "\n+ " );
422 position = lgmot + 2;
423 }
424 else
425 position = position + lgmot;
426
427 tooutput( df, v );
428 }
429
430 return( position );
431 }
432
sortnet(ptfig,df)433 void sortnet( ptfig, df )
434 lofig_list *ptfig;
435 FILE *df;
436 {
437 losig_list *scanlosig;
438 locon_list *scanlocon;
439 chain_list *scanchain;
440 ptype_list *ptl;
441 convindex *conv;
442 num_list *scannum;
443 loctc_list *ptctc;
444 int i;
445
446 for( scanlosig = ptfig->LOSIG ; scanlosig ; scanlosig = scanlosig->NEXT )
447 {
448 ptl = getptype(scanlosig->USER,SPI_DRIVER_PTYPE);
449 conv = (convindex*)(ptl->DATA);
450 if( scanlosig->TYPE == EXTERNAL )
451 {
452
453 if( scanlosig->TYPE == EXTERNAL )
454 {
455 ptl = getptype( scanlosig->USER, LOFIGCHAIN );
456
457 if( !ptl )
458 {
459 fflush( stdout );
460 fprintf( stderr, "*** spi error *** : LOFIGCHAIN missing.\n" );
461 EXIT(1);
462 }
463
464 for( scanchain = (chain_list*)(ptl->DATA) ;
465 scanchain ;
466 scanchain = scanchain->NEXT
467 )
468 {
469 scanlocon = (locon_list*)scanchain->DATA ;
470 if( scanlocon->ROOT == ptfig )
471 {
472 if( scanlocon->PNODE )
473 {
474 for( scannum = scanlocon->PNODE ;
475 scannum ;
476 scannum = scannum->NEXT
477 )
478 {
479 spi_vect( scanlocon->NAME );
480 tooutput( df,
481 "* %s %d = %s\n",
482 SPI_NETNAME,
483 scannum->DATA + conv->premier - 1 ,
484 scanlocon->NAME
485 );
486 }
487 }
488 else
489 {
490 spi_vect( scanlocon->NAME );
491 tooutput( df,
492 "* %s %d = %s\n",
493 SPI_NETNAME,
494 conv->premier,
495 scanlocon->NAME
496 );
497 }
498 }
499 }
500 }
501 }
502 else
503 if( scanlosig->NAMECHAIN )
504 {
505 i = 0 ;
506 if( scanlosig->PRCN )
507 {
508 if( scanlosig->PRCN->PWIRE )
509 i = scanlosig->PRCN->PWIRE->NODE1 ;
510 else
511 if( scanlosig->PRCN->PCTC )
512 {
513 ptctc = (loctc_list*)scanlosig->PRCN->PCTC->DATA;
514 if( ptctc->SIG1 == scanlosig )
515 i = ptctc->NODE1;
516 else
517 i = ptctc->NODE2;
518 }
519
520 if( i != 0 )
521 i = i + conv->premier - 1 ;
522 }
523
524 if( i == 0 );
525 i = conv->premier ;
526
527 spi_vect( (char*)scanlosig->NAMECHAIN->DATA );
528 tooutput( df,
529 "* %s %d = %s\n",
530 SPI_NETNAME,
531 i,
532 (char*)scanlosig->NAMECHAIN->DATA
533 ) ;
534 }
535 }
536 }
537
sortinstance(ptfig,df)538 void sortinstance( ptfig, df )
539 lofig_list *ptfig;
540 FILE *df;
541 {
542 loins_list *scanloins;
543 locon_list *scanloconins;
544 ptype_list *pt;
545 char v[1024];
546 int lgmot;
547 int colonne;
548
549 for( scanloins = ptfig->LOINS ; scanloins ; scanloins = scanloins->NEXT )
550 {
551 sprintf( v, "x%s ", scanloins->INSNAME );
552 colonne = strlen( v );
553 tooutput( df, v );
554
555 /* L'ordre des connecteurs entre la lofig et sa version instanci�e n'est
556 pas le meme */
557
558 pt = getptype( scanloins->USER, PH_INTERF );
559 if( pt )
560 colonne = sortconnecteur_ordre( df,
561 (chain_list*)(pt->DATA),
562 scanloins->LOCON,
563 colonne
564 );
565 else
566 for( scanloconins = scanloins->LOCON ;
567 scanloconins ;
568 scanloconins = scanloconins->NEXT
569 )
570 colonne = sortconnecteur( df, scanloconins, colonne );
571
572 sprintf( v, "%s\n", scanloins->FIGNAME );
573 lgmot = strlen(v);
574 if( lgmot+colonne >= SPI_MAX_COL -2 )
575 tooutput( df, "\n+" );
576 tooutput( df, v );
577 }
578 }
579
sorttransistormos(ptfig,df,vss,vdd)580 void sorttransistormos( ptfig, df, vss, vdd )
581 lofig_list *ptfig;
582 FILE *df;
583 char *vss;
584 char *vdd;
585 {
586 lotrs_list *scantrs;
587 int nb;
588 ht *trname;
589 char name[1024], *ptr ;
590
591 for( scantrs = ptfig->LOTRS, nb=1 ; scantrs ; scantrs = scantrs->NEXT, nb++ );
592
593 trname = addht(nb);
594
595 nb = 0;
596
597 for( scantrs = ptfig->LOTRS; scantrs; scantrs = scantrs->NEXT )
598 {
599 if( scantrs->TRNAME )
600 {
601 if( gethtitem( trname, scantrs->TRNAME ) != EMPTYHT )
602 {
603 do
604 {
605 nb++;
606 sprintf( name, "%s_%d", scantrs->TRNAME, nb );
607 ptr = namealloc( name );
608 }
609 while( gethtitem( trname, ptr ) != EMPTYHT );
610 addhtitem( trname, ptr, 1 );
611 tooutput( df, "M%s ", name );
612 }
613 else
614 {
615 tooutput( df, "M%s ", scantrs->TRNAME );
616 addhtitem( trname, scantrs->TRNAME, 1 );
617 }
618 }
619 else
620 {
621 do
622 {
623 nb++;
624 sprintf( name, "%d", nb );
625 ptr = namealloc( name );
626 }
627 while( gethtitem( trname, ptr ) != EMPTYHT );
628 tooutput( df, "M%s ", name );
629 addhtitem( trname, ptr, 1 );
630 }
631
632 sortconnecteur( df, scantrs->DRAIN,1 );
633 sortconnecteur( df, scantrs->GRID,1 );
634 sortconnecteur( df, scantrs->SOURCE,1 );
635 if( scantrs->BULK->SIG )
636 {
637 sortconnecteur( df, scantrs->BULK,1 );
638 }
639 else
640 {
641 if( IsTransN(scantrs->TYPE) )
642 {
643 if( !vss )
644 {
645 fflush( stdout );
646 fprintf( stderr,
647 "*** spi error *** : Can't find signal VSS on figure %s.\n",
648 ptfig->NAME
649 );
650 EXIT(1);
651 }
652
653 tooutput( df, "%s ", vss );
654 }
655 else
656 {
657 if( !vdd )
658 {
659 fflush( stdout );
660 fprintf( stderr,
661 "*** spi error *** : Can't find signal VDD on figure %s.\n",
662 ptfig->NAME
663 );
664 EXIT(1);
665 }
666
667 tooutput( df, "%s ", vdd );
668 }
669 }
670
671 tooutput( df, "%s ", spitransmodel( scantrs->TYPE ) );
672 #define SCALED(x,y) (double)((double)(x)/(double)(y))
673
674 if(scantrs->LENGTH!=0)
675 tooutput( df, "L=%gU ", SCALED(scantrs->LENGTH, SCALE_X));
676
677 if(scantrs->WIDTH!=0)
678 tooutput( df, "W=%gU ", SCALED(scantrs->WIDTH, SCALE_X));
679
680 if( scantrs->XS != 0 )
681 tooutput( df,
682 "AS=%gP ",
683 SCALED(scantrs->XS * scantrs->WIDTH, SCALE_X * SCALE_X)
684 );
685
686 if( scantrs->XD != 0 )
687 tooutput( df,
688 "AD=%gP ",
689 SCALED(scantrs->XD * scantrs->WIDTH, SCALE_X * SCALE_X)
690 );
691
692 if( scantrs->PS != 0 )
693 tooutput( df, "PS=%gU ", SCALED(scantrs->PS, SCALE_X));
694
695 if( scantrs->PD != 0 )
696 tooutput( df, "PD=%gU ", SCALED(scantrs->PD, SCALE_X));
697
698 tooutput( df, "\n" );
699 }
700
701 delht( trname );
702 }
703
sortcircuit(ptfig,df)704 void sortcircuit( ptfig, df )
705 lofig_list *ptfig;
706 FILE *df;
707 {
708 char *vdd, *vss;
709 locon_list *scancon;
710 ptype_list *pt;
711 int colonne;
712 char v[1024];
713
714 cherche_alim( ptfig, &vdd, &vss );
715
716 /* Sortie des instances et des transistors */
717
718 sprintf( v, "\n.subckt %s ", ptfig->NAME );
719 colonne = strlen( v );
720
721 tooutput( df, v );
722
723 pt = getptype( ptfig->USER, PH_INTERF );
724 if( pt )
725 colonne = sortconnecteur_ordre( df,
726 (chain_list*)(pt->DATA),
727 ptfig->LOCON,
728 colonne
729 );
730 else
731 for( scancon = ptfig->LOCON ; scancon ; scancon = scancon->NEXT )
732 colonne = sortconnecteur( df, scancon, colonne );
733
734 tooutput( df,"\n" );
735
736 if( SPI_NAMEDNODES == FALSE ) {
737 sortnet( ptfig, df );
738 }
739
740 sortinstance( ptfig, df );
741 sorttransistormos( ptfig, df, vss, vdd);
742
743 sort_locap(ptfig,df) ;
744 sort_lores(ptfig,df) ;
745 sort_loself(ptfig,df) ;
746
747 sortrcn( ptfig, df, vss );
748
749 tooutput( df, ".ends %s\n\n", ptfig->NAME );
750 }
751
spicesavelofig(ptfig)752 void spicesavelofig( ptfig )
753 lofig_list *ptfig;
754 {
755 FILE *df; /* descripteur de fichier de sortie */
756 chain_list *scanchain;
757 locon_list *scancon;
758 num_list *scannum;
759 char v[1024];
760 ptype_list *pt;
761 char *nom;
762 time_t secondes;
763 struct tm *jours;
764 char *env;
765 int colonne;
766 int lgmot;
767
768 env = mbkgetenv( "MBK_SPI_TN" );
769
770 if(env)
771 TNMOS = env;
772 else
773 TNMOS = "TN";
774
775 env = mbkgetenv( "MBK_SPI_TP" );
776
777 if(env)
778 TPMOS = env;
779 else
780 TPMOS = "TP";
781
782 env = mbkgetenv( "MBK_SPI_NETNAME" );
783
784 if( env )
785 SPI_NETNAME = env;
786 else
787 SPI_NETNAME = "NET";
788
789 env = mbkgetenv( "MBK_SPI_NAMEDNODES" );
790
791 if( env )
792 SPI_NAMEDNODES = TRUE ;
793 else
794 SPI_NAMEDNODES = FALSE ;
795
796 spi_init_lang();
797
798 /* Ouverture du fichier de sortie */
799 df = mbkfopen( ptfig->NAME, OUT_LO, WRITE_TEXT );
800 if( !df )
801 {
802 fflush( stdout );
803 fprintf( stderr, "*** mbk error : savelofig impossible.\n" );
804 fprintf( stderr,
805 "Can't open file %s.%s for writing.\n",
806 ptfig->NAME,
807 OUT_LO
808 );
809 EXIT(1);
810 }
811
812
813 time( &secondes );
814 jours = localtime( &secondes );
815
816 tooutput( df, "* Spice description of %s\n", ptfig->NAME );
817 tooutput( df, "* Spice driver version %d\n",VERSION );
818 tooutput( df,
819 "* Date ( dd/mm/yyyy hh:mm:ss ): %2d/%02d/%04d at %2d:%02d:%02d\n\n",
820 jours->tm_mday,
821 jours->tm_mon+1,
822 jours->tm_year+1900,
823 jours->tm_hour,
824 jours->tm_min,
825 jours->tm_sec
826 );
827
828 /* On va travailler sur les fonctions RCN : */
829 lofigchain( ptfig );
830
831 signalnoeud( ptfig ); /* Calcule les noeuds Spice */
832
833 /* Sort la ligne *interf */
834
835 colonne = strlen( "* INTERF " );
836 tooutput( df, "* INTERF " );
837
838 pt = getptype( ptfig->USER, PH_INTERF );
839 if( pt )
840 {
841 for( scanchain = (chain_list*)(pt->DATA) ;
842 scanchain ;
843 scanchain = scanchain->NEXT
844 )
845 {
846 nom = ((char*)(scanchain->DATA));
847 strcpy( v, nom );
848 spi_vect( v );
849
850 lgmot = strlen(v)+1;
851 if( colonne+lgmot >= SPI_MAX_COL-2 )
852 {
853 colonne = strlen( "* INTERF " );
854 tooutput( df, "\n* INTERF " );
855 }
856 colonne = colonne + lgmot;
857
858 tooutput( df, "%s ", v );
859
860 }
861 }
862 else
863 {
864 for( scancon = ptfig->LOCON ; scancon ; scancon = scancon->NEXT )
865 {
866 if( scancon->PNODE )
867 {
868 for( scannum = scancon->PNODE ; scannum ; scannum = scannum->NEXT )
869 {
870 strcpy( v, scancon->NAME );
871 spi_vect( v );
872
873 lgmot = strlen(v)+1;
874 if( colonne+lgmot >= SPI_MAX_COL-2 )
875 {
876 colonne = strlen( "* INTERF " );
877 tooutput( df, "\n* INTERF " );
878 }
879 colonne = colonne + lgmot;
880
881 tooutput( df, "%s ", v );
882
883 }
884 }
885 else
886 {
887 strcpy( v, scancon->NAME );
888 spi_vect( v );
889
890 lgmot = strlen(v)+1;
891 if( colonne+lgmot >= SPI_MAX_COL-2 )
892 {
893 colonne = strlen( "* INTERF " );
894 tooutput( df, "\n* INTERF " );
895 }
896 colonne = colonne + lgmot;
897
898 tooutput( df, "%s ", v );
899 }
900 }
901 }
902
903 tooutput( df, "\n\n" );
904
905 /* Sort les .include */
906
907 for( scanchain = ptfig->MODELCHAIN; scanchain; scanchain = scanchain->NEXT )
908 {
909 tooutput( df, ".INCLUDE %s.%s\n", (char*)scanchain->DATA, OUT_LO );
910 }
911
912 sortcircuit( ptfig, df );
913
914 if( fclose(df) == -1 )
915 {
916 fflush( stdout );
917 fprintf( stderr,
918 "*** mbk error *** : Can't close file %s.\n,",
919 ptfig->NAME
920 );
921 EXIT(1);
922 }
923 }
924
tooutput(FILE * fd,...)925 void tooutput( FILE *fd, ... )
926 {
927 va_list index;
928 char *fmt;
929
930 va_start( index, fd );
931
932 fmt = va_arg( index, char* );
933
934 if( vfprintf( fd, fmt, index ) < 0 )
935 {
936 fflush( stdout );
937 fprintf( stderr, "*** spi error *** : Error while writing file.\n" );
938 perror( "System say " );
939 EXIT( 1 );
940 }
941
942 va_end( index );
943 }
944
spi_vect(s)945 void spi_vect( s )
946 char *s;
947 {
948 int i,p1;
949
950 if( s == NULL )
951 return;
952 if( s[0] == '\0' )
953 return;
954
955
956 /* Positionne i sur le premier caractere non espace a la fin de la chaine */
957 i = strlen( s ) ;
958 do
959 i--;
960 while( s[i] == ' ' && i >0 );
961
962 /* passe un eventuel paquet de nombres */
963 if( i )
964 {
965 p1 = i;
966 while( isdigit( (int)s[i] ) && i >0 )
967 i--;
968 if( p1 != i && s[i] == ' ' )
969 {
970 s[i] = '[';
971 s[p1+1] = ']';
972 s[p1+2] = '\0' ;
973 }
974 }
975 }
976
977
978 /****************************************************************************************************/
979 /************************************** locap, lores and loself *************************************/
980 /****************************************************************************************************/
981
sort_locap(lofig_list * ptfig,FILE * df)982 void sort_locap(lofig_list *ptfig,FILE *df)
983 {
984 locap_list *scancap = NULL ;
985 int nb = 0 ;
986 ht *capname = NULL ;
987 char name[1024] ;
988 char *ptr = NULL ;
989
990 for(scancap = ptfig -> LOCAP,nb = 1 ; scancap != NULL; scancap = scancap -> NEXT,nb++) ;
991
992 capname = addht(nb) ;
993
994 nb = 0 ;
995
996 for(scancap = ptfig -> LOCAP ; scancap != NULL ; scancap = scancap -> NEXT)
997 {
998 if(scancap -> NAME != NULL)
999 {
1000 if(gethtitem(capname,scancap -> NAME) != EMPTYHT)
1001 {
1002 do
1003 {
1004 nb++ ;
1005 sprintf(name,"%s_%d",scancap -> NAME,nb) ;
1006 ptr = namealloc(name) ;
1007 }
1008
1009 while(gethtitem(capname,ptr) != EMPTYHT) ;
1010
1011 addhtitem(capname,ptr,1) ;
1012 tooutput(df,"C%s ",name) ;
1013 }
1014 else
1015 {
1016 tooutput(df,"C%s ",scancap -> NAME) ;
1017 addhtitem(capname,scancap -> NAME,1) ;
1018 }
1019 }
1020 else
1021 {
1022 do
1023 {
1024 nb++ ;
1025 sprintf(name,"%d",nb) ;
1026 ptr = namealloc(name) ;
1027 }
1028
1029 while(gethtitem(capname,ptr) != EMPTYHT) ;
1030
1031 tooutput(df,"C%s ",name) ;
1032 addhtitem(capname,ptr,1) ;
1033 }
1034
1035 sortconnecteur(df,scancap -> TCON,1) ;
1036 sortconnecteur(df,scancap -> BCON,1) ;
1037
1038 tooutput(df,"%g ",(float)scancap -> CAPA) ;
1039
1040 tooutput(df,"\n") ;
1041 }
1042
1043 delht(capname) ;
1044 }
1045
1046 /****************************************************************************************************/
1047
sort_lores(lofig_list * ptfig,FILE * df)1048 void sort_lores(lofig_list *ptfig,FILE *df)
1049 {
1050 lores_list *scanres = NULL ;
1051 int nb = 0 ;
1052 ht *resname = NULL ;
1053 char name[1024] ;
1054 char *ptr = NULL ;
1055
1056 for(scanres = ptfig -> LORES,nb = 1 ; scanres != NULL; scanres = scanres -> NEXT,nb++) ;
1057
1058 resname = addht(nb) ;
1059
1060 nb = 0 ;
1061
1062 for(scanres = ptfig -> LORES ; scanres != NULL ; scanres = scanres -> NEXT)
1063 {
1064 if(scanres -> NAME != NULL)
1065 {
1066 if(gethtitem(resname,scanres -> NAME) != EMPTYHT)
1067 {
1068 do
1069 {
1070 nb++ ;
1071 sprintf(name,"%s_%d",scanres -> NAME,nb) ;
1072 ptr = namealloc(name) ;
1073 }
1074
1075 while(gethtitem(resname,ptr) != EMPTYHT) ;
1076
1077 addhtitem(resname,ptr,1) ;
1078 tooutput(df,"R%s ",name) ;
1079 }
1080 else
1081 {
1082 tooutput(df,"R%s ",scanres -> NAME) ;
1083 addhtitem(resname,scanres -> NAME,1) ;
1084 }
1085 }
1086 else
1087 {
1088 do
1089 {
1090 nb++ ;
1091 sprintf(name,"%d",nb) ;
1092 ptr = namealloc(name) ;
1093 }
1094
1095 while(gethtitem(resname,ptr) != EMPTYHT) ;
1096
1097 tooutput(df,"R%s ",name) ;
1098 addhtitem(resname,ptr,1) ;
1099 }
1100
1101 sortconnecteur(df,scanres -> RCON1,1) ;
1102 sortconnecteur(df,scanres -> RCON2,1) ;
1103
1104 tooutput(df,"%g ",(float)scanres -> RESI) ;
1105
1106 tooutput(df,"\n") ;
1107 }
1108
1109 delht(resname) ;
1110 }
1111
1112 /****************************************************************************************************/
1113
sort_loself(lofig_list * ptfig,FILE * df)1114 void sort_loself(lofig_list *ptfig,FILE *df)
1115 {
1116 loself_list *scanself = NULL ;
1117 int nb = 0 ;
1118 ht *selfname = NULL ;
1119 char name[1024] ;
1120 char *ptr = NULL ;
1121
1122 for(scanself = ptfig -> LOSELF,nb = 1 ; scanself != NULL; scanself = scanself -> NEXT,nb++) ;
1123
1124 selfname = addht(nb) ;
1125
1126 nb = 0 ;
1127
1128 for(scanself = ptfig -> LOSELF ; scanself != NULL ; scanself = scanself -> NEXT)
1129 {
1130 if(scanself -> NAME != NULL)
1131 {
1132 if(gethtitem(selfname,scanself -> NAME) != EMPTYHT)
1133 {
1134 do
1135 {
1136 nb++ ;
1137 sprintf(name,"%s_%d",scanself -> NAME,nb) ;
1138 ptr = namealloc(name) ;
1139 }
1140
1141 while(gethtitem(selfname,ptr) != EMPTYHT) ;
1142
1143 addhtitem(selfname,ptr,1) ;
1144 tooutput(df,"L%s ",name) ;
1145 }
1146 else
1147 {
1148 tooutput(df,"L%s ",scanself -> NAME) ;
1149 addhtitem(selfname,scanself -> NAME,1) ;
1150 }
1151 }
1152 else
1153 {
1154 do
1155 {
1156 nb++ ;
1157 sprintf(name,"%d",nb) ;
1158 ptr = namealloc(name) ;
1159 }
1160
1161 while(gethtitem(selfname,ptr) != EMPTYHT) ;
1162
1163 tooutput(df,"L%s ",name) ;
1164 addhtitem(selfname,ptr,1) ;
1165 }
1166
1167 sortconnecteur(df,scanself -> SCON1,1) ;
1168 sortconnecteur(df,scanself -> SCON2,1) ;
1169
1170 tooutput(df,"%g ",(float)scanself -> SELF) ;
1171
1172 tooutput(df,"\n") ;
1173 }
1174
1175 delht(selfname) ;
1176 }
1177