1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : SPF Version 1.00 */
6 /* Fichier : spef_drive.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Olivier BICHAUT */
13 /****************************************************************************/
15 /****************************************************************************/
17 /****************************************************************************/
20 #include "spef_drive.h"
21 #include "spef_util.h"
23 #define SPEF_NAME_INDEX 0xfab60614
25 /****************************************************************************/
27 /****************************************************************************/
28 /****************************************************************************/
30 /****************************************************************************/
32 /****************************************************************************/
34 /****************************************************************************/
36 /****************************************************************************/
37 /* function spef_addslash() ajoute des backslash pour qu'un nom contenant */
38 /* des [ ] ne soit pas pris comme un vecteur */
39 /****************************************************************************/
40 static void addnameindex(ptype_list
**user
, long *val
)
42 *user
=addptype(*user
, SPEF_NAME_INDEX
, (void *)*val
);
45 static void removenameindex(ptype_list
**user
)
47 *user
=testanddelptype(*user
, SPEF_NAME_INDEX
);
50 static char *spef_getitem(void *me
, char type
, char *buf
)
55 case 'i': if ((pt
=getptype(((loins_list
*)me
)->USER
, SPEF_NAME_INDEX
))!=NULL
)
56 sprintf(buf
, "*%ld", (long)pt
->DATA
);
58 strcpy(buf
, ((loins_list
*)me
)->INSNAME
);
60 case 't': if ((pt
=getptype(((lotrs_list
*)me
)->USER
, SPEF_NAME_INDEX
))!=NULL
)
61 sprintf(buf
, "*%ld", (long)pt
->DATA
);
63 strcpy(buf
, ((lotrs_list
*)me
)->TRNAME
!=NULL
?((lotrs_list
*)me
)->TRNAME
:"?");
65 case 's': if ((pt
=getptype(((losig_list
*)me
)->USER
, SPEF_NAME_INDEX
))!=NULL
)
66 sprintf(buf
, "*%ld", (long)pt
->DATA
);
76 char *spef_addslash(char *str
)
81 while (str
[i
] != '\0'){
82 if ((str
[i
] == SPEF_INFO
->PREFIX_BUS_DELIMITER
) || (str
[i
] == SPEF_INFO
->SUFFIX_BUS_DELIMITER
)){
96 return namealloc (ss
);
98 /****************************************************************************/
99 /* function spef_printheader() ecrit l'entete du fichier spef */
100 /****************************************************************************/
101 void spef_printheader(FILE *file
, lofig_list
*ptfig
)
107 date
= ctime (&counter
) ;
108 date
[strlen (date
) - 1] = '\0' ;
112 fprintf(file
, "*SPEF %s\n", SPEF_INFO
->SPEF
);
113 fprintf(file
, "*DESIGN \"%s\"\n", ptfig
->NAME
);
114 fprintf(file
, "*DATE \"%s\"\n", date
);
115 fprintf(file
, "*VENDOR \"AVERTEC\"\n");
116 fprintf(file
, "*PROGRAM \"spef_driver\"\n");
117 fprintf(file
, "*VERSION \"1.0\"\n");
119 fprintf(file
, "*DESIGN_FLOW ");
120 for(chain
= SPEF_INFO
->DESIGN_FLOW
; chain
; chain
= chain
->NEXT
)
121 fprintf(file
, "%s ", (char*)chain
->DATA
);
124 fprintf(file
, "*DIVIDER %c\n", SPEF_INFO
->DIVIDER
);
125 fprintf(file
, "*DELIMITER %c\n", SPEF_INFO
->DELIMITER
);
126 fprintf(file
, "*BUS_DELIMITER %c%c\n", SPEF_INFO
->PREFIX_BUS_DELIMITER
, SPEF_INFO
->SUFFIX_BUS_DELIMITER
);
127 if(SPEF_INFO
->SPEF_T_UNIT
== 'N')
128 fprintf(file
, "*T_UNIT %g NS\n", SPEF_INFO
->SPEF_T_SCALE
);
129 else if(SPEF_INFO
->SPEF_T_UNIT
== 'P')
130 fprintf(file
, "*T_UNIT %g PS\n", SPEF_INFO
->SPEF_T_SCALE
);
131 if(SPEF_INFO
->SPEF_CAP_UNIT
== 'P')
132 fprintf(file
, "*C_UNIT %g PF\n", SPEF_INFO
->SPEF_CAP_SCALE
);
134 fprintf(file
, "*C_UNIT %g FF\n", SPEF_INFO
->SPEF_CAP_SCALE
* 1000.0);
135 if(SPEF_INFO
->SPEF_RES_UNIT
== 'O')
136 fprintf(file
, "*R_UNIT %g OHM\n", SPEF_INFO
->SPEF_RES_SCALE
);
138 fprintf(file
, "*R_UNIT %g KOHM\n", SPEF_INFO
->SPEF_RES_SCALE
/ 1000.0);
139 if(SPEF_INFO
->SPEF_L_UNIT
== 'H')
140 fprintf(file
, "*L_UNIT %g HENRY\n", SPEF_INFO
->SPEF_L_SCALE
);
141 else if(SPEF_INFO
->SPEF_L_UNIT
== 'M')
142 fprintf(file
, "*L_UNIT %g MH\n", SPEF_INFO
->SPEF_L_SCALE
);
143 else if(SPEF_INFO
->SPEF_L_UNIT
== 'U')
144 fprintf(file
, "*L_UNIT %g UH\n", SPEF_INFO
->SPEF_L_SCALE
);
146 /****************************************************************************/
147 /* function spef_printconn() ecrit les connecteurs d'un net */
148 /****************************************************************************/
149 static char *getpnode(locon_list
*lc
, char *buf
, int incompmode
)
151 if (incompmode
&& lc
->PNODE
!=NULL
&& lc
->PNODE
->NEXT
==NULL
) sprintf(buf
," *x %ld", lc
->PNODE
->DATA
);
156 static char *convertname(char *name
, char *buf
)
158 if (strchr(name
, ' '))
159 sprintf(buf
, "%s%c%d%c", vectorradical(name
), SPEF_INFO
->PREFIX_BUS_DELIMITER
,
160 vectorindex(name
), SPEF_INFO
->SUFFIX_BUS_DELIMITER
);
161 else if (strchr(name
, SPEF_INFO
->PREFIX_BUS_DELIMITER
))
162 strcpy(buf
, spef_addslash(name
));
169 void spef_printconn(FILE *file
, losig_list
*ptsig
)
176 char buf
[1024], buf1
[10], buf2
[1024];
180 fprintf(file
, "\n*CONN\n");
181 ptype
= getptype(ptsig
->USER
, LOFIGCHAIN
);
184 for(chain
= (chain_list
*)ptype
->DATA
; chain
; chain
= chain
->NEXT
) {
185 ptcon
= (locon_list
*)chain
->DATA
;
186 if (ptcon
->PNODE
!=NULL
) {
187 if (gethtitem(modeht
, (void *)ptcon
->PNODE
->DATA
)!=EMPTYHT
) break;
188 else addhtitem(modeht
, (void *)ptcon
->PNODE
->DATA
, 0);
192 if (chain
!=NULL
) incompmode
=1;
193 for(chain
= (chain_list
*)ptype
->DATA
; chain
; chain
= chain
->NEXT
) {
194 ptcon
= (locon_list
*)chain
->DATA
;
195 if(ptcon
->DIRECTION
!= 'X')
196 direction
= ptcon
->DIRECTION
;
199 for(num
= ptcon
->PNODE
; num
; num
= num
->NEXT
) {
200 if(ptcon
->TYPE
== 'I'){
201 fprintf(file
, "*I %s%c%s %c *D %s%s\n", spef_getitem((loins_list
*)ptcon
->ROOT
, 'i', buf
), SPEF_INFO
->DELIMITER
, convertname(ptcon
->NAME
, buf2
), direction
, ((loins_list
*)ptcon
->ROOT
)->FIGNAME
, getpnode(ptcon
, buf1
, incompmode
));
203 else // zinaps : 24/4/2003
204 if(ptcon
->TYPE
== 'T'){
205 fprintf(file
, "*I %s%c%c %c *D %s%s\n", spef_getitem((lotrs_list
*)ptcon
->ROOT
, 't', buf
), SPEF_INFO
->DELIMITER
, tolower(ptcon
->NAME
[0]), direction
, getlotrsmodel((lotrs_list
*)ptcon
->ROOT
), getpnode(ptcon
, buf1
, incompmode
));
208 fprintf(file
, "*P %s %c%s\n", convertname(ptcon
->NAME
, buf
), direction
, getpnode(ptcon
, buf1
, incompmode
));
214 /****************************************************************************/
215 /* function spef_printnameorindex() ecrit un nom de net ou son index.node */
216 /****************************************************************************/
217 void spef_printnameorindex(FILE *file
, losig_list
*ptsig
, long node
)
225 ptype
= getptype(ptsig
->USER
, LOFIGCHAIN
);
227 for(chain
= (chain_list
*)ptype
->DATA
; chain
; chain
= chain
->NEXT
) {
228 ptcon
= (locon_list
*)chain
->DATA
;
229 for(num
= ptcon
->PNODE
; num
; num
= num
->NEXT
) {
230 if(num
->DATA
== node
){
231 if(ptcon
->TYPE
== 'I'){
232 if (strchr(ptcon
->NAME
, ' '))
233 fprintf(file
, "%s%c%s%c%d%c ", spef_getitem((loins_list
*)ptcon
->ROOT
, 'i', buf
), SPEF_INFO
->DELIMITER
, vectorradical(ptcon
->NAME
),
234 SPEF_INFO
->PREFIX_BUS_DELIMITER
, vectorindex(ptcon
->NAME
), SPEF_INFO
->SUFFIX_BUS_DELIMITER
);
235 else if (strchr(ptcon
->NAME
, SPEF_INFO
->PREFIX_BUS_DELIMITER
))
236 fprintf(file
, "%s%c%s ", spef_getitem((loins_list
*)ptcon
->ROOT
, 'i', buf
), SPEF_INFO
->DELIMITER
, spef_addslash(ptcon
->NAME
));
238 fprintf(file
, "%s%c%s ", spef_getitem((loins_list
*)ptcon
->ROOT
, 'i', buf
), SPEF_INFO
->DELIMITER
, ptcon
->NAME
);
241 if(ptcon
->TYPE
== 'T'){
242 fprintf(file
, "%s%c%c ", spef_getitem((lotrs_list
*)ptcon
->ROOT
, 't', buf
), SPEF_INFO
->DELIMITER
, tolower(ptcon
->NAME
[0]));
245 if (strchr(ptcon
->NAME
, ' '))
246 fprintf(file
, "%s%c%d%c ", vectorradical(ptcon
->NAME
), SPEF_INFO
->PREFIX_BUS_DELIMITER
,
247 vectorindex(ptcon
->NAME
), SPEF_INFO
->SUFFIX_BUS_DELIMITER
);
248 else if (strchr(ptcon
->NAME
, SPEF_INFO
->PREFIX_BUS_DELIMITER
))
249 fprintf(file
, "%s ", spef_addslash(ptcon
->NAME
));
251 fprintf(file
, "%s ", ptcon
->NAME
);
257 fprintf(file
, "%s%c%ld ", spef_getitem(ptsig
, 's', buf
), SPEF_INFO
->DELIMITER
, node
);
260 /****************************************************************************/
261 /* function spef_printnamemap() ecrit la table d'index des signaux */
262 /****************************************************************************/
263 static int spef_isalim(losig_list
*losig
)
265 return mbk_LosigIsVSS(losig
) || mbk_LosigIsVDD(losig
);
268 void spef_printnamemap(FILE *file
, lofig_list
*ptfig
)
276 fprintf(file
, "\n*NAME_MAP\n");
277 for(losig
=ptfig
->LOSIG
;losig
;losig
=losig
->NEXT
){
278 if(spef_isalim(losig
))
282 if(prcn->PCTC || prcn->PWIRE){*/
283 if (strchr(getsigname(losig
), ' '))
284 fprintf(file
, "*%ld %s%c%d%c\n", index
, vectorradical(getsigname(losig
)),
285 SPEF_INFO
->PREFIX_BUS_DELIMITER
, vectorindex(getsigname(losig
)), SPEF_INFO
->SUFFIX_BUS_DELIMITER
);
286 else if (strchr(getsigname(losig
), SPEF_INFO
->PREFIX_BUS_DELIMITER
))
287 fprintf(file
, "*%ld %s\n", index
, spef_addslash(getsigname(losig
)));
289 fprintf(file
, "*%ld %s\n", index
, getsigname(losig
));
290 addnameindex(&losig
->USER
, &index
);
293 for(lt
=ptfig
->LOTRS
;lt
!=NULL
;lt
=lt
->NEXT
)
295 if (lt
->TRNAME
!=NULL
&& strlen(lt
->TRNAME
)>7)
297 fprintf(file
, "*%ld %s\n", index
, lt
->TRNAME
);
298 addnameindex(<
->USER
, &index
);
301 for(li
=ptfig
->LOINS
;li
!=NULL
;li
=li
->NEXT
)
303 if (strlen(li
->INSNAME
)>7)
305 fprintf(file
, "*%ld %s\n", index
, li
->INSNAME
);
306 addnameindex(&li
->USER
, &index
);
312 static void spef_cleannamemap(lofig_list
*ptfig
)
319 for(losig
=ptfig
->LOSIG
;losig
;losig
=losig
->NEXT
){
320 removenameindex(&losig
->USER
);
322 for(lt
=ptfig
->LOTRS
;lt
!=NULL
;lt
=lt
->NEXT
)
324 removenameindex(<
->USER
);
326 for(li
=ptfig
->LOINS
;li
!=NULL
;li
=li
->NEXT
)
328 removenameindex(&li
->USER
);
332 /****************************************************************************/
333 /* function spef_printports() ecrit l'interface du circuit */
334 /****************************************************************************/
335 void spef_printports(FILE *file
, lofig_list
*ptfig
)
339 fprintf(file
, "\n*PORTS\n");
340 for(locon
=ptfig
->LOCON
;locon
;locon
=locon
->NEXT
){
341 if (strchr(locon
->NAME
, ' '))
342 fprintf(file
, "%s%c%d%c %c\n", vectorradical(locon
->NAME
), SPEF_INFO
->PREFIX_BUS_DELIMITER
,
343 vectorindex(locon
->NAME
), SPEF_INFO
->SUFFIX_BUS_DELIMITER
, locon
->DIRECTION
);
345 fprintf(file
, "%s %c\n", locon
->NAME
, locon
->DIRECTION
);
348 /****************************************************************************/
349 /* function spef_printdnets() drive les RC de tous les signaux */
350 /****************************************************************************/
351 void spef_printdnets(FILE *file
, lofig_list
*ptfig
)
363 for(losig
=ptfig
->LOSIG
;losig
;losig
=losig
->NEXT
){
364 if(spef_isalim(losig
))
366 rcn_refresh_signal(ptfig
, losig
);
370 if(prcn
->PCTC
|| prcn
->PWIRE
){
371 if(SPEF_INFO
->SPEF_CAP_UNIT
== 'P')
372 fprintf(file
, "\n*D_NET %s %g\n", spef_getitem(losig
, 's', buf
), rcn_getcapa( ptfig
, losig
));
373 else if(SPEF_INFO
->SPEF_CAP_UNIT
== 'F')
374 fprintf(file
, "\n*D_NET %s %g\n", spef_getitem(losig
, 's', buf
), rcn_getcapa( ptfig
,losig
) * 1000.0);
375 spef_printconn(file
, losig
);
376 if(prcn
->PCTC
){ /* drive la liste des capas */
377 fprintf(file
, "*CAP\n");
380 for(chain
=prcn
->PCTC
;chain
;chain
=chain
->NEXT
){
381 ctc
=(loctc_list
*)chain
->DATA
;
382 if (!spef_isalim(ctc
->SIG1
) || !spef_isalim(ctc
->SIG2
))
384 fprintf(file
, "%ld ", nbcap
);
386 if(!spef_isalim(ctc
->SIG1
))
387 spef_printnameorindex(file
, ctc
->SIG1
, ctc
->NODE1
);
388 if(!spef_isalim(ctc
->SIG2
))
389 spef_printnameorindex(file
, ctc
->SIG2
, ctc
->NODE2
);
390 if(SPEF_INFO
->SPEF_CAP_UNIT
== 'P')
391 fprintf(file
, "%g\n", ctc
->CAPA
);
392 else if(SPEF_INFO
->SPEF_CAP_UNIT
== 'F')
393 fprintf(file
, "%g\n", ctc
->CAPA
* 1000.0);
397 if(prcn
->PWIRE
){ /* drive la liste des capas des resistances */
398 for(wire
=prcn
->PWIRE
;wire
;wire
=wire
->NEXT
){
399 if(wire
->CAPA
> 0.0) {
400 if (!doneprintcapa
) {
402 fprintf(file
, "*CAP\n");
405 fprintf(file
, "%ld ", nbcap
);
407 spef_printnameorindex(file
, losig
, wire
->NODE1
);
408 if(SPEF_INFO
->SPEF_CAP_UNIT
== 'P')
409 fprintf(file
, "%g\n", wire
->CAPA
/2.0);
410 else if(SPEF_INFO
->SPEF_CAP_UNIT
== 'F')
411 fprintf(file
, "%g\n", wire
->CAPA
* 500.0);
412 fprintf(file
, "%ld ", nbcap
);
414 spef_printnameorindex(file
, losig
, wire
->NODE2
);
415 if(SPEF_INFO
->SPEF_CAP_UNIT
== 'P')
416 fprintf(file
, "%g\n", wire
->CAPA
/2.0);
417 else if(SPEF_INFO
->SPEF_CAP_UNIT
== 'F')
418 fprintf(file
, "%g\n", wire
->CAPA
* 500.0);
422 if(prcn
->PWIRE
){ /* drive la liste des resistances */
423 fprintf(file
, "*RES\n");
425 for(wire
=prcn
->PWIRE
;wire
;wire
=wire
->NEXT
){
426 fprintf(file
, "%ld ", nbres
);
428 spef_printnameorindex(file
, losig
, wire
->NODE1
);
429 spef_printnameorindex(file
, losig
, wire
->NODE2
);
430 if(SPEF_INFO
->SPEF_RES_UNIT
== 'O')
431 fprintf(file
, "%g\n", wire
->RESI
);
432 if(SPEF_INFO
->SPEF_RES_UNIT
== 'K')
433 fprintf(file
, "%g\n", wire
->RESI
/ 1000.0);
436 fprintf(file
, "\n*END\n");
441 /****************************************************************************/
442 void spef_drive(lofig_list
*ptfig
, FILE *outputfile
)
447 if (outputfile
!=NULL
) file
=outputfile
;
450 sprintf(buf
,"%s.spef", ptfig
->NAME
);
451 file
= fopen (buf
, "w+");
454 spef_printheader(file
, ptfig
);
455 spef_printnamemap(file
, ptfig
);
456 spef_printports(file
, ptfig
);
457 spef_printdnets(file
, ptfig
);
458 spef_cleannamemap(ptfig
);
459 if (outputfile
==NULL
) fclose(file
);