Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / lib / lib_drive.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : LIB Version 1.00 */
6 /* Fichier : lib_drive.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /****************************************************************************/
14
15 /****************************************************************************/
16 /* includes */
17 /****************************************************************************/
18
19 #include "lib.h"
20
21 /****************************************************************************/
22 /* functions */
23 /****************************************************************************/
24 extern ht* tut_tablasharea;
25 int FLAGBUS = 0;
26 char buftunit[1024];
27 static ptype_list *libpowerptype=NULL;
28
29 static inline ttvline_list *lib_getnodeinputline(ttvevent_list *ev, int ttx)
30 {
31 if (ttx) return ev->INPATH;
32 else return ev->INLINE;
33 }
34
35 /****************************************************************************/
36 /* function lib_drive */
37 /****************************************************************************/
38 void lib_drive (chain_list *figlistx, chain_list *befiglistx, char *name, char *suffix)
39 {
40 FILE *f ;
41 ttvfig_list *ttvfig ;
42 chain_list *ttv ;
43 chain_list *chain;
44 timing_cell *cell;
45 int cmpt=0;
46 ttvinfo_list *ttvinfo = NULL;
47 chain_list *figlist, *befiglist, *tofree ;
48
49 lib_drive_remove_null( figlistx, befiglistx, &figlist, &befiglist );
50
51 printf("\n\n ###################################\n");
52 printf(" # #\n");
53 printf(" # liberty driver version 1.00 #\n");
54 printf(" # #\n");
55 printf(" ###################################\n\n");
56 printf(" WRITING FILE: %s ...\n\n", name);
57
58 if(!(f = mbkfopen (name, NULL, WRITE_TEXT))){
59 fprintf (stderr, "LIB ERROR : no file %s\n", name);
60 EXIT (EXIT_FAILURE) ;
61 }
62
63 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_NODE_NAME_ONLY);
64
65 for(chain=figlist;chain;chain=chain->NEXT){
66 ttvfig=(ttvfig_list*)chain->DATA;
67 cell = stm_getcell (ttvfig->INFO->FIGNAME) ;
68 stm_modtbl_findtemplates(cell);
69 }
70
71 if(figlist){
72 if(figlist->DATA)
73 ttvinfo = ((ttvfig_list*)figlist->DATA)->INFO;
74 }
75
76 if(V_STR_TAB[__TMA_LIBRARY].VALUE)
77 lib_driveheader(f, V_STR_TAB[__TMA_LIBRARY].VALUE, ttvinfo);
78 else
79 lib_driveheader(f, name, ttvinfo);
80
81 if(V_BOOL_TAB[__TUT_CALC_DERATE].VALUE) {
82 lib_driveopcond(f, "OP1", LIB_NOM_PROCESS, TUT_MAXTEMP, TUT_MAXVOLT);
83 lib_driveopcond(f, "OP2", LIB_NOM_PROCESS, TUT_MAXTEMP, TUT_MINVOLT);
84 lib_driveopcond(f, "OP3", LIB_NOM_PROCESS, TUT_MINTEMP, TUT_MAXVOLT);
85 lib_driveopcond(f, "OP4", LIB_NOM_PROCESS, TUT_MINTEMP, TUT_MINVOLT);
86 }
87
88 saut(f,1);
89
90 if(STM_TEMPLATES_CHAIN){
91 lib_drivetemplate(f);
92 }
93
94
95 saut(f,1);
96
97 lib_drive_power_supply_group(f, figlist, ttvinfo);
98
99 saut(f,1);
100
101 lib_drivebustype(f, figlist);
102
103
104 saut(f,1);
105 tofree=befiglist;
106 for(ttv = figlist ; ttv ; ttv = ttv->NEXT){
107 saut(f,1);
108 ttvfig=(ttvfig_list*)ttv->DATA;
109 if(befiglist){
110 lib_drivecell (f, ttvfig, (befig_list*)befiglist->DATA, suffix);
111 befiglist=befiglist->NEXT;
112 }
113 else
114 lib_drivecell (f, ttvfig, NULL, suffix);
115 cmpt++;
116 printf(" -> writing cell%d: %s\n", cmpt, lib_unsuffix(ttvfig->INFO->FIGNAME, suffix));
117 }
118
119 saut(f,1);
120 fprintf(f,"}\n");
121
122 fclose (f) ;
123 printf("\n ...DONE\n\n");
124
125 ttv_search_mode(0, TTV_MORE_OPTIONS_USE_NODE_NAME_ONLY);
126
127 freechain( figlist );
128 freechain( tofree );
129 }
130
131 /****************************************************************************/
132 /* function lib_drivebusorpin */
133 /****************************************************************************/
134 void lib_drivebusorpin (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, befig_list *ptcellbefig, cbhseq *ptcbhseq, int *flagbus, int n, char**busname, int nbrail)
135 {
136 int ninter;
137 int lsb = 0, msb = 0;
138 char *previousname = NULL, *devectname;
139 ttvsig_list *bussig;
140
141 devectname = ttv_devect(ttvsig->NAME);
142 if(*flagbus)
143 if(strcmp(*busname,vectorradical(devectname))){
144 *flagbus = 0;
145 space(f,8);
146 fprintf(f, "}\n\n");
147 }
148 if((ttvsig->NAME != devectname) && (!*flagbus)){
149 ninter = n;
150 *flagbus = 1;
151 lsb = vectorindex(devectname);
152 *busname = vectorradical(devectname);
153 bussig = ttvsig;
154 for(ninter=n; ninter < ttvfig->NBCONSIG; ninter++){
155 ttvsig = ttvfig->CONSIG[ninter];
156 devectname = ttv_devect(ttvsig->NAME);
157 if((vectorradical(devectname) != previousname) && (n != ninter))
158 break;
159 previousname = vectorradical(devectname);
160 msb = vectorindex(devectname);
161 }
162 space(f,8);
163 fprintf(f, "bus (%s) {\n", *busname);
164 space(f,12);
165 fprintf(f, "bus_type : bus_%d_%d ;\n", msb, lsb);
166
167 }
168 ttvsig = ttvfig->CONSIG[n];
169 FLAGBUS = *flagbus;
170 lib_drivepin(f, ttvfig, ttvsig, ptcellbefig, ptcbhseq, nbrail);
171 FLAGBUS = 0;
172 if(*flagbus)
173 if((n + 1) == ttvfig->NBCONSIG){
174 *flagbus = 0;
175 space(f,8);
176 fprintf(f, "}\n");
177 }
178 }
179
180 /****************************************************************************/
181 /* function lib_getpinname */
182 /****************************************************************************/
183 char *lib_getpinname(char *str)
184 {
185 char *signame;
186 static char buf[1024];
187
188 signame = ttv_devect(str);
189 if(vectorindex(signame) == -1){
190 return signame;
191 }else{
192 if(LIB_BUS_DELIM[1] != '\0')
193 sprintf(buf, "%s%c%d%c", vectorradical(signame), LIB_BUS_DELIM[0], vectorindex(signame), LIB_BUS_DELIM[1]);
194 else
195 sprintf(buf, "%s%c%d", vectorradical(signame), LIB_BUS_DELIM[0], vectorindex(signame));
196 return buf;
197 }
198 }
199
200 /****************************************************************************/
201 /* function lib_drive_generated_clocks */
202 /****************************************************************************/
203 void lib_drive_generated_clock (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, ptype_list *ptype)
204 {
205 chain_list *chain=NULL;
206 ptype_list *pt;
207 int mbdb;
208 float duty_cycle;
209 char master[1024];
210
211 space(f,8);
212 fprintf(f,"generated_clock (%s) {\n", lib_getpinname(ttvsig->NAME));
213 sscanf(ptype->DATA, "%d %g%% %s", &mbdb, &duty_cycle, master);
214 space(f,12);
215 fprintf(f,"clock_pin : %s ;\n", lib_getpinname(ttvsig->NAME));
216 if ((pt=getptype(ttvfig->USER, LIB_GENERATED_CLOCK_MASTERS))==NULL){
217 chain = addchain(chain, namealloc(master));
218 ttvfig->USER=addptype(ttvfig->USER, LIB_GENERATED_CLOCK_MASTERS, chain);
219 }else{
220 pt->DATA = addchain(pt->DATA, namealloc(master));
221 }
222 space(f,12);
223 fprintf(f,"master_pin : %s ;\n", lib_getpinname(master));
224 if(mbdb < 0){
225 space(f,12);
226 fprintf(f,"multiplied_by : %d ;\n", abs(mbdb));
227 }else{
228 space(f,12);
229 fprintf(f,"divided_by : %d ;\n", mbdb);
230 }
231 space(f,12);
232 fprintf(f,"duty_cycle : %g ;\n", duty_cycle);
233 space(f,8);
234 fprintf(f,"}\n");
235 }
236
237 /****************************************************************************/
238 /* function lib_drive_generated_clocks */
239 /****************************************************************************/
240 void lib_drive_generated_clocks (FILE *f, ttvfig_list *ttvfig)
241 {
242 ptype_list *ptype;
243 ttvsig_list *ttvsig ;
244 int n;
245
246 for (n=0; n < ttvfig->NBEBREAKSIG; n++){
247 ttvsig=ttvfig->EBREAKSIG[n];
248 if ((ttvsig->TYPE & TTV_SIG_C)!=TTV_SIG_C){
249 ptype = getptype(ttvsig->USER, LIB_GENERATED_CLOCK_INFO);
250 if(ptype)
251 lib_drive_generated_clock(f, ttvfig, ttvsig, ptype);
252 }
253 }
254 for (n=0; n < ttvfig->NBCONSIG; n++){
255 ttvsig=ttvfig->CONSIG[n];
256 ptype = getptype(ttvsig->USER, LIB_GENERATED_CLOCK_INFO);
257 if(ptype)
258 lib_drive_generated_clock(f, ttvfig, ttvsig, ptype);
259 }
260 }
261
262 /****************************************************************************/
263 /* function lib_get_pscale */
264 /****************************************************************************/
265 float lib_get_pscale()
266 {
267 float pscale;
268
269 if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "1mW"))
270 pscale = 1e3;
271 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "100uW"))
272 pscale = 1e4;
273 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "10uW"))
274 pscale = 1e5;
275 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "1uW"))
276 pscale = 1e6;
277 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "100nW"))
278 pscale = 1e7;
279 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "10nW"))
280 pscale = 1e8;
281 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "1nW"))
282 pscale = 1e9;
283 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "100pW"))
284 pscale = 1e10;
285 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "10pW"))
286 pscale = 1e11;
287 else if(!strcmp(V_STR_TAB[__TMA_PUNIT].VALUE, "1pW"))
288 pscale = 1e12;
289 else
290 pscale = 1e6;
291
292 return pscale;
293 }
294
295 /****************************************************************************/
296 /* function lib_drivecell */
297 /****************************************************************************/
298 void lib_drivecell (FILE *f, ttvfig_list *ttvfig, befig_list *ptcellbefig, char *suffix)
299 {
300 int n ;
301 ttvsig_list *ttvsig ;
302 char *name, *busname;
303 cbhseq *ptcbhseq=NULL;
304 int flagbus = 0, nbrail;
305 ptype_list *ptype;
306 tma_leak_pow_list *tlp;
307 float pscale = lib_get_pscale();
308
309 name=lib_unsuffix (ttvfig->INFO->FIGNAME, suffix);
310 tab(f);
311 fprintf(f,"cell (%s) {\n", name);
312 if(tut_tablasharea){
313 tab(f);
314 tab(f);
315 if(gethtitem(tut_tablasharea,name) != EMPTYHT)
316 fprintf(f,"area : %.2f ;\n",(double)(gethtitem(tut_tablasharea,name))/1000.0);
317 else
318 fprintf(f,"area : 0.0 ;\n");
319 }else{
320 tab(f);
321 tab(f);
322 fprintf(f,"area : 0.0 ;\n");
323 }
324
325 if((ptype = getptype(ttvfig->USER, TTV_CELL_LEAKAGE_POWER)) != NULL){
326 tab(f);
327 tab(f);
328 fprintf(f,"cell_leakage_power : %.2g ;\n", *(float*)&ptype->DATA * pscale);
329 }
330
331 if((ptype = getptype(ttvfig->USER, TTV_LEAKAGE_POWER)) != NULL){
332 for(tlp = (tma_leak_pow_list*)ptype->DATA; tlp; tlp=tlp->NEXT){
333 space(f,8);
334 fprintf(f,"leakage_power () {\n");
335 space(f,12);
336 fprintf(f,"when : \"");
337 cbh_writeabl(f,tlp->PATTERN, 'L');
338 fprintf(f,"\" ;\n");
339 space(f,12);
340 fprintf(f,"value : %.2g ;\n", tlp->VALUE * pscale );
341 space(f,8);
342 fprintf(f,"}\n");
343
344 }
345 }
346
347 if(ptcellbefig){
348 if((ptype = getptype(ttvfig->USER, TTV_FIG_CBHSEQ)) != NULL){
349 ptcbhseq = (cbhseq*)ptype->DATA;
350 lib_driveseqfunc(f,ptcbhseq);
351 }
352 }
353 nbrail = lib_drive_rail_connection(f, ttvfig);
354 lib_drive_generated_clocks(f, ttvfig);
355 flagbus = 0;
356 for (n=0; n < ttvfig->NBEBREAKSIG; n++){
357 ttvsig=ttvfig->EBREAKSIG[n];
358 if ((ttvsig->TYPE & TTV_SIG_C)!=TTV_SIG_C)
359 lib_drivepin(f, ttvfig, ttvsig, NULL, NULL, nbrail);
360 }
361 if(flagbus){
362 flagbus = 0;
363 space(f,8);
364 fprintf(f, "}\n\n");
365 }
366 flagbus = 0;
367 for (n=0; n < ttvfig->NBCONSIG; n++){
368 ttvsig=ttvfig->CONSIG[n];
369 if (((ttvsig->TYPE & TTV_SIG_CI)==TTV_SIG_CI)
370 && ((ttvsig->TYPE & TTV_SIG_CB)!=TTV_SIG_CB)
371 && ((ttvsig->TYPE & TTV_SIG_CT)!=TTV_SIG_CT))
372 lib_drivebusorpin(f, ttvfig, ttvsig, NULL, NULL, &flagbus, n, &busname, nbrail);
373 }
374 if(flagbus){
375 flagbus = 0;
376 space(f,8);
377 fprintf(f, "}\n\n");
378 }
379 flagbus = 0;
380 for (n=0; n < ttvfig->NBCONSIG; n++){
381 ttvsig=ttvfig->CONSIG[n];
382 if ((ttvsig->TYPE & TTV_SIG_CO)==TTV_SIG_CO)
383 lib_drivebusorpin(f, ttvfig, ttvsig, ptcellbefig, ptcbhseq, &flagbus, n, &busname, nbrail);
384 }
385 if(flagbus){
386 flagbus = 0;
387 space(f,8);
388 fprintf(f, "}\n\n");
389 }
390 flagbus = 0;
391 for (n=0; n < ttvfig->NBCONSIG; n++){
392 ttvsig=ttvfig->CONSIG[n];
393 if ((ttvsig->TYPE & TTV_SIG_CX)==TTV_SIG_CX)
394 lib_drivebusorpin(f, ttvfig, ttvsig, ptcellbefig, ptcbhseq, &flagbus, n, &busname, nbrail);
395 }
396 if(flagbus){
397 flagbus = 0;
398 space(f,8);
399 fprintf(f, "}\n\n");
400 }
401 tab(f);
402 fprintf(f,"}\n");
403 if (ptcbhseq) cbh_delseq(ptcbhseq);
404
405 }
406 /****************************************************************************/
407 /* function lib_driveseqfunc */
408 /****************************************************************************/
409 void lib_driveseqfunc (FILE *f, cbhseq *ptcbhseq)
410 {
411 if(ptcbhseq){
412 if(ptcbhseq->SEQTYPE==CBH_LATCH){
413 space(f, 8);
414 fprintf(f,"latch(");
415 if(ptcbhseq->NAME){
416 fprintf(f,"%s",ptcbhseq->NAME);
417 if(ptcbhseq->NEGNAME)
418 fprintf(f,",%s",ptcbhseq->NEGNAME);
419 fprintf(f,") {\n");
420 }else if(ptcbhseq->NEGNAME){
421 fprintf(f,"%s) {\n",ptcbhseq->NEGNAME);
422 }
423 if(ptcbhseq->CLOCK){
424 space(f, 12);
425 fprintf(f,"enable : \"");
426 cbh_writeabl(f,ptcbhseq->CLOCK, 'L');
427 fprintf(f,"\" ;\n");
428 }
429 if(ptcbhseq->DATA){
430 space(f, 12);
431 fprintf(f,"data_in : \"");
432 cbh_writeabl(f,ptcbhseq->DATA, 'L');
433 fprintf(f,"\" ;\n");
434 }
435 if(ptcbhseq->RESET){
436 space(f, 12);
437 fprintf(f,"clear : \"");
438 cbh_writeabl(f,ptcbhseq->RESET, 'L');
439 fprintf(f,"\" ;\n");
440 }
441 if(ptcbhseq->SET){
442 space(f, 12);
443 fprintf(f,"preset : \"");
444 cbh_writeabl(f,ptcbhseq->SET, 'L');
445 fprintf(f,"\" ;\n");
446 }
447 if(ptcbhseq->RSCONF){
448 space(f, 12);
449 fprintf(f,"clear_preset_var1 : ");
450 cbh_writeabl(f,ptcbhseq->RSCONF, 'L');
451 fprintf(f," ;\n");
452 }
453 if(ptcbhseq->RSCONFNEG){
454 space(f, 12);
455 fprintf(f,"clear_preset_var2 : ");
456 cbh_writeabl(f,ptcbhseq->RSCONFNEG, 'L');
457 fprintf(f," ;\n");
458 }
459 saut(f,1);
460 space(f, 8);
461 fprintf(f,"}\n");
462 }else if(ptcbhseq->SEQTYPE==CBH_FLIPFLOP){
463 space(f, 8);
464 fprintf(f,"ff(");
465 if(ptcbhseq->NAME){
466 fprintf(f,"%s",ptcbhseq->NAME);
467 if(ptcbhseq->NEGNAME)
468 fprintf(f,",%s",ptcbhseq->NEGNAME);
469 fprintf(f,") {\n");
470 }else if(ptcbhseq->NEGNAME){
471 fprintf(f,"%s) {\n",ptcbhseq->NEGNAME);
472 }
473 if(ptcbhseq->CLOCK){
474 space(f, 12);
475 fprintf(f,"clocked_on : \"");
476 cbh_writeabl(f,ptcbhseq->CLOCK, 'L');
477 fprintf(f,"\" ;\n");
478 }
479 if(ptcbhseq->SLAVECLOCK){
480 space(f, 12);
481 fprintf(f,"clocked_on_also : \"");
482 cbh_writeabl(f,ptcbhseq->SLAVECLOCK, 'L');
483 fprintf(f,"\" ;\n");
484 }
485 if(ptcbhseq->DATA){
486 space(f, 12);
487 fprintf(f,"next_state : \"");
488 cbh_writeabl(f,ptcbhseq->DATA, 'L');
489 fprintf(f,"\" ;\n");
490 }
491 if(ptcbhseq->RESET){
492 space(f, 12);
493 fprintf(f,"clear : \"");
494 cbh_writeabl(f,ptcbhseq->RESET, 'L');
495 fprintf(f,"\" ;\n");
496 }
497 if(ptcbhseq->SET){
498 space(f, 12);
499 fprintf(f,"preset : \"");
500 cbh_writeabl(f,ptcbhseq->SET, 'L');
501 fprintf(f,"\" ;\n");
502 }
503 if(ptcbhseq->RSCONF){
504 space(f, 12);
505 fprintf(f,"clear_preset_var1 : ");
506 cbh_writeabl(f,ptcbhseq->RSCONF, 'L');
507 fprintf(f," ;\n");
508 }
509 if(ptcbhseq->RSCONFNEG){
510 space(f, 12);
511 fprintf(f,"clear_preset_var2 : ");
512 cbh_writeabl(f,ptcbhseq->RSCONFNEG, 'L');
513 fprintf(f," ;\n");
514 }
515 saut(f,1);
516 space(f, 8);
517 fprintf(f,"}\n");
518 }
519 }
520 }
521
522 /****************************************************************************/
523 /* function lib_get_tg_pinname */
524 /****************************************************************************/
525 char *lib_get_tg_pinname(char *str)
526 {
527 char *signame;
528 static char buf[1024];
529
530 signame = ttv_devect(str);
531 if(vectorindex(signame) == -1){
532 return signame;
533 }else{
534 if(LIB_BUS_DELIM[1] != '\0')
535 sprintf(buf, "%s_%d_", vectorradical(signame), vectorindex(signame));
536 else
537 sprintf(buf, "%s_%d", vectorradical(signame), vectorindex(signame));
538 return buf;
539 }
540 }
541 /****************************************************************************/
542 /* function lib_clock_true */
543 /****************************************************************************/
544 void lib_drive_clock_true(FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig)
545 {
546 ptype_list *pt;
547 chain_list *chain;
548 if ((pt=getptype(ttvfig->USER, LIB_GENERATED_CLOCK_MASTERS))!=NULL){
549 for(chain=pt->DATA; chain; chain=chain->NEXT){
550 if((char*)chain->DATA == ttvsig->NAME){
551 space(f,12);
552 fprintf(f,"clock : true ;\n");
553 break;
554 }
555 }
556 }
557 }
558
559
560 /****************************************************************************/
561 /* function lib_drivepin */
562 /****************************************************************************/
563 void lib_drivepin (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, befig_list *ptcellbefig, cbhseq *ptcbhseq, int nbrail)
564 {
565 chain_list *chtsname=NULL;
566 bepor_list *ptbepor=NULL;
567 char *signame;
568 char *pinname;
569
570 signame = ttv_devect(ttvsig->NAME);
571 if(ptcellbefig){
572 for(ptbepor=ptcellbefig->BEPOR; ptbepor; ptbepor=ptbepor->NEXT){
573 if(ptbepor->NAME==signame) break;
574 }
575 }
576
577 space(f,8);
578 pinname = lib_getpinname(ttvsig->NAME);
579 if(isdigit(pinname[0]))
580 fprintf(f,"pin (\"%s\") {\n", pinname);
581 else
582 fprintf(f,"pin (%s) {\n", pinname);
583 chtsname=lib_drivecombfunc(f,signame,ptcellbefig,ptcbhseq);
584 lib_drivedirection(f, ttvsig, ptbepor, chtsname, nbrail);
585 lib_drive_clock_true(f, ttvfig, ttvsig);
586 if((ttvsig->TYPE & TTV_SIG_C) == TTV_SIG_C)
587 lib_drivecapacitance(f, ttvsig);
588 if(!getptype (ttvsig->USER, TTV_SIG_ASYNCHRON)){
589 lib_drivetiming(f, ttvfig, ttvsig, chtsname,ptcbhseq, ptcellbefig);
590 }
591 if(( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 1 )
592 ||( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 5 ))
593 lib_drivepower(f, ttvfig, ttvsig, chtsname, ptcellbefig);
594 freechain(chtsname);
595 space(f,8);
596 fprintf(f,"}\n");
597
598 }
599
600 /****************************************************************************/
601 /* function lib_drivecombfunc */
602 /****************************************************************************/
603 chain_list* lib_drivecombfunc (FILE *f, char *name, befig_list *ptcellbefig, cbhseq *ptcbhseq)
604 {
605 cbhcomb *ptcbhcomb;
606 chain_list *chtsname=NULL;
607
608 if(ptcellbefig){
609 ptcbhcomb = cbh_getcombfunc(ptcellbefig, ptcbhseq, name);
610 if(ptcbhcomb){
611 if(ptcbhcomb->FUNCTION){
612 space(f,12);
613 fprintf(f,"function : \"");
614 cbh_writeabl(f, ptcbhcomb->FUNCTION, 'L');
615 fprintf(f,"\" ;\n");
616 }
617 if(ptcbhcomb->HZFUNC){
618 chtsname=supportChain_listExpr(ptcbhcomb->HZFUNC);
619
620 space(f,12);
621 fprintf(f,"three_state : \"");
622 cbh_writeabl(f, ptcbhcomb->HZFUNC, 'L');
623 fprintf(f,"\" ;\n");
624 }
625 if(ptcbhcomb->CONFLICT){
626 space(f,12);
627 fprintf(f,"x_function : \"");
628 cbh_writeabl(f, ptcbhcomb->CONFLICT, 'L');
629 fprintf(f,"\" ;\n");
630 }
631 cbh_delcomb(ptcbhcomb);
632 }
633 }
634 return chtsname;
635 }
636
637 /****************************************************************************/
638 /* function lib_drivecapacitance */
639 /****************************************************************************/
640 void lib_drivecapacitance (FILE *f, ttvsig_list *ttvsig)
641 {
642 float cumin,cumax,cdmin,cdmax;
643 double capaupmin,capaupmax,capadnmin,capadnmax;
644 int flag = 0;
645 float max_capa;
646 ptype_list *ptype;
647
648 if(((ttvsig->TYPE & TTV_SIG_CI) == TTV_SIG_CI) || (V_BOOL_TAB[__TMA_DRIVECAPAOUT].VALUE == 1)){
649 if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 ){
650 if(ttv_getsigcapas ( ttvsig,
651 NULL, &cumin, &cumax,
652 NULL, &cdmin, &cdmax)){
653 capaupmin = cumin*1000.0;
654 capaupmax = cumax*1000.0;
655 capadnmin = cdmin*1000.0;
656 capadnmax = cdmax*1000.0;
657 if( 0.99*(double)ttvsig->CAPA < ((double)capaupmin))
658 capaupmin = 0.99*(double)ttvsig->CAPA;
659 if( 0.99*(double)ttvsig->CAPA < ((double)capadnmin))
660 capadnmin = 0.99*(double)ttvsig->CAPA;
661 if( 1.01*(double)ttvsig->CAPA > ((double)capaupmax))
662 capaupmax = 1.01*(double)ttvsig->CAPA;
663 if( 1.01*(double)ttvsig->CAPA > ((double)capadnmax))
664 capadnmax = 1.01*(double)ttvsig->CAPA;
665 flag = 1;
666 }else{
667 flag = 0;
668 }
669 }
670 if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"ff")){
671 space(f,12);
672 fprintf(f,"capacitance : %.2f ;\n",(double)ttvsig->CAPA);
673 if (( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 ) && flag) {
674 space(f,12);
675 fprintf(f,"rise_capacitance_range ( %.2f , %.2f ) ;\n",
676 capaupmin,capaupmax);
677 space(f,12);
678 fprintf(f,"fall_capacitance_range ( %.2f , %.2f ) ;\n",
679 capadnmin,capadnmax);
680 }
681 }else if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"pf")){
682 space(f,12);
683 fprintf(f,"capacitance : %.5f ;\n",(double)ttvsig->CAPA / 1000.0);
684 if (( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 ) && flag) {
685 space(f,12);
686 fprintf(f,"rise_capacitance_range ( %.5f , %.5f ) ;\n",(double)capaupmin/1000.0,(double)capaupmax/1000.0);
687 space(f,12);
688 fprintf(f,"fall_capacitance_range ( %.5f , %.5f ) ;\n",(double)capadnmin/1000.0,(double)capadnmax/1000.0);
689 }
690 }
691 }
692 if((ttvsig->TYPE & TTV_SIG_CO) == TTV_SIG_CO){
693 ptype = getptype(ttvsig->USER, LIB_MAX_CAPACITANCE);
694 if(ptype){
695 max_capa = *(float*)&ptype->DATA;
696 if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"ff")){
697 space(f,12);
698 fprintf(f,"max_capacitance : %.2f ;\n", max_capa * 1e15);
699 }else if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"pf")){
700 space(f,12);
701 fprintf(f,"max_capacitance : %.5f ;\n", max_capa * 1e12);
702 }
703 }
704 }
705
706 }
707
708 /****************************************************************************/
709 /* function lib_drivedirection */
710 /****************************************************************************/
711 void lib_drivedirection (FILE *f, ttvsig_list *ttvsig, bepor_list *ptbepor, chain_list *chtsname, int nbrail)
712 {
713 char *dir, *level=NULL ;
714 float low, high, alim, nom_voltage;
715 ptype_list *ptype;
716
717 if ((ttvsig->TYPE & TTV_SIG_CX)==TTV_SIG_CX){
718 if(ptbepor){
719 switch(ptbepor->DIRECTION){
720 case 'I' : dir="input"; break;
721 case 'O' : dir="output"; break;
722 case 'Z' : dir="output"; break;
723 case 'T' : dir="inout"; break;
724 case 'B' : dir="output"; break;
725 case 'X' : dir="input"; break;
726 default : dir="input";
727 }
728 }else{
729 dir="input";
730 }
731 }
732 else if ((ttvsig->TYPE & TTV_SIG_CT)==TTV_SIG_CT)
733 dir="inout";
734 else if ((ttvsig->TYPE & TTV_SIG_CB)==TTV_SIG_CB)
735 dir="output";
736 else if ((ttvsig->TYPE & TTV_SIG_CZ)==TTV_SIG_CZ)
737 dir="output";
738 else if ((ttvsig->TYPE & TTV_SIG_CO)==TTV_SIG_CO)
739 dir="output";
740 else
741 dir="input";
742
743 if ((ttvsig->TYPE & TTV_SIG_C)!=TTV_SIG_C)
744 dir="internal";
745
746 space(f,12);
747 fprintf(f,"direction : %s ;\n", dir);
748
749 if(libpowerptype && (nbrail > 1)){
750 nom_voltage = ttvsig->ROOT->INFO->VDD;
751 for(ptype = libpowerptype; ptype && !level; ptype = ptype->NEXT){
752 if (!ttv_get_signal_swing(ttvsig->ROOT, ttvsig, &low, &high)){
753 alim = high - low;
754 if(!mbk_cmpdouble(*(float*)&ptype->DATA, alim, 1e6)){
755 level = (char*)ptype->TYPE;
756 }
757 }else if(high > 0.0){
758 alim = high - low;
759 if(!mbk_cmpdouble(nom_voltage, alim, 1e6)){
760 level = namealloc("VDD0");
761 }
762 }
763 }
764 if(!strcmp(dir, "inout")){
765 space(f,12);
766 fprintf(f, "input_signal_level : %s ;\n", level);
767 space(f,12);
768 fprintf(f, "output_signal_level : %s ;\n", level);
769 }else if((!strcmp(dir, "input"))/*||(!strcmp(dir, "internal"))*/){
770 space(f,12);
771 fprintf(f, "input_signal_level : %s ;\n", level);
772 }else{
773 space(f,12);
774 fprintf(f, "output_signal_level : %s ;\n", level);
775 }
776 }
777 }
778
779 /****************************************************************************/
780 /* function lib_drive_pos */
781 /****************************************************************************/
782 void lib_drive_pos(FILE *f, ttvfig_list *ttvfig, chain_list *chain_posname, chain_list *chain_pos, char type, chain_list *chain_nonunate, befig_list *ptcellbefig)
783 {
784 int nline = 0;
785 char typel;
786 chain_list *ch, *chx, *abl ;
787 ttvline_list *line;
788 char buf[1024];
789 char bufsig[1024];
790 char bufttype[1024];
791 char *relpinname;
792 char *pinname;
793
794 ttv_getsigname(ttvfig, bufsig, ((ttvline_list*)chain_pos->DATA)->ROOT->ROOT);
795
796 for(chx=chain_posname; chx; chx=chx->NEXT){
797 pinname = lib_get_tg_pinname(bufsig);
798 if(type == 'M')
799 sprintf(buf, "maxd_%s_", pinname);
800 else
801 sprintf(buf, "mind_%s_", pinname);
802 relpinname = lib_get_tg_pinname((char*)chx->DATA);
803 strcat(buf, relpinname);
804
805 nline=0;
806 for(ch=chain_pos; ch; ch=ch->NEXT){
807 line=(ttvline_list*)ch->DATA;
808
809 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
810 typel = line->ROOT->TYPE;
811 nline++;
812 }
813 }
814 if(nline==1){
815 if((typel & TTV_NODE_UP) == TTV_NODE_UP)
816 sprintf(bufttype,"preset");
817 else
818 sprintf(bufttype,"clear");
819 strcat(buf, "_");
820 strcat(buf, bufttype);
821 }
822 strcat(buf, "_positive_unate");
823 space(f,12);
824 fprintf(f,"timing (%s) {\n", buf);
825 relpinname = lib_getpinname((char*)chx->DATA);
826 space(f,16);
827 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
828 if(chain_nonunate && ptcellbefig){
829 abl = NULL;
830 for(ch=chain_nonunate; ch; ch=ch->NEXT){
831 if(!strcmp(relpinname,(char*)ch->DATA)){
832 abl = cbh_calccondition(ptcellbefig, pinname, relpinname, CBH_NONINVERT);
833 break;
834 }
835 }
836 if(abl){
837 space(f,16);
838 fprintf(f,"when : \"");
839 cbh_writeabl(f, abl, 'L');
840 fprintf(f,"\" ;\n");
841 space(f,16);
842 fprintf(f,"sdf_cond : \"");
843 cbh_writeabl(f, abl, 'L');
844 fprintf(f,"\" ;\n");
845 }
846 }
847 space(f,16);
848 fprintf(f,"timing_sense : positive_unate ;\n");
849 if(nline==1){
850 space(f,16);
851 fprintf(f,"timing_type : %s ;\n", bufttype);
852 }
853 for(ch=chain_pos; ch; ch=ch->NEXT){
854 line=(ttvline_list*)ch->DATA;
855 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
856 if(type == 'M')
857 lib_drivedelaymax(f, ttvfig, line);
858 else
859 lib_drivedelaymin(f, ttvfig, line);
860 }
861 }
862 space(f,12);
863 fprintf(f,"}\n");
864 }
865 }
866
867 /****************************************************************************/
868 /* function lib_drive_neg */
869 /****************************************************************************/
870 void lib_drive_neg(FILE *f, ttvfig_list *ttvfig, chain_list *chain_negname, chain_list *chain_neg, char type, chain_list *chain_nonunate, befig_list *ptcellbefig)
871 {
872 int nline = 0;
873 char typel;
874 chain_list *ch, *chx, *abl ;
875 ttvline_list *line;
876 char buf[1024];
877 char bufsig[1024];
878 char bufttype[1024];
879 char *relpinname;
880 char *pinname;
881
882 ttv_getsigname(ttvfig, bufsig, ((ttvline_list*)chain_neg->DATA)->ROOT->ROOT);
883
884 for(chx=chain_negname; chx; chx=chx->NEXT){
885 pinname = lib_get_tg_pinname(bufsig);
886 if(type == 'M')
887 sprintf(buf, "maxd_%s_", pinname);
888 else
889 sprintf(buf, "mind_%s_", pinname);
890 relpinname = lib_get_tg_pinname((char*)chx->DATA);
891 strcat(buf, relpinname);
892
893 nline=0;
894 for(ch=chain_neg; ch; ch=ch->NEXT){
895 line=(ttvline_list*)ch->DATA;
896 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
897 typel = line->ROOT->TYPE;
898 nline++;
899 }
900 }
901 if(nline==1){
902 if((typel & TTV_NODE_UP) == TTV_NODE_UP)
903 sprintf(bufttype,"preset");
904 else
905 sprintf(bufttype,"clear");
906 strcat(buf, "_");
907 strcat(buf, bufttype);
908 }
909 strcat(buf, "_negative_unate");
910 space(f,12);
911 fprintf(f,"timing (%s) {\n", buf);
912 relpinname = lib_getpinname((char*)chx->DATA);
913 space(f,16);
914 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
915 if(chain_nonunate && ptcellbefig){
916 abl = NULL;
917 for(ch=chain_nonunate; ch; ch=ch->NEXT){
918 if(!strcmp(relpinname,(char*)ch->DATA)){
919 abl = cbh_calccondition(ptcellbefig, pinname, relpinname, CBH_INVERT);
920 break;
921 }
922 }
923 if(abl){
924 space(f,16);
925 fprintf(f,"when : \"");
926 cbh_writeabl(f, abl, 'L');
927 fprintf(f,"\" ;\n");
928 space(f,16);
929 fprintf(f,"sdf_cond : \"");
930 cbh_writeabl(f, abl, 'L');
931 fprintf(f,"\" ;\n");
932 }
933 }
934 space(f,16);
935 fprintf(f,"timing_sense : negative_unate ;\n");
936 if(nline==1){
937 space(f,16);
938 fprintf(f,"timing_type : %s ;\n", bufttype);
939 }
940 for(ch=chain_neg; ch; ch=ch->NEXT){
941 line=(ttvline_list*)ch->DATA;
942 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
943 if(type == 'M')
944 lib_drivedelaymax(f, ttvfig, line);
945 else
946 lib_drivedelaymin(f, ttvfig, line);
947 }
948 }
949 space(f,12);
950 fprintf(f,"}\n");
951 }
952 }
953
954 /****************************************************************************/
955 /* function lib_drive_tri */
956 /****************************************************************************/
957 void lib_drive_tri(FILE *f, ttvfig_list *ttvfig, chain_list *chain_triname, chain_list *chain_tri, char type)
958 {
959 int nline = 0, tristate = 0, ttype = 0, tsense = 0;
960 char typel;
961 chain_list *ch, *chx ;
962 ttvline_list *line;
963 char buf[1024];
964 char bufsig[1024];
965 char bufttype[1024];
966 char buftsense[1024];
967 char *relpinname;
968 char *pinname;
969
970 ttv_getsigname(ttvfig, bufsig, ((ttvline_list*)chain_tri->DATA)->ROOT->ROOT);
971
972 for(chx=chain_triname; chx; chx=chx->NEXT){
973 pinname = lib_get_tg_pinname(bufsig);
974 if(type == 'M')
975 sprintf(buf, "maxd_%s_", pinname);
976 else
977 sprintf(buf, "mind_%s_", pinname);
978 relpinname = lib_get_tg_pinname((char*)chx->DATA);
979 strcat(buf, relpinname);
980
981 nline=0;
982 tristate=0;
983 ttype=0;
984 tsense=0;
985 for(ch=chain_tri; ch; ch=ch->NEXT){
986 line=(ttvline_list*)ch->DATA;
987 if((!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA))
988 &&((line->TYPE & TTV_LINE_HZ)!=TTV_LINE_HZ)){
989 if(((line->NODE->TYPE & TTV_NODE_UP) == TTV_NODE_UP) && (nline == 0)){
990 sprintf(buftsense,"positive_unate");
991 tsense=1;
992 }else if(nline == 0){
993 sprintf(buftsense, "negative_unate");
994 tsense=1;
995 }
996 typel = line->ROOT->TYPE;
997 nline++;
998 }else if((!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA))
999 &&((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ)){
1000 tristate = 1;
1001 }
1002 }
1003 if(nline==1 && tristate){
1004 if((typel & TTV_NODE_UP) == TTV_NODE_UP)
1005 sprintf(bufttype,"three_state_enable_rise");
1006 else
1007 sprintf(bufttype,"three_state_enable_fall");
1008 ttype=1;
1009 }else if(tristate){
1010 sprintf(bufttype,"three_state_enable");
1011 ttype=1;
1012 }
1013
1014 if(ttype){
1015 strcat(buf, "_");
1016 strcat(buf, bufttype);
1017 }
1018 if(tsense){
1019 strcat(buf, "_");
1020 strcat(buf, buftsense);
1021 }
1022
1023 if(tsense || ttype){
1024 space(f,12);
1025 fprintf(f,"timing (%s) {\n", buf);
1026 relpinname = lib_getpinname((char*)chx->DATA);
1027 space(f,16);
1028 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1029 }
1030
1031 if(tsense){
1032 space(f,16);
1033 fprintf(f,"timing_sense : %s ;\n", buftsense);
1034 }
1035 if(ttype){
1036 space(f,16);
1037 fprintf(f,"timing_type : %s ;\n", bufttype);
1038 }
1039
1040 for(ch=chain_tri; ch; ch=ch->NEXT){
1041 line=(ttvline_list*)ch->DATA;
1042 if((!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA))
1043 &&((line->TYPE & TTV_LINE_HZ)!=TTV_LINE_HZ)){
1044 if(type == 'M')
1045 lib_drivedelaymax(f, ttvfig, line);
1046 else
1047 lib_drivedelaymin(f, ttvfig, line);
1048 }
1049 }
1050 if(tsense || ttype){
1051 space(f,12);
1052 fprintf(f,"}\n");
1053 }
1054 }
1055 for(chx=chain_triname; chx; chx=chx->NEXT){
1056 pinname = lib_get_tg_pinname(bufsig);
1057 if(type == 'M')
1058 sprintf(buf, "maxd_%s_", pinname);
1059 else
1060 sprintf(buf, "mind_%s_", pinname);
1061 relpinname = lib_get_tg_pinname((char*)chx->DATA);
1062 strcat(buf, relpinname);
1063
1064 nline=0;
1065 ttype=0;
1066 tsense=0;
1067 for(ch=chain_tri; ch; ch=ch->NEXT){
1068 line=(ttvline_list*)ch->DATA;
1069 if((!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA))
1070 &&((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ)){
1071 if(((line->NODE->TYPE & TTV_NODE_UP) == TTV_NODE_UP) && (nline == 0)){
1072 sprintf(buftsense,"positive_unate");
1073 tsense=1;
1074 }else if(nline == 0){
1075 sprintf(buftsense,"negative_unate");
1076 tsense=1;
1077 }
1078 typel = line->ROOT->TYPE;
1079 nline++;
1080 }
1081 }
1082 if(nline==1){
1083 if((typel & TTV_NODE_UP) == TTV_NODE_UP){
1084 sprintf(bufttype,"three_state_disable_fall");
1085 }else{
1086 sprintf(bufttype,"three_state_disable_rise");
1087 }
1088 ttype=1;
1089 }else if(nline>1){
1090 sprintf(bufttype,"three_state_disable");
1091 ttype=1;
1092 }
1093 if(ttype){
1094 strcat(buf, "_");
1095 strcat(buf, bufttype);
1096 }
1097 if(tsense){
1098 strcat(buf, "_");
1099 strcat(buf, buftsense);
1100 }
1101
1102 if(tsense || ttype){
1103 space(f,12);
1104 fprintf(f,"timing (%s) {\n", buf);
1105 relpinname = lib_getpinname((char*)chx->DATA);
1106 space(f,16);
1107 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1108 }
1109
1110 if(tsense){
1111 space(f,16);
1112 fprintf(f,"timing_sense : %s ;\n", buftsense);
1113 }
1114 if(ttype){
1115 space(f,16);
1116 fprintf(f,"timing_type : %s ;\n", bufttype);
1117 }
1118
1119 for(ch=chain_tri; ch; ch=ch->NEXT){
1120 line=(ttvline_list*)ch->DATA;
1121 if((!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA))
1122 &&((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ)){
1123 if(type == 'M')
1124 lib_drivedelaymax(f, ttvfig, line);
1125 else
1126 lib_drivedelaymin(f, ttvfig, line);
1127 }
1128 }
1129 if(tsense || ttype){
1130 space(f,12);
1131 fprintf(f,"}\n");
1132 }
1133 }
1134 }
1135
1136 /****************************************************************************/
1137 /* function lib_drivepower_with_sdfcond */
1138 /****************************************************************************/
1139 void lib_drivepower_with_sdfcond (FILE *f, ttvfig_list *ttvfig, befig_list *ptcellbefig, chain_list *chain_name, chain_list *chain, int type, chain_list *chain_nonunate)
1140 {
1141 ttvline_list *line;
1142 timing_model *tmodel;
1143 chain_list *chx, *ch;
1144 char buf[1024];
1145 char bufsig[1024];
1146 char *relpinname;
1147 char *pinname;
1148 int driveok, rise, fall;
1149 chain_list *abl;
1150
1151 for(ch=chain; ch; ch=ch->NEXT){
1152 if(ch->DATA){
1153 ttv_getsigname(ttvfig, bufsig, ((ttvline_list*)ch->DATA)->ROOT->ROOT);
1154 break;
1155 }
1156 }
1157
1158 for(chx=chain_name; chx; chx=chx->NEXT){
1159 driveok = 0;
1160 for(ch=chain; ch; ch=ch->NEXT){
1161 line=(ttvline_list*)ch->DATA;
1162 if(!line) continue;
1163 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
1164 if(line->MDMAX){
1165 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, line->MDMAX);
1166 if(tmodel->ENERGYTYPE == STM_ENERGY_TABLE){
1167 driveok = 1;
1168 }
1169 }
1170 }
1171 }
1172 if(chain_nonunate && !ptcellbefig && (type == CBH_INVERT)){
1173 for(ch=chain_nonunate; ch; ch=ch->NEXT){
1174 if(!strcmp(relpinname,(char*)ch->DATA)){
1175 driveok = 0;
1176 break;
1177 }
1178 }
1179 }
1180 if(driveok){
1181 abl = NULL;
1182 pinname = lib_get_tg_pinname(bufsig);
1183 if(type == CBH_NONINVERT){
1184 sprintf(buf, "energy_pos_%s_", pinname);
1185 }else if(type == CBH_INVERT){
1186 sprintf(buf, "energy_neg_%s_", pinname);
1187 }else{
1188 sprintf(buf, "energy_nun_%s_", pinname);
1189 }
1190 relpinname = lib_get_tg_pinname((char*)chx->DATA);
1191 strcat(buf, relpinname);
1192 relpinname = lib_getpinname((char*)chx->DATA);
1193 if(chain_nonunate && ptcellbefig){
1194 for(ch=chain_nonunate; ch; ch=ch->NEXT){
1195 if(!strcmp(relpinname,(char*)ch->DATA)){
1196 abl = cbh_calccondition(ptcellbefig, pinname, relpinname, type);
1197 break;
1198 }
1199 }
1200 }
1201 space(f,12);
1202 fprintf(f,"internal_power (%s) {\n", buf);
1203 space(f,16);
1204 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1205 if(ptcellbefig && abl){
1206 space(f,16);
1207 fprintf(f,"when : \"");
1208 cbh_writeabl(f, abl, 'L');
1209 fprintf(f,"\" ;\n");
1210 }
1211 rise = 0;
1212 fall = 0;
1213 for(ch=chain; ch; ch=ch->NEXT){
1214 line=(ttvline_list*)ch->DATA;
1215 if(!line) continue;
1216 if(!strcmp(line->NODE->ROOT->NAME,(char*)chx->DATA)){
1217 if(line->MDMAX && line->MFMAX){
1218 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, line->MDMAX);
1219 if(tmodel->ENERGYTYPE == STM_ENERGY_TABLE){
1220 if((line->ROOT->TYPE & TTV_NODE_UP)==TTV_NODE_UP && !rise){
1221 rise = 1;
1222 space(f,16);
1223 if(tmodel->ENERGYMODEL.ETABLE->CST != STM_NOVALUE){
1224 fprintf(f,"rise_power (scalar) {\n");
1225 lib_drivelutconst(f, tmodel->ENERGYMODEL.ETABLE->CST, 'E');
1226 }else{
1227 fprintf(f,"rise_power (energy_%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
1228 lib_drivelut (f, tmodel, 'E');
1229 }
1230 space(f,16);
1231 fprintf(f,"}\n");
1232 }else if(!fall){
1233 fall = 1;
1234 space(f,16);
1235 if(tmodel->ENERGYMODEL.ETABLE->CST != STM_NOVALUE){
1236 fprintf(f,"fall_power (scalar) {\n");
1237 lib_drivelutconst(f, tmodel->ENERGYMODEL.ETABLE->CST, 'E');
1238 }else{
1239 fprintf(f,"fall_power (energy_%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
1240 lib_drivelut (f, tmodel, 'E');
1241 }
1242 space(f,16);
1243 fprintf(f,"}\n");
1244 }
1245 }
1246 }
1247 }
1248 }
1249 space(f,12);
1250 fprintf(f,"}\n");
1251 }
1252 }
1253 }
1254 /****************************************************************************/
1255 /* function lib_drivepower */
1256 /****************************************************************************/
1257 void lib_drivepower (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, chain_list *chtsname, befig_list *ptcellbefig)
1258 {
1259 ttvevent_list *outevent, *outevent2, *event_rise, *event_fall;
1260 ttvline_list *line, *line2, *line3;
1261 timing_model *tmodel, *tmodel2, *tmodel3;
1262 chain_list *chain_pos, *chain_neg, *chain_tri, *chain_posname, *chain_negname, *chain_triname, *chain_nonunate;
1263 int ev, ev2;
1264 int ttx;
1265 char buf[1024];
1266 char bufsig[1024];
1267 char *pinname;
1268 ptype_list *ptyperise, *ptypefall;
1269 char flagtri;
1270 chain_list *ch, *ch2, *ch3, *abl;
1271
1272
1273 if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_TTX)==TTV_FILE_TTX)
1274 ttx=1;
1275 else if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_DTX)==TTV_FILE_DTX)
1276 ttx=0;
1277 else
1278 ttx=1;
1279
1280 chain_pos = NULL;
1281 chain_neg = NULL;
1282 chain_tri = NULL;
1283 chain_posname = NULL;
1284 chain_negname = NULL;
1285 chain_triname = NULL;
1286 chain_nonunate = NULL;
1287 if((ttvsig->TYPE & TTV_SIG_CO)==TTV_SIG_CO) {
1288 for(ev=0;ev < 2; ev++){
1289 outevent=&ttvsig->NODE[ev];
1290 for (line = lib_getnodeinputline(outevent, ttx) ; line ; line = line->NEXT){
1291 flagtri = 0;
1292 if(chtsname){
1293 for(ch=chtsname; ch; ch=ch->NEXT){
1294 if(!strcmp(line->NODE->ROOT->NAME,(char*)ch->DATA)){
1295 flagtri = 1;
1296 break;
1297 }
1298 }
1299 }else{
1300 if(((ttvsig->TYPE & TTV_SIG_CZ)==TTV_SIG_CZ) || ((ttvsig->TYPE & TTV_SIG_CT)==TTV_SIG_CT)){
1301 for(ev2=0;ev2 < 2; ev2++){
1302 outevent2=&ttvsig->NODE[ev2];
1303 for (line2 = lib_getnodeinputline(outevent2, ttx) ; line2 ; line2 = line2->NEXT){
1304 if(((line2->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) &&
1305 (line->NODE->ROOT==line2->NODE->ROOT) &&
1306 (line->ROOT->ROOT==line2->ROOT->ROOT)){
1307 flagtri = 1;
1308 break;
1309 }
1310 }
1311 }
1312 }
1313 }
1314 if(((line->TYPE & TTV_LINE_A)==TTV_LINE_A) ||
1315 (getptype (line->NODE->ROOT->USER, TTV_SIG_CLOCK) && !getptype (line->ROOT->ROOT->USER, TTV_SIG_CLOCK) && V_BOOL_TAB[__LIB_DRIVE_COMB_AS_ACCESS].VALUE)){
1316 flagtri = 1;
1317 }
1318
1319 if(flagtri){
1320 chain_tri=addchain(chain_tri, line);
1321 chain_triname=addname(chain_triname, line->NODE->ROOT->NAME);
1322 }else{
1323 if((line->NODE->TYPE ) == (line->ROOT->TYPE )){
1324 if(ptcellbefig){
1325 abl = cbh_calccondition(ptcellbefig, line->ROOT->ROOT->NAME, line->NODE->ROOT->NAME, CBH_NONINVERT);
1326 if(!abl || (abl && (strcmp (VALUE_ATOM (abl), "'0'")))) {
1327 chain_pos=addchain(chain_pos, line);
1328 chain_posname=addname(chain_posname, line->NODE->ROOT->NAME);
1329 }
1330 }else{
1331 chain_pos=addchain(chain_pos, line);
1332 chain_posname=addname(chain_posname, line->NODE->ROOT->NAME);
1333 }
1334 }else{
1335 if(ptcellbefig){
1336 abl = cbh_calccondition(ptcellbefig, line->ROOT->ROOT->NAME, line->NODE->ROOT->NAME, CBH_INVERT);
1337 if(!abl || (abl && (strcmp (VALUE_ATOM (abl), "'0'")))) {
1338 chain_neg=addchain(chain_neg, line);
1339 chain_negname=addname(chain_negname, line->NODE->ROOT->NAME);
1340 }
1341 }else{
1342 chain_neg=addchain(chain_neg, line);
1343 chain_negname=addname(chain_negname, line->NODE->ROOT->NAME);
1344 }
1345 }
1346 }
1347 }
1348 }
1349 for(ch=chain_posname; ch; ch=ch->NEXT){
1350 for(ch2=chain_negname; ch2; ch2=ch2->NEXT){
1351 if(!strcmp((char*)ch->DATA,(char*)ch2->DATA)){
1352 chain_nonunate=addname(chain_nonunate, ch->DATA);
1353 }
1354 }
1355 }
1356 /* if(!ptcellbefig){
1357 for(ch=chain_nonunate; ch; ch=ch->NEXT){
1358 for(ch2=chain_pos; ch2; ch2=ch2->NEXT){
1359 line2=(ttvline_list*)ch2->DATA;
1360 if(!line2) continue;
1361 if(!strcmp(line2->NODE->ROOT->NAME,(char*)ch->DATA)){
1362 for(ch3=chain_neg; ch3; ch3=ch3->NEXT){
1363 line3=(ttvline_list*)ch3->DATA;
1364 if(!line3) continue;
1365 if(!strcmp(line3->NODE->ROOT->NAME,(char*)ch->DATA)){
1366 if(line2->ROOT == line3->ROOT){
1367 if(line2->MDMAX && line3->MDMAX){
1368 tmodel2=stm_getmodel(ttvfig->INFO->FIGNAME, line2->MDMAX);
1369 tmodel3=stm_getmodel(ttvfig->INFO->FIGNAME, line3->MDMAX);
1370 if((tmodel2->ENERGYTYPE == STM_ENERGY_TABLE) && (tmodel3->ENERGYTYPE == STM_ENERGY_TABLE)){
1371 if(stm_modtbl_value_minslew_maxcapa(tmodel2->ENERGYMODEL.ETABLE) <= stm_modtbl_value_minslew_maxcapa(tmodel3->ENERGYMODEL.ETABLE)){
1372 ch2->DATA = NULL;
1373 }else{
1374 ch3->DATA = NULL;
1375 }
1376 }
1377 }
1378 }
1379 }
1380 }
1381 }
1382 }
1383 }
1384 }*/
1385 if(chain_posname){
1386 if(chain_pos){
1387 lib_drivepower_with_sdfcond (f, ttvfig, ptcellbefig, chain_posname, chain_pos, CBH_NONINVERT, chain_nonunate);
1388 freechain(chain_pos);
1389 }
1390 freechain(chain_posname);
1391 }
1392 if(chain_negname){
1393 if(chain_neg){
1394 lib_drivepower_with_sdfcond (f, ttvfig, ptcellbefig, chain_negname, chain_neg, CBH_INVERT, chain_nonunate);
1395 freechain(chain_neg);
1396 }
1397 freechain(chain_negname);
1398 }
1399 if(chain_triname){
1400 if(chain_tri){
1401 lib_drivepower_with_sdfcond (f, ttvfig, ptcellbefig, chain_triname, chain_tri, 0, NULL);
1402 freechain(chain_tri);
1403 }
1404 freechain(chain_triname);
1405 }
1406 if(chain_nonunate){
1407 freechain(chain_nonunate);
1408 }
1409 }else{
1410 event_rise = &ttvsig->NODE[1];
1411 ptyperise = getptype (event_rise->USER, LIB_CONNECTOR_ENERGY_MODEL_NAME) ;
1412 event_fall = &ttvsig->NODE[0];
1413 ptypefall = getptype (event_fall->USER, LIB_CONNECTOR_ENERGY_MODEL_NAME) ;
1414 if(ptyperise || ptypefall){
1415 ttv_getsigname(ttvfig, bufsig, ttvsig);
1416 pinname = lib_get_tg_pinname(bufsig);
1417 sprintf(buf, "energy_%s", pinname);
1418 space(f,12);
1419 fprintf(f,"internal_power (%s) {\n", buf);
1420 if(ptyperise && ptypefall){
1421 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, (char*)ptyperise->DATA);
1422 space(f,16);
1423 if(tmodel->ENERGYMODEL.ETABLE->CST != STM_NOVALUE){
1424 fprintf(f,"rise_power (scalar) {\n");
1425 lib_drivelutconst(f, tmodel->ENERGYMODEL.ETABLE->CST, 'E');
1426 }else{
1427 fprintf(f,"rise_power (energy_%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
1428 lib_drivelut (f, tmodel, 'E');
1429 }
1430 space(f,16);
1431 fprintf(f,"}\n");
1432 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, (char*)ptypefall->DATA);
1433 space(f,16);
1434 if(tmodel->ENERGYMODEL.ETABLE->CST != STM_NOVALUE){
1435 fprintf(f,"fall_power (scalar) {\n");
1436 lib_drivelutconst(f, tmodel->ENERGYMODEL.ETABLE->CST, 'E');
1437 }else{
1438 fprintf(f,"fall_power (energy_%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
1439 lib_drivelut (f, tmodel, 'E');
1440 }
1441 space(f,16);
1442 fprintf(f,"}\n");
1443 }else{
1444 if(ptyperise){
1445 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, (char*)ptyperise->DATA);
1446 }else{
1447 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, (char*)ptypefall->DATA);
1448 }
1449 space(f,16);
1450 if(tmodel->ENERGYMODEL.ETABLE->CST != STM_NOVALUE){
1451 fprintf(f,"power (scalar) {\n");
1452 lib_drivelutconst(f, tmodel->ENERGYMODEL.ETABLE->CST, 'E');
1453 }else{
1454 fprintf(f,"power (energy_%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
1455 lib_drivelut (f, tmodel, 'E');
1456 }
1457 space(f,16);
1458 fprintf(f,"}\n");
1459 }
1460 space(f,12);
1461 fprintf(f,"}\n");
1462 }
1463 }
1464 }
1465
1466 /****************************************************************************/
1467 /* function lib_drivetiming */
1468 /****************************************************************************/
1469 void lib_drivetiming (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, chain_list *chtsname, cbhseq *ptcbhseq, befig_list *ptcellbefig)
1470 {
1471 int ev, ev2 ;
1472 ttvevent_list *ckevent ;
1473 ttvevent_list *outevent, *outevent2 ;
1474 ttvevent_list *inevent ;
1475 chain_list *ch,*ch2;
1476 chain_list *chain, *chain_pos, *chain_neg, *chain_posname, *chain_negname, *chain_tri, *chain_triname, *abl, *chain_nonunate;
1477 ptype_list *ptype ;
1478 ttvline_list *line, *line2 ;
1479 char flagtri;
1480 char flagmin = 1;
1481 char flag_async_direct = 0;
1482 char LIB_DRIVEDELAY = 'M';
1483 int ttx;
1484
1485 if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_TTX)==TTV_FILE_TTX)
1486 ttx=1;
1487 else if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_DTX)==TTV_FILE_DTX)
1488 ttx=0;
1489 else
1490 ttx=1;
1491
1492 if (!strcasecmp (V_STR_TAB[__TMA_DRIVEDELAY].VALUE, "max")) LIB_DRIVEDELAY = 'M';
1493 else if (!strcasecmp (V_STR_TAB[__TMA_DRIVEDELAY].VALUE, "min")) LIB_DRIVEDELAY = 'm';
1494 else if (!strcasecmp (V_STR_TAB[__TMA_DRIVEDELAY].VALUE, "both")) LIB_DRIVEDELAY = 'B';
1495
1496 if ((((ttvsig->TYPE & TTV_SIG_CI)==TTV_SIG_CI)
1497 && ((ttvsig->TYPE & TTV_SIG_CB)!=TTV_SIG_CB))
1498 || ((ttvsig->TYPE & TTV_SIG_CT)==TTV_SIG_CT)){
1499
1500 if (ttx)
1501 ttv_expfigsig (ttvfig, ttvsig, ttvfig->INFO->LEVEL, ttvfig->INFO->LEVEL, TTV_STS_DUAL_P|TTV_STS_DUAL_J|TTV_STS_DUAL_T, TTV_FILE_TTX) ;
1502 else
1503 ttv_expfigsig (ttvfig, ttvsig, ttvfig->INFO->LEVEL, ttvfig->INFO->LEVEL, TTV_STS_DUAL_F|TTV_STS_DUAL_E|TTV_STS_DUAL_D, TTV_FILE_DTX) ;
1504
1505 chain=NULL;
1506 for(ev=0; ev < 2; ev++){
1507 inevent=&ttvsig->NODE[ev];
1508 if (ttx)
1509 ptype = getptype (inevent->USER, TTV_NODE_DUALPATH) ;
1510 else
1511 ptype = getptype (inevent->USER, TTV_NODE_DUALLINE) ;
1512
1513 if (ptype)
1514 for (ch = (chain_list*)ptype->DATA ; ch ; ch = ch->NEXT)
1515 if((((ttvline_list*)ch->DATA)->TYPE & TTV_LINE_U)==TTV_LINE_U)
1516 chain=addevent(chain, ((ttvline_list*)ch->DATA)->ROOT);
1517 }
1518 for(ch = chain; ch; ch=ch->NEXT){
1519 ckevent=(ttvevent_list*)ch->DATA;
1520 if(ckevent)
1521 lib_drivesetup_group(f, ttvfig, ttvsig, ckevent);
1522 }
1523 freechain(chain);
1524
1525 chain=NULL;
1526 for(ev=0; ev < 2; ev++){
1527 inevent=&ttvsig->NODE[ev];
1528 if (ttx)
1529 ptype = getptype (inevent->USER, TTV_NODE_DUALPATH) ;
1530 else
1531 ptype = getptype (inevent->USER, TTV_NODE_DUALLINE) ;
1532 if (ptype)
1533 for (ch = (chain_list*)ptype->DATA ; ch ; ch = ch->NEXT)
1534 if((((ttvline_list*)ch->DATA)->TYPE & TTV_LINE_O)==TTV_LINE_O)
1535 chain=addevent(chain, ((ttvline_list*)ch->DATA)->ROOT);
1536 }
1537 for(ch = chain; ch; ch=ch->NEXT){
1538 ckevent=(ttvevent_list*)ch->DATA;
1539 if(ckevent)
1540 lib_drivehold_group(f, ttvfig, ttvsig, ckevent);
1541 }
1542 freechain(chain);
1543 }
1544 if((ttvsig->TYPE & TTV_SIG_CO)==TTV_SIG_CO) {
1545 chain=NULL;
1546 flagmin = 1;
1547 for(ev=0;ev < 2; ev++){
1548 outevent=&ttvsig->NODE[ev];
1549 for (line = lib_getnodeinputline(outevent, ttx) ; line ; line = line->NEXT){
1550 if(((line->TYPE & TTV_LINE_A)==TTV_LINE_A) ||
1551 (getptype (line->NODE->ROOT->USER, TTV_SIG_CLOCK) && !getptype (line->ROOT->ROOT->USER, TTV_SIG_CLOCK) && V_BOOL_TAB[__LIB_DRIVE_COMB_AS_ACCESS].VALUE)){
1552 chain=addevent(chain, line->NODE);
1553 if((LIB_DRIVEDELAY == 'm') || (LIB_DRIVEDELAY == 'B')){
1554 if(!line->MDMIN)
1555 flagmin = 0;
1556 }else{
1557 flagmin = 0;
1558 }
1559 }
1560 }
1561 }
1562 for(ch = chain; ch; ch=ch->NEXT){
1563 ckevent=(ttvevent_list*)ch->DATA;
1564 if(ckevent){
1565 flag_async_direct = 0;
1566 for(ev=0;ev < 2; ev++){
1567 outevent=&ttvsig->NODE[ev];
1568 for (line = lib_getnodeinputline(outevent, ttx) ; line ; line = line->NEXT){
1569 if((line->NODE == ckevent) && getptype (ckevent->ROOT->USER, TTV_SIG_ASYNCHRON) && ((line->TYPE & TTV_LINE_A)!=TTV_LINE_A))
1570 flag_async_direct = 1;
1571 }
1572 }
1573 if(flag_async_direct) continue;
1574 if((LIB_DRIVEDELAY == 'M') || (LIB_DRIVEDELAY == 'B'))
1575 lib_driveaccess_group(f, ttvfig, ttvsig, ckevent, ptcbhseq, 'M');
1576 if(flagmin)
1577 lib_driveaccess_group(f, ttvfig, ttvsig, ckevent, ptcbhseq, 'm');
1578 }
1579 }
1580 freechain(chain);
1581 chain_tri=NULL;
1582 chain_triname=NULL;
1583 chain_posname=NULL;
1584 chain_negname=NULL;
1585 chain_pos=NULL;
1586 chain_neg=NULL;
1587 chain_nonunate = NULL;
1588 for(ev=0;ev < 2; ev++){
1589 outevent=&ttvsig->NODE[ev];
1590 for (line = lib_getnodeinputline(outevent, ttx) ; line ; line = line->NEXT){
1591 if(getptype(line->USER, LIB_DRIVED_LINE)) continue;
1592 if(((line->TYPE & TTV_LINE_U)!=TTV_LINE_U)
1593 &&((line->TYPE & TTV_LINE_O)!=TTV_LINE_O)
1594 &&((line->TYPE & TTV_LINE_A)!=TTV_LINE_A)){
1595 flagtri = 0;
1596 if(chtsname){
1597 for(ch=chtsname; ch; ch=ch->NEXT){
1598 if(!strcmp(line->NODE->ROOT->NAME,(char*)ch->DATA)){
1599 flagtri = 1;
1600 break;
1601 }
1602 }
1603 }else{
1604 if(((ttvsig->TYPE & TTV_SIG_CZ)==TTV_SIG_CZ) || ((ttvsig->TYPE & TTV_SIG_CT)==TTV_SIG_CT)){
1605 for(ev2=0;ev2 < 2; ev2++){
1606 outevent2=&ttvsig->NODE[ev2];
1607 for (line2 = lib_getnodeinputline(outevent2, ttx) ; line2 ; line2 = line2->NEXT){
1608 if(((line2->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) &&
1609 (line->NODE->ROOT==line2->NODE->ROOT) &&
1610 (line->ROOT->ROOT==line2->ROOT->ROOT)){
1611 flagtri = 1;
1612 break;
1613 }
1614 }
1615 }
1616 }
1617 }
1618 if(flagtri){
1619 chain_tri=addchain(chain_tri, line);
1620 for(chain = chain_triname; chain; chain = chain->NEXT)
1621 if(!strcmp(line->NODE->ROOT->NAME, (char*)chain->DATA))
1622 break;
1623 if(!chain)
1624 chain_triname=addname(chain_triname, line->NODE->ROOT->NAME);
1625 }else{
1626 if((line->NODE->TYPE ) == (line->ROOT->TYPE )){
1627 if(ptcellbefig){
1628 abl = cbh_calccondition(ptcellbefig, line->ROOT->ROOT->NAME, line->NODE->ROOT->NAME, CBH_NONINVERT);
1629 if(!abl || (abl && (strcmp (VALUE_ATOM (abl), "'0'")))) {
1630 chain_pos=addchain(chain_pos, line);
1631 chain_posname=addname(chain_posname, line->NODE->ROOT->NAME);
1632 }
1633 }else{
1634 chain_pos=addchain(chain_pos, line);
1635 chain_posname=addname(chain_posname, line->NODE->ROOT->NAME);
1636 }
1637 }else{
1638 if(ptcellbefig){
1639 abl = cbh_calccondition(ptcellbefig, line->ROOT->ROOT->NAME, line->NODE->ROOT->NAME, CBH_INVERT);
1640 if(!abl || (abl && (strcmp (VALUE_ATOM (abl), "'0'")))) {
1641 chain_neg=addchain(chain_neg, line);
1642 chain_negname=addname(chain_negname, line->NODE->ROOT->NAME);
1643 }
1644 }else{
1645 chain_neg=addchain(chain_neg, line);
1646 chain_negname=addname(chain_negname, line->NODE->ROOT->NAME);
1647 }
1648 }
1649 }
1650 }
1651 }
1652 }
1653 for(ch=chain_posname; ch; ch=ch->NEXT){
1654 for(ch2=chain_negname; ch2; ch2=ch2->NEXT){
1655 if(!strcmp((char*)ch->DATA,(char*)ch2->DATA)){
1656 chain_nonunate=addname(chain_nonunate, ch->DATA);
1657 }
1658 }
1659 }
1660 if(chain_posname){
1661 if(chain_pos){
1662 if((LIB_DRIVEDELAY == 'M') || (LIB_DRIVEDELAY == 'B'))
1663 lib_drive_pos(f, ttvfig, chain_posname, chain_pos, 'M', chain_nonunate, ptcellbefig);
1664 if((LIB_DRIVEDELAY == 'm') || (LIB_DRIVEDELAY == 'B')){
1665 flagmin = 1;
1666 for(chain = chain_pos; chain; chain = chain->NEXT)
1667 if(!((ttvline_list*)chain->DATA)->MDMIN)
1668 flagmin = 0;
1669 if(flagmin)
1670 lib_drive_pos(f, ttvfig, chain_posname, chain_pos, 'm', chain_nonunate, ptcellbefig);
1671 }
1672 freechain(chain_pos);
1673 }
1674 freechain(chain_posname);
1675 }
1676 if(chain_negname){
1677 if(chain_neg){
1678 if((LIB_DRIVEDELAY == 'M') || (LIB_DRIVEDELAY == 'B'))
1679 lib_drive_neg(f, ttvfig, chain_negname, chain_neg, 'M', chain_nonunate, ptcellbefig);
1680 if((LIB_DRIVEDELAY == 'm') || (LIB_DRIVEDELAY == 'B')){
1681 flagmin = 1;
1682 for(chain = chain_neg; chain; chain = chain->NEXT)
1683 if(!((ttvline_list*)chain->DATA)->MDMIN)
1684 flagmin = 0;
1685 if(flagmin)
1686 lib_drive_neg(f, ttvfig, chain_negname, chain_neg, 'm', chain_nonunate, ptcellbefig);
1687 }
1688 freechain(chain_neg);
1689 }
1690 freechain(chain_negname);
1691 }
1692 if(chain_triname){
1693 if(chain_tri){
1694 if((LIB_DRIVEDELAY == 'M') || (LIB_DRIVEDELAY == 'B'))
1695 lib_drive_tri(f, ttvfig, chain_triname, chain_tri, 'M');
1696 if((LIB_DRIVEDELAY == 'm') || (LIB_DRIVEDELAY == 'B')){
1697 flagmin = 1;
1698 for(chain = chain_tri; chain; chain = chain->NEXT)
1699 if((!((ttvline_list*)chain->DATA)->MDMIN) && ((((ttvline_list*)chain->DATA)->TYPE & TTV_LINE_HZ)!=TTV_LINE_HZ))
1700 flagmin = 0;
1701 if(flagmin)
1702 lib_drive_tri(f, ttvfig, chain_triname, chain_tri, 'm');
1703 }
1704 freechain(chain_tri);
1705 }
1706 freechain(chain_triname);
1707 }
1708 if(chain_nonunate){
1709 freechain(chain_nonunate);
1710 }
1711 for(ev=0;ev < 2; ev++){
1712 outevent=&ttvsig->NODE[ev];
1713 for (line = lib_getnodeinputline(outevent, ttx) ; line ; line = line->NEXT)
1714 if(getptype(line->USER, LIB_DRIVED_LINE))
1715 line->USER = delptype(line->USER, LIB_DRIVED_LINE);
1716 }
1717 }
1718 }
1719
1720 /****************************************************************************/
1721 /* function lib_drivesetup_group */
1722 /****************************************************************************/
1723 void lib_drivesetup_group (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, ttvevent_list *ckevent)
1724 {
1725 char buf[1024];
1726 ttvline_list *line ;
1727 char buftiming[1024];
1728 char bufsig[1024];
1729 char bufttype[1024];
1730 char *relpinname;
1731 char *pinname;
1732 int ttx;
1733
1734 if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_TTX)==TTV_FILE_TTX)
1735 ttx=1;
1736 else if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_DTX)==TTV_FILE_DTX)
1737 ttx=0;
1738 else
1739 ttx=1;
1740
1741 ttv_getsigname(ttvfig, bufsig, ttvsig);
1742 pinname = lib_get_tg_pinname(bufsig);
1743 sprintf(buftiming, "%s_", pinname);
1744 ttv_getsigname(ttvfig, buf, ckevent->ROOT);
1745 relpinname = lib_get_tg_pinname(buf);
1746 strcat(buftiming, relpinname);
1747 if((ckevent->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
1748 if(getptype (ttvsig->USER, TTV_SIG_ASYNCHRON))
1749 sprintf(bufttype, "recovery_rising");
1750 else
1751 sprintf(bufttype, "setup_rising");
1752 }else{
1753 if(getptype (ttvsig->USER, TTV_SIG_ASYNCHRON))
1754 sprintf(bufttype, "recovery_falling");
1755 else
1756 sprintf(bufttype, "setup_falling");
1757 }
1758 strcat(buftiming, "_");
1759 strcat(buftiming, bufttype);
1760
1761 space(f,12);
1762 fprintf(f,"timing (%s) {\n", buftiming);
1763
1764 space(f,16);
1765 fprintf(f,"timing_type : %s ;\n", bufttype);
1766
1767 relpinname = lib_getpinname(buf);
1768 space(f,16);
1769 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1770
1771 for(line=lib_getnodeinputline(ckevent, ttx);line;line=line->NEXT)
1772 if(line->NODE->ROOT==ttvsig)
1773 if((line->TYPE & TTV_LINE_U)==TTV_LINE_U)
1774 lib_drivesetup(f, ttvfig, line);
1775
1776 space(f,12);
1777 fprintf(f,"}\n");
1778 }
1779
1780 /****************************************************************************/
1781 /* function lib_drivehold_group */
1782 /****************************************************************************/
1783 void lib_drivehold_group (FILE *f, ttvfig_list *ttvfig, ttvsig_list *ttvsig, ttvevent_list *ckevent)
1784 {
1785 char buf[1024];
1786 ttvline_list *line ;
1787 char buftiming[1024];
1788 char bufsig[1024];
1789 char bufttype[1024];
1790 char *relpinname;
1791 char *pinname;
1792 int ttx;
1793
1794 if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_TTX)==TTV_FILE_TTX)
1795 ttx=1;
1796 else if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_DTX)==TTV_FILE_DTX)
1797 ttx=0;
1798 else
1799 ttx=1;
1800
1801 ttv_getsigname(ttvfig, bufsig, ttvsig);
1802 pinname = lib_get_tg_pinname(bufsig);
1803 sprintf(buftiming, "%s_", pinname);
1804 ttv_getsigname(ttvfig, buf, ckevent->ROOT);
1805 relpinname = lib_get_tg_pinname(buf);
1806 strcat(buftiming, relpinname);
1807 if((ckevent->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
1808 if(getptype (ttvsig->USER, TTV_SIG_ASYNCHRON))
1809 sprintf(bufttype, "removal_rising");
1810 else
1811 sprintf(bufttype, "hold_rising");
1812 }else{
1813 if(getptype (ttvsig->USER, TTV_SIG_ASYNCHRON))
1814 sprintf(bufttype, "removal_falling");
1815 else
1816 sprintf(bufttype, "hold_falling");
1817 }
1818 strcat(buftiming, "_");
1819 strcat(buftiming, bufttype);
1820
1821 space(f,12);
1822 fprintf(f,"timing (%s) {\n", buftiming);
1823
1824 space(f,16);
1825 fprintf(f,"timing_type : %s ;\n", bufttype);
1826
1827 relpinname = lib_getpinname(buf);
1828 space(f,16);
1829 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1830
1831 for(line=lib_getnodeinputline(ckevent, ttx);line;line=line->NEXT)
1832 if(line->NODE->ROOT==ttvsig)
1833 if((line->TYPE & TTV_LINE_O)==TTV_LINE_O)
1834 lib_drivehold(f, ttvfig, line);
1835
1836 space(f,12);
1837 fprintf(f,"}\n");
1838 }
1839
1840 /****************************************************************************/
1841 /* function lib_driveaccess_group */
1842 /****************************************************************************/
1843 void lib_driveaccess_group (FILE *f, ttvfig_list *ttvfig, ttvsig_list *outsig, ttvevent_list *ckevent, cbhseq *ptcbhseq, char type)
1844 {
1845 char buf[1024];
1846 int ev ;
1847 ttvline_list *line ;
1848 chain_list *chain, *ch;
1849 int flag=0;
1850 int access=0;
1851 char buftiming[1024];
1852 char bufsig[1024];
1853 char bufttype[1024];
1854 char buftsense[1024];
1855 char *relpinname;
1856 char *pinname;
1857 int ttx;
1858
1859 if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_TTX)==TTV_FILE_TTX)
1860 ttx=1;
1861 else if ((ttv_getloadedfigtypes(ttvfig) & TTV_FILE_DTX)==TTV_FILE_DTX)
1862 ttx=0;
1863 else
1864 ttx=1;
1865
1866 ttv_getsigname(ttvfig, bufsig, outsig);
1867 pinname = lib_get_tg_pinname(bufsig);
1868 if(type == 'M')
1869 sprintf(buftiming, "maxd_%s_", pinname);
1870 else
1871 sprintf(buftiming, "mind_%s_", pinname);
1872
1873 ttv_getsigname(ttvfig, buf, ckevent->ROOT);
1874 relpinname = lib_get_tg_pinname(buf);
1875 strcat(buftiming, relpinname);
1876
1877 if(ptcbhseq){
1878 if(ptcbhseq->RESET){
1879 chain=supportChain_listExpr(ptcbhseq->RESET);
1880 for(ch=chain; ch; ch=ch->NEXT)
1881 if(!strcmp(buf,(char*)ch->DATA)){
1882 if(!strcmp(outsig->NAME,ptcbhseq->PIN))
1883 flag=1;
1884 else if(!strcmp(outsig->NAME,ptcbhseq->NEGPIN))
1885 flag=2;
1886 break;
1887 }
1888 freechain(chain);
1889 }
1890 if(ptcbhseq->SET){
1891 chain=supportChain_listExpr(ptcbhseq->SET);
1892 for(ch=chain; ch; ch=ch->NEXT)
1893 if(!strcmp(buf,(char*)ch->DATA)){
1894 if(!strcmp(outsig->NAME,ptcbhseq->PIN))
1895 flag=2;
1896 else if(!strcmp(outsig->NAME,ptcbhseq->NEGPIN))
1897 flag=1;
1898 break;
1899 }
1900 freechain(chain);
1901 }
1902 }
1903 if(!flag){
1904 if((ckevent->TYPE & TTV_NODE_UP)==TTV_NODE_UP)
1905 sprintf(bufttype,"rising_edge");
1906 else
1907 sprintf(bufttype,"falling_edge");
1908 strcat(buftiming, "_");
1909 strcat(buftiming, bufttype);
1910
1911 space(f,12);
1912 fprintf(f,"timing (%s) {\n", buftiming);
1913 space(f,16);
1914 fprintf(f,"timing_type : %s ;\n", bufttype);
1915 relpinname = lib_getpinname(buf);
1916 space(f,16);
1917 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1918 }
1919
1920
1921
1922 for (ev = 0 ; ev < 2 ; ev++){
1923 access = 0;
1924 for(line = lib_getnodeinputline(&outsig->NODE[ev], ttx) ; line ; line = line->NEXT)
1925 if(line->NODE == ckevent)
1926 if((line->TYPE & TTV_LINE_A)==TTV_LINE_A) access=1;
1927 for(line = lib_getnodeinputline(&outsig->NODE[ev], ttx) ; line ; line = line->NEXT)
1928 if(line->NODE == ckevent)
1929 if(((line->TYPE & TTV_LINE_A)==TTV_LINE_A) ||
1930 (((line->TYPE & TTV_LINE_A)!=TTV_LINE_A) && getptype (line->NODE->ROOT->USER, TTV_SIG_CLOCK) && !getptype (line->ROOT->ROOT->USER, TTV_SIG_CLOCK) &&
1931 !access && V_BOOL_TAB[__LIB_DRIVE_COMB_AS_ACCESS].VALUE)){
1932
1933 if(!getptype(line->USER, LIB_DRIVED_LINE))
1934 line->USER = addptype(line->USER, LIB_DRIVED_LINE, NULL);
1935 if(flag){
1936 if((line->ROOT->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
1937 sprintf(bufttype,"preset");
1938 else
1939 sprintf(bufttype,"clear");
1940
1941
1942 if(ckevent->TYPE == line->ROOT->TYPE )
1943 sprintf(buftsense,"positive_unate");
1944 else
1945 sprintf(buftsense,"negative_unate");
1946 strcat(buftiming, "_");
1947 strcat(buftiming, bufttype);
1948 strcat(buftiming, "_");
1949 strcat(buftiming, buftsense);
1950
1951 space(f,12);
1952 fprintf(f,"timing (%s) {\n", buftiming);
1953 space(f,16);
1954 fprintf(f,"timing_type : %s ;\n", bufttype);
1955 space(f,16);
1956 fprintf(f,"timing_sense : %s ;\n", buftsense);
1957 relpinname = lib_getpinname(buf);
1958 space(f,16);
1959 fprintf(f,"related_pin : \"%s\" ;\n", relpinname);
1960 }
1961 if(type == 'M')
1962 lib_drivedelaymax(f, ttvfig, line);
1963 else
1964 lib_drivedelaymin(f, ttvfig, line);
1965 if(flag){
1966 space(f,12);
1967 fprintf(f,"}\n");
1968 }
1969 }
1970 }
1971 if(!flag){
1972 space(f,12);
1973 fprintf(f,"}\n");
1974 }
1975
1976 }
1977
1978 /****************************************************************************/
1979 /* function lib_get_timing_sense */
1980 /****************************************************************************/
1981 char *lib_get_timing_sense (ttvsig_list *outsig, ttvsig_list *ptsig)
1982 {
1983 int ev ;
1984 ttvline_list *line ;
1985 int neg = 0 ;
1986 int pos = 0 ;
1987
1988 // a ajouter si utilise un jour: prise en compte ttvfig en dtx
1989
1990 for (ev = 0 ; ev < 2 ; ev++)
1991 for(line = (&outsig->NODE[ev])->INPATH ; line ; line = line->NEXT)
1992 if(line->NODE->ROOT == ptsig)
1993 if(((line->TYPE & TTV_LINE_U)!=TTV_LINE_U)
1994 &&((line->TYPE & TTV_LINE_O)!=TTV_LINE_O)
1995 &&((line->TYPE & TTV_LINE_A)!=TTV_LINE_A))
1996 {
1997 if((line->ROOT->TYPE & (TTV_NODE_UP|TTV_NODE_DOWN)) == (line->NODE->TYPE & (TTV_NODE_UP|TTV_NODE_DOWN)))
1998 pos = 1 ;
1999 if((line->ROOT->TYPE & (TTV_NODE_UP|TTV_NODE_DOWN)) != (line->NODE->TYPE & (TTV_NODE_UP|TTV_NODE_DOWN)))
2000 neg = 1 ;
2001 }
2002
2003 if((neg == 1) && (pos == 1))
2004 return("non_unate") ;
2005 else if(neg == 1)
2006 return("negative_unate") ;
2007 else if(pos == 1)
2008 return("positive_unate") ;
2009 else
2010 return(NULL) ;
2011
2012 }
2013
2014 /****************************************************************************/
2015 /* function lib_drivesetup */
2016 /****************************************************************************/
2017 void lib_drivesetup (FILE *f, ttvfig_list *ttvfig, ttvline_list *line)
2018 {
2019
2020 if((line->NODE->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
2021 if(line->MDMAX)
2022 lib_driveconstraintmodel(f, ttvfig, line->MDMAX, 'R');
2023 else
2024 lib_drive_cst_constraint(f, line->VALMAX/TTV_UNIT, 'R');
2025 }else{
2026 if(line->MDMAX)
2027 lib_driveconstraintmodel(f, ttvfig, line->MDMAX, 'F');
2028 else
2029 lib_drive_cst_constraint(f, line->VALMAX/TTV_UNIT, 'F');
2030 }
2031 }
2032
2033
2034 /****************************************************************************/
2035 /* function lib_drivehold */
2036 /****************************************************************************/
2037 void lib_drivehold (FILE *f, ttvfig_list *ttvfig, ttvline_list *line)
2038 {
2039
2040 if((line->NODE->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
2041 if(line->MDMAX)
2042 lib_driveconstraintmodel(f, ttvfig, line->MDMAX, 'R');
2043 else
2044 lib_drive_cst_constraint(f, line->VALMAX/TTV_UNIT, 'R');
2045 }else{
2046 if(line->MDMAX)
2047 lib_driveconstraintmodel(f, ttvfig, line->MDMAX, 'F');
2048 else
2049 lib_drive_cst_constraint(f, line->VALMAX/TTV_UNIT, 'F');
2050 }
2051 }
2052
2053 /****************************************************************************/
2054 /* function lib_drivedelaymax */
2055 /****************************************************************************/
2056 void lib_drivedelaymax (FILE *f, ttvfig_list *ttvfig, ttvline_list *line)
2057 {
2058 lofig_list *lofig;
2059 char typemax ;
2060 double rmax, c1max, c2max ;
2061 locon_list *locon=NULL ;
2062 rcx_list *ptrcx ;
2063 rcx_slope slope;
2064 long search;
2065 float capa;
2066 char trans;
2067
2068 lofig = ttv_getrcxlofig (ttvfig);
2069 if(lofig == NULL)
2070 {
2071 c1max = line->ROOT->ROOT->CAPA / 1000.0 ;
2072 c2max = 0.0 ;
2073 rmax = -1.0;
2074 typemax = RCX_CAPALOAD ;
2075 }
2076 else
2077 {
2078 locon = rcx_gethtrcxcon(NULL,lofig,line->ROOT->ROOT->NAME) ;
2079
2080 if((locon == NULL) || (locon->PNODE == NULL) ||
2081 ((ptrcx = getrcx(locon->SIG)) == NULL))
2082 {
2083 c1max = line->ROOT->ROOT->CAPA / 1000.0 ;
2084 c2max = 0.0 ;
2085 rmax = -1.0 ;
2086 typemax = RCX_CAPALOAD ;
2087 }
2088 else
2089 {
2090 if( rcx_crosstalkactive( RCX_QUERY ) != RCX_NOCROSSTALK ) {
2091 slope.F0MAX = ttv_getslopenode( line->ROOT->ROOT->ROOT,
2092 line->ROOT->ROOT->ROOT->INFO->LEVEL,
2093 line->ROOT,
2094 search |
2095 TTV_FIND_GATE |
2096 TTV_FIND_RC |
2097 TTV_FIND_MAX,
2098 TTV_MODE_LINE
2099 )/TTV_UNIT;
2100 slope.FCCMAX = ttv_getslopenode( line->ROOT->ROOT->ROOT,
2101 line->ROOT->ROOT->ROOT->INFO->LEVEL,
2102 line->ROOT,
2103 search |
2104 TTV_FIND_GATE |
2105 TTV_FIND_RC |
2106 TTV_FIND_MAX,
2107 TTV_MODE_DELAY
2108 )/TTV_UNIT;
2109 }
2110 else {
2111 slope.F0MAX = -1.0 ;
2112 slope.FCCMAX = -1.0 ;
2113 }
2114
2115 slope.SENS = ((line->ROOT->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
2116 ? TRC_SLOPE_UP : TRC_SLOPE_DOWN;
2117 slope.CCA = -1.0 ;
2118
2119 typemax = rcx_rcnload( lofig,
2120 locon->SIG,
2121 locon->PNODE,
2122 &rmax, &c1max, &c2max,
2123 RCX_BESTLOAD,
2124 0.0,
2125 &slope,
2126 RCX_MAX
2127 ) ;
2128
2129 }
2130 }
2131 capa = ((typemax==RCX_CAPALOAD) ? c1max*1000.0 : (c1max+c2max)*1000.0);
2132
2133 if((line->ROOT->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
2134 trans = 'R';
2135 if((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) trans = 'F';
2136 if(line->MDMAX)
2137 lib_drivedelaymodel(f, ttvfig, line->MDMAX, trans, capa);
2138 else
2139 lib_driveintrinsic(f, line->VALMAX/TTV_UNIT, trans);
2140 if(line->MFMAX)
2141 lib_driveslewmodel(f, ttvfig, line->MFMAX, trans, capa);
2142 else
2143 lib_driveslew(f, line->FMAX/TTV_UNIT, trans);
2144 }else{
2145 trans = 'F';
2146 if((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) trans = 'R';
2147 if(line->MDMAX)
2148 lib_drivedelaymodel(f, ttvfig, line->MDMAX, trans, capa);
2149 else
2150 lib_driveintrinsic(f, line->VALMAX/TTV_UNIT, trans);
2151 if(line->MFMAX)
2152 lib_driveslewmodel(f, ttvfig, line->MFMAX, trans, capa);
2153 else
2154 lib_driveslew(f, line->FMAX/TTV_UNIT, trans);
2155 }
2156 }
2157
2158 /****************************************************************************/
2159 /* function lib_drivedelaymin */
2160 /****************************************************************************/
2161 void lib_drivedelaymin (FILE *f, ttvfig_list *ttvfig, ttvline_list *line)
2162 {
2163 lofig_list *lofig;
2164 char typemin ;
2165 double rmin, c1min, c2min ;
2166 locon_list *locon=NULL ;
2167 rcx_list *ptrcx ;
2168 rcx_slope slope;
2169 long search;
2170 float capa;
2171 char trans;
2172
2173 lofig = ttv_getrcxlofig (ttvfig);
2174 if(lofig == NULL)
2175 {
2176 c1min = line->ROOT->ROOT->CAPA / 1000.0 ;
2177 c2min = 0.0 ;
2178 rmin = -1.0;
2179 typemin = RCX_CAPALOAD ;
2180 }
2181 else
2182 {
2183 locon = rcx_gethtrcxcon(NULL,lofig,line->ROOT->ROOT->NAME) ;
2184
2185 if((locon == NULL) || (locon->PNODE == NULL) ||
2186 ((ptrcx = getrcx(locon->SIG)) == NULL))
2187 {
2188 c1min = line->ROOT->ROOT->CAPA / 1000.0 ;
2189 c2min = 0.0 ;
2190 rmin = -1.0 ;
2191 typemin = RCX_CAPALOAD ;
2192 }
2193 else
2194 {
2195 if( rcx_crosstalkactive( RCX_QUERY ) != RCX_NOCROSSTALK ) {
2196 slope.F0MAX = ttv_getslopenode( line->ROOT->ROOT->ROOT,
2197 line->ROOT->ROOT->ROOT->INFO->LEVEL,
2198 line->ROOT,
2199 search |
2200 TTV_FIND_GATE |
2201 TTV_FIND_RC |
2202 TTV_FIND_MAX,
2203 TTV_MODE_LINE
2204 )/TTV_UNIT;
2205 slope.FCCMAX = ttv_getslopenode( line->ROOT->ROOT->ROOT,
2206 line->ROOT->ROOT->ROOT->INFO->LEVEL,
2207 line->ROOT,
2208 search |
2209 TTV_FIND_GATE |
2210 TTV_FIND_RC |
2211 TTV_FIND_MAX,
2212 TTV_MODE_DELAY
2213 )/TTV_UNIT;
2214 }
2215 else {
2216 slope.F0MAX = -1.0 ;
2217 slope.FCCMAX = -1.0 ;
2218 }
2219
2220 slope.SENS = ((line->ROOT->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
2221 ? TRC_SLOPE_UP : TRC_SLOPE_DOWN;
2222 slope.CCA = -1.0 ;
2223
2224 typemin = rcx_rcnload( lofig,
2225 locon->SIG,
2226 locon->PNODE,
2227 &rmin, &c1min, &c2min,
2228 RCX_BESTLOAD,
2229 0.0,
2230 &slope,
2231 RCX_MIN
2232 ) ;
2233
2234 }
2235 }
2236 capa = ((typemin==RCX_CAPALOAD) ? c1min*1000.0 : (c1min+c2min)*1000.0);
2237
2238 if((line->ROOT->TYPE & TTV_NODE_UP)==TTV_NODE_UP){
2239 trans = 'R';
2240 if((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) trans = 'F';
2241 if(line->MDMIN)
2242 lib_drivedelaymodel(f, ttvfig, line->MDMIN, trans, capa);
2243 else
2244 lib_driveintrinsic(f, line->VALMIN/TTV_UNIT, trans);
2245 if(line->MFMIN)
2246 lib_driveslewmodel(f, ttvfig, line->MFMIN, trans, capa);
2247 else
2248 lib_driveslew(f, line->FMIN/TTV_UNIT, trans);
2249 }else{
2250 trans = 'F';
2251 if((line->TYPE & TTV_LINE_HZ)==TTV_LINE_HZ) trans = 'R';
2252 if(line->MDMIN)
2253 lib_drivedelaymodel(f, ttvfig, line->MDMIN, trans, capa);
2254 else
2255 lib_driveintrinsic(f, line->VALMIN/TTV_UNIT, trans);
2256 if(line->MFMIN)
2257 lib_driveslewmodel(f, ttvfig, line->MFMIN, trans, capa);
2258 else
2259 lib_driveslew(f, line->FMIN/TTV_UNIT, trans);
2260 }
2261 }
2262
2263 /****************************************************************************/
2264 /* function lib_driveheader */
2265 /****************************************************************************/
2266 void lib_driveheader (FILE *f, char *libname, ttvinfo_list *ttvinfo)
2267 {
2268
2269 char *tecname;
2270 char *dmname;
2271 char *vunit;
2272 char *tunit;
2273 char *punit;
2274 char *cunit;
2275 char *runit;
2276 char *curunit;
2277 double voltage;
2278 double temp, sutr, sltr, sutf, sltf, dtr, dtf;
2279 time_t counter;
2280 char *date;
2281 double rise_temp_derating = 0.0 ;
2282 double fall_temp_derating = 0.0 ;
2283 double rise_volt_derating = 0.0 ;
2284 double fall_volt_derating = 0.0 ;
2285 char buffer[2048];
2286 float slewderate;
2287
2288 time (&counter) ;
2289 date = ctime (&counter) ;
2290 date[strlen (date) - 1] = '\0' ;
2291 tecname="cmos";
2292 dmname="table_lookup";
2293 vunit="1V";
2294 tunit=V_STR_TAB[__TMA_TUNIT].VALUE;
2295 cunit=V_STR_TAB[__TMA_CUNIT].VALUE;
2296 punit=V_STR_TAB[__TMA_PUNIT].VALUE;
2297 runit="1ohm";
2298 curunit="1mA";
2299 slewderate = V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE;
2300
2301 if(!ttvinfo){
2302 voltage = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
2303 temp = STM_DEFAULT_TEMP;
2304 sutr = STM_DEFAULT_SMAXR;
2305 sltr = STM_DEFAULT_SMINR;
2306 sutf = STM_DEFAULT_SMAXF;
2307 sltf = STM_DEFAULT_SMINF;
2308 dtr = 0.5;
2309 dtf = 0.5;
2310 }else{
2311 voltage = ttvinfo->VDD;
2312 temp = ttvinfo->TEMP;
2313 sutr = sutf = ttvinfo->STHHIGH;
2314 sltr = sltf = ttvinfo->STHLOW;
2315 dtr = dtf = ttvinfo->DTH;
2316 }
2317
2318 /* Derating */
2319 if(V_BOOL_TAB[__TUT_CALC_DERATE].VALUE) {
2320 if(V_FLOAT_TAB[__TUT_MIN_VOLT].VALUE < TUT_MINTEMPVOLT)
2321 TUT_MINVOLT = 0.9 * voltage ;
2322 if(V_FLOAT_TAB[__TUT_MAX_VOLT].VALUE < TUT_MINTEMPVOLT)
2323 TUT_MAXVOLT = 1.1 * voltage ;
2324 if(V_FLOAT_TAB[__TUT_MIN_TEMP].VALUE < TUT_MINTEMPVOLT)
2325 TUT_MINTEMP = 0.5 * temp ;
2326 if(V_FLOAT_TAB[__TUT_MAX_TEMP].VALUE < TUT_MINTEMPVOLT)
2327 TUT_MAXTEMP = 1.5 * temp ;
2328
2329 rise_temp_derating = lib_derate_temp(TUT_MINTEMP,TUT_MAXTEMP,LIB_RISING);
2330 fall_temp_derating = lib_derate_temp(TUT_MINTEMP,TUT_MAXTEMP,LIB_FALLING);
2331 rise_volt_derating = lib_derate_tension(TUT_MINVOLT,TUT_MAXVOLT,LIB_RISING);
2332 fall_volt_derating = lib_derate_tension(TUT_MINVOLT,TUT_MAXVOLT,LIB_FALLING);
2333 }
2334
2335 #if 1
2336 sprintf(buffer,"liberty data flow `%s`\n",libname);
2337 avt_printExecInfoFlourish(f, "/*", buffer, "*/");
2338 #else
2339 fprintf(f,"/*****************************************************************\n");
2340 fprintf(f,"*\n");
2341 fprintf(f,"* LIBRARY : %s\n", libname);
2342 fprintf(f,"*\n");
2343 fprintf(f,"* Comment : This library was created by\n");
2344 fprintf(f,"* AVERTEC with TMA\n");
2345 fprintf(f,"*\n");
2346 fprintf(f,"* date : %s\n", date);
2347 fprintf(f,"*\n");
2348 fprintf(f,"*****************************************************************/\n");
2349 #endif
2350
2351 saut(f,2);
2352
2353 fprintf(f,"library (%s) {\n",libname);
2354 saut(f,1);
2355 tab(f);
2356 fprintf(f,"technology (%s) ;\n",tecname);
2357 tab(f);
2358 fprintf(f,"date : \"%s\" ;\n",date);
2359 // if(STM_TEMPLATES_CHAIN){
2360 tab(f);
2361 fprintf(f,"delay_model : %s ;\n",dmname);
2362 if(V_BOOL_TAB[__TUT_CALC_DERATE].VALUE) {
2363 tab(f);
2364 fprintf(f,"k_process_rise_propagation : %.4f ;\n", LIB_DERATE_PROCESS) ;
2365 tab(f);
2366 fprintf(f,"k_temp_rise_propagation : %.4f ;\n",
2367 rise_temp_derating) ;
2368 tab(f);
2369 fprintf(f,"k_volt_rise_propagation : %.4f ;\n",
2370 rise_volt_derating) ;
2371 tab(f);
2372 fprintf(f,"k_process_fall_propagation : %.4f ;\n", LIB_DERATE_PROCESS) ;
2373 tab(f);
2374 fprintf(f,"k_temp_fall_propagation : %.4f ;\n",
2375 fall_temp_derating) ;
2376 tab(f);
2377 fprintf(f,"k_volt_fall_propagation : %.4f ;\n",
2378 fall_volt_derating) ;
2379 tab(f);
2380 fprintf(f,"k_process_rise_transition : %.4f ;\n", LIB_DERATE_PROCESS) ;
2381 tab(f);
2382 fprintf(f,"k_temp_rise_transition : %.4f ;\n",
2383 rise_temp_derating) ;
2384 tab(f);
2385 fprintf(f,"k_volt_rise_transition : %.4f ;\n",
2386 rise_volt_derating) ;
2387 tab(f);
2388 fprintf(f,"k_process_fall_transition : %.4f ;\n", LIB_DERATE_PROCESS) ;
2389 tab(f);
2390 fprintf(f,"k_temp_fall_transition : %.4f ;\n",
2391 fall_temp_derating) ;
2392 tab(f);
2393 fprintf(f,"k_volt_fall_transition : %.4f ;\n",
2394 fall_volt_derating) ;
2395
2396 tab(f);
2397 fprintf(f,"k_process_hold_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2398 tab(f);
2399 fprintf(f,"k_process_hold_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2400 tab(f);
2401 fprintf(f,"k_temp_hold_rise : %.4f ;\n",
2402 rise_temp_derating) ;
2403 tab(f);
2404 fprintf(f,"k_temp_hold_fall : %.4f ;\n",
2405 fall_temp_derating) ;
2406 tab(f);
2407 fprintf(f,"k_volt_hold_rise : %.4f ;\n",
2408 rise_volt_derating) ;
2409 tab(f);
2410 fprintf(f,"k_volt_hold_fall : %.4f ;\n",
2411 fall_volt_derating) ;
2412 tab(f);
2413 fprintf(f,"k_process_setup_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2414 tab(f);
2415 fprintf(f,"k_process_setup_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2416 tab(f);
2417 fprintf(f,"k_temp_setup_rise : %.4f ;\n",
2418 rise_temp_derating) ;
2419 tab(f);
2420 fprintf(f,"k_temp_setup_fall : %.4f ;\n",
2421 fall_temp_derating) ;
2422 tab(f);
2423 fprintf(f,"k_volt_setup_rise : %.4f ;\n",
2424 rise_volt_derating) ;
2425 tab(f);
2426 fprintf(f,"k_volt_setup_fall : %.4f ;\n",
2427 fall_volt_derating) ;
2428 }
2429 /* }else{
2430 tab(f);
2431 fprintf(f,"default_intrinsic_rise : 1.0 ;\n");
2432 tab(f);
2433 fprintf(f,"default_intrinsic_fall : 1.0 ;\n");
2434 tab(f);
2435 fprintf(f,"default_slope_rise : 0.0 ;\n");
2436 tab(f);
2437 fprintf(f,"default_slope_fall : 0.0 ;\n");
2438 tab(f);
2439 fprintf(f,"default_inout_pin_rise_res : 0.0 ;\n");
2440 tab(f);
2441 fprintf(f,"default_inout_pin_fall_res : 0.0 ;\n");
2442 tab(f);
2443 fprintf(f,"default_output_pin_rise_res : 0.0 ;\n");
2444 tab(f);
2445 fprintf(f,"default_output_pin_fall_res : 0.0 ;\n");
2446 tab(f);
2447 fprintf(f,"default_rise_pin_resistance : 0.0 ;\n");
2448 tab(f);
2449 fprintf(f,"default_fall_pin_resistance : 0.0 ;\n");
2450 tab(f);
2451 fprintf(f,"default_rise_delay_intercept : 0.0 ;\n");
2452 tab(f);
2453 fprintf(f,"default_fall_delay_intercept : 0.0 ;\n");
2454 if(V_BOOL_TAB[__TUT_CALC_DERATE].VALUE) {
2455 tab(f);
2456 fprintf(f,"k_process_intrinsic_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2457 tab(f);
2458 fprintf(f,"k_process_intrinsic_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2459 tab(f);
2460 fprintf(f,"k_temp_intrinsic_fall : %.4f ;\n",
2461 fall_temp_derating) ;
2462 tab(f);
2463 fprintf(f,"k_temp_intrinsic_rise : %.4f ;\n",
2464 rise_temp_derating) ;
2465 tab(f);
2466 fprintf(f,"k_volt_intrinsic_fall : %.4f ;\n",
2467 fall_volt_derating) ;
2468 tab(f);
2469 fprintf(f,"k_volt_intrinsic_rise : %.4f ;\n",
2470 rise_volt_derating) ;
2471 tab(f);
2472 fprintf(f,"k_process_slope_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2473 tab(f);
2474 fprintf(f,"k_process_slope_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2475 tab(f);
2476 fprintf(f,"k_temp_slope_fall : %.4f ;\n",
2477 fall_temp_derating) ;
2478 tab(f);
2479 fprintf(f,"k_temp_slope_rise : %.4f ;\n",
2480 rise_temp_derating) ;
2481 tab(f);
2482 fprintf(f,"k_volt_slope_fall : %.4f ;\n",
2483 fall_volt_derating) ;
2484 tab(f);
2485 fprintf(f,"k_volt_slope_rise : %.4f ;\n",
2486 rise_volt_derating) ;
2487 tab(f);
2488 fprintf(f,"k_process_hold_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2489 tab(f);
2490 fprintf(f,"k_process_hold_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2491 tab(f);
2492 fprintf(f,"k_temp_hold_rise : %.4f ;\n",
2493 rise_temp_derating) ;
2494 tab(f);
2495 fprintf(f,"k_temp_hold_fall : %.4f ;\n",
2496 fall_temp_derating) ;
2497 tab(f);
2498 fprintf(f,"k_volt_hold_rise : %.4f ;\n",
2499 rise_volt_derating) ;
2500 tab(f);
2501 fprintf(f,"k_volt_hold_fall : %.4f ;\n",
2502 fall_volt_derating) ;
2503 tab(f);
2504 fprintf(f,"k_process_setup_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2505 tab(f);
2506 fprintf(f,"k_process_setup_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2507 tab(f);
2508 fprintf(f,"k_temp_setup_rise : %.4f ;\n",
2509 rise_temp_derating) ;
2510 tab(f);
2511 fprintf(f,"k_temp_setup_fall : %.4f ;\n",
2512 fall_temp_derating) ;
2513 tab(f);
2514 fprintf(f,"k_volt_setup_rise : %.4f ;\n",
2515 rise_volt_derating) ;
2516 tab(f);
2517 fprintf(f,"k_volt_setup_fall : %.4f ;\n",
2518 fall_volt_derating) ;
2519 }
2520 }*/
2521
2522
2523 tab(f);
2524 fprintf(f,"nom_voltage : %.2f ;\n",voltage);
2525 tab(f);
2526 fprintf(f,"nom_temperature : %.1f ;\n",temp);
2527 tab(f);
2528 fprintf(f,"nom_process : %.1f ;\n",LIB_NOM_PROCESS);
2529 tab(f);
2530 fprintf(f,"slew_derate_from_library : %.1f ;\n",slewderate);
2531 if(!strcasecmp(cunit,"ff")){
2532 tab(f);
2533 fprintf(f,"default_fanout_load : 1000.0 ;\n");
2534 }else if(!strcasecmp(cunit,"pf")){
2535 tab(f);
2536 fprintf(f,"default_fanout_load : 1.0 ;\n");
2537 }
2538 if(!strcasecmp(cunit,"ff")){
2539 tab(f);
2540 fprintf(f,"default_inout_pin_cap : 1000.0 ;\n");
2541 }else if(!strcasecmp(cunit,"pf")){
2542 tab(f);
2543 fprintf(f,"default_inout_pin_cap : 1.0 ;\n");
2544 }
2545 if(!strcasecmp(cunit,"ff")){
2546 tab(f);
2547 fprintf(f,"default_input_pin_cap : 1000.0 ;\n");
2548 }else if(!strcasecmp(cunit,"pf")){
2549 tab(f);
2550 fprintf(f,"default_input_pin_cap : 1.0 ;\n");
2551 }
2552 tab(f);
2553 fprintf(f,"default_output_pin_cap : 0.0 ;\n");
2554 tab(f);
2555 fprintf(f,"voltage_unit : \"%s\" ;\n",vunit);
2556 tab(f);
2557 fprintf(f,"time_unit : \"1%s\" ;\n",tunit);
2558 tab(f);
2559 fprintf(f,"capacitive_load_unit (1,%s) ;\n",cunit);
2560 tab(f);
2561 fprintf(f,"pulling_resistance_unit : \"%s\" ;\n",runit);
2562 tab(f);
2563 fprintf(f,"current_unit : \"%s\" ;\n",curunit);
2564 if(V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE && (V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE != 5)){
2565 tab(f);
2566 fprintf(f,"leakage_power_unit : \"%s\" ;\n", punit);
2567 tab(f);
2568 fprintf(f,"default_cell_leakage_power : 0.0 ;\n");
2569 }
2570 if(dtr < 0.0){
2571 dtr = 0.5;
2572 }
2573 if(dtf < 0.0){
2574 dtf = 0.5;
2575 }
2576 tab(f);
2577 fprintf(f,"input_threshold_pct_rise : %.1f ;\n", dtr*100);
2578 tab(f);
2579 fprintf(f,"input_threshold_pct_fall : %.1f ;\n", dtf*100);
2580 tab(f);
2581 fprintf(f,"output_threshold_pct_rise : %.1f ;\n", dtr*100);
2582 tab(f);
2583 fprintf(f,"output_threshold_pct_fall : %.1f ;\n", dtf*100);
2584 if((sltf < 0.0) || (sutf < 0.0) || (sltr < 0.0) || (sutr < 0.0))
2585 fprintf (stderr, "***lib warning: slew thresholds are not set***\n");
2586 if(sltf < 0.0){
2587 sltf = 0.2;
2588 }
2589 if(sutf < 0.0){
2590 sutf = 0.8;
2591 }
2592 if(sltr < 0.0){
2593 sltr = 0.2;
2594 }
2595 if(sutr < 0.0){
2596 sutr = 0.8;
2597 }
2598 tab(f);
2599 fprintf(f,"slew_lower_threshold_pct_fall : %.1f ;\n", sltf*100);
2600 tab(f);
2601 fprintf(f,"slew_upper_threshold_pct_fall : %.1f ;\n", sutf*100);
2602 tab(f);
2603 fprintf(f,"slew_lower_threshold_pct_rise : %.1f ;\n", sltr*100);
2604 tab(f);
2605 fprintf(f,"slew_upper_threshold_pct_rise : %.1f ;\n", sutr*100);
2606 fflush (f);
2607
2608 }
2609
2610 /****************************************************************************/
2611 /* function lib_scm2thr */
2612 /****************************************************************************/
2613 double lib_scm2thr(double fscm)
2614 {
2615 /* return (elpScm2Thr(fscm, STM_DEFAULT_SMINR,
2616 STM_DEFAULT_SMAXR, STM_DEFAULT_VT,
2617 V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE, V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE, elpRISE));*/
2618 return fscm;
2619 }
2620
2621 /****************************************************************************/
2622 /* function lib_driveindex */
2623 /****************************************************************************/
2624 void lib_driveindex (FILE *f, timing_ttable *template, int n)
2625 {
2626 int x,y;
2627
2628 space(f,n);
2629 fprintf(f,"index_1 (\"");
2630 for(x=0 ; x < template->NX ; x++){
2631 if((template->XTYPE==STM_INPUT_SLEW) || (template->XTYPE==STM_CLOCK_SLEW)){
2632 fprintf(f,"%s", pfloat(buftunit,lib_scm2thr(template->XRANGE[x])/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
2633 }
2634 else{
2635 if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"ff")){
2636 fprintf(f,"%.2f", template->XRANGE[x]);
2637 }else if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"pf")){
2638 fprintf(f,"%.5f", template->XRANGE[x]/1000.0);
2639 }
2640 }
2641 if((template->NX - x) > 1){
2642 fprintf(f,", ");
2643 }
2644 }
2645 fprintf(f,"\");\n");
2646
2647 if(template->NY){
2648 space(f,n);
2649 fprintf(f,"index_2 (\"");
2650 for(y=0 ; y < template->NY ; y++){
2651 if((template->YTYPE==STM_INPUT_SLEW) || (template->YTYPE==STM_CLOCK_SLEW)){
2652 fprintf(f,"%s", pfloat(buftunit,lib_scm2thr(template->YRANGE[y])/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
2653 }
2654 else{
2655 if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"ff")){
2656 fprintf(f,"%.2f", template->YRANGE[y]);
2657 }else if(!strcasecmp(V_STR_TAB[__TMA_CUNIT].VALUE,"pf")){
2658 fprintf(f,"%.5f", template->YRANGE[y]/1000.0);
2659 }
2660 }
2661 if((template->NY - y) > 1){
2662 fprintf(f,", ");
2663 }
2664 }
2665 fprintf(f,"\");\n");
2666 }
2667
2668 }
2669
2670 /****************************************************************************/
2671 /* function lib_drivelut */
2672 /****************************************************************************/
2673 void lib_drivelut (FILE *f, timing_model *tmodel, char type)
2674 {
2675 int x,y;
2676 char nx;
2677 char ny;
2678 float *values1d;
2679 float **values2d;
2680
2681 if(type == 'E'){
2682 nx=tmodel->ENERGYMODEL.ETABLE->NX;
2683 ny=tmodel->ENERGYMODEL.ETABLE->NY;
2684 values1d=tmodel->ENERGYMODEL.ETABLE->SET1D;
2685 values2d=tmodel->ENERGYMODEL.ETABLE->SET2D;
2686 }else{
2687 nx=tmodel->UMODEL.TABLE->NX;
2688 ny=tmodel->UMODEL.TABLE->NY;
2689 values1d=tmodel->UMODEL.TABLE->SET1D;
2690 values2d=tmodel->UMODEL.TABLE->SET2D;
2691 }
2692
2693 if (V_BOOL_TAB[__LIB_DRIVE_TABLE_INDEX].VALUE)
2694 lib_driveindex(f, tmodel->UMODEL.TABLE->TEMPLATE, 20);
2695 if(values1d){
2696 space(f,20);
2697 fprintf(f,"values (\"");
2698 for(x=0 ; x < nx ; x++){
2699 if(type == 'S')
2700 fprintf(f,"%s", pfloat(buftunit, lib_scm2thr(values1d[x])/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
2701 else if(type == 'D')
2702 fprintf(f,"%s", pfloat(buftunit, values1d[x]));
2703 else
2704 fprintf(f,"%s", ppower(buftunit, values1d[x]));
2705 if((nx-x) > 1){
2706 fprintf(f,", ");
2707 }
2708 }
2709 fprintf(f,"\");\n");
2710 }else if(values2d){
2711 space(f,20);
2712 fprintf(f,"values (\"");
2713 for(x=0 ; x < nx ; x++){
2714 for(y=0 ; y < ny ; y++){
2715 if(type == 'S')
2716 fprintf(f,"%s", pfloat(buftunit, lib_scm2thr(values2d[x][y])/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
2717 else if(type == 'D')
2718 fprintf(f,"%s", pfloat(buftunit, values2d[x][y]));
2719 else
2720 fprintf(f,"%s", ppower(buftunit, values2d[x][y]));
2721 if((ny-y) > 1){
2722 fprintf(f,", ");
2723 }else if((nx-x) > 1){
2724 fprintf(f,"\", \\\n");
2725 space(f, 28);
2726 fprintf(f,"\"");
2727 }
2728 else
2729 fprintf(f,"\");\n");
2730 }
2731 }
2732 }
2733 }
2734
2735 /****************************************************************************/
2736 /* function lib_drivelutconst */
2737 /****************************************************************************/
2738 void lib_drivelutconst (FILE *f, float value, char type)
2739 {
2740 // int x,y;
2741
2742
2743 space(f,20);
2744 if(type == 'E')
2745 fprintf(f,"values (\"%s\");\n", ppower(buftunit, value));
2746 else
2747 fprintf(f,"values (\"%s\");\n", pfloat(buftunit, value));
2748 /* fprintf(f,"values (\"");
2749 for(x=0 ; x < 2 ; x++){
2750 for(y=0 ; y < 2 ; y++){
2751 fprintf(f,"%s", pfloat(buftunit, value));
2752 if((2-y) > 1){
2753 fprintf(f,", ");
2754 }else if((2-x) > 1){
2755 fprintf(f,"\", \\\n");
2756 space(f, 28);
2757 fprintf(f,"\"");
2758 }
2759 else
2760 fprintf(f,"\");\n");
2761 }
2762 }*/
2763 }
2764
2765 int lib_drive_rail_connection(FILE *f, ttvfig_list *ttvfig)
2766 {
2767 int i, nbrail=0;
2768 ttvsig_list *ttvsig;
2769 float low=-1.0, high=-1.0, alim, nom_voltage;
2770 ptype_list *ptype;
2771 char *name;
2772 char buf[1024];
2773 chain_list *cl=NULL,*chain;
2774 char flagdefault;
2775
2776 nom_voltage = ttvfig->INFO->VDD;
2777
2778
2779 if(libpowerptype){
2780 cl = ttv_getsigbytype_and_netname(ttvfig,NULL,TTV_SIG_C|TTV_SIG_B,NULL) ;
2781 for (chain = cl; chain; chain = chain->NEXT){
2782 ttvsig=(ttvsig_list *)chain->DATA;
2783 if (ttv_get_signal_swing(ttvfig, ttvsig, &low, &high) && (high > 0.0)){
2784 alim = high - low;
2785 if(!mbk_cmpdouble(nom_voltage, alim, 1e6)){
2786 flagdefault = 1;
2787 break;
2788 }
2789 }
2790 }
2791
2792 i = 0;
2793 for(ptype = libpowerptype; ptype; ptype = ptype->NEXT){
2794 for (chain = cl; chain; chain = chain->NEXT){
2795 ttvsig=(ttvsig_list *)chain->DATA;
2796 if (!ttv_get_signal_swing(ttvfig, ttvsig, &low, &high)){
2797 alim = high - low;
2798 if(!mbk_cmpdouble(*(float*)&ptype->DATA, alim, 1e6)){
2799 if(flagdefault){
2800 // space(f,8);
2801 // fprintf(f, "rail_connection (PV0, VDD0) ;\n");
2802 nbrail++;
2803 flagdefault = 0;
2804 }
2805 i++;
2806 sprintf (buf, "PV%d", i);
2807 name = namealloc(buf);
2808 // space(f,8);
2809 // fprintf(f, "rail_connection (%s, %s) ;\n", name, (char*)ptype->TYPE);
2810 nbrail++;
2811 break;
2812 }
2813 }
2814 }
2815 }
2816 if(cl) freechain(cl);
2817 }
2818 return nbrail;
2819 }
2820
2821 void lib_drive_power_supply_group(FILE *f, chain_list *figlist, ttvinfo_list *ttvinfo)
2822 {
2823 int i;
2824 chain_list *ttv,*cl,*chain;
2825 ttvfig_list *ttvfig;
2826 ttvsig_list *ttvsig;
2827 float low, high, alim, nom_voltage;
2828 ptype_list *ptype;
2829 char *name;
2830 char buf[1024];
2831
2832 if(!ttvinfo){
2833 nom_voltage = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
2834 }else{
2835 nom_voltage = ttvinfo->VDD;
2836 }
2837
2838 i = 0;
2839 for(ttv = figlist ; ttv ; ttv = ttv->NEXT){
2840 ttvfig=(ttvfig_list*)ttv->DATA;
2841 cl = ttv_getsigbytype_and_netname(ttvfig,NULL,TTV_SIG_C|TTV_SIG_B,NULL) ;
2842 for (chain = cl; chain; chain = chain->NEXT){
2843 ttvsig=(ttvsig_list *)chain->DATA;
2844 if (!ttv_get_signal_swing(ttvfig, ttvsig, &low, &high)){
2845 alim = high - low;
2846 if(mbk_cmpdouble(nom_voltage, alim, 1e6)){
2847 for(ptype = libpowerptype; ptype; ptype = ptype->NEXT){
2848 if(!mbk_cmpdouble(*(float*)&ptype->DATA, alim, 1e6)) break;
2849 }
2850 if(!ptype){
2851 i++;
2852 sprintf (buf, "VDD%d", i);
2853 name = namealloc(buf);
2854 libpowerptype = addptype(libpowerptype, (long)name, NULL);
2855 *(float*)&libpowerptype->DATA = alim;
2856 }
2857 }
2858 }
2859 }
2860 if(cl) freechain(cl);
2861 }
2862 if(libpowerptype){
2863 libpowerptype = (ptype_list*)reverse((chain_list*)libpowerptype);
2864 tab(f);
2865 fprintf(f, "power_supply () {\n");
2866 space(f,8);
2867 fprintf(f, "default_power_rail : VDD0 ;\n");
2868 for(ptype = libpowerptype; ptype; ptype = ptype->NEXT){
2869 space(f,8);
2870 fprintf(f, "power_rail (%s, %.2f) ;\n", (char*)ptype->TYPE, *(float*)&ptype->DATA);
2871 }
2872 tab(f);
2873 fprintf(f, "}\n");
2874 }
2875 }
2876
2877 /****************************************************************************/
2878 /* function lib_drivebustype */
2879 /****************************************************************************/
2880 void lib_drivebustype (FILE *f, chain_list *figlist)
2881 {
2882 chain_list *ttv;
2883 chain_list *buschain = NULL, *chain;
2884 ttvfig_list *ttvfig;
2885 ttvsig_list *ttvsig;
2886 int flagbus = 0, lsb = 0, msb = 0, width = 0;
2887 char *previousname = NULL, *devectname, *busname;
2888 int n, ninter ;
2889 typedef struct msblsb {
2890 int MSB;
2891 int LSB;
2892 } msblsb;
2893 msblsb *vect;
2894
2895
2896 for(ttv = figlist ; ttv ; ttv = ttv->NEXT){
2897 ttvfig=(ttvfig_list*)ttv->DATA;
2898 flagbus = 0;
2899 for (n=0; n < ttvfig->NBCONSIG; n++){
2900 ttvsig=ttvfig->CONSIG[n];
2901
2902 devectname = ttv_devect(ttvsig->NAME);
2903 if(flagbus)
2904 if(strcmp(busname,vectorradical(devectname))){
2905 flagbus = 0;
2906 }
2907 if((ttvsig->NAME != devectname) && (!flagbus)){
2908 ninter = n;
2909 flagbus = 1;
2910 lsb = vectorindex(devectname);
2911 busname = vectorradical(devectname);
2912 for(ninter=n; ninter < ttvfig->NBCONSIG; ninter++){
2913 ttvsig = ttvfig->CONSIG[ninter];
2914 devectname = ttv_devect(ttvsig->NAME);
2915 if((vectorradical(devectname) != previousname) && (n != ninter))
2916 break;
2917 previousname = vectorradical(devectname);
2918 msb = vectorindex(devectname);
2919 }
2920 if(!buschain){
2921 vect = (msblsb*)mbkalloc (sizeof (struct msblsb));
2922 vect->MSB = msb;
2923 vect->LSB = lsb;
2924 buschain = addchain(buschain, vect);
2925 }else{
2926 for(chain = buschain; chain; chain = chain->NEXT){
2927 if((((msblsb*)chain->DATA)->MSB == msb) && (((msblsb*)chain->DATA)->LSB == lsb))
2928 break;
2929 }
2930 if(!chain){
2931 vect = (msblsb*)mbkalloc (sizeof (struct msblsb));
2932 vect->MSB = msb;
2933 vect->LSB = lsb;
2934 buschain = addchain(buschain, vect);
2935 }
2936 }
2937 }
2938 ttvsig = ttvfig->CONSIG[n];
2939 if(flagbus)
2940 if((n + 1) == ttvfig->NBCONSIG){
2941 flagbus = 0;
2942 }
2943 }
2944 if(flagbus){
2945 flagbus = 0;
2946 }
2947 }
2948 if(buschain){
2949 if(LIB_BUS_DELIM[1] != '\0'){
2950 tab(f);
2951 fprintf(f, "bus_naming_style : \"%%s%c%%d%c\" ;\n", LIB_BUS_DELIM[0], LIB_BUS_DELIM[1]);
2952 }
2953 else {
2954 tab(f);
2955 fprintf(f, "bus_naming_style : \"%%s%c%%d\" ;\n", LIB_BUS_DELIM[0]);
2956 }
2957 }
2958 for(chain = buschain; chain; chain = chain->NEXT){
2959 msb = ((msblsb*)chain->DATA)->MSB;
2960 lsb = ((msblsb*)chain->DATA)->LSB;
2961 tab(f);
2962 fprintf(f, "type (bus_%d_%d) {\n", msb, lsb);
2963 tab(f);
2964 fprintf(f, "base_type : array;\n");
2965 tab(f);
2966 fprintf(f, "data_type : bit;\n");
2967 if(msb > lsb)
2968 width = msb - lsb + 1;
2969 else
2970 width = lsb - msb + 1;
2971 tab(f);
2972 fprintf(f, "bit_width : %d;\n", width);
2973 tab(f);
2974 fprintf(f, "bit_from : %d;\n", msb);
2975 tab(f);
2976 fprintf(f, "bit_to : %d;\n", lsb);
2977 if(msb > lsb) {
2978 tab(f);
2979 fprintf(f, "downto : true;\n");
2980 }
2981 else {
2982 tab(f);
2983 fprintf(f, "downto : false;\n");
2984 }
2985 tab(f);
2986 fprintf(f, "}\n");
2987
2988 mbkfree(chain->DATA);
2989 }
2990 freechain(buschain);
2991 buschain = NULL;
2992
2993 }
2994
2995 /****************************************************************************/
2996 /* function lib_drivetemplate */
2997 /****************************************************************************/
2998 void lib_drivetemplate (FILE *f)
2999 {
3000 chain_list *tempchain;
3001 char *var1,*var2;
3002 timing_ttable *template;
3003
3004
3005 for(tempchain=STM_TEMPLATES_CHAIN;tempchain;tempchain=tempchain->NEXT){
3006 template=(timing_ttable*)(tempchain->DATA);
3007 tab(f);
3008 fprintf(f,"lu_table_template (%s) {\n",template->NAME);
3009 space(f,8);
3010 if(template->XTYPE==STM_INPUT_SLEW && template->YTYPE==STM_CLOCK_SLEW){
3011 var1="constrained_pin_transition";
3012 var2="related_pin_transition";
3013 }
3014 else if(template->XTYPE==STM_CLOCK_SLEW && template->YTYPE==STM_INPUT_SLEW){
3015 var2="constrained_pin_transition";
3016 var1="related_pin_transition";
3017 }
3018 else if(template->XTYPE==STM_CLOCK_SLEW)
3019 var1="input_net_transition";
3020 else if(template->XTYPE==STM_LOAD)
3021 var1="total_output_net_capacitance";
3022 else if(template->XTYPE==STM_INPUT_SLEW){
3023 if(template->XTYPEBIS)
3024 var1="constrained_pin_transition";
3025 else
3026 var1="input_net_transition";
3027 }
3028 if(template->YTYPE==STM_LOAD)
3029 var2="total_output_net_capacitance";
3030
3031
3032 fprintf(f,"variable_1 : %s;\n",var1);
3033 if(template->NY){
3034 space(f,8);
3035 fprintf(f,"variable_2 : %s;\n",var2);
3036 }
3037 lib_driveindex (f, template, 8);
3038
3039 tab(f);
3040 fprintf(f,"}\n");
3041 }
3042
3043 if(( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 1 )
3044 ||( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 5 )){
3045 for(tempchain=STM_TEMPLATES_CHAIN;tempchain;tempchain=tempchain->NEXT){
3046 template=(timing_ttable*)(tempchain->DATA);
3047 if((template->XTYPE==STM_INPUT_SLEW && template->YTYPE==STM_CLOCK_SLEW)
3048 || (template->XTYPE==STM_CLOCK_SLEW && template->YTYPE==STM_INPUT_SLEW))
3049 continue;
3050 tab(f);
3051 fprintf(f,"power_lut_template (energy_%s) {\n",template->NAME);
3052 space(f,8);
3053 if((template->XTYPE==STM_CLOCK_SLEW)
3054 || (template->XTYPE==STM_INPUT_SLEW))
3055 var1="input_transition_time";
3056 else if(template->XTYPE==STM_LOAD)
3057 var1="total_output_net_capacitance";
3058 if(template->YTYPE==STM_LOAD)
3059 var2="total_output_net_capacitance";
3060
3061 fprintf(f,"variable_1 : %s;\n",var1);
3062 if(template->NY){
3063 space(f,8);
3064 fprintf(f,"variable_2 : %s;\n",var2);
3065 }
3066 lib_driveindex (f, template, 8);
3067
3068 tab(f);
3069 fprintf(f,"}\n");
3070 }
3071 }
3072 /* tab(f);
3073 fprintf(f,"lu_table_template (%s) {\n", TEMP_CONST_NAME);
3074 space(f,8);
3075 fprintf(f,"variable_1 : input_net_transition;\n");
3076 space(f,8);
3077 fprintf(f,"variable_2 : total_output_net_capacitance;\n");
3078 space(f,8);
3079 fprintf(f,"index_1 (\"1.0, 2.0\");\n");
3080 space(f,8);
3081 fprintf(f,"index_2 (\"1.0, 2.0\");\n");
3082 tab(f);
3083 fprintf(f,"}\n");
3084 tab(f);
3085 fprintf(f,"lu_table_template (%s) {\n", TEMP_SETHOL_CONST_NAME);
3086 space(f,8);
3087 fprintf(f,"variable_1 : constrained_pin_transition;\n");
3088 space(f,8);
3089 fprintf(f,"variable_2 : related_pin_transition;\n");
3090 space(f,8);
3091 fprintf(f,"index_1 (\"1.0, 2.0\");\n");
3092 space(f,8);
3093 fprintf(f,"index_2 (\"1.0, 2.0\");\n");
3094 tab(f);
3095 fprintf(f,"}\n");*/
3096
3097 }
3098
3099
3100 /****************************************************************************/
3101 /* function lib_driveconstraintmodel */
3102 /****************************************************************************/
3103 void lib_driveconstraintmodel (FILE *f, ttvfig_list *ttvfig, char* name, char type)
3104 {
3105 timing_model *tmodel ;
3106 float constante ;
3107
3108 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, name);
3109 constante=tmodel->UMODEL.TABLE->CST;
3110
3111 if(constante!=STM_NOVALUE){
3112 lib_drive_cst_constraint(f, constante, type);
3113 }else{
3114 space(f,16);
3115 if(type=='R')
3116 fprintf(f,"rise_constraint (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3117 else if(type=='F')
3118 fprintf(f,"fall_constraint (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3119
3120 lib_drivelut (f, tmodel, 'D');
3121 space(f,16);
3122 fprintf(f,"}\n");
3123 }
3124 }
3125
3126 /****************************************************************************/
3127 /* function lib_drivedelaymodel */
3128 /****************************************************************************/
3129 void lib_drivedelaymodel (FILE *f, ttvfig_list *ttvfig, char* name, char type, float capa)
3130 {
3131 timing_model *tmodel ;
3132 float constante ;
3133
3134 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, name);
3135 constante=tmodel->UMODEL.TABLE->CST;
3136
3137 if(constante!=STM_NOVALUE){
3138 lib_driveintrinsic(f, constante, type);
3139 }else{
3140 space(f,16);
3141 if(type=='R')
3142 fprintf(f,"cell_rise (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3143 else if(type=='F')
3144 fprintf(f,"cell_fall (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3145 if (getptype(ttvfig->USER, TTV_FIG_CAPAOUT_HANDLED)==NULL)
3146 {
3147 if(V_BOOL_TAB[__TMA_DRIVECAPAOUT].VALUE == 0 && !V_BOOL_TAB[__TMA_CHARAC_PRECISION].VALUE)
3148 stm_mod_shift(tmodel, capa);
3149 }
3150 lib_drivelut (f, tmodel, 'D');
3151 space(f,16);
3152 fprintf(f,"}\n");
3153 }
3154 }
3155
3156 /****************************************************************************/
3157 /* function lib_driveslewmodel */
3158 /****************************************************************************/
3159 void lib_driveslewmodel (FILE *f, ttvfig_list *ttvfig, char* name, char type, float capa)
3160 {
3161 timing_model *tmodel ;
3162 float constante ;
3163
3164 tmodel=stm_getmodel(ttvfig->INFO->FIGNAME, name);
3165 constante=tmodel->UMODEL.TABLE->CST;
3166
3167
3168 if(constante!=STM_NOVALUE){
3169 lib_driveslew(f, constante, type);
3170 }else{
3171 space(f,16);
3172 if(type=='R')
3173 fprintf(f,"rise_transition (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3174 else if(type=='F')
3175 fprintf(f,"fall_transition (%s) {\n",tmodel->UMODEL.TABLE->TEMPLATE->NAME);
3176 if (getptype(ttvfig->USER, TTV_FIG_CAPAOUT_HANDLED)==NULL)
3177 {
3178 if(V_BOOL_TAB[__TMA_DRIVECAPAOUT].VALUE == 0 && !V_BOOL_TAB[__TMA_CHARAC_PRECISION].VALUE)
3179 stm_mod_shift(tmodel, capa);
3180 }
3181 lib_drivelut (f, tmodel, 'S');
3182 space(f,16);
3183 fprintf(f,"}\n");
3184 }
3185 }
3186
3187 /****************************************************************************/
3188 /* function lib_drive_cst_constraint */
3189 /****************************************************************************/
3190 void lib_drive_cst_constraint(FILE *f, float value, char type)
3191 {
3192 space(f,16);
3193 // if(STM_TEMPLATES_CHAIN){
3194 if(type=='R')
3195 fprintf(f,"rise_constraint (scalar) {\n");
3196 else if(type=='F')
3197 fprintf(f,"fall_constraint (scalar) {\n");
3198 lib_drivelutconst (f, value, 'D');
3199 space(f,16);
3200 fprintf(f,"}\n");
3201
3202 /* }else{
3203 if(type=='R'){
3204 fprintf(f,"intrinsic_rise : %s ;\n", pfloat(buftunit,value));
3205 }if(type=='F'){
3206 fprintf(f,"intrinsic_fall : %s ;\n", pfloat(buftunit,value));
3207 }
3208 }*/
3209
3210 }
3211
3212
3213 /****************************************************************************/
3214 /* function lib_driveintrinsic */
3215 /****************************************************************************/
3216 void lib_driveintrinsic (FILE *f, float value, char type)
3217 {
3218 space(f,16);
3219 // if(STM_TEMPLATES_CHAIN){
3220 if(type=='R')
3221 fprintf(f,"cell_rise (scalar) {\n");
3222 else if(type=='F')
3223 fprintf(f,"cell_fall (scalar) {\n");
3224 lib_drivelutconst (f, value, 'D');
3225 space(f,16);
3226 fprintf(f,"}\n");
3227
3228 /* }else{
3229 if(type=='R'){
3230 fprintf(f,"intrinsic_rise : %s ;\n", pfloat(buftunit,value));
3231 }if(type=='F'){
3232 fprintf(f,"intrinsic_fall : %s ;\n", pfloat(buftunit,value));
3233 }
3234 }*/
3235 }
3236
3237 /****************************************************************************/
3238 /* function lib_driveslew */
3239 /****************************************************************************/
3240 void lib_driveslew (FILE *f, float value, char type)
3241 {
3242 space(f,16);
3243 // if(STM_TEMPLATES_CHAIN){
3244 if(type=='R')
3245 fprintf(f,"rise_transition (scalar) {\n");
3246 else if(type=='F')
3247 fprintf(f,"fall_transition (scalar) {\n");
3248 lib_drivelutconst (f, lib_scm2thr(value)/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE, 'S');
3249 space(f,16);
3250 fprintf(f,"}\n");
3251
3252 /* }else{
3253 if(type=='R')
3254 fprintf(f,"slope_rise : %s ;\n", pfloat(buftunit,lib_scm2thr(value)/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
3255 if(type=='F')
3256 fprintf(f,"slope_fall : %s ;\n", pfloat(buftunit,lib_scm2thr(value)/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
3257 }*/
3258
3259 }
3260
3261
3262 /****************************************************************************/
3263 /* function space */
3264 /****************************************************************************/
3265 void space (FILE *f, int nb)
3266 {
3267 int i;
3268
3269 if(FLAGBUS) tab(f);
3270 for (i=0 ; i < nb ;i++){
3271 fprintf(f," ");
3272 }
3273 }
3274
3275 /****************************************************************************/
3276 /* function tab */
3277 /****************************************************************************/
3278 void tab (FILE *f)
3279 {
3280 fprintf(f," ");
3281 }
3282
3283 /****************************************************************************/
3284 /* function saut */
3285 /****************************************************************************/
3286 void saut (FILE *f, int nb)
3287 {
3288 int i;
3289
3290 for (i=0 ; i < nb ;i++){
3291 fprintf(f,"\n");
3292 }
3293 }
3294
3295 /****************************************************************************/
3296 /* function addevent */
3297 /****************************************************************************/
3298 chain_list *addevent (chain_list *chain, ttvevent_list *event)
3299 {
3300 chain_list *ch ;
3301
3302 for(ch=chain; ch; ch=ch->NEXT){
3303 if(ch->DATA==event)
3304 return chain;
3305 }
3306 return(addchain(chain, event));
3307 }
3308 /****************************************************************************/
3309 /* function addname */
3310 /****************************************************************************/
3311 chain_list *addname (chain_list *chain, char *name)
3312 {
3313 chain_list *ch ;
3314
3315 for(ch=chain; ch; ch=ch->NEXT){
3316 if(ch->DATA==name)
3317 return chain;
3318 }
3319 return(addchain(chain, name));
3320 }
3321 /****************************************************************************/
3322 /* function pfloat */
3323 /****************************************************************************/
3324 char *pfloat (char *buf, float time)
3325 {
3326
3327 if(!strcasecmp (V_STR_TAB[__TMA_TUNIT].VALUE, "ps")){
3328 sprintf (buf, "%.1f", time) ;
3329 }else if(!strcasecmp(V_STR_TAB[__TMA_TUNIT].VALUE,"ns")){
3330 sprintf (buf, "%.4f", time/1000.0) ;
3331 }
3332
3333 return (buf) ;
3334 }
3335
3336 /****************************************************************************/
3337 /* function ppower */
3338 /****************************************************************************/
3339 char *ppower (char *buf, float power)
3340 {
3341
3342 if(!strcasecmp (V_STR_TAB[__TMA_CUNIT].VALUE, "pf"))
3343 sprintf (buf, "%.4f", power*1e12) ;
3344 else if(!strcasecmp (V_STR_TAB[__TMA_CUNIT].VALUE, "ff"))
3345 sprintf (buf, "%.1f", power*1e15) ;
3346
3347 return (buf) ;
3348 }
3349 /****************************************************************************/
3350 /* function lib_driveopcond : operating conditions */
3351 /****************************************************************************/
3352 void lib_driveopcond (FILE *f, char *opcondname, double process, double temp,
3353 double volt)
3354 {
3355 tab(f);
3356 fprintf(f,"operating_conditions(%s) {\n", opcondname) ;
3357 space(f, 8);
3358 fprintf(f,"process : %.1f ;\n", process) ;
3359 space(f, 8);
3360 fprintf(f,"temperature : %.1f ;\n", temp) ;
3361 space(f, 8);
3362 fprintf(f,"voltage : %.2f ;\n", volt) ;
3363 tab(f);
3364 fprintf(f,"}\n") ;
3365 }
3366
3367 /****************************************************************************/
3368 /* function lib_derate_tension : */
3369 /* tpfinal = tpinitial*(1.0+dV*derate_tension) */
3370 /****************************************************************************/
3371 double lib_derate_tension(double V0, double V1, int transition)
3372 {
3373 double derate_tension = 0.0 ;
3374 double rapport_Ids = 1.0 ;
3375
3376 switch(transition) {
3377 case LIB_RISING : rapport_Ids = mcc_calcRapIdsVolt(MCC_TECHFILE,
3378 NULL, MCC_PMOS,
3379 MCC_TYPICAL, MCC_TECSIZE*1.0e-6,
3380 12.0*MCC_TECSIZE*1.0e-6, MCC_TEMP,
3381 V0, V1) ;
3382 break ;
3383 case LIB_FALLING : rapport_Ids = mcc_calcRapIdsVolt(MCC_TECHFILE,
3384 NULL, MCC_NMOS,
3385 MCC_TYPICAL, MCC_TECSIZE*1.0e-6,
3386 6.0*MCC_TECSIZE*1.0e-6, MCC_TEMP,
3387 V0, V1) ;
3388 break ;
3389 }
3390
3391 derate_tension = 1.0/(rapport_Ids-1.0)-1.0/(V1-V0) ;
3392
3393 return(derate_tension) ;
3394 }
3395
3396 /****************************************************************************/
3397 /* function lib_derate_temp : */
3398 /* tpfinal = tpinitial*(1.0+dV*derate_temp) */
3399 /****************************************************************************/
3400 double lib_derate_temp(double T0, double T1, int transition)
3401 {
3402 double derate_temp = 0.0 ;
3403 double rapport_Ids = 1.0 ;
3404
3405 switch(transition) {
3406 case LIB_RISING : rapport_Ids = mcc_calcRapIdsTemp(MCC_TECHFILE,
3407 NULL, MCC_PMOS,
3408 MCC_TYPICAL, MCC_TECSIZE*1.0e-6,
3409 12.0*MCC_TECSIZE*1.0e-6, MCC_VDDmax,
3410 T0, T1) ;
3411 derate_temp = (rapport_Ids-1.0)/(T1-T0) ;
3412 break ;
3413 case LIB_FALLING : rapport_Ids = mcc_calcRapIdsTemp(MCC_TECHFILE,
3414 NULL, MCC_NMOS,
3415 MCC_TYPICAL, MCC_TECSIZE*1.0e-6,
3416 6.0*MCC_TECSIZE*1.0e-6, MCC_VDDmax,
3417 T0, T1) ;
3418 derate_temp = (1.0/rapport_Ids-1.0)/(T1-T0) ;
3419 break ;
3420 }
3421
3422 return(derate_temp) ;
3423 }
3424
3425 /****************************************************************************/
3426 /* function lib_drive_remove_null */
3427 /* fonction de blindage lors de l'appel depuis les api : enleve les */
3428 /* champs null de la liste. */
3429 /****************************************************************************/
3430 void lib_drive_remove_null( chain_list *figlistx,
3431 chain_list *befiglistx,
3432 chain_list **figlist,
3433 chain_list **befiglist
3434 )
3435 {
3436 chain_list *chaintv, *chainbe ;
3437
3438 *figlist = NULL ;
3439 *befiglist = NULL ;
3440
3441 for( chaintv = figlistx, chainbe = befiglistx ;
3442 chaintv ;
3443 chaintv = chaintv->NEXT,
3444 chainbe = ( chainbe ? chainbe->NEXT : NULL )
3445 )
3446 {
3447 if( chaintv->DATA ) {
3448 *figlist = addchain( *figlist, chaintv->DATA );
3449 if( chainbe )
3450 *befiglist = addchain( *befiglist, chainbe->DATA );
3451 }
3452 }
3453
3454 *figlist = reverse( *figlist );
3455 *befiglist = reverse( *befiglist );
3456 }