1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : LIB Version 1.00 */
6 /* Fichier : lib_drive.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Gilles Augustins */
13 /****************************************************************************/
15 /****************************************************************************/
17 /****************************************************************************/
21 /****************************************************************************/
23 /****************************************************************************/
24 extern ht
* tut_tablasharea
;
27 static ptype_list
*libpowerptype
=NULL
;
29 static inline ttvline_list
*lib_getnodeinputline(ttvevent_list
*ev
, int ttx
)
31 if (ttx
) return ev
->INPATH
;
32 else return ev
->INLINE
;
35 /****************************************************************************/
36 /* function lib_drive */
37 /****************************************************************************/
38 void lib_drive (chain_list
*figlistx
, chain_list
*befiglistx
, char *name
, char *suffix
)
46 ttvinfo_list
*ttvinfo
= NULL
;
47 chain_list
*figlist
, *befiglist
, *tofree
;
49 lib_drive_remove_null( figlistx
, befiglistx
, &figlist
, &befiglist
);
51 printf("\n\n ###################################\n");
53 printf(" # liberty driver version 1.00 #\n");
55 printf(" ###################################\n\n");
56 printf(" WRITING FILE: %s ...\n\n", name
);
58 if(!(f
= mbkfopen (name
, NULL
, WRITE_TEXT
))){
59 fprintf (stderr
, "LIB ERROR : no file %s\n", name
);
63 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_NODE_NAME_ONLY
);
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
);
73 ttvinfo
= ((ttvfig_list
*)figlist
->DATA
)->INFO
;
76 if(V_STR_TAB
[__TMA_LIBRARY
].VALUE
)
77 lib_driveheader(f
, V_STR_TAB
[__TMA_LIBRARY
].VALUE
, ttvinfo
);
79 lib_driveheader(f
, name
, ttvinfo
);
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
);
90 if(STM_TEMPLATES_CHAIN
){
97 lib_drive_power_supply_group(f
, figlist
, ttvinfo
);
101 lib_drivebustype(f
, figlist
);
106 for(ttv
= figlist
; ttv
; ttv
= ttv
->NEXT
){
108 ttvfig
=(ttvfig_list
*)ttv
->DATA
;
110 lib_drivecell (f
, ttvfig
, (befig_list
*)befiglist
->DATA
, suffix
);
111 befiglist
=befiglist
->NEXT
;
114 lib_drivecell (f
, ttvfig
, NULL
, suffix
);
116 printf(" -> writing cell%d: %s\n", cmpt
, lib_unsuffix(ttvfig
->INFO
->FIGNAME
, suffix
));
123 printf("\n ...DONE\n\n");
125 ttv_search_mode(0, TTV_MORE_OPTIONS_USE_NODE_NAME_ONLY
);
127 freechain( figlist
);
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
)
137 int lsb
= 0, msb
= 0;
138 char *previousname
= NULL
, *devectname
;
141 devectname
= ttv_devect(ttvsig
->NAME
);
143 if(strcmp(*busname
,vectorradical(devectname
))){
148 if((ttvsig
->NAME
!= devectname
) && (!*flagbus
)){
151 lsb
= vectorindex(devectname
);
152 *busname
= vectorradical(devectname
);
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
))
159 previousname
= vectorradical(devectname
);
160 msb
= vectorindex(devectname
);
163 fprintf(f
, "bus (%s) {\n", *busname
);
165 fprintf(f
, "bus_type : bus_%d_%d ;\n", msb
, lsb
);
168 ttvsig
= ttvfig
->CONSIG
[n
];
170 lib_drivepin(f
, ttvfig
, ttvsig
, ptcellbefig
, ptcbhseq
, nbrail
);
173 if((n
+ 1) == ttvfig
->NBCONSIG
){
180 /****************************************************************************/
181 /* function lib_getpinname */
182 /****************************************************************************/
183 char *lib_getpinname(char *str
)
186 static char buf
[1024];
188 signame
= ttv_devect(str
);
189 if(vectorindex(signame
) == -1){
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]);
195 sprintf(buf
, "%s%c%d", vectorradical(signame
), LIB_BUS_DELIM
[0], vectorindex(signame
));
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
)
205 chain_list
*chain
=NULL
;
212 fprintf(f
,"generated_clock (%s) {\n", lib_getpinname(ttvsig
->NAME
));
213 sscanf(ptype
->DATA
, "%d %g%% %s", &mbdb
, &duty_cycle
, master
);
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
);
220 pt
->DATA
= addchain(pt
->DATA
, namealloc(master
));
223 fprintf(f
,"master_pin : %s ;\n", lib_getpinname(master
));
226 fprintf(f
,"multiplied_by : %d ;\n", abs(mbdb
));
229 fprintf(f
,"divided_by : %d ;\n", mbdb
);
232 fprintf(f
,"duty_cycle : %g ;\n", duty_cycle
);
237 /****************************************************************************/
238 /* function lib_drive_generated_clocks */
239 /****************************************************************************/
240 void lib_drive_generated_clocks (FILE *f
, ttvfig_list
*ttvfig
)
243 ttvsig_list
*ttvsig
;
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
);
251 lib_drive_generated_clock(f
, ttvfig
, ttvsig
, ptype
);
254 for (n
=0; n
< ttvfig
->NBCONSIG
; n
++){
255 ttvsig
=ttvfig
->CONSIG
[n
];
256 ptype
= getptype(ttvsig
->USER
, LIB_GENERATED_CLOCK_INFO
);
258 lib_drive_generated_clock(f
, ttvfig
, ttvsig
, ptype
);
262 /****************************************************************************/
263 /* function lib_get_pscale */
264 /****************************************************************************/
265 float lib_get_pscale()
269 if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "1mW"))
271 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "100uW"))
273 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "10uW"))
275 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "1uW"))
277 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "100nW"))
279 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "10nW"))
281 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "1nW"))
283 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "100pW"))
285 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "10pW"))
287 else if(!strcmp(V_STR_TAB
[__TMA_PUNIT
].VALUE
, "1pW"))
295 /****************************************************************************/
296 /* function lib_drivecell */
297 /****************************************************************************/
298 void lib_drivecell (FILE *f
, ttvfig_list
*ttvfig
, befig_list
*ptcellbefig
, char *suffix
)
301 ttvsig_list
*ttvsig
;
302 char *name
, *busname
;
303 cbhseq
*ptcbhseq
=NULL
;
304 int flagbus
= 0, nbrail
;
306 tma_leak_pow_list
*tlp
;
307 float pscale
= lib_get_pscale();
309 name
=lib_unsuffix (ttvfig
->INFO
->FIGNAME
, suffix
);
311 fprintf(f
,"cell (%s) {\n", name
);
315 if(gethtitem(tut_tablasharea
,name
) != EMPTYHT
)
316 fprintf(f
,"area : %.2f ;\n",(double)(gethtitem(tut_tablasharea
,name
))/1000.0);
318 fprintf(f
,"area : 0.0 ;\n");
322 fprintf(f
,"area : 0.0 ;\n");
325 if((ptype
= getptype(ttvfig
->USER
, TTV_CELL_LEAKAGE_POWER
)) != NULL
){
328 fprintf(f
,"cell_leakage_power : %.2g ;\n", *(float*)&ptype
->DATA
* pscale
);
331 if((ptype
= getptype(ttvfig
->USER
, TTV_LEAKAGE_POWER
)) != NULL
){
332 for(tlp
= (tma_leak_pow_list
*)ptype
->DATA
; tlp
; tlp
=tlp
->NEXT
){
334 fprintf(f
,"leakage_power () {\n");
336 fprintf(f
,"when : \"");
337 cbh_writeabl(f
,tlp
->PATTERN
, 'L');
340 fprintf(f
,"value : %.2g ;\n", tlp
->VALUE
* pscale
);
348 if((ptype
= getptype(ttvfig
->USER
, TTV_FIG_CBHSEQ
)) != NULL
){
349 ptcbhseq
= (cbhseq
*)ptype
->DATA
;
350 lib_driveseqfunc(f
,ptcbhseq
);
353 nbrail
= lib_drive_rail_connection(f
, ttvfig
);
354 lib_drive_generated_clocks(f
, ttvfig
);
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
);
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
);
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
);
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
);
403 if (ptcbhseq
) cbh_delseq(ptcbhseq
);
406 /****************************************************************************/
407 /* function lib_driveseqfunc */
408 /****************************************************************************/
409 void lib_driveseqfunc (FILE *f
, cbhseq
*ptcbhseq
)
412 if(ptcbhseq
->SEQTYPE
==CBH_LATCH
){
416 fprintf(f
,"%s",ptcbhseq
->NAME
);
417 if(ptcbhseq
->NEGNAME
)
418 fprintf(f
,",%s",ptcbhseq
->NEGNAME
);
420 }else if(ptcbhseq
->NEGNAME
){
421 fprintf(f
,"%s) {\n",ptcbhseq
->NEGNAME
);
425 fprintf(f
,"enable : \"");
426 cbh_writeabl(f
,ptcbhseq
->CLOCK
, 'L');
431 fprintf(f
,"data_in : \"");
432 cbh_writeabl(f
,ptcbhseq
->DATA
, 'L');
437 fprintf(f
,"clear : \"");
438 cbh_writeabl(f
,ptcbhseq
->RESET
, 'L');
443 fprintf(f
,"preset : \"");
444 cbh_writeabl(f
,ptcbhseq
->SET
, 'L');
447 if(ptcbhseq
->RSCONF
){
449 fprintf(f
,"clear_preset_var1 : ");
450 cbh_writeabl(f
,ptcbhseq
->RSCONF
, 'L');
453 if(ptcbhseq
->RSCONFNEG
){
455 fprintf(f
,"clear_preset_var2 : ");
456 cbh_writeabl(f
,ptcbhseq
->RSCONFNEG
, 'L');
462 }else if(ptcbhseq
->SEQTYPE
==CBH_FLIPFLOP
){
466 fprintf(f
,"%s",ptcbhseq
->NAME
);
467 if(ptcbhseq
->NEGNAME
)
468 fprintf(f
,",%s",ptcbhseq
->NEGNAME
);
470 }else if(ptcbhseq
->NEGNAME
){
471 fprintf(f
,"%s) {\n",ptcbhseq
->NEGNAME
);
475 fprintf(f
,"clocked_on : \"");
476 cbh_writeabl(f
,ptcbhseq
->CLOCK
, 'L');
479 if(ptcbhseq
->SLAVECLOCK
){
481 fprintf(f
,"clocked_on_also : \"");
482 cbh_writeabl(f
,ptcbhseq
->SLAVECLOCK
, 'L');
487 fprintf(f
,"next_state : \"");
488 cbh_writeabl(f
,ptcbhseq
->DATA
, 'L');
493 fprintf(f
,"clear : \"");
494 cbh_writeabl(f
,ptcbhseq
->RESET
, 'L');
499 fprintf(f
,"preset : \"");
500 cbh_writeabl(f
,ptcbhseq
->SET
, 'L');
503 if(ptcbhseq
->RSCONF
){
505 fprintf(f
,"clear_preset_var1 : ");
506 cbh_writeabl(f
,ptcbhseq
->RSCONF
, 'L');
509 if(ptcbhseq
->RSCONFNEG
){
511 fprintf(f
,"clear_preset_var2 : ");
512 cbh_writeabl(f
,ptcbhseq
->RSCONFNEG
, 'L');
522 /****************************************************************************/
523 /* function lib_get_tg_pinname */
524 /****************************************************************************/
525 char *lib_get_tg_pinname(char *str
)
528 static char buf
[1024];
530 signame
= ttv_devect(str
);
531 if(vectorindex(signame
) == -1){
534 if(LIB_BUS_DELIM
[1] != '\0')
535 sprintf(buf
, "%s_%d_", vectorradical(signame
), vectorindex(signame
));
537 sprintf(buf
, "%s_%d", vectorradical(signame
), vectorindex(signame
));
541 /****************************************************************************/
542 /* function lib_clock_true */
543 /****************************************************************************/
544 void lib_drive_clock_true(FILE *f
, ttvfig_list
*ttvfig
, ttvsig_list
*ttvsig
)
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
){
552 fprintf(f
,"clock : true ;\n");
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
)
565 chain_list
*chtsname
=NULL
;
566 bepor_list
*ptbepor
=NULL
;
570 signame
= ttv_devect(ttvsig
->NAME
);
572 for(ptbepor
=ptcellbefig
->BEPOR
; ptbepor
; ptbepor
=ptbepor
->NEXT
){
573 if(ptbepor
->NAME
==signame
) break;
578 pinname
= lib_getpinname(ttvsig
->NAME
);
579 if(isdigit(pinname
[0]))
580 fprintf(f
,"pin (\"%s\") {\n", pinname
);
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
);
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
);
600 /****************************************************************************/
601 /* function lib_drivecombfunc */
602 /****************************************************************************/
603 chain_list
* lib_drivecombfunc (FILE *f
, char *name
, befig_list
*ptcellbefig
, cbhseq
*ptcbhseq
)
606 chain_list
*chtsname
=NULL
;
609 ptcbhcomb
= cbh_getcombfunc(ptcellbefig
, ptcbhseq
, name
);
611 if(ptcbhcomb
->FUNCTION
){
613 fprintf(f
,"function : \"");
614 cbh_writeabl(f
, ptcbhcomb
->FUNCTION
, 'L');
617 if(ptcbhcomb
->HZFUNC
){
618 chtsname
=supportChain_listExpr(ptcbhcomb
->HZFUNC
);
621 fprintf(f
,"three_state : \"");
622 cbh_writeabl(f
, ptcbhcomb
->HZFUNC
, 'L');
625 if(ptcbhcomb
->CONFLICT
){
627 fprintf(f
,"x_function : \"");
628 cbh_writeabl(f
, ptcbhcomb
->CONFLICT
, 'L');
631 cbh_delcomb(ptcbhcomb
);
637 /****************************************************************************/
638 /* function lib_drivecapacitance */
639 /****************************************************************************/
640 void lib_drivecapacitance (FILE *f
, ttvsig_list
*ttvsig
)
642 float cumin
,cumax
,cdmin
,cdmax
;
643 double capaupmin
,capaupmax
,capadnmin
,capadnmax
;
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
;
670 if(!strcasecmp(V_STR_TAB
[__TMA_CUNIT
].VALUE
,"ff")){
672 fprintf(f
,"capacitance : %.2f ;\n",(double)ttvsig
->CAPA
);
673 if (( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
) && flag
) {
675 fprintf(f
,"rise_capacitance_range ( %.2f , %.2f ) ;\n",
676 capaupmin
,capaupmax
);
678 fprintf(f
,"fall_capacitance_range ( %.2f , %.2f ) ;\n",
679 capadnmin
,capadnmax
);
681 }else if(!strcasecmp(V_STR_TAB
[__TMA_CUNIT
].VALUE
,"pf")){
683 fprintf(f
,"capacitance : %.5f ;\n",(double)ttvsig
->CAPA
/ 1000.0);
684 if (( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
) && flag
) {
686 fprintf(f
,"rise_capacitance_range ( %.5f , %.5f ) ;\n",(double)capaupmin
/1000.0,(double)capaupmax
/1000.0);
688 fprintf(f
,"fall_capacitance_range ( %.5f , %.5f ) ;\n",(double)capadnmin
/1000.0,(double)capadnmax
/1000.0);
692 if((ttvsig
->TYPE
& TTV_SIG_CO
) == TTV_SIG_CO
){
693 ptype
= getptype(ttvsig
->USER
, LIB_MAX_CAPACITANCE
);
695 max_capa
= *(float*)&ptype
->DATA
;
696 if(!strcasecmp(V_STR_TAB
[__TMA_CUNIT
].VALUE
,"ff")){
698 fprintf(f
,"max_capacitance : %.2f ;\n", max_capa
* 1e15
);
699 }else if(!strcasecmp(V_STR_TAB
[__TMA_CUNIT
].VALUE
,"pf")){
701 fprintf(f
,"max_capacitance : %.5f ;\n", max_capa
* 1e12
);
708 /****************************************************************************/
709 /* function lib_drivedirection */
710 /****************************************************************************/
711 void lib_drivedirection (FILE *f
, ttvsig_list
*ttvsig
, bepor_list
*ptbepor
, chain_list
*chtsname
, int nbrail
)
713 char *dir
, *level
=NULL
;
714 float low
, high
, alim
, nom_voltage
;
717 if ((ttvsig
->TYPE
& TTV_SIG_CX
)==TTV_SIG_CX
){
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";
732 else if ((ttvsig
->TYPE
& TTV_SIG_CT
)==TTV_SIG_CT
)
734 else if ((ttvsig
->TYPE
& TTV_SIG_CB
)==TTV_SIG_CB
)
736 else if ((ttvsig
->TYPE
& TTV_SIG_CZ
)==TTV_SIG_CZ
)
738 else if ((ttvsig
->TYPE
& TTV_SIG_CO
)==TTV_SIG_CO
)
743 if ((ttvsig
->TYPE
& TTV_SIG_C
)!=TTV_SIG_C
)
747 fprintf(f
,"direction : %s ;\n", dir
);
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
)){
754 if(!mbk_cmpdouble(*(float*)&ptype
->DATA
, alim
, 1e6
)){
755 level
= (char*)ptype
->TYPE
;
757 }else if(high
> 0.0){
759 if(!mbk_cmpdouble(nom_voltage
, alim
, 1e6
)){
760 level
= namealloc("VDD0");
764 if(!strcmp(dir
, "inout")){
766 fprintf(f
, "input_signal_level : %s ;\n", level
);
768 fprintf(f
, "output_signal_level : %s ;\n", level
);
769 }else if((!strcmp(dir
, "input"))/*||(!strcmp(dir, "internal"))*/){
771 fprintf(f
, "input_signal_level : %s ;\n", level
);
774 fprintf(f
, "output_signal_level : %s ;\n", level
);
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
)
786 chain_list
*ch
, *chx
, *abl
;
794 ttv_getsigname(ttvfig
, bufsig
, ((ttvline_list
*)chain_pos
->DATA
)->ROOT
->ROOT
);
796 for(chx
=chain_posname
; chx
; chx
=chx
->NEXT
){
797 pinname
= lib_get_tg_pinname(bufsig
);
799 sprintf(buf
, "maxd_%s_", pinname
);
801 sprintf(buf
, "mind_%s_", pinname
);
802 relpinname
= lib_get_tg_pinname((char*)chx
->DATA
);
803 strcat(buf
, relpinname
);
806 for(ch
=chain_pos
; ch
; ch
=ch
->NEXT
){
807 line
=(ttvline_list
*)ch
->DATA
;
809 if(!strcmp(line
->NODE
->ROOT
->NAME
,(char*)chx
->DATA
)){
810 typel
= line
->ROOT
->TYPE
;
815 if((typel
& TTV_NODE_UP
) == TTV_NODE_UP
)
816 sprintf(bufttype
,"preset");
818 sprintf(bufttype
,"clear");
820 strcat(buf
, bufttype
);
822 strcat(buf
, "_positive_unate");
824 fprintf(f
,"timing (%s) {\n", buf
);
825 relpinname
= lib_getpinname((char*)chx
->DATA
);
827 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
828 if(chain_nonunate
&& ptcellbefig
){
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
);
838 fprintf(f
,"when : \"");
839 cbh_writeabl(f
, abl
, 'L');
842 fprintf(f
,"sdf_cond : \"");
843 cbh_writeabl(f
, abl
, 'L');
848 fprintf(f
,"timing_sense : positive_unate ;\n");
851 fprintf(f
,"timing_type : %s ;\n", bufttype
);
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
)){
857 lib_drivedelaymax(f
, ttvfig
, line
);
859 lib_drivedelaymin(f
, ttvfig
, line
);
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
)
874 chain_list
*ch
, *chx
, *abl
;
882 ttv_getsigname(ttvfig
, bufsig
, ((ttvline_list
*)chain_neg
->DATA
)->ROOT
->ROOT
);
884 for(chx
=chain_negname
; chx
; chx
=chx
->NEXT
){
885 pinname
= lib_get_tg_pinname(bufsig
);
887 sprintf(buf
, "maxd_%s_", pinname
);
889 sprintf(buf
, "mind_%s_", pinname
);
890 relpinname
= lib_get_tg_pinname((char*)chx
->DATA
);
891 strcat(buf
, relpinname
);
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
;
902 if((typel
& TTV_NODE_UP
) == TTV_NODE_UP
)
903 sprintf(bufttype
,"preset");
905 sprintf(bufttype
,"clear");
907 strcat(buf
, bufttype
);
909 strcat(buf
, "_negative_unate");
911 fprintf(f
,"timing (%s) {\n", buf
);
912 relpinname
= lib_getpinname((char*)chx
->DATA
);
914 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
915 if(chain_nonunate
&& ptcellbefig
){
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
);
925 fprintf(f
,"when : \"");
926 cbh_writeabl(f
, abl
, 'L');
929 fprintf(f
,"sdf_cond : \"");
930 cbh_writeabl(f
, abl
, 'L');
935 fprintf(f
,"timing_sense : negative_unate ;\n");
938 fprintf(f
,"timing_type : %s ;\n", bufttype
);
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
)){
944 lib_drivedelaymax(f
, ttvfig
, line
);
946 lib_drivedelaymin(f
, ttvfig
, line
);
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
)
959 int nline
= 0, tristate
= 0, ttype
= 0, tsense
= 0;
961 chain_list
*ch
, *chx
;
966 char buftsense
[1024];
970 ttv_getsigname(ttvfig
, bufsig
, ((ttvline_list
*)chain_tri
->DATA
)->ROOT
->ROOT
);
972 for(chx
=chain_triname
; chx
; chx
=chx
->NEXT
){
973 pinname
= lib_get_tg_pinname(bufsig
);
975 sprintf(buf
, "maxd_%s_", pinname
);
977 sprintf(buf
, "mind_%s_", pinname
);
978 relpinname
= lib_get_tg_pinname((char*)chx
->DATA
);
979 strcat(buf
, relpinname
);
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");
992 }else if(nline
== 0){
993 sprintf(buftsense
, "negative_unate");
996 typel
= line
->ROOT
->TYPE
;
998 }else if((!strcmp(line
->NODE
->ROOT
->NAME
,(char*)chx
->DATA
))
999 &&((line
->TYPE
& TTV_LINE_HZ
)==TTV_LINE_HZ
)){
1003 if(nline
==1 && tristate
){
1004 if((typel
& TTV_NODE_UP
) == TTV_NODE_UP
)
1005 sprintf(bufttype
,"three_state_enable_rise");
1007 sprintf(bufttype
,"three_state_enable_fall");
1010 sprintf(bufttype
,"three_state_enable");
1016 strcat(buf
, bufttype
);
1020 strcat(buf
, buftsense
);
1023 if(tsense
|| ttype
){
1025 fprintf(f
,"timing (%s) {\n", buf
);
1026 relpinname
= lib_getpinname((char*)chx
->DATA
);
1028 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
1033 fprintf(f
,"timing_sense : %s ;\n", buftsense
);
1037 fprintf(f
,"timing_type : %s ;\n", bufttype
);
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
)){
1045 lib_drivedelaymax(f
, ttvfig
, line
);
1047 lib_drivedelaymin(f
, ttvfig
, line
);
1050 if(tsense
|| ttype
){
1055 for(chx
=chain_triname
; chx
; chx
=chx
->NEXT
){
1056 pinname
= lib_get_tg_pinname(bufsig
);
1058 sprintf(buf
, "maxd_%s_", pinname
);
1060 sprintf(buf
, "mind_%s_", pinname
);
1061 relpinname
= lib_get_tg_pinname((char*)chx
->DATA
);
1062 strcat(buf
, relpinname
);
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");
1074 }else if(nline
== 0){
1075 sprintf(buftsense
,"negative_unate");
1078 typel
= line
->ROOT
->TYPE
;
1083 if((typel
& TTV_NODE_UP
) == TTV_NODE_UP
){
1084 sprintf(bufttype
,"three_state_disable_fall");
1086 sprintf(bufttype
,"three_state_disable_rise");
1090 sprintf(bufttype
,"three_state_disable");
1095 strcat(buf
, bufttype
);
1099 strcat(buf
, buftsense
);
1102 if(tsense
|| ttype
){
1104 fprintf(f
,"timing (%s) {\n", buf
);
1105 relpinname
= lib_getpinname((char*)chx
->DATA
);
1107 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
1112 fprintf(f
,"timing_sense : %s ;\n", buftsense
);
1116 fprintf(f
,"timing_type : %s ;\n", bufttype
);
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
)){
1124 lib_drivedelaymax(f
, ttvfig
, line
);
1126 lib_drivedelaymin(f
, ttvfig
, line
);
1129 if(tsense
|| ttype
){
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
)
1142 timing_model
*tmodel
;
1143 chain_list
*chx
, *ch
;
1148 int driveok
, rise
, fall
;
1151 for(ch
=chain
; ch
; ch
=ch
->NEXT
){
1153 ttv_getsigname(ttvfig
, bufsig
, ((ttvline_list
*)ch
->DATA
)->ROOT
->ROOT
);
1158 for(chx
=chain_name
; chx
; chx
=chx
->NEXT
){
1160 for(ch
=chain
; ch
; ch
=ch
->NEXT
){
1161 line
=(ttvline_list
*)ch
->DATA
;
1163 if(!strcmp(line
->NODE
->ROOT
->NAME
,(char*)chx
->DATA
)){
1165 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, line
->MDMAX
);
1166 if(tmodel
->ENERGYTYPE
== STM_ENERGY_TABLE
){
1172 if(chain_nonunate
&& !ptcellbefig
&& (type
== CBH_INVERT
)){
1173 for(ch
=chain_nonunate
; ch
; ch
=ch
->NEXT
){
1174 if(!strcmp(relpinname
,(char*)ch
->DATA
)){
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
);
1188 sprintf(buf
, "energy_nun_%s_", pinname
);
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
);
1202 fprintf(f
,"internal_power (%s) {\n", buf
);
1204 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
1205 if(ptcellbefig
&& abl
){
1207 fprintf(f
,"when : \"");
1208 cbh_writeabl(f
, abl
, 'L');
1209 fprintf(f
,"\" ;\n");
1213 for(ch
=chain
; ch
; ch
=ch
->NEXT
){
1214 line
=(ttvline_list
*)ch
->DATA
;
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
){
1223 if(tmodel
->ENERGYMODEL
.ETABLE
->CST
!= STM_NOVALUE
){
1224 fprintf(f
,"rise_power (scalar) {\n");
1225 lib_drivelutconst(f
, tmodel
->ENERGYMODEL
.ETABLE
->CST
, 'E');
1227 fprintf(f
,"rise_power (energy_%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
1228 lib_drivelut (f
, tmodel
, 'E');
1235 if(tmodel
->ENERGYMODEL
.ETABLE
->CST
!= STM_NOVALUE
){
1236 fprintf(f
,"fall_power (scalar) {\n");
1237 lib_drivelutconst(f
, tmodel
->ENERGYMODEL
.ETABLE
->CST
, 'E');
1239 fprintf(f
,"fall_power (energy_%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
1240 lib_drivelut (f
, tmodel
, 'E');
1254 /****************************************************************************/
1255 /* function lib_drivepower */
1256 /****************************************************************************/
1257 void lib_drivepower (FILE *f
, ttvfig_list
*ttvfig
, ttvsig_list
*ttvsig
, chain_list
*chtsname
, befig_list
*ptcellbefig
)
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
;
1268 ptype_list
*ptyperise
, *ptypefall
;
1270 chain_list
*ch
, *ch2
, *ch3
, *abl
;
1273 if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_TTX
)==TTV_FILE_TTX
)
1275 else if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_DTX
)==TTV_FILE_DTX
)
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
){
1293 for(ch
=chtsname
; ch
; ch
=ch
->NEXT
){
1294 if(!strcmp(line
->NODE
->ROOT
->NAME
,(char*)ch
->DATA
)){
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
)){
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
)){
1320 chain_tri
=addchain(chain_tri
, line
);
1321 chain_triname
=addname(chain_triname
, line
->NODE
->ROOT
->NAME
);
1323 if((line
->NODE
->TYPE
) == (line
->ROOT
->TYPE
)){
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
);
1331 chain_pos
=addchain(chain_pos
, line
);
1332 chain_posname
=addname(chain_posname
, line
->NODE
->ROOT
->NAME
);
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
);
1342 chain_neg
=addchain(chain_neg
, line
);
1343 chain_negname
=addname(chain_negname
, line
->NODE
->ROOT
->NAME
);
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
);
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)){
1387 lib_drivepower_with_sdfcond (f
, ttvfig
, ptcellbefig
, chain_posname
, chain_pos
, CBH_NONINVERT
, chain_nonunate
);
1388 freechain(chain_pos
);
1390 freechain(chain_posname
);
1394 lib_drivepower_with_sdfcond (f
, ttvfig
, ptcellbefig
, chain_negname
, chain_neg
, CBH_INVERT
, chain_nonunate
);
1395 freechain(chain_neg
);
1397 freechain(chain_negname
);
1401 lib_drivepower_with_sdfcond (f
, ttvfig
, ptcellbefig
, chain_triname
, chain_tri
, 0, NULL
);
1402 freechain(chain_tri
);
1404 freechain(chain_triname
);
1407 freechain(chain_nonunate
);
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
);
1419 fprintf(f
,"internal_power (%s) {\n", buf
);
1420 if(ptyperise
&& ptypefall
){
1421 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, (char*)ptyperise
->DATA
);
1423 if(tmodel
->ENERGYMODEL
.ETABLE
->CST
!= STM_NOVALUE
){
1424 fprintf(f
,"rise_power (scalar) {\n");
1425 lib_drivelutconst(f
, tmodel
->ENERGYMODEL
.ETABLE
->CST
, 'E');
1427 fprintf(f
,"rise_power (energy_%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
1428 lib_drivelut (f
, tmodel
, 'E');
1432 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, (char*)ptypefall
->DATA
);
1434 if(tmodel
->ENERGYMODEL
.ETABLE
->CST
!= STM_NOVALUE
){
1435 fprintf(f
,"fall_power (scalar) {\n");
1436 lib_drivelutconst(f
, tmodel
->ENERGYMODEL
.ETABLE
->CST
, 'E');
1438 fprintf(f
,"fall_power (energy_%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
1439 lib_drivelut (f
, tmodel
, 'E');
1445 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, (char*)ptyperise
->DATA
);
1447 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, (char*)ptypefall
->DATA
);
1450 if(tmodel
->ENERGYMODEL
.ETABLE
->CST
!= STM_NOVALUE
){
1451 fprintf(f
,"power (scalar) {\n");
1452 lib_drivelutconst(f
, tmodel
->ENERGYMODEL
.ETABLE
->CST
, 'E');
1454 fprintf(f
,"power (energy_%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
1455 lib_drivelut (f
, tmodel
, 'E');
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
)
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
;
1478 ttvline_list
*line
, *line2
;
1481 char flag_async_direct
= 0;
1482 char LIB_DRIVEDELAY
= 'M';
1485 if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_TTX
)==TTV_FILE_TTX
)
1487 else if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_DTX
)==TTV_FILE_DTX
)
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';
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
)){
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
) ;
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
) ;
1506 for(ev
=0; ev
< 2; ev
++){
1507 inevent
=&ttvsig
->NODE
[ev
];
1509 ptype
= getptype (inevent
->USER
, TTV_NODE_DUALPATH
) ;
1511 ptype
= getptype (inevent
->USER
, TTV_NODE_DUALLINE
) ;
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
);
1518 for(ch
= chain
; ch
; ch
=ch
->NEXT
){
1519 ckevent
=(ttvevent_list
*)ch
->DATA
;
1521 lib_drivesetup_group(f
, ttvfig
, ttvsig
, ckevent
);
1526 for(ev
=0; ev
< 2; ev
++){
1527 inevent
=&ttvsig
->NODE
[ev
];
1529 ptype
= getptype (inevent
->USER
, TTV_NODE_DUALPATH
) ;
1531 ptype
= getptype (inevent
->USER
, TTV_NODE_DUALLINE
) ;
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
);
1537 for(ch
= chain
; ch
; ch
=ch
->NEXT
){
1538 ckevent
=(ttvevent_list
*)ch
->DATA
;
1540 lib_drivehold_group(f
, ttvfig
, ttvsig
, ckevent
);
1544 if((ttvsig
->TYPE
& TTV_SIG_CO
)==TTV_SIG_CO
) {
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')){
1562 for(ch
= chain
; ch
; ch
=ch
->NEXT
){
1563 ckevent
=(ttvevent_list
*)ch
->DATA
;
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;
1573 if(flag_async_direct
) continue;
1574 if((LIB_DRIVEDELAY
== 'M') || (LIB_DRIVEDELAY
== 'B'))
1575 lib_driveaccess_group(f
, ttvfig
, ttvsig
, ckevent
, ptcbhseq
, 'M');
1577 lib_driveaccess_group(f
, ttvfig
, ttvsig
, ckevent
, ptcbhseq
, 'm');
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
)){
1597 for(ch
=chtsname
; ch
; ch
=ch
->NEXT
){
1598 if(!strcmp(line
->NODE
->ROOT
->NAME
,(char*)ch
->DATA
)){
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
)){
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
))
1624 chain_triname
=addname(chain_triname
, line
->NODE
->ROOT
->NAME
);
1626 if((line
->NODE
->TYPE
) == (line
->ROOT
->TYPE
)){
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
);
1634 chain_pos
=addchain(chain_pos
, line
);
1635 chain_posname
=addname(chain_posname
, line
->NODE
->ROOT
->NAME
);
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
);
1645 chain_neg
=addchain(chain_neg
, line
);
1646 chain_negname
=addname(chain_negname
, line
->NODE
->ROOT
->NAME
);
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
);
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')){
1666 for(chain
= chain_pos
; chain
; chain
= chain
->NEXT
)
1667 if(!((ttvline_list
*)chain
->DATA
)->MDMIN
)
1670 lib_drive_pos(f
, ttvfig
, chain_posname
, chain_pos
, 'm', chain_nonunate
, ptcellbefig
);
1672 freechain(chain_pos
);
1674 freechain(chain_posname
);
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')){
1682 for(chain
= chain_neg
; chain
; chain
= chain
->NEXT
)
1683 if(!((ttvline_list
*)chain
->DATA
)->MDMIN
)
1686 lib_drive_neg(f
, ttvfig
, chain_negname
, chain_neg
, 'm', chain_nonunate
, ptcellbefig
);
1688 freechain(chain_neg
);
1690 freechain(chain_negname
);
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')){
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
))
1702 lib_drive_tri(f
, ttvfig
, chain_triname
, chain_tri
, 'm');
1704 freechain(chain_tri
);
1706 freechain(chain_triname
);
1709 freechain(chain_nonunate
);
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
);
1720 /****************************************************************************/
1721 /* function lib_drivesetup_group */
1722 /****************************************************************************/
1723 void lib_drivesetup_group (FILE *f
, ttvfig_list
*ttvfig
, ttvsig_list
*ttvsig
, ttvevent_list
*ckevent
)
1726 ttvline_list
*line
;
1727 char buftiming
[1024];
1729 char bufttype
[1024];
1734 if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_TTX
)==TTV_FILE_TTX
)
1736 else if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_DTX
)==TTV_FILE_DTX
)
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");
1751 sprintf(bufttype
, "setup_rising");
1753 if(getptype (ttvsig
->USER
, TTV_SIG_ASYNCHRON
))
1754 sprintf(bufttype
, "recovery_falling");
1756 sprintf(bufttype
, "setup_falling");
1758 strcat(buftiming
, "_");
1759 strcat(buftiming
, bufttype
);
1762 fprintf(f
,"timing (%s) {\n", buftiming
);
1765 fprintf(f
,"timing_type : %s ;\n", bufttype
);
1767 relpinname
= lib_getpinname(buf
);
1769 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
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
);
1780 /****************************************************************************/
1781 /* function lib_drivehold_group */
1782 /****************************************************************************/
1783 void lib_drivehold_group (FILE *f
, ttvfig_list
*ttvfig
, ttvsig_list
*ttvsig
, ttvevent_list
*ckevent
)
1786 ttvline_list
*line
;
1787 char buftiming
[1024];
1789 char bufttype
[1024];
1794 if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_TTX
)==TTV_FILE_TTX
)
1796 else if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_DTX
)==TTV_FILE_DTX
)
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");
1811 sprintf(bufttype
, "hold_rising");
1813 if(getptype (ttvsig
->USER
, TTV_SIG_ASYNCHRON
))
1814 sprintf(bufttype
, "removal_falling");
1816 sprintf(bufttype
, "hold_falling");
1818 strcat(buftiming
, "_");
1819 strcat(buftiming
, bufttype
);
1822 fprintf(f
,"timing (%s) {\n", buftiming
);
1825 fprintf(f
,"timing_type : %s ;\n", bufttype
);
1827 relpinname
= lib_getpinname(buf
);
1829 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
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
);
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
)
1847 ttvline_list
*line
;
1848 chain_list
*chain
, *ch
;
1851 char buftiming
[1024];
1853 char bufttype
[1024];
1854 char buftsense
[1024];
1859 if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_TTX
)==TTV_FILE_TTX
)
1861 else if ((ttv_getloadedfigtypes(ttvfig
) & TTV_FILE_DTX
)==TTV_FILE_DTX
)
1866 ttv_getsigname(ttvfig
, bufsig
, outsig
);
1867 pinname
= lib_get_tg_pinname(bufsig
);
1869 sprintf(buftiming
, "maxd_%s_", pinname
);
1871 sprintf(buftiming
, "mind_%s_", pinname
);
1873 ttv_getsigname(ttvfig
, buf
, ckevent
->ROOT
);
1874 relpinname
= lib_get_tg_pinname(buf
);
1875 strcat(buftiming
, relpinname
);
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
))
1884 else if(!strcmp(outsig
->NAME
,ptcbhseq
->NEGPIN
))
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
))
1896 else if(!strcmp(outsig
->NAME
,ptcbhseq
->NEGPIN
))
1904 if((ckevent
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
)
1905 sprintf(bufttype
,"rising_edge");
1907 sprintf(bufttype
,"falling_edge");
1908 strcat(buftiming
, "_");
1909 strcat(buftiming
, bufttype
);
1912 fprintf(f
,"timing (%s) {\n", buftiming
);
1914 fprintf(f
,"timing_type : %s ;\n", bufttype
);
1915 relpinname
= lib_getpinname(buf
);
1917 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
1922 for (ev
= 0 ; ev
< 2 ; ev
++){
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
)){
1933 if(!getptype(line
->USER
, LIB_DRIVED_LINE
))
1934 line
->USER
= addptype(line
->USER
, LIB_DRIVED_LINE
, NULL
);
1936 if((line
->ROOT
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
1937 sprintf(bufttype
,"preset");
1939 sprintf(bufttype
,"clear");
1942 if(ckevent
->TYPE
== line
->ROOT
->TYPE
)
1943 sprintf(buftsense
,"positive_unate");
1945 sprintf(buftsense
,"negative_unate");
1946 strcat(buftiming
, "_");
1947 strcat(buftiming
, bufttype
);
1948 strcat(buftiming
, "_");
1949 strcat(buftiming
, buftsense
);
1952 fprintf(f
,"timing (%s) {\n", buftiming
);
1954 fprintf(f
,"timing_type : %s ;\n", bufttype
);
1956 fprintf(f
,"timing_sense : %s ;\n", buftsense
);
1957 relpinname
= lib_getpinname(buf
);
1959 fprintf(f
,"related_pin : \"%s\" ;\n", relpinname
);
1962 lib_drivedelaymax(f
, ttvfig
, line
);
1964 lib_drivedelaymin(f
, ttvfig
, line
);
1978 /****************************************************************************/
1979 /* function lib_get_timing_sense */
1980 /****************************************************************************/
1981 char *lib_get_timing_sense (ttvsig_list
*outsig
, ttvsig_list
*ptsig
)
1984 ttvline_list
*line
;
1988 // a ajouter si utilise un jour: prise en compte ttvfig en dtx
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
))
1997 if((line
->ROOT
->TYPE
& (TTV_NODE_UP
|TTV_NODE_DOWN
)) == (line
->NODE
->TYPE
& (TTV_NODE_UP
|TTV_NODE_DOWN
)))
1999 if((line
->ROOT
->TYPE
& (TTV_NODE_UP
|TTV_NODE_DOWN
)) != (line
->NODE
->TYPE
& (TTV_NODE_UP
|TTV_NODE_DOWN
)))
2003 if((neg
== 1) && (pos
== 1))
2004 return("non_unate") ;
2006 return("negative_unate") ;
2008 return("positive_unate") ;
2014 /****************************************************************************/
2015 /* function lib_drivesetup */
2016 /****************************************************************************/
2017 void lib_drivesetup (FILE *f
, ttvfig_list
*ttvfig
, ttvline_list
*line
)
2020 if((line
->NODE
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
){
2022 lib_driveconstraintmodel(f
, ttvfig
, line
->MDMAX
, 'R');
2024 lib_drive_cst_constraint(f
, line
->VALMAX
/TTV_UNIT
, 'R');
2027 lib_driveconstraintmodel(f
, ttvfig
, line
->MDMAX
, 'F');
2029 lib_drive_cst_constraint(f
, line
->VALMAX
/TTV_UNIT
, 'F');
2034 /****************************************************************************/
2035 /* function lib_drivehold */
2036 /****************************************************************************/
2037 void lib_drivehold (FILE *f
, ttvfig_list
*ttvfig
, ttvline_list
*line
)
2040 if((line
->NODE
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
){
2042 lib_driveconstraintmodel(f
, ttvfig
, line
->MDMAX
, 'R');
2044 lib_drive_cst_constraint(f
, line
->VALMAX
/TTV_UNIT
, 'R');
2047 lib_driveconstraintmodel(f
, ttvfig
, line
->MDMAX
, 'F');
2049 lib_drive_cst_constraint(f
, line
->VALMAX
/TTV_UNIT
, 'F');
2053 /****************************************************************************/
2054 /* function lib_drivedelaymax */
2055 /****************************************************************************/
2056 void lib_drivedelaymax (FILE *f
, ttvfig_list
*ttvfig
, ttvline_list
*line
)
2060 double rmax
, c1max
, c2max
;
2061 locon_list
*locon
=NULL
;
2068 lofig
= ttv_getrcxlofig (ttvfig
);
2071 c1max
= line
->ROOT
->ROOT
->CAPA
/ 1000.0 ;
2074 typemax
= RCX_CAPALOAD
;
2078 locon
= rcx_gethtrcxcon(NULL
,lofig
,line
->ROOT
->ROOT
->NAME
) ;
2080 if((locon
== NULL
) || (locon
->PNODE
== NULL
) ||
2081 ((ptrcx
= getrcx(locon
->SIG
)) == NULL
))
2083 c1max
= line
->ROOT
->ROOT
->CAPA
/ 1000.0 ;
2086 typemax
= RCX_CAPALOAD
;
2090 if( rcx_crosstalkactive( RCX_QUERY
) != RCX_NOCROSSTALK
) {
2091 slope
.F0MAX
= ttv_getslopenode( line
->ROOT
->ROOT
->ROOT
,
2092 line
->ROOT
->ROOT
->ROOT
->INFO
->LEVEL
,
2100 slope
.FCCMAX
= ttv_getslopenode( line
->ROOT
->ROOT
->ROOT
,
2101 line
->ROOT
->ROOT
->ROOT
->INFO
->LEVEL
,
2111 slope
.F0MAX
= -1.0 ;
2112 slope
.FCCMAX
= -1.0 ;
2115 slope
.SENS
= ((line
->ROOT
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
2116 ? TRC_SLOPE_UP
: TRC_SLOPE_DOWN
;
2119 typemax
= rcx_rcnload( lofig
,
2122 &rmax
, &c1max
, &c2max
,
2131 capa
= ((typemax
==RCX_CAPALOAD
) ? c1max
*1000.0 : (c1max
+c2max
)*1000.0);
2133 if((line
->ROOT
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
){
2135 if((line
->TYPE
& TTV_LINE_HZ
)==TTV_LINE_HZ
) trans
= 'F';
2137 lib_drivedelaymodel(f
, ttvfig
, line
->MDMAX
, trans
, capa
);
2139 lib_driveintrinsic(f
, line
->VALMAX
/TTV_UNIT
, trans
);
2141 lib_driveslewmodel(f
, ttvfig
, line
->MFMAX
, trans
, capa
);
2143 lib_driveslew(f
, line
->FMAX
/TTV_UNIT
, trans
);
2146 if((line
->TYPE
& TTV_LINE_HZ
)==TTV_LINE_HZ
) trans
= 'R';
2148 lib_drivedelaymodel(f
, ttvfig
, line
->MDMAX
, trans
, capa
);
2150 lib_driveintrinsic(f
, line
->VALMAX
/TTV_UNIT
, trans
);
2152 lib_driveslewmodel(f
, ttvfig
, line
->MFMAX
, trans
, capa
);
2154 lib_driveslew(f
, line
->FMAX
/TTV_UNIT
, trans
);
2158 /****************************************************************************/
2159 /* function lib_drivedelaymin */
2160 /****************************************************************************/
2161 void lib_drivedelaymin (FILE *f
, ttvfig_list
*ttvfig
, ttvline_list
*line
)
2165 double rmin
, c1min
, c2min
;
2166 locon_list
*locon
=NULL
;
2173 lofig
= ttv_getrcxlofig (ttvfig
);
2176 c1min
= line
->ROOT
->ROOT
->CAPA
/ 1000.0 ;
2179 typemin
= RCX_CAPALOAD
;
2183 locon
= rcx_gethtrcxcon(NULL
,lofig
,line
->ROOT
->ROOT
->NAME
) ;
2185 if((locon
== NULL
) || (locon
->PNODE
== NULL
) ||
2186 ((ptrcx
= getrcx(locon
->SIG
)) == NULL
))
2188 c1min
= line
->ROOT
->ROOT
->CAPA
/ 1000.0 ;
2191 typemin
= RCX_CAPALOAD
;
2195 if( rcx_crosstalkactive( RCX_QUERY
) != RCX_NOCROSSTALK
) {
2196 slope
.F0MAX
= ttv_getslopenode( line
->ROOT
->ROOT
->ROOT
,
2197 line
->ROOT
->ROOT
->ROOT
->INFO
->LEVEL
,
2205 slope
.FCCMAX
= ttv_getslopenode( line
->ROOT
->ROOT
->ROOT
,
2206 line
->ROOT
->ROOT
->ROOT
->INFO
->LEVEL
,
2216 slope
.F0MAX
= -1.0 ;
2217 slope
.FCCMAX
= -1.0 ;
2220 slope
.SENS
= ((line
->ROOT
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
2221 ? TRC_SLOPE_UP
: TRC_SLOPE_DOWN
;
2224 typemin
= rcx_rcnload( lofig
,
2227 &rmin
, &c1min
, &c2min
,
2236 capa
= ((typemin
==RCX_CAPALOAD
) ? c1min
*1000.0 : (c1min
+c2min
)*1000.0);
2238 if((line
->ROOT
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
){
2240 if((line
->TYPE
& TTV_LINE_HZ
)==TTV_LINE_HZ
) trans
= 'F';
2242 lib_drivedelaymodel(f
, ttvfig
, line
->MDMIN
, trans
, capa
);
2244 lib_driveintrinsic(f
, line
->VALMIN
/TTV_UNIT
, trans
);
2246 lib_driveslewmodel(f
, ttvfig
, line
->MFMIN
, trans
, capa
);
2248 lib_driveslew(f
, line
->FMIN
/TTV_UNIT
, trans
);
2251 if((line
->TYPE
& TTV_LINE_HZ
)==TTV_LINE_HZ
) trans
= 'R';
2253 lib_drivedelaymodel(f
, ttvfig
, line
->MDMIN
, trans
, capa
);
2255 lib_driveintrinsic(f
, line
->VALMIN
/TTV_UNIT
, trans
);
2257 lib_driveslewmodel(f
, ttvfig
, line
->MFMIN
, trans
, capa
);
2259 lib_driveslew(f
, line
->FMIN
/TTV_UNIT
, trans
);
2263 /****************************************************************************/
2264 /* function lib_driveheader */
2265 /****************************************************************************/
2266 void lib_driveheader (FILE *f
, char *libname
, ttvinfo_list
*ttvinfo
)
2278 double temp
, sutr
, sltr
, sutf
, sltf
, dtr
, dtf
;
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 ;
2289 date
= ctime (&counter
) ;
2290 date
[strlen (date
) - 1] = '\0' ;
2292 dmname
="table_lookup";
2294 tunit
=V_STR_TAB
[__TMA_TUNIT
].VALUE
;
2295 cunit
=V_STR_TAB
[__TMA_CUNIT
].VALUE
;
2296 punit
=V_STR_TAB
[__TMA_PUNIT
].VALUE
;
2299 slewderate
= V_FLOAT_TAB
[__LIB_SLEW_DERATE
].VALUE
;
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
;
2311 voltage
= ttvinfo
->VDD
;
2312 temp
= ttvinfo
->TEMP
;
2313 sutr
= sutf
= ttvinfo
->STHHIGH
;
2314 sltr
= sltf
= ttvinfo
->STHLOW
;
2315 dtr
= dtf
= ttvinfo
->DTH
;
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
;
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
);
2336 sprintf(buffer
,"liberty data flow `%s`\n",libname
);
2337 avt_printExecInfoFlourish(f
, "/*", buffer
, "*/");
2339 fprintf(f
,"/*****************************************************************\n");
2341 fprintf(f
,"* LIBRARY : %s\n", libname
);
2343 fprintf(f
,"* Comment : This library was created by\n");
2344 fprintf(f
,"* AVERTEC with TMA\n");
2346 fprintf(f
,"* date : %s\n", date
);
2348 fprintf(f
,"*****************************************************************/\n");
2353 fprintf(f
,"library (%s) {\n",libname
);
2356 fprintf(f
,"technology (%s) ;\n",tecname
);
2358 fprintf(f
,"date : \"%s\" ;\n",date
);
2359 // if(STM_TEMPLATES_CHAIN){
2361 fprintf(f
,"delay_model : %s ;\n",dmname
);
2362 if(V_BOOL_TAB
[__TUT_CALC_DERATE
].VALUE
) {
2364 fprintf(f
,"k_process_rise_propagation : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2366 fprintf(f
,"k_temp_rise_propagation : %.4f ;\n",
2367 rise_temp_derating
) ;
2369 fprintf(f
,"k_volt_rise_propagation : %.4f ;\n",
2370 rise_volt_derating
) ;
2372 fprintf(f
,"k_process_fall_propagation : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2374 fprintf(f
,"k_temp_fall_propagation : %.4f ;\n",
2375 fall_temp_derating
) ;
2377 fprintf(f
,"k_volt_fall_propagation : %.4f ;\n",
2378 fall_volt_derating
) ;
2380 fprintf(f
,"k_process_rise_transition : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2382 fprintf(f
,"k_temp_rise_transition : %.4f ;\n",
2383 rise_temp_derating
) ;
2385 fprintf(f
,"k_volt_rise_transition : %.4f ;\n",
2386 rise_volt_derating
) ;
2388 fprintf(f
,"k_process_fall_transition : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2390 fprintf(f
,"k_temp_fall_transition : %.4f ;\n",
2391 fall_temp_derating
) ;
2393 fprintf(f
,"k_volt_fall_transition : %.4f ;\n",
2394 fall_volt_derating
) ;
2397 fprintf(f
,"k_process_hold_rise : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2399 fprintf(f
,"k_process_hold_fall : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2401 fprintf(f
,"k_temp_hold_rise : %.4f ;\n",
2402 rise_temp_derating
) ;
2404 fprintf(f
,"k_temp_hold_fall : %.4f ;\n",
2405 fall_temp_derating
) ;
2407 fprintf(f
,"k_volt_hold_rise : %.4f ;\n",
2408 rise_volt_derating
) ;
2410 fprintf(f
,"k_volt_hold_fall : %.4f ;\n",
2411 fall_volt_derating
) ;
2413 fprintf(f
,"k_process_setup_rise : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2415 fprintf(f
,"k_process_setup_fall : %.4f ;\n", LIB_DERATE_PROCESS
) ;
2417 fprintf(f
,"k_temp_setup_rise : %.4f ;\n",
2418 rise_temp_derating
) ;
2420 fprintf(f
,"k_temp_setup_fall : %.4f ;\n",
2421 fall_temp_derating
) ;
2423 fprintf(f
,"k_volt_setup_rise : %.4f ;\n",
2424 rise_volt_derating
) ;
2426 fprintf(f
,"k_volt_setup_fall : %.4f ;\n",
2427 fall_volt_derating
) ;
2431 fprintf(f,"default_intrinsic_rise : 1.0 ;\n");
2433 fprintf(f,"default_intrinsic_fall : 1.0 ;\n");
2435 fprintf(f,"default_slope_rise : 0.0 ;\n");
2437 fprintf(f,"default_slope_fall : 0.0 ;\n");
2439 fprintf(f,"default_inout_pin_rise_res : 0.0 ;\n");
2441 fprintf(f,"default_inout_pin_fall_res : 0.0 ;\n");
2443 fprintf(f,"default_output_pin_rise_res : 0.0 ;\n");
2445 fprintf(f,"default_output_pin_fall_res : 0.0 ;\n");
2447 fprintf(f,"default_rise_pin_resistance : 0.0 ;\n");
2449 fprintf(f,"default_fall_pin_resistance : 0.0 ;\n");
2451 fprintf(f,"default_rise_delay_intercept : 0.0 ;\n");
2453 fprintf(f,"default_fall_delay_intercept : 0.0 ;\n");
2454 if(V_BOOL_TAB[__TUT_CALC_DERATE].VALUE) {
2456 fprintf(f,"k_process_intrinsic_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2458 fprintf(f,"k_process_intrinsic_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2460 fprintf(f,"k_temp_intrinsic_fall : %.4f ;\n",
2461 fall_temp_derating) ;
2463 fprintf(f,"k_temp_intrinsic_rise : %.4f ;\n",
2464 rise_temp_derating) ;
2466 fprintf(f,"k_volt_intrinsic_fall : %.4f ;\n",
2467 fall_volt_derating) ;
2469 fprintf(f,"k_volt_intrinsic_rise : %.4f ;\n",
2470 rise_volt_derating) ;
2472 fprintf(f,"k_process_slope_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2474 fprintf(f,"k_process_slope_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2476 fprintf(f,"k_temp_slope_fall : %.4f ;\n",
2477 fall_temp_derating) ;
2479 fprintf(f,"k_temp_slope_rise : %.4f ;\n",
2480 rise_temp_derating) ;
2482 fprintf(f,"k_volt_slope_fall : %.4f ;\n",
2483 fall_volt_derating) ;
2485 fprintf(f,"k_volt_slope_rise : %.4f ;\n",
2486 rise_volt_derating) ;
2488 fprintf(f,"k_process_hold_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2490 fprintf(f,"k_process_hold_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2492 fprintf(f,"k_temp_hold_rise : %.4f ;\n",
2493 rise_temp_derating) ;
2495 fprintf(f,"k_temp_hold_fall : %.4f ;\n",
2496 fall_temp_derating) ;
2498 fprintf(f,"k_volt_hold_rise : %.4f ;\n",
2499 rise_volt_derating) ;
2501 fprintf(f,"k_volt_hold_fall : %.4f ;\n",
2502 fall_volt_derating) ;
2504 fprintf(f,"k_process_setup_rise : %.4f ;\n", LIB_DERATE_PROCESS) ;
2506 fprintf(f,"k_process_setup_fall : %.4f ;\n", LIB_DERATE_PROCESS) ;
2508 fprintf(f,"k_temp_setup_rise : %.4f ;\n",
2509 rise_temp_derating) ;
2511 fprintf(f,"k_temp_setup_fall : %.4f ;\n",
2512 fall_temp_derating) ;
2514 fprintf(f,"k_volt_setup_rise : %.4f ;\n",
2515 rise_volt_derating) ;
2517 fprintf(f,"k_volt_setup_fall : %.4f ;\n",
2518 fall_volt_derating) ;
2524 fprintf(f
,"nom_voltage : %.2f ;\n",voltage
);
2526 fprintf(f
,"nom_temperature : %.1f ;\n",temp
);
2528 fprintf(f
,"nom_process : %.1f ;\n",LIB_NOM_PROCESS
);
2530 fprintf(f
,"slew_derate_from_library : %.1f ;\n",slewderate
);
2531 if(!strcasecmp(cunit
,"ff")){
2533 fprintf(f
,"default_fanout_load : 1000.0 ;\n");
2534 }else if(!strcasecmp(cunit
,"pf")){
2536 fprintf(f
,"default_fanout_load : 1.0 ;\n");
2538 if(!strcasecmp(cunit
,"ff")){
2540 fprintf(f
,"default_inout_pin_cap : 1000.0 ;\n");
2541 }else if(!strcasecmp(cunit
,"pf")){
2543 fprintf(f
,"default_inout_pin_cap : 1.0 ;\n");
2545 if(!strcasecmp(cunit
,"ff")){
2547 fprintf(f
,"default_input_pin_cap : 1000.0 ;\n");
2548 }else if(!strcasecmp(cunit
,"pf")){
2550 fprintf(f
,"default_input_pin_cap : 1.0 ;\n");
2553 fprintf(f
,"default_output_pin_cap : 0.0 ;\n");
2555 fprintf(f
,"voltage_unit : \"%s\" ;\n",vunit
);
2557 fprintf(f
,"time_unit : \"1%s\" ;\n",tunit
);
2559 fprintf(f
,"capacitive_load_unit (1,%s) ;\n",cunit
);
2561 fprintf(f
,"pulling_resistance_unit : \"%s\" ;\n",runit
);
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)){
2566 fprintf(f
,"leakage_power_unit : \"%s\" ;\n", punit
);
2568 fprintf(f
,"default_cell_leakage_power : 0.0 ;\n");
2577 fprintf(f
,"input_threshold_pct_rise : %.1f ;\n", dtr
*100);
2579 fprintf(f
,"input_threshold_pct_fall : %.1f ;\n", dtf
*100);
2581 fprintf(f
,"output_threshold_pct_rise : %.1f ;\n", dtr
*100);
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");
2599 fprintf(f
,"slew_lower_threshold_pct_fall : %.1f ;\n", sltf
*100);
2601 fprintf(f
,"slew_upper_threshold_pct_fall : %.1f ;\n", sutf
*100);
2603 fprintf(f
,"slew_lower_threshold_pct_rise : %.1f ;\n", sltr
*100);
2605 fprintf(f
,"slew_upper_threshold_pct_rise : %.1f ;\n", sutr
*100);
2610 /****************************************************************************/
2611 /* function lib_scm2thr */
2612 /****************************************************************************/
2613 double lib_scm2thr(double fscm
)
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));*/
2621 /****************************************************************************/
2622 /* function lib_driveindex */
2623 /****************************************************************************/
2624 void lib_driveindex (FILE *f
, timing_ttable
*template, int 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
));
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);
2641 if((template->NX
- x
) > 1){
2645 fprintf(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
));
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);
2661 if((template->NY
- y
) > 1){
2665 fprintf(f
,"\");\n");
2670 /****************************************************************************/
2671 /* function lib_drivelut */
2672 /****************************************************************************/
2673 void lib_drivelut (FILE *f
, timing_model
*tmodel
, char type
)
2682 nx
=tmodel
->ENERGYMODEL
.ETABLE
->NX
;
2683 ny
=tmodel
->ENERGYMODEL
.ETABLE
->NY
;
2684 values1d
=tmodel
->ENERGYMODEL
.ETABLE
->SET1D
;
2685 values2d
=tmodel
->ENERGYMODEL
.ETABLE
->SET2D
;
2687 nx
=tmodel
->UMODEL
.TABLE
->NX
;
2688 ny
=tmodel
->UMODEL
.TABLE
->NY
;
2689 values1d
=tmodel
->UMODEL
.TABLE
->SET1D
;
2690 values2d
=tmodel
->UMODEL
.TABLE
->SET2D
;
2693 if (V_BOOL_TAB
[__LIB_DRIVE_TABLE_INDEX
].VALUE
)
2694 lib_driveindex(f
, tmodel
->UMODEL
.TABLE
->TEMPLATE
, 20);
2697 fprintf(f
,"values (\"");
2698 for(x
=0 ; x
< nx
; x
++){
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
]));
2704 fprintf(f
,"%s", ppower(buftunit
, values1d
[x
]));
2709 fprintf(f
,"\");\n");
2712 fprintf(f
,"values (\"");
2713 for(x
=0 ; x
< nx
; x
++){
2714 for(y
=0 ; y
< ny
; y
++){
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
]));
2720 fprintf(f
,"%s", ppower(buftunit
, values2d
[x
][y
]));
2723 }else if((nx
-x
) > 1){
2724 fprintf(f
,"\", \\\n");
2729 fprintf(f
,"\");\n");
2735 /****************************************************************************/
2736 /* function lib_drivelutconst */
2737 /****************************************************************************/
2738 void lib_drivelutconst (FILE *f
, float value
, char type
)
2745 fprintf(f
,"values (\"%s\");\n", ppower(buftunit
, value
));
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));
2754 }else if((2-x) > 1){
2755 fprintf(f,"\", \\\n");
2760 fprintf(f,"\");\n");
2765 int lib_drive_rail_connection(FILE *f
, ttvfig_list
*ttvfig
)
2768 ttvsig_list
*ttvsig
;
2769 float low
=-1.0, high
=-1.0, alim
, nom_voltage
;
2773 chain_list
*cl
=NULL
,*chain
;
2776 nom_voltage
= ttvfig
->INFO
->VDD
;
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)){
2785 if(!mbk_cmpdouble(nom_voltage
, alim
, 1e6
)){
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
)){
2798 if(!mbk_cmpdouble(*(float*)&ptype
->DATA
, alim
, 1e6
)){
2801 // fprintf(f, "rail_connection (PV0, VDD0) ;\n");
2806 sprintf (buf
, "PV%d", i
);
2807 name
= namealloc(buf
);
2809 // fprintf(f, "rail_connection (%s, %s) ;\n", name, (char*)ptype->TYPE);
2816 if(cl
) freechain(cl
);
2821 void lib_drive_power_supply_group(FILE *f
, chain_list
*figlist
, ttvinfo_list
*ttvinfo
)
2824 chain_list
*ttv
,*cl
,*chain
;
2825 ttvfig_list
*ttvfig
;
2826 ttvsig_list
*ttvsig
;
2827 float low
, high
, alim
, nom_voltage
;
2833 nom_voltage
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
2835 nom_voltage
= ttvinfo
->VDD
;
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
)){
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;
2852 sprintf (buf
, "VDD%d", i
);
2853 name
= namealloc(buf
);
2854 libpowerptype
= addptype(libpowerptype
, (long)name
, NULL
);
2855 *(float*)&libpowerptype
->DATA
= alim
;
2860 if(cl
) freechain(cl
);
2863 libpowerptype
= (ptype_list
*)reverse((chain_list
*)libpowerptype
);
2865 fprintf(f
, "power_supply () {\n");
2867 fprintf(f
, "default_power_rail : VDD0 ;\n");
2868 for(ptype
= libpowerptype
; ptype
; ptype
= ptype
->NEXT
){
2870 fprintf(f
, "power_rail (%s, %.2f) ;\n", (char*)ptype
->TYPE
, *(float*)&ptype
->DATA
);
2877 /****************************************************************************/
2878 /* function lib_drivebustype */
2879 /****************************************************************************/
2880 void lib_drivebustype (FILE *f
, chain_list
*figlist
)
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
;
2889 typedef struct msblsb
{
2896 for(ttv
= figlist
; ttv
; ttv
= ttv
->NEXT
){
2897 ttvfig
=(ttvfig_list
*)ttv
->DATA
;
2899 for (n
=0; n
< ttvfig
->NBCONSIG
; n
++){
2900 ttvsig
=ttvfig
->CONSIG
[n
];
2902 devectname
= ttv_devect(ttvsig
->NAME
);
2904 if(strcmp(busname
,vectorradical(devectname
))){
2907 if((ttvsig
->NAME
!= devectname
) && (!flagbus
)){
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
))
2917 previousname
= vectorradical(devectname
);
2918 msb
= vectorindex(devectname
);
2921 vect
= (msblsb
*)mbkalloc (sizeof (struct msblsb
));
2924 buschain
= addchain(buschain
, vect
);
2926 for(chain
= buschain
; chain
; chain
= chain
->NEXT
){
2927 if((((msblsb
*)chain
->DATA
)->MSB
== msb
) && (((msblsb
*)chain
->DATA
)->LSB
== lsb
))
2931 vect
= (msblsb
*)mbkalloc (sizeof (struct msblsb
));
2934 buschain
= addchain(buschain
, vect
);
2938 ttvsig
= ttvfig
->CONSIG
[n
];
2940 if((n
+ 1) == ttvfig
->NBCONSIG
){
2949 if(LIB_BUS_DELIM
[1] != '\0'){
2951 fprintf(f
, "bus_naming_style : \"%%s%c%%d%c\" ;\n", LIB_BUS_DELIM
[0], LIB_BUS_DELIM
[1]);
2955 fprintf(f
, "bus_naming_style : \"%%s%c%%d\" ;\n", LIB_BUS_DELIM
[0]);
2958 for(chain
= buschain
; chain
; chain
= chain
->NEXT
){
2959 msb
= ((msblsb
*)chain
->DATA
)->MSB
;
2960 lsb
= ((msblsb
*)chain
->DATA
)->LSB
;
2962 fprintf(f
, "type (bus_%d_%d) {\n", msb
, lsb
);
2964 fprintf(f
, "base_type : array;\n");
2966 fprintf(f
, "data_type : bit;\n");
2968 width
= msb
- lsb
+ 1;
2970 width
= lsb
- msb
+ 1;
2972 fprintf(f
, "bit_width : %d;\n", width
);
2974 fprintf(f
, "bit_from : %d;\n", msb
);
2976 fprintf(f
, "bit_to : %d;\n", lsb
);
2979 fprintf(f
, "downto : true;\n");
2983 fprintf(f
, "downto : false;\n");
2988 mbkfree(chain
->DATA
);
2990 freechain(buschain
);
2995 /****************************************************************************/
2996 /* function lib_drivetemplate */
2997 /****************************************************************************/
2998 void lib_drivetemplate (FILE *f
)
3000 chain_list
*tempchain
;
3002 timing_ttable
*template;
3005 for(tempchain
=STM_TEMPLATES_CHAIN
;tempchain
;tempchain
=tempchain
->NEXT
){
3006 template=(timing_ttable
*)(tempchain
->DATA
);
3008 fprintf(f
,"lu_table_template (%s) {\n",template->NAME
);
3010 if(template->XTYPE
==STM_INPUT_SLEW
&& template->YTYPE
==STM_CLOCK_SLEW
){
3011 var1
="constrained_pin_transition";
3012 var2
="related_pin_transition";
3014 else if(template->XTYPE
==STM_CLOCK_SLEW
&& template->YTYPE
==STM_INPUT_SLEW
){
3015 var2
="constrained_pin_transition";
3016 var1
="related_pin_transition";
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";
3026 var1
="input_net_transition";
3028 if(template->YTYPE
==STM_LOAD
)
3029 var2
="total_output_net_capacitance";
3032 fprintf(f
,"variable_1 : %s;\n",var1
);
3035 fprintf(f
,"variable_2 : %s;\n",var2
);
3037 lib_driveindex (f
, template, 8);
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
))
3051 fprintf(f
,"power_lut_template (energy_%s) {\n",template->NAME
);
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";
3061 fprintf(f
,"variable_1 : %s;\n",var1
);
3064 fprintf(f
,"variable_2 : %s;\n",var2
);
3066 lib_driveindex (f
, template, 8);
3073 fprintf(f,"lu_table_template (%s) {\n", TEMP_CONST_NAME);
3075 fprintf(f,"variable_1 : input_net_transition;\n");
3077 fprintf(f,"variable_2 : total_output_net_capacitance;\n");
3079 fprintf(f,"index_1 (\"1.0, 2.0\");\n");
3081 fprintf(f,"index_2 (\"1.0, 2.0\");\n");
3085 fprintf(f,"lu_table_template (%s) {\n", TEMP_SETHOL_CONST_NAME);
3087 fprintf(f,"variable_1 : constrained_pin_transition;\n");
3089 fprintf(f,"variable_2 : related_pin_transition;\n");
3091 fprintf(f,"index_1 (\"1.0, 2.0\");\n");
3093 fprintf(f,"index_2 (\"1.0, 2.0\");\n");
3100 /****************************************************************************/
3101 /* function lib_driveconstraintmodel */
3102 /****************************************************************************/
3103 void lib_driveconstraintmodel (FILE *f
, ttvfig_list
*ttvfig
, char* name
, char type
)
3105 timing_model
*tmodel
;
3108 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, name
);
3109 constante
=tmodel
->UMODEL
.TABLE
->CST
;
3111 if(constante
!=STM_NOVALUE
){
3112 lib_drive_cst_constraint(f
, constante
, type
);
3116 fprintf(f
,"rise_constraint (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3118 fprintf(f
,"fall_constraint (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3120 lib_drivelut (f
, tmodel
, 'D');
3126 /****************************************************************************/
3127 /* function lib_drivedelaymodel */
3128 /****************************************************************************/
3129 void lib_drivedelaymodel (FILE *f
, ttvfig_list
*ttvfig
, char* name
, char type
, float capa
)
3131 timing_model
*tmodel
;
3134 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, name
);
3135 constante
=tmodel
->UMODEL
.TABLE
->CST
;
3137 if(constante
!=STM_NOVALUE
){
3138 lib_driveintrinsic(f
, constante
, type
);
3142 fprintf(f
,"cell_rise (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3144 fprintf(f
,"cell_fall (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3145 if (getptype(ttvfig
->USER
, TTV_FIG_CAPAOUT_HANDLED
)==NULL
)
3147 if(V_BOOL_TAB
[__TMA_DRIVECAPAOUT
].VALUE
== 0 && !V_BOOL_TAB
[__TMA_CHARAC_PRECISION
].VALUE
)
3148 stm_mod_shift(tmodel
, capa
);
3150 lib_drivelut (f
, tmodel
, 'D');
3156 /****************************************************************************/
3157 /* function lib_driveslewmodel */
3158 /****************************************************************************/
3159 void lib_driveslewmodel (FILE *f
, ttvfig_list
*ttvfig
, char* name
, char type
, float capa
)
3161 timing_model
*tmodel
;
3164 tmodel
=stm_getmodel(ttvfig
->INFO
->FIGNAME
, name
);
3165 constante
=tmodel
->UMODEL
.TABLE
->CST
;
3168 if(constante
!=STM_NOVALUE
){
3169 lib_driveslew(f
, constante
, type
);
3173 fprintf(f
,"rise_transition (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3175 fprintf(f
,"fall_transition (%s) {\n",tmodel
->UMODEL
.TABLE
->TEMPLATE
->NAME
);
3176 if (getptype(ttvfig
->USER
, TTV_FIG_CAPAOUT_HANDLED
)==NULL
)
3178 if(V_BOOL_TAB
[__TMA_DRIVECAPAOUT
].VALUE
== 0 && !V_BOOL_TAB
[__TMA_CHARAC_PRECISION
].VALUE
)
3179 stm_mod_shift(tmodel
, capa
);
3181 lib_drivelut (f
, tmodel
, 'S');
3187 /****************************************************************************/
3188 /* function lib_drive_cst_constraint */
3189 /****************************************************************************/
3190 void lib_drive_cst_constraint(FILE *f
, float value
, char type
)
3193 // if(STM_TEMPLATES_CHAIN){
3195 fprintf(f
,"rise_constraint (scalar) {\n");
3197 fprintf(f
,"fall_constraint (scalar) {\n");
3198 lib_drivelutconst (f
, value
, 'D');
3204 fprintf(f,"intrinsic_rise : %s ;\n", pfloat(buftunit,value));
3206 fprintf(f,"intrinsic_fall : %s ;\n", pfloat(buftunit,value));
3213 /****************************************************************************/
3214 /* function lib_driveintrinsic */
3215 /****************************************************************************/
3216 void lib_driveintrinsic (FILE *f
, float value
, char type
)
3219 // if(STM_TEMPLATES_CHAIN){
3221 fprintf(f
,"cell_rise (scalar) {\n");
3223 fprintf(f
,"cell_fall (scalar) {\n");
3224 lib_drivelutconst (f
, value
, 'D');
3230 fprintf(f,"intrinsic_rise : %s ;\n", pfloat(buftunit,value));
3232 fprintf(f,"intrinsic_fall : %s ;\n", pfloat(buftunit,value));
3237 /****************************************************************************/
3238 /* function lib_driveslew */
3239 /****************************************************************************/
3240 void lib_driveslew (FILE *f
, float value
, char type
)
3243 // if(STM_TEMPLATES_CHAIN){
3245 fprintf(f
,"rise_transition (scalar) {\n");
3247 fprintf(f
,"fall_transition (scalar) {\n");
3248 lib_drivelutconst (f
, lib_scm2thr(value
)/V_FLOAT_TAB
[__LIB_SLEW_DERATE
].VALUE
, 'S');
3254 fprintf(f,"slope_rise : %s ;\n", pfloat(buftunit,lib_scm2thr(value)/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
3256 fprintf(f,"slope_fall : %s ;\n", pfloat(buftunit,lib_scm2thr(value)/V_FLOAT_TAB[__LIB_SLEW_DERATE].VALUE));
3262 /****************************************************************************/
3263 /* function space */
3264 /****************************************************************************/
3265 void space (FILE *f
, int nb
)
3270 for (i
=0 ; i
< nb
;i
++){
3275 /****************************************************************************/
3277 /****************************************************************************/
3283 /****************************************************************************/
3285 /****************************************************************************/
3286 void saut (FILE *f
, int nb
)
3290 for (i
=0 ; i
< nb
;i
++){
3295 /****************************************************************************/
3296 /* function addevent */
3297 /****************************************************************************/
3298 chain_list
*addevent (chain_list
*chain
, ttvevent_list
*event
)
3302 for(ch
=chain
; ch
; ch
=ch
->NEXT
){
3306 return(addchain(chain
, event
));
3308 /****************************************************************************/
3309 /* function addname */
3310 /****************************************************************************/
3311 chain_list
*addname (chain_list
*chain
, char *name
)
3315 for(ch
=chain
; ch
; ch
=ch
->NEXT
){
3319 return(addchain(chain
, name
));
3321 /****************************************************************************/
3322 /* function pfloat */
3323 /****************************************************************************/
3324 char *pfloat (char *buf
, float time
)
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) ;
3336 /****************************************************************************/
3337 /* function ppower */
3338 /****************************************************************************/
3339 char *ppower (char *buf
, float power
)
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
) ;
3349 /****************************************************************************/
3350 /* function lib_driveopcond : operating conditions */
3351 /****************************************************************************/
3352 void lib_driveopcond (FILE *f
, char *opcondname
, double process
, double temp
,
3356 fprintf(f
,"operating_conditions(%s) {\n", opcondname
) ;
3358 fprintf(f
,"process : %.1f ;\n", process
) ;
3360 fprintf(f
,"temperature : %.1f ;\n", temp
) ;
3362 fprintf(f
,"voltage : %.2f ;\n", volt
) ;
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
)
3373 double derate_tension
= 0.0 ;
3374 double rapport_Ids
= 1.0 ;
3376 switch(transition
) {
3377 case LIB_RISING
: rapport_Ids
= mcc_calcRapIdsVolt(MCC_TECHFILE
,
3379 MCC_TYPICAL
, MCC_TECSIZE
*1.0e-6,
3380 12.0*MCC_TECSIZE
*1.0e-6, MCC_TEMP
,
3383 case LIB_FALLING
: rapport_Ids
= mcc_calcRapIdsVolt(MCC_TECHFILE
,
3385 MCC_TYPICAL
, MCC_TECSIZE
*1.0e-6,
3386 6.0*MCC_TECSIZE
*1.0e-6, MCC_TEMP
,
3391 derate_tension
= 1.0/(rapport_Ids
-1.0)-1.0/(V1
-V0
) ;
3393 return(derate_tension
) ;
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
)
3402 double derate_temp
= 0.0 ;
3403 double rapport_Ids
= 1.0 ;
3405 switch(transition
) {
3406 case LIB_RISING
: rapport_Ids
= mcc_calcRapIdsTemp(MCC_TECHFILE
,
3408 MCC_TYPICAL
, MCC_TECSIZE
*1.0e-6,
3409 12.0*MCC_TECSIZE
*1.0e-6, MCC_VDDmax
,
3411 derate_temp
= (rapport_Ids
-1.0)/(T1
-T0
) ;
3413 case LIB_FALLING
: rapport_Ids
= mcc_calcRapIdsTemp(MCC_TECHFILE
,
3415 MCC_TYPICAL
, MCC_TECSIZE
*1.0e-6,
3416 6.0*MCC_TECSIZE
*1.0e-6, MCC_VDDmax
,
3418 derate_temp
= (1.0/rapport_Ids
-1.0)/(T1
-T0
) ;
3422 return(derate_temp
) ;
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
3436 chain_list
*chaintv
, *chainbe
;
3441 for( chaintv
= figlistx
, chainbe
= befiglistx
;
3443 chaintv
= chaintv
->NEXT
,
3444 chainbe
= ( chainbe
? chainbe
->NEXT
: NULL
)
3447 if( chaintv
->DATA
) {
3448 *figlist
= addchain( *figlist
, chaintv
->DATA
);
3450 *befiglist
= addchain( *befiglist
, chainbe
->DATA
);
3454 *figlist
= reverse( *figlist
);
3455 *befiglist
= reverse( *befiglist
);