14 #define API_USE_REAL_TYPES
15 #include "api_communication.h"
17 #include "ttv_API_LOCAL.h"
20 #define TTV_DUP_LOFIG_PTYPE 0x23450001
21 #define TTV_DONE_PTYPE 0x23450002
22 #define TTV_TEMP_PTYPE 0x0fab007
24 #define TTV_mark_OUT 2
27 #define IFGNS(a) if (GENIUS_GLOBAL_LOFIG!=NULL) { a }
29 static int CALLED_TTV_FUNCTION
;
30 static lofig_list
*current_dup_lofig
;
32 static ttvfig_list
*current_ttvfig
;
33 static lofig_list
*TTV_BASE_LOFIG
, editmodelofig
;
34 static chain_list
*ALL_ADDED_NODES
;
35 static loins_list
*loins_removed
;
36 static losig_list
*losig_removed
;
37 static chain_list
*ALL_MY_TTV
=NULL
;
38 static char *TTV_FUNCTIONS_FILE
;
39 static double TTVSLOPE
=200e-12, TTVCAPA
=0;
40 static chain_list
*ALL_LINES
=NULL
;
41 static int TTVFLAGS
=0;
42 static char *TTV_FORCED_NAME
=NULL
;
43 static float ttv_low
=-1, ttv_high
=-1;
45 #define TTV_INSTANCE_MODE 1
46 #define TTV_DRIVE_DTX 2
48 static mbk_options_pack_struct ttv_opack
[]=
50 {"ttvUseInstanceMode", TTV_INSTANCE_MODE
},
51 {"ttvDriveDTX", TTV_DRIVE_DTX
}
55 void ttv_SetOutputSwing(double vss
, double vdd
)
61 void ttv_API_AtLoad_Initialize() // commentaire pour desactiver l'ajout de token
63 TTVFLAGS
=mbk_ReadFlags(__API_FLAGS
, ttv_opack
, sizeof(ttv_opack
)/sizeof(*ttv_opack
), 0, 0);
66 void ttv_API_Action_Initialize() // commentaire pour desactiver l'ajout de token
70 CALLED_TTV_FUNCTION
=0;
71 current_dup_lofig
=NULL
;
73 TTV_FUNCTIONS_FILE
=NULL
;
76 void ttv_SetBaseNetlist(lofig_list
*lf
)
82 if (!TTV_FUNCTIONS_FILE
&& lf
!=NULL
)
84 sprintf (buf
, "%s_functions.c", lf
->NAME
);
85 TTV_FUNCTIONS_FILE
= namealloc (buf
);
89 void ttv_UseInstanceMode()
91 TTV_FORCED_NAME
=gen_getinstancename();
94 void ttv_SetFunctionsFile (char *functions_file
)
96 TTV_FUNCTIONS_FILE
= namealloc (functions_file
);
99 static void checkformoretags(ttvsig_list
*ptsig
)
101 if((ptsig
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_Q
| TTV_SIG_R
| TTV_SIG_B
|
104 ptsig
->NODE
[0].TYPE
|= TTV_NODE_STOP
;
105 ptsig
->NODE
[1].TYPE
|= TTV_NODE_STOP
;
110 static ttvsig_list
*ttvapi_GetNode(char *node
, char *root
, float capa
)
113 char temp
[1024], *code
;
115 node
=ttv_revect(gen_makesignalname(node
));
116 root
=ttv_revect(gen_makesignalname(root
));
118 sprintf(temp
,"*:%s",node
);
119 code
=namealloc(temp
);
120 if ((res
=gethtitem(nodeht
, code
))!=EMPTYHT
)
122 if (capa
!=0.0 && ((ttvsig_list
*)res
)->CAPA
==0.0)
123 ((ttvsig_list
*)res
)->CAPA
=capa
;
124 return (ttvsig_list
*)res
;
127 sprintf(temp
,"%s:%s",root
,node
);
128 code
=namealloc(temp
);
129 if ((res
=gethtitem(nodeht
, code
))!=EMPTYHT
)
131 if (capa
!=0.0 && ((ttvsig_list
*)res
)->CAPA
==0.0)
132 ((ttvsig_list
*)res
)->CAPA
=capa
;
133 return (ttvsig_list
*)res
;
136 ALL_ADDED_NODES
=ttv_addrefsig(current_ttvfig
, node
, root
, capa
, 0, ALL_ADDED_NODES
) ;
137 addhtitem(nodeht
, code
, (long)ALL_ADDED_NODES
->DATA
);
138 sprintf(temp
,"*:%s",node
);
139 code
=namealloc(temp
);
140 addhtitem(nodeht
, code
, (long)ALL_ADDED_NODES
->DATA
);
141 return (ttvsig_list
*)ALL_ADDED_NODES
->DATA
;
144 static void GrabCreatedNodes(chain_list
*cl
)
146 char temp
[1024], *code
;
151 tvs
=(ttvsig_list
*)cl
->DATA
;
152 sprintf(temp
,"%s:%s",tvs
->NETNAME
,tvs
->NAME
);
153 code
=namealloc(temp
);
154 if (gethtitem(nodeht
, code
)==EMPTYHT
)
156 addhtitem(nodeht
, code
, (long)tvs
);
157 sprintf(temp
,"*:%s",tvs
->NAME
);
158 code
=namealloc(temp
);
159 addhtitem(nodeht
, code
, (long)tvs
);
160 ALL_ADDED_NODES
=addchain(ALL_ADDED_NODES
, tvs
);
166 static double ttv_get_transistor_capa (locon_list
*cir_ptcon
)
169 lotrs_list
*trs
, *shrinked_trs
;
171 trs
= (lotrs_list
*)cir_ptcon
->ROOT
;
173 // shrinked_trs = duplotrs (trs);
174 ELP_CALC_ONLY_CAPA
= 1;
176 //elpLotrsShrink (shrinked_trs);
177 if (trs
->GRID
== cir_ptcon
)
178 trcapa
= elpGetCapaFromLocon (shrinked_trs
->GRID
,ELP_CAPA_TYPICAL
,elpTYPICAL
);
180 if (trs
->DRAIN
== cir_ptcon
)
181 trcapa
= elpGetCapaFromLocon (shrinked_trs
->DRAIN
,ELP_CAPA_TYPICAL
,elpTYPICAL
);
183 if (trs
->SOURCE
== cir_ptcon
)
184 trcapa
= elpGetCapaFromLocon (shrinked_trs
->SOURCE
,ELP_CAPA_TYPICAL
,elpTYPICAL
);
186 // mbkfree (shrinked_trs);
187 ELP_CALC_ONLY_CAPA
= 0;
192 //--- copied directly from tas -----
193 static float ttvapi_tas_gettotalcapa(lofig_list
*lofig
, losig_list
*losig
)
199 lofig
= TAS_CONTEXT
->TAS_LOFIG
;
200 if(elpIsCapaSig(lofig
, losig
, ELP_CAPA_TYPICAL
)){
201 return ((elpGetCapaSig(lofig
, losig
, ELP_CAPA_TYPICAL
) + rcn_getcapa(lofig
,losig
)) * 1000.0);
203 for(chain
= (chain_list
*)getptype(losig
->USER
,LOFIGCHAIN
)->DATA
; chain
; chain
= chain
->NEXT
)
204 capa
+= elpGetCapaFromLocon((locon_list
*)chain
->DATA
,ELP_CAPA_TYPICAL
,elpTYPICAL
);
205 elpAddCapaSig(lofig
, losig
, capa
, ELP_CAPA_TYPICAL
);
206 return ((capa
+ rcn_getcapa(lofig
,losig
)) * 1000.0);
209 //---------------------------------
211 static void SetConCapa(lofig_list
*lf
, chain_list
*cl
)
221 tvs
=(ttvsig_list
*)cl
->DATA
;
222 if ((tvs
->TYPE
& TTV_SIG_CX
)==TTV_SIG_CX
)
223 tvs
->USER
=addptype(tvs
->USER
, TTV_TEMP_PTYPE
, (void *)0);
224 if ((ls
=mbk_quickly_getlosigbyname(lf
, tvs
->NETNAME
))!=NULL
)
226 tvs
->CAPA
=ttvapi_tas_gettotalcapa(lf
, ls
);
232 static void UpdateRCXLocon(char *con_name
, char *insname
, char *rcxname
)
235 chain_list
*lst
, *cl
;
238 sins
=gen_get_hier_instance(LATEST_GNS_RUN
, insname
);
239 if (sins
->FLAGS
& LOINS_IS_BLACKBOX
) return;
240 ls
=gen_corresp_sig (con_name
, sins
->CRT
);
241 cl
=lst
=GrabAllConnectorsThruCorresp(con_name
, ls
, sins
->CRT
, NULL
);
244 lc
=(locon_list
*)cl
->DATA
;
245 addloconrcxname(lc
, rcxname
);
251 static int CheckFirstCallForThisModel()
254 loins_list
*li
, *prev
, *next
;
257 losig_list
*ls
, *prevls
, *nextls
;
260 IFGNS( if (TTV_BASE_LOFIG
==NULL
) TTV_BASE_LOFIG
=__gns_GetNetlist (); )
261 IFGNS( if ((TTVFLAGS
& TTV_INSTANCE_MODE
)==0 && TTV_FORCED_NAME
==NULL
&& (p
=getptype(TTV_BASE_LOFIG
->USER
, TTV_DONE_PTYPE
))!=NULL
) return 1; )
263 if (current_dup_lofig
!=NULL
) return 0;
265 CALLED_TTV_FUNCTION
=1;
267 ALL_ADDED_NODES
=NULL
;
272 yagenv (tas_yaginit
);
275 if (TTV_BASE_LOFIG
==NULL
) return 1;
277 current_dup_lofig
=rduplofig(TTV_BASE_LOFIG
);
279 if (TTV_FORCED_NAME
!=NULL
)
280 current_dup_lofig
->NAME
=TTV_FORCED_NAME
;
281 else IFGNS( if (TTVFLAGS
& TTV_INSTANCE_MODE
) current_dup_lofig
->NAME
=gen_getinstancename(); )
286 for (li
=current_dup_lofig
->LOINS
, prev
=NULL
; li
!=NULL
; li
=next
)
290 if (!(((tvf
=ttv_gethtmodel(li
->FIGNAME
))!=NULL
|| (tvf
=ttv_gethtmodel(li
->INSNAME
))!=NULL
) && tvf
->STATUS
& TTV_STS_DTX
))
292 if (prev
==NULL
) current_dup_lofig
->LOINS
=li
->NEXT
;
293 else prev
->NEXT
=li
->NEXT
;
294 li
->NEXT
=loins_removed
; loins_removed
=li
;
298 lofigchain(current_dup_lofig
);
300 for (ls
=current_dup_lofig
->LOSIG
, prevls
=NULL
; ls
!=NULL
; ls
=nextls
)
303 if (getptype(ls
->USER
,LOFIGCHAIN
)->DATA
==NULL
)
305 if (prevls
==NULL
) current_dup_lofig
->LOSIG
=ls
->NEXT
;
306 else prevls
->NEXT
=ls
->NEXT
;
307 ls
->NEXT
=losig_removed
; losig_removed
=ls
;
314 if ((tvf
=ttv_gethtmodel(current_dup_lofig
->NAME
))!=NULL
)
316 if((cell
= stm_getcell(tvf
->INFO
->FIGNAME
)) != NULL
){
317 stm_freecell(tvf
->INFO
->FIGNAME
) ;
320 ttv_unlockttvfig(tvf
);
321 ttv_freeallttvfig(tvf
);
324 IFGNS( memcpy(&tmpctx
, genius_external_getcontext(), sizeof(tmpctx
));
325 mbkSwitchContext(&tmpctx
); // passage dans le context NORMAL pour les modeles de transistors
328 tas_TechnoParameters();
329 tas_capasig(current_dup_lofig
);
330 elpLofigAddCapas ( current_dup_lofig
, elpTYPICAL
);
332 IFGNS( mbkSwitchContext(&tmpctx
); )
336 current_ttvfig
= tas_builtfig(current_dup_lofig
);
338 ttv_lockttvfig(current_ttvfig
);
340 tas_loconorient(current_dup_lofig
, current_ttvfig
);
342 tas_setsigname(current_dup_lofig
);
344 IFGNS( memcpy(&tmpctx
, genius_external_getcontext(), sizeof(tmpctx
));
345 mbkSwitchContext(&tmpctx
); // passage dans le context NORMAL pour les modeles de transistors
348 rcx_create(current_dup_lofig
);
350 tas_builtrcxview(current_dup_lofig
, current_ttvfig
);
352 buildrcx(current_dup_lofig
);
354 IFGNS( mbkSwitchContext(&tmpctx
); )
356 tas_detecloconsig(current_dup_lofig
, current_ttvfig
);
358 tas_calcrcxdelay(current_dup_lofig
, current_ttvfig
, TTV_FILE_DTX
);
360 tas_builtline(current_ttvfig
, TTV_LINE_D
);
362 tas_cleanfig(current_dup_lofig
, current_ttvfig
);
364 GrabCreatedNodes((chain_list
*)current_ttvfig
->ELCMDSIG
);
365 GrabCreatedNodes((chain_list
*)current_ttvfig
->ELATCHSIG
);
366 GrabCreatedNodes((chain_list
*)current_ttvfig
->EBREAKSIG
);
367 GrabCreatedNodes((chain_list
*)current_ttvfig
->EPRESIG
);
368 GrabCreatedNodes((chain_list
*)current_ttvfig
->EXTSIG
);
369 GrabCreatedNodes((chain_list
*)current_ttvfig
->ESIG
);
370 GrabCreatedNodes((chain_list
*)current_ttvfig
->CONSIG
);
371 SetConCapa(current_dup_lofig
, (chain_list
*)current_ttvfig
->CONSIG
);
372 GrabCreatedNodes((chain_list
*)current_ttvfig
->NCSIG
);
373 current_ttvfig
->NBCONSIG
=current_ttvfig
->NBELCMDSIG
=current_ttvfig
->NBELATCHSIG
=
374 current_ttvfig
->NBEBREAKSIG
=current_ttvfig
->NBEPRESIG
=current_ttvfig
->NBEXTSIG
=current_ttvfig
->NBNCSIG
=0;
379 static chain_list
*tabtochain(ttvsig_list
***tab
, int nb
)
383 for (i
=0;i
<nb
;i
++) cl
=addchain(cl
, (*tab
)[i
]);
386 *tab
=(ttvsig_list
**)cl
;
389 void ttv_EditTimingFigure(ttvfig_list
*tvf
)
393 if (TTV_BASE_LOFIG
!=NULL
|| tvf
==NULL
)
398 ttv_API_Action_Initialize();
400 CALLED_TTV_FUNCTION
=1;
402 ALL_ADDED_NODES
=NULL
;
407 yagenv (tas_yaginit
);
409 current_dup_lofig
=TTV_BASE_LOFIG
=&editmodelofig
;
410 current_ttvfig
= tvf
;
412 ttv_lockttvfig(current_ttvfig
);
414 ttv_setcachesize(-1,-1);
415 //ttv_disablecache(tvf) ; // desactivation du cache
416 //ttv_setcachesize(TTV_ALLOC_MAX, TTV_ALLOC_MAX) ; // desactivation du cache
417 type
=ttv_getloadedfigtypes(tvf
);
419 /* if (type & TTV_FILE_DTX)
421 uncache=ttv_levelise(tvf,tvf->INFO->LEVEL,TTV_FIND_LINE);
424 if (type & TTV_FILE_TTX)
426 uncache=ttv_levelise(tvf,tvf->INFO->LEVEL,TTV_FIND_PATH);
434 GrabCreatedNodes(tabtochain(¤t_ttvfig
->CONSIG
, current_ttvfig
->NBCONSIG
));
435 GrabCreatedNodes(tabtochain(¤t_ttvfig
->ELCMDSIG
, current_ttvfig
->NBELCMDSIG
));
436 GrabCreatedNodes(tabtochain(¤t_ttvfig
->ELATCHSIG
, current_ttvfig
->NBELATCHSIG
));
437 GrabCreatedNodes(tabtochain(¤t_ttvfig
->EBREAKSIG
, current_ttvfig
->NBEBREAKSIG
));
438 GrabCreatedNodes(tabtochain(¤t_ttvfig
->EPRESIG
, current_ttvfig
->NBEPRESIG
));
439 GrabCreatedNodes(tabtochain(¤t_ttvfig
->EXTSIG
, current_ttvfig
->NBEXTSIG
));
440 GrabCreatedNodes(tabtochain(¤t_ttvfig
->NCSIG
, current_ttvfig
->NBNCSIG
));
441 SetConCapa(current_dup_lofig
, (chain_list
*)current_ttvfig
->CONSIG
);
442 current_ttvfig
->NBCONSIG
=current_ttvfig
->NBELCMDSIG
=current_ttvfig
->NBELATCHSIG
=
443 current_ttvfig
->NBEBREAKSIG
=current_ttvfig
->NBEPRESIG
=current_ttvfig
->NBEXTSIG
=current_ttvfig
->NBNCSIG
=0;
447 void ttv_CreateTimingFigure(lofig_list
*lf
)
449 ttv_API_Action_Initialize();
450 ttv_SetBaseNetlist(lf
);
454 void ttv_dir_to_index(char *dir
, int *a
, int *b
)
456 if (strlen(dir
)!=2) { *a
=-1; return ; }
457 if (dir
[0]=='u' || dir
[0]=='U') *a
=1;
458 else if (dir
[0]=='d' || dir
[0]=='D') *a
=0;
459 else { *a
=-1; return ; }
460 if (dir
[1]=='u' || dir
[1]=='U') *b
=1;
461 else if (dir
[1]=='d' || dir
[1]=='D') *b
=0;
462 else { *a
=-1; return ; }
465 static char *getsignal(char *name
, char *type
, float *capa
)
467 losig_list
*ls
=NULL
, *cls
;
470 chain_list
*arbo
, *main_arbo
;
474 arbo
=main_arbo
=gen_hierarchical_split(gen_makesignalname(name
));
475 if (GENIUS_GLOBAL_LOFIG
!=NULL
)
477 if (arbo
->NEXT
==NULL
)
479 sight
=gen_get_losig_ht(TTV_BASE_LOFIG
);
481 if ((l
=gethtitem(sight
, arbo
->DATA
))==EMPTYHT
) ls
=NULL
;
482 else ls
=(losig_list
*)l
;
486 if (ls
->TYPE
=='E') *type
='c';
492 for (li
=TTV_BASE_LOFIG
->LOINS
; li
!=NULL
&& li
->INSNAME
!=arbo
->DATA
; li
=li
->NEXT
) ;
495 for (lc
=li
->LOCON
; lc
!=NULL
&& lc
->NAME
!=arbo
->NEXT
->DATA
; lc
=lc
->NEXT
) ;
499 if (ls
->TYPE
=='E') *type
='n';
505 sight
=gen_get_losig_ht(TTV_BASE_LOFIG
);
507 if ((l
=gethtitem(sight
, arbo
->DATA
))==EMPTYHT
) ls
=NULL
;
508 else ls
=(losig_list
*)l
;
512 if (ls
->TYPE
=='E') *type
='n';
518 cls
=gen_corresp_sig (gen_makesignalname(name
), CUR_CORRESP_TABLE
);
521 // rcn_refresh_signal(GENIUS_GLOBAL_LOFIG, cls);
522 *capa
=ttvapi_tas_gettotalcapa(GENIUS_GLOBAL_LOFIG
, cls
);
527 else if (TTV_BASE_LOFIG
!=&editmodelofig
)
529 ls
=mbk_quickly_getlosigbyname(TTV_BASE_LOFIG
, (char *)arbo
->DATA
);
532 *capa
=rcn_getcapa(NULL
, ls
);
533 if (ls
->TYPE
=='E') *type
='c';
544 if (ls
==NULL
) { *type
='s'; return namealloc(name
); }
545 return gen_losigname(ls
);
548 static void SetNodeType(ttvsig_list
*tvs
, char type
)
550 if (TTV_BASE_LOFIG
==&editmodelofig
&& type
=='s' && (tvs
->TYPE
& (TTV_SIG_C
|TTV_SIG_Q
|TTV_SIG_B
|TTV_SIG_L
|TTV_SIG_R
))!=0) return;
555 if ((tvs
->TYPE
& TTV_SIG_N
)==TTV_SIG_N
556 ||(tvs
->TYPE
& TTV_SIG_S
)==TTV_SIG_S
)
558 avt_errmsg(TTV_API_ERRMSG
, "003", AVT_WARNING
, (tvs
->TYPE
& TTV_SIG_N
)==TTV_SIG_N
?'n':'s',type
);
559 // avt_error("ttvapi", 3, AVT_WAR, "conflicting node type old:'%c' new:'%c'\n",(tvs->TYPE & TTV_SIG_N)==TTV_SIG_N?'n':'s',type);
562 tvs
->TYPE
|=TTV_SIG_C
;
563 checkformoretags(tvs
);
566 if ((tvs
->TYPE
& TTV_SIG_N
)==TTV_SIG_C
567 ||(tvs
->TYPE
& TTV_SIG_S
)==TTV_SIG_S
)
569 avt_errmsg(TTV_API_ERRMSG
, "003", AVT_WARNING
, (tvs
->TYPE
& TTV_SIG_C
)==TTV_SIG_N
?'c':'s',type
);
570 // avt_error("ttvapi", 3, AVT_WAR, "conflicting node type old:'%c' new:'%c'\n",(tvs->TYPE & TTV_SIG_C)==TTV_SIG_N?'c':'s',type);
573 tvs
->TYPE
|=TTV_SIG_N
;
574 checkformoretags(tvs
);
577 if ((tvs
->TYPE
& TTV_SIG_N
)==TTV_SIG_C
578 ||(tvs
->TYPE
& TTV_SIG_S
)==TTV_SIG_N
)
580 avt_errmsg(TTV_API_ERRMSG
, "003", AVT_WARNING
, (tvs
->TYPE
& TTV_SIG_C
)==TTV_SIG_N
?'c':'n',type
);
581 // avt_error("ttvapi", 3, AVT_WAR, "conflicting node type old:'%c' new:'%c'\n",(tvs->TYPE & TTV_SIG_C)==TTV_SIG_N?'c':'n',type);
584 if ((tvs
->TYPE
& (TTV_SIG_Q
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
))!=0) return;
585 tvs
->TYPE
|=TTV_SIG_S
;
586 checkformoretags(tvs
);
591 avt_errmsg(TTV_API_ERRMSG
, "004", AVT_ERROR
, type
);
592 // avt_error("ttvapi", 3, AVT_ERR, "type '%c' is unknown\n",type);
597 char gettype(int type
)
599 if ((type
& TTV_SIG_L
)==TTV_SIG_L
) return 'l';
600 if ((type
& TTV_SIG_R
)==TTV_SIG_R
) return 'r';
601 if ((type
& TTV_SIG_Q
)==TTV_SIG_Q
) return 'q';
602 if ((type
& TTV_SIG_B
)==TTV_SIG_B
) return 'b';
606 static int CompareSubtype(ttvsig_list
*tvs0
, ttvsig_list
*tvs1
)
609 if (tvs0
->NETNAME
!=tvs1
->NETNAME
) return 0;
610 t0
=(tvs0
->TYPE
& TTV_SIG_TYPE
) & ~TTV_SIG_TYPECON
;
611 t1
=(tvs1
->TYPE
& TTV_SIG_TYPE
) & ~TTV_SIG_TYPECON
;
615 tvs0
->TYPE
&= ~TTV_SIG_S
;
616 tvs1
->TYPE
&= ~TTV_SIG_S
;
619 checkformoretags(tvs0
);
620 checkformoretags(tvs1
);
624 static void SetNodeSubtype(ttvsig_list
*tvs
, char subtype
)
629 if ((tvs
->TYPE
& (TTV_SIG_L
| TTV_SIG_R
/*| TTV_SIG_B*/))!=0)
631 avt_errmsg(TTV_API_ERRMSG
, "005", AVT_WARNING
, gettype(tvs
->TYPE
), subtype
);
632 // avt_error("ttvapi", 2, AVT_WAR, "overriding type '%c' with '%c'\n",gettype(tvs->TYPE), subtype);
634 tvs
->TYPE
&=~(TTV_SIG_R
|TTV_SIG_L
|/*TTV_SIG_B|*/TTV_SIG_S
);
635 tvs
->TYPE
|=TTV_SIG_Q
;
636 checkformoretags(tvs
);
639 if ((tvs
->TYPE
& (TTV_SIG_Q
| TTV_SIG_R
| TTV_SIG_B
))!=0)
641 avt_errmsg(TTV_API_ERRMSG
, "005", AVT_WARNING
, gettype(tvs
->TYPE
), subtype
);
642 // avt_error("ttvapi", 2, AVT_WAR, "overriding type '%c' with '%c'\n",gettype(tvs->TYPE), subtype);
644 tvs
->TYPE
&=~(TTV_SIG_R
|TTV_SIG_Q
|TTV_SIG_B
|TTV_SIG_S
);
645 tvs
->TYPE
|=TTV_SIG_LL
;
646 checkformoretags(tvs
);
649 if ((tvs
->TYPE
& (TTV_SIG_Q
| TTV_SIG_R
| TTV_SIG_B
))!=0)
651 avt_errmsg(TTV_API_ERRMSG
, "005", AVT_WARNING
, gettype(tvs
->TYPE
), subtype
);
652 // avt_error("ttvapi", 2, AVT_WAR, "overriding type '%c' with '%c'\n",gettype(tvs->TYPE), subtype);
654 tvs
->TYPE
&=~(TTV_SIG_R
|TTV_SIG_Q
|TTV_SIG_B
|TTV_SIG_S
);
655 tvs
->TYPE
|=TTV_SIG_LF
;
656 checkformoretags(tvs
);
659 if ((tvs
->TYPE
& (TTV_SIG_L
| TTV_SIG_R
/* | TTV_SIG_Q*/))!=0)
661 avt_errmsg(TTV_API_ERRMSG
, "005", AVT_WARNING
, gettype(tvs
->TYPE
), subtype
);
662 // avt_error("ttvapi", 2, AVT_WAR, "overriding type '%c' with '%c'\n",gettype(tvs->TYPE), subtype);
664 tvs
->TYPE
|=TTV_SIG_B
;
665 tvs
->TYPE
&=~TTV_SIG_S
;
666 checkformoretags(tvs
);
669 if ((tvs
->TYPE
& (TTV_SIG_L
| TTV_SIG_Q
| TTV_SIG_B
))!=0)
671 avt_errmsg(TTV_API_ERRMSG
, "005", AVT_WARNING
, gettype(tvs
->TYPE
), subtype
);
672 // avt_error("ttvapi", 2, AVT_WAR, "overriding type '%c' with '%c'\n",gettype(tvs->TYPE), subtype);
674 tvs
->TYPE
&=~(TTV_SIG_L
|TTV_SIG_Q
|TTV_SIG_B
|TTV_SIG_S
);
675 tvs
->TYPE
|=TTV_SIG_R
;
676 checkformoretags(tvs
);
681 avt_errmsg(TTV_API_ERRMSG
, "006", AVT_ERROR
, subtype
);
682 // avt_error("ttvapi", 3, AVT_ERR, "subtype '%c' is unknown\n",subtype);
687 static void SetAsBreakpointIfNeeded(ttvsig_list
*tsig
)
689 if ((tsig
->TYPE
& TTV_SIG_L
)!=TTV_SIG_L
&& (tsig
->TYPE
& TTV_SIG_Q
)!=TTV_SIG_Q
)
691 tsig
->TYPE
&=~(TTV_SIG_Q
|TTV_SIG_S
);
692 tsig
->TYPE
|=TTV_SIG_B
;
693 checkformoretags(tsig
);
697 ttvsig_list
*ttv_SetNodeSubtype(char *node
, char subtype
)
704 if (CheckFirstCallForThisModel()) return NULL
;
705 if ((sin
=getsignal(node
, &it
, &capa
))==NULL
) return NULL
;
706 tsin
=ttvapi_GetNode(node
, sin
, capa
);
707 SetNodeType(tsin
, it
);
708 SetNodeSubtype(tsin
, subtype
);
712 ttvsig_list
*ttv_AddConnector(char *name
, char dir
)
718 case 'i': type
=TTV_SIG_CI
; break;
719 case 'o': type
=TTV_SIG_CO
; break;
720 case 'z': type
=TTV_SIG_CZ
; break;
721 case 'b': type
=TTV_SIG_CB
; break;
722 case 't': type
=TTV_SIG_CT
; break;
723 case 'x': type
=TTV_SIG_CX
; break;
724 default: type
=TTV_SIG_CI
;
725 avt_errmsg(TTV_API_ERRMSG
, "054", AVT_ERROR
, dir
);
727 tvs
=ttv_AddCustomNode(name
, name
, 'c', ' ');
728 tvs
->TYPE
&=~(TTV_SIG_CI
|TTV_SIG_CO
|TTV_SIG_CZ
|TTV_SIG_CB
|TTV_SIG_CT
|TTV_SIG_CX
);
733 ttvsig_list
*ttv_AddCommand(char *name
)
735 return ttv_SetNodeSubtype(name
, 'q');
738 ttvsig_list
*ttv_AddLatch(char *name
)
741 if (CheckFirstCallForThisModel()) return NULL
;
742 tsin
=ttv_SetNodeSubtype(name
, 'l');
743 tsin
->TYPE
|=TTV_SIG_LL
;
744 checkformoretags(tsin
);
748 ttvsig_list
*ttv_AddFlipFlop(char *name
)
751 if (CheckFirstCallForThisModel()) return NULL
;
752 tsin
=ttv_SetNodeSubtype(name
, 'l');
753 tsin
->TYPE
|=TTV_SIG_LF
;
754 checkformoretags(tsin
);
758 ttvsig_list
*ttv_AddPrecharge(char *name
)
760 return ttv_SetNodeSubtype(name
, 'r');
763 ttvsig_list
*ttv_AddBreakpoint(char *name
)
765 return ttv_SetNodeSubtype(name
, 'b');
768 TimingSignal
*ttv_GetNode(char *node
, char *signal
)
771 if (CheckFirstCallForThisModel()) return NULL
;
772 tvs
=ttvapi_GetNode(node
, signal
, 0.0);
776 TimingSignal
*ttv_AddCustomNode(char *node
, char *signal
, char type
, char subtype
)
779 if (CheckFirstCallForThisModel()) return NULL
;
780 if (tolower(type
)!='c' && tolower(type
)!='n' && tolower(type
)!='s')
782 IFGNS ( avt_errmsg(TTV_API_ERRMSG
, "007", AVT_ERROR
, gen_info(), type
); )
783 //IFGNS ( avt_error("ttvapi", 2, AVT_ERR, "%s: invalid node type '%c', ttv_AddCustomSignal ignored\n", gen_info(), type); )
785 tvs
=ttvapi_GetNode(node
, signal
, 0.0);
786 SetNodeType(tvs
, type
);
787 if (subtype
!=' ') SetNodeSubtype(tvs
, subtype
);
791 void ttv_Config(double value
, double out_capa
)
797 char *ttv_getarcdef(ttvline_list
*tvl
)
801 ttvsig_list
*tvss
, *tvsd
;
802 tvss
=tvl
->NODE
->ROOT
;
803 tvsd
=tvl
->ROOT
->ROOT
;
805 if ((tvl
->TYPE
& TTV_LINE_U
)==TTV_LINE_U
) type
="setup";
806 else if ((tvl
->TYPE
& TTV_LINE_O
)==TTV_LINE_O
) type
="hold";
807 else if ((tvl
->TYPE
& TTV_LINE_A
)==TTV_LINE_A
) type
="access";
809 if ((TTVFLAGS
& TTV_INSTANCE_MODE
)==0)
810 sprintf(temp
,"%s_%s_%s_%c%c", type
, tvss
->NAME
, tvsd
->NAME
,
811 tvl
->NODE
==&tvss
->NODE
[1]?'u':'d',
812 tvl
->ROOT
==&tvsd
->NODE
[1]?'u':'d');
814 sprintf(temp
,"%s-%s_%s_%s_%c%c", gen_getinstancename(), type
, tvss
->NAME
, tvsd
->NAME
,
815 tvl
->NODE
==&tvss
->NODE
[1]?'u':'d',
816 tvl
->ROOT
==&tvsd
->NODE
[1]?'u':'d');
817 return namealloc(temp
);
820 static double ttv_tas_thr2scm (double fthr
, int dir
)
826 return elpThr2Scm (fthr
, elpGeneral
[elpGSLTHR
],
827 elpGeneral
[elpGSHTHR
],
828 elpGetModelType (TRANSN
)->elpModel
[elpVT
],
829 0.0, elpGeneral
[elpGVDDMAX
], elpFALL
);
834 return elpThr2Scm (fthr
, elpGeneral
[elpGSLTHR
],
835 elpGeneral
[elpGSHTHR
],
836 elpGetModelType (TRANSP
)->elpModel
[elpVT
],
837 elpGeneral
[elpGVDDMAX
], elpGeneral
[elpGVDDMAX
], elpRISE
);
842 void checkslope(char *type
, char *input
, char *output
, char *dir
, double *val
)
847 *val
=(TAS_CONTEXT
->FRONT_CON
/TTV_UNIT
)*1e-12;
848 avt_errmsg(TTV_API_ERRMSG
, "008", AVT_ERROR
, type
, TAS_CONTEXT
->FRONT_CON
/TTV_UNIT
, input
, output
, dir
);
849 // avt_error("ttvapi", 1, AVT_WAR, "nul or negative %sslope set to %gps for line %s¤4->¤.%s %s\n", type, TAS_CONTEXT->FRONT_CON/TTV_UNIT, input, output, dir);
853 ttvline_list
*ttv_AddCustomLine(TimingSignal
*input
, TimingSignal
*output
, double max_delay
, double max_slope
, double min_delay
, double min_slope
, char *dir
, int type
)
856 long vali
, valo
, LD
, LE
, LF
, loaded
;
857 ptype_list
*pti
, *pto
;
859 ttvevent_list
*lnode
, *cmdnode
;
861 if (CheckFirstCallForThisModel()) return NULL
;
862 ttv_dir_to_index(dir
, &a
, &b
);
865 char *where
="somewhere";
866 IFGNS ( where
=gen_info(); )
867 avt_errmsg(TTV_API_ERRMSG
, "009", AVT_ERROR
, where
, dir
);
868 // avt_error("ttvapi", 3, AVT_ERR, "%s: invalid direction '%s', timing line creation ignored\n", where, dir);
872 if ((pti
=getptype(input
->USER
, TTV_TEMP_PTYPE
))!=NULL
) vali
=(long)pti
->DATA
;
873 if ((pto
=getptype(output
->USER
, TTV_TEMP_PTYPE
))!=NULL
) valo
=(long)pto
->DATA
;
879 if (TTV_BASE_LOFIG
==&editmodelofig
)
881 loaded
=ttv_getloadedfigtypes(current_ttvfig
);
882 if ((loaded
& TTV_FILE_TTX
)==TTV_FILE_TTX
)
888 if ((type
& TTV_LINE_D
)==TTV_LINE_D
) { type
&=~TTV_LINE_D
; type
|=LD
; }
889 if ((type
& TTV_LINE_E
)==TTV_LINE_E
) { type
&=~TTV_LINE_E
; type
|=LE
; }
890 if ((type
& TTV_LINE_F
)==TTV_LINE_F
) { type
&=~TTV_LINE_F
; type
|=LF
; }
899 if (type
==TTV_SETUP
) type
=TTV_LINE_U
;
900 else if (type
==TTV_HOLD
) type
=TTV_LINE_O
;
901 else type
=TTV_LINE_A
;
904 if (((input
->TYPE
|output
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
911 if (((input
->TYPE
|output
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
917 if ((type
& (TTV_LINE_O
|TTV_LINE_A
|TTV_LINE_U
))!=0)
920 SetAsBreakpointIfNeeded(input
);
921 SetAsBreakpointIfNeeded(output
);
922 if ((type
& TTV_LINE_A
)!=TTV_LINE_A
) vali
|=TTV_mark_IN
, valo
|=TTV_mark_IN
;
923 else vali
|=TTV_mark_IN
, valo
|=TTV_mark_OUT
;
925 if ((type
& TTV_LINE_A
)==TTV_LINE_A
)
926 lnode
=&output
->NODE
[b
], cmdnode
=&input
->NODE
[a
];
928 lnode
=&input
->NODE
[a
], cmdnode
=&output
->NODE
[(b
+1) & 1];
929 if (lnode
->ROOT
->TYPE
& TTV_SIG_L
)
931 if ((pt
=getptype(lnode
->ROOT
->USER
, TTV_SIG_CMD
))==NULL
)
932 pt
=lnode
->ROOT
->USER
=addptype(lnode
->ROOT
->USER
, TTV_SIG_CMD
, NULL
);
934 if (getchain(pt
->DATA
, cmdnode
)==NULL
)
935 pt
->DATA
=addchain((chain_list
*)pt
->DATA
, cmdnode
);
942 if ((type
& TTV_LINE_HZ
)==TTV_LINE_HZ
) valo
|=TTV_mark_HZ
;
945 if (pti
!=NULL
) pti
->DATA
=(void *)vali
;
946 if (pto
!=NULL
) pto
->DATA
=(void *)valo
;
948 if (CompareSubtype(input
, output
))
953 tvl
=ttv_addline(current_ttvfig
,
954 &output
->NODE
[b
], &input
->NODE
[a
],
955 (long)(max_delay
*1e12
*TTV_UNIT
),
956 (long)ttv_tas_thr2scm(max_slope
*1e12
*TTV_UNIT
, b
),
957 (long)(min_delay
*1e12
*TTV_UNIT
),
958 (long)ttv_tas_thr2scm(min_slope
*1e12
*TTV_UNIT
, b
),
961 ALL_LINES
=addchain(ALL_LINES
, tvl
);
966 void ttv_Associate_Model(ttvline_list
*tvl
, void *func
)
969 timing_model
*tmodel
;
972 double capa
= 0.0, slope
= STM_DEF_SLEW
;
973 float vt
=STM_NOVALUE
, vdd
=STM_NOVALUE
, vf
=STM_NOVALUE
, vth
=STM_NOVALUE
;
975 if (func
==NULL
|| TTV_BASE_LOFIG
==&editmodelofig
) return ;
976 if (tvl
==NULL
|| CheckFirstCallForThisModel()) { APIFreeCallFunc(func
); return ;}
978 nt
=ttv_getarcdef(tvl
);
980 stm_addfctmodel (current_ttvfig
->INSNAME
, nt
, "?", nt
, func
);
982 tmodel
=stm_getmodel(current_ttvfig
->INSNAME
, nt
);
984 stm_mod_setcaracslew (tmodel
, 0.2 * slope
);
985 stm_mod_setcaracslew (tmodel
, 1.8 * slope
);
986 // TODO get the real value of the capa
987 capa
=tvl
->ROOT
->ROOT
->CAPA
; // en Ff
988 stm_mod_setcaracload (tmodel
, 0.2 * capa
);
989 stm_mod_setcaracload (tmodel
, 1.8 * capa
);
992 // vdd/2, vdd, vt, vfinal
993 if (nt
[strlen(nt
)-1]=='d') vf
=0.0;
994 else if (ttv_high
!=-1) vf
=ttv_high
-ttv_low
;
998 vdd
=ttv_high
-ttv_low
;
1000 vth
=vdd
*V_FLOAT_TAB
[__SIM_VTH
].VALUE
;
1002 stm_mod_update(tmodel
, vth
, vdd
, vt
, vf
);
1004 if ((tvl
->TYPE
& (TTV_LINE_O
|TTV_LINE_U
))==0
1005 || (tvl
->TYPE
& TTV_LINE_A
)==TTV_LINE_A
)
1006 ttv_addcaracline(tvl
, nt
, nt
, nt
, nt
);
1008 ttv_addcaracline(tvl
, nt
, nt
, NULL
, NULL
);
1009 hli
=gethierlofiginfo(TTV_BASE_LOFIG
);
1010 ai
=getarcinfo(hli
, nt
);
1011 ai
->MODEL
=(APICallFunc
*)func
;
1015 void ttv_Associate_Sim(ttvline_list
*tvl
, void *func
)
1021 if (func
==NULL
|| TTV_BASE_LOFIG
==&editmodelofig
) return ;
1022 if (tvl
==NULL
|| CheckFirstCallForThisModel()) {APIFreeCallFunc(func
); return ;}
1024 nt
=ttv_getarcdef(tvl
);
1025 hli
=gethierlofiginfo(TTV_BASE_LOFIG
);
1026 ai
=getarcinfo(hli
, nt
);
1027 ai
->SIM
=(APICallFunc
*)func
;
1030 void ttv_Associate_Env(ttvline_list
*tvl
, void *func
)
1036 if (func
==NULL
|| TTV_BASE_LOFIG
==&editmodelofig
) return ;
1037 if (tvl
==NULL
|| CheckFirstCallForThisModel()) {APIFreeCallFunc(func
); return ;}
1039 nt
=ttv_getarcdef(tvl
);
1041 hli
=gethierlofiginfo(TTV_BASE_LOFIG
);
1042 ai
=getarcinfo(hli
, nt
);
1043 ai
->ENV
=(APICallFunc
*)func
;
1046 void ttv_Associate_Ctk_Env(ttvline_list
*tvl
, void *func
)
1052 if (func
==NULL
|| TTV_BASE_LOFIG
==&editmodelofig
) return ;
1053 if (tvl
==NULL
|| CheckFirstCallForThisModel()) return ;
1055 nt
=ttv_getarcdef(tvl
);
1057 hli
=gethierlofiginfo(TTV_BASE_LOFIG
);
1058 ai
=getarcinfo(hli
, nt
);
1059 ai
->CTK_ENV
=(APICallFunc
*)func
;
1062 ttvline_list
*ttv_AddTiming(char *input
, char *output
, double max_delay
, double max_slope
, double min_delay
, double min_slope
, char *dir
)
1066 ttvsig_list
*tsin
, *tsout
;
1067 long linetype
=TTV_LINE_F
;
1070 if (CheckFirstCallForThisModel()) return NULL
;
1072 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1073 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1075 checkslope("min", input
, output
, dir
, &min_slope
);
1076 checkslope("max", input
, output
, dir
, &max_slope
);
1078 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1079 SetNodeType(tsin
, it
);
1080 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1081 SetNodeType(tsout
, ot
);
1083 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1084 linetype
=TTV_LINE_D
;
1086 return ttv_AddCustomLine(tsin
, tsout
, max_delay
, max_slope
, min_delay
, min_slope
, dir
, linetype
);
1088 ttvline_list
*ttv_AddHZTiming(char *input
, char *output
, double max_delay
, double min_delay
, char *dir
)
1092 ttvsig_list
*tsin
, *tsout
;
1093 long linetype
=TTV_LINE_F
|TTV_LINE_HZ
;
1096 if (CheckFirstCallForThisModel()) return NULL
;
1098 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1099 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1101 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1102 SetNodeType(tsin
, it
);
1103 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1104 SetNodeType(tsout
, ot
);
1106 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1107 linetype
=TTV_LINE_D
|TTV_LINE_HZ
;
1109 return ttv_AddCustomLine(tsin
, tsout
, max_delay
, 0, min_delay
, 0, dir
, linetype
);
1112 ttvline_list
*ttv_AddSetup(char *input
, char *output
, double delay
, char *dir
)
1116 ttvsig_list
*tsin
, *tsout
;
1117 long linetype
=TTV_LINE_E
;
1120 if (CheckFirstCallForThisModel()) return NULL
;
1122 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1123 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1125 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1126 SetNodeType(tsin
, it
);
1127 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1128 SetNodeType(tsout
, ot
);
1130 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1131 linetype
=TTV_LINE_D
;
1133 return ttv_AddCustomLine(tsin
, tsout
, delay
, 0, delay
, 0, dir
, linetype
|TTV_LINE_U
);
1136 ttvline_list
*ttv_AddHold(char *input
, char *output
, double delay
, char *dir
)
1140 ttvsig_list
*tsin
, *tsout
;
1141 long linetype
=TTV_LINE_E
;
1144 if (CheckFirstCallForThisModel()) return NULL
;
1146 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1147 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1149 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1150 SetNodeType(tsin
, it
);
1151 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1152 SetNodeType(tsout
, ot
);
1154 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1155 linetype
=TTV_LINE_D
;
1157 return ttv_AddCustomLine(tsin
, tsout
, delay
, 0, delay
, 0, dir
, linetype
|TTV_LINE_O
);
1161 ttvline_list
*ttv_AddAccess(char *input
, char *output
, double max_delay
, double max_slope
, double min_delay
, double min_slope
, char *dir
)
1165 ttvsig_list
*tsin
, *tsout
;
1167 long linetype
=TTV_LINE_E
;
1171 if (CheckFirstCallForThisModel()) return NULL
;
1173 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1174 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1176 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1177 SetNodeType(tsin
, it
);
1178 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1179 SetNodeType(tsout
, ot
);
1181 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1182 linetype
=TTV_LINE_D
;
1184 tl
=ttv_AddCustomLine(tsin
, tsout
, max_delay
, max_slope
, min_delay
, min_slope
, dir
, linetype
|TTV_LINE_A
);
1187 ttv_SetLineCommand(tl
, input
, input
, dir0
);
1191 ttvline_list
*ttv_AddHZAccess(char *input
, char *output
, double max_delay
, double min_delay
, char *dir
)
1195 ttvsig_list
*tsin
, *tsout
;
1196 long linetype
=TTV_LINE_E
;
1201 if (CheckFirstCallForThisModel()) return NULL
;
1203 if ((sin
=getsignal(input
, &it
, &capa0
))==NULL
) return NULL
;
1204 if ((sout
=getsignal(output
, &ot
, &capa1
))==NULL
) return NULL
;
1206 tsin
=ttvapi_GetNode(input
, sin
, capa0
);
1207 SetNodeType(tsin
, it
);
1208 tsout
=ttvapi_GetNode(output
, sout
, capa1
);
1209 SetNodeType(tsout
, ot
);
1211 if (((tsin
->TYPE
|tsout
->TYPE
) & (TTV_SIG_C
|TTV_SIG_N
))!=0)
1212 linetype
=TTV_LINE_D
|TTV_LINE_HZ
;
1214 tl
=ttv_AddCustomLine(tsin
, tsout
, max_delay
, 0, min_delay
, 0, dir
, linetype
|TTV_LINE_A
);
1217 ttv_SetLineCommand(tl
, input
, input
, dir0
);
1221 void ShareStmFCTModels()
1227 char *nt
, *key
, *nt0
, *nt1
, *nt2
, *nt3
;
1230 char trans
, temp
[4096];
1233 timing_model
*tmodel
;
1235 CreateNameAllocator(1024, &na
, CASE_SENSITIVE
);
1236 uniquemodels
=addht(1024);
1237 hli
=gethierlofiginfo(TTV_BASE_LOFIG
);
1239 for (cl
=ALL_LINES
, cnt
=0; cl
!=NULL
; cl
=cl
->NEXT
)
1241 tvl
=(ttvline_list
*)cl
->DATA
;
1242 nt
=ttv_getarcdef(tvl
);
1243 ai
=getarcinfo(hli
, nt
);
1246 if (ai
->MODEL
!=NULL
)
1247 { APIPrintCallFunc(ai
->MODEL
, &temp
[strlen(temp
)]); strcat(temp
,"|"); }
1249 { APIPrintCallFunc(ai
->SIM
, &temp
[strlen(temp
)]); strcat(temp
,"|"); }
1251 { APIPrintCallFunc(ai
->ENV
, &temp
[strlen(temp
)]); strcat(temp
,"|"); }
1252 if (ai
->CTK_ENV
!=NULL
)
1253 { APIPrintCallFunc(ai
->CTK_ENV
, &temp
[strlen(temp
)]); strcat(temp
,"|"); }
1255 if (strlen(temp
)!=0)
1257 key
=NameAlloc(&na
, temp
);
1258 l
=gethtitem(uniquemodels
, key
);
1264 stm_freemodel(current_ttvfig
->INSNAME
, nt
);
1266 if ((tvl
->TYPE
& (TTV_LINE_O
|TTV_LINE_U
))==0
1267 || (tvl
->TYPE
& TTV_LINE_A
)==TTV_LINE_A
)
1268 ttv_addcaracline(tvl
, nt
, nt
, nt
, nt
);
1270 ttv_addcaracline(tvl
, nt
, nt
, NULL
, NULL
);
1274 addhtitem(uniquemodels
, key
, (long)nt
);
1278 if (tvl
->ROOT
==&tvl
->ROOT
->ROOT
->NODE
[0]) trans
='d'; else trans
='u';
1279 sprintf(temp
,"cst_%.1fps_%c", tvl
->VALMAX
/TTV_UNIT
, trans
); nt0
=namealloc(temp
);
1280 stm_addconstmodel(current_ttvfig
->INSNAME
, nt0
, tvl
->VALMAX
/TTV_UNIT
);
1282 sprintf(temp
,"cst_%.1fps_%c", tvl
->VALMIN
/TTV_UNIT
, trans
); nt2
=namealloc(temp
);
1283 stm_addconstmodel(current_ttvfig
->INSNAME
, nt2
, tvl
->VALMIN
/TTV_UNIT
);
1287 tmodel
=stm_getmodel(current_ttvfig
->INSNAME
, nt0
);
1288 stm_mod_update(tmodel
, STM_NOVALUE
, STM_NOVALUE
, STM_NOVALUE
, 0.0);
1289 tmodel
=stm_getmodel(current_ttvfig
->INSNAME
, nt2
);
1290 stm_mod_update(tmodel
, STM_NOVALUE
, STM_NOVALUE
, STM_NOVALUE
, 0.0);
1293 if (!((tvl
->TYPE
& (TTV_LINE_O
|TTV_LINE_U
))==0
1294 || (tvl
->TYPE
& TTV_LINE_A
)==TTV_LINE_A
))
1296 ttv_addcaracline(tvl
, nt0
, nt2
, NULL
, NULL
);
1300 sprintf(temp
,"cst_%.1fps_%c", tvl
->FMAX
/TTV_UNIT
, trans
); nt1
=namealloc(temp
);
1301 stm_addconstmodel(current_ttvfig
->INSNAME
, nt1
, tvl
->FMAX
/TTV_UNIT
);
1302 sprintf(temp
,"cst_%.1fps_%c", tvl
->FMIN
/TTV_UNIT
, trans
); nt3
=namealloc(temp
);
1303 stm_addconstmodel(current_ttvfig
->INSNAME
, nt3
, tvl
->FMIN
/TTV_UNIT
);
1307 tmodel
=stm_getmodel(current_ttvfig
->INSNAME
, nt1
);
1308 stm_mod_update(tmodel
, STM_NOVALUE
, STM_NOVALUE
, STM_NOVALUE
, 0.0);
1309 tmodel
=stm_getmodel(current_ttvfig
->INSNAME
, nt3
);
1310 stm_mod_update(tmodel
, STM_NOVALUE
, STM_NOVALUE
, STM_NOVALUE
, 0.0);
1313 ttv_addcaracline(tvl
, nt0
, nt2
, nt1
, nt3
);
1320 avt_fprintf(stdout
,"[¤1info¤.] %d/%d timing lines share their model\n",cnt
,total
);
1321 DeleteNameAllocator(&na
);
1322 delht(uniquemodels
);
1323 freechain(ALL_LINES
);
1326 static void ChangeConDir(ttvsig_list
*tvs
)
1331 if ((pt
=getptype(tvs
->USER
, TTV_TEMP_PTYPE
))!=NULL
)
1335 if ((val
& (TTV_mark_IN
|TTV_mark_OUT
))==(TTV_mark_IN
|TTV_mark_OUT
))
1337 if (val
& TTV_mark_HZ
) type
=TTV_SIG_CT
;
1338 else type
=TTV_SIG_CB
;
1340 else if ((val
& TTV_mark_OUT
)==TTV_mark_OUT
)
1342 if (val
& TTV_mark_HZ
) type
=TTV_SIG_CZ
;
1343 else type
=TTV_SIG_CO
;
1345 else if ((val
& TTV_mark_IN
)==TTV_mark_IN
)
1349 tvs
->TYPE
&=~TTV_SIG_CX
;
1351 tvs
->USER
=delptype(tvs
->USER
, TTV_TEMP_PTYPE
);
1355 static void DispatchNodes()
1360 freechain((chain_list
*)current_ttvfig
->NCSIG
); current_ttvfig
->NCSIG
=NULL
;
1361 freechain((chain_list
*)current_ttvfig
->ELCMDSIG
); current_ttvfig
->ELCMDSIG
=NULL
;
1362 freechain((chain_list
*)current_ttvfig
->ELATCHSIG
); current_ttvfig
->ELATCHSIG
=NULL
;
1363 freechain((chain_list
*)current_ttvfig
->EPRESIG
); current_ttvfig
->EPRESIG
=NULL
;
1364 freechain((chain_list
*)current_ttvfig
->EBREAKSIG
); current_ttvfig
->EBREAKSIG
=NULL
;
1365 freechain((chain_list
*)current_ttvfig
->ESIG
); current_ttvfig
->ESIG
=NULL
;
1366 freechain((chain_list
*)current_ttvfig
->CONSIG
); current_ttvfig
->CONSIG
=NULL
;
1368 for (cl
=ALL_ADDED_NODES
; cl
!=NULL
; cl
=cl
->NEXT
)
1370 tvs
=(ttvsig_list
*)cl
->DATA
;
1371 if ((tvs
->TYPE
& TTV_SIG_C
)==TTV_SIG_C
)
1374 current_ttvfig
->CONSIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->CONSIG
, tvs
);
1376 if ((tvs
->TYPE
& TTV_SIG_N
)==TTV_SIG_N
)
1377 current_ttvfig
->NCSIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->NCSIG
, tvs
);
1378 if ((tvs
->TYPE
& TTV_SIG_Q
)==TTV_SIG_Q
)
1379 current_ttvfig
->ELCMDSIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->ELCMDSIG
, tvs
);
1380 if ((tvs
->TYPE
& TTV_SIG_L
)==TTV_SIG_L
)
1381 current_ttvfig
->ELATCHSIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->ELATCHSIG
, tvs
);
1382 if ((tvs
->TYPE
& TTV_SIG_R
)==TTV_SIG_R
)
1383 current_ttvfig
->EPRESIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->EPRESIG
, tvs
);
1384 if ((tvs
->TYPE
& TTV_SIG_B
)==TTV_SIG_B
)
1385 current_ttvfig
->EBREAKSIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->EBREAKSIG
, tvs
);
1386 if ((tvs
->TYPE
& TTV_SIG_S
)==TTV_SIG_S
)
1387 current_ttvfig
->ESIG
=(ttvsig_list
**)addchain((chain_list
*)current_ttvfig
->ESIG
, tvs
);
1389 freechain(ALL_ADDED_NODES
);
1392 void ttv_API_Action_Terminate() // commentaire pour desactiver l'ajout de token
1396 long loaded
, filetype
;
1401 if (CALLED_TTV_FUNCTION
==0)
1403 hli
=gethierlofiginfo(CUR_HIER_LOFIG
);
1404 if (hli
->BUILD_TTV
==NULL
) return;
1406 if (CheckFirstCallForThisModel()) return;
1409 ShareStmFCTModels();
1412 if (TTV_BASE_LOFIG
==NULL
) return;
1414 if (TTV_BASE_LOFIG
==&editmodelofig
) editmode
=1;
1418 filetype
=TTV_FILE_DTX
;
1421 loaded
=ttv_getloadedfigtypes(current_ttvfig
);
1422 if ((loaded
& TTV_FILE_TTX
)==TTV_FILE_TTX
) filetype
=TTV_FILE_TTX
;
1425 current_ttvfig
->STATUS
|= TTV_STS_DTX
;
1427 delete = tas_deleteflatemptyfig(current_ttvfig
, filetype
, 'Y');
1429 tas_detectloop(current_ttvfig
, filetype
);
1431 ttv_builtrefsig(current_ttvfig
);
1435 ttv_setttvlevel(current_ttvfig
) ;
1436 ttv_setsigttvfiglevel(current_ttvfig
) ;
1441 ttv_setttvdate (current_ttvfig
, TTV_DATE_LOCAL
);
1442 current_ttvfig
->INFO
->TOOLNAME
= namealloc ("ttv_API");
1443 current_ttvfig
->INFO
->TOOLVERSION
= namealloc ("1.0");
1444 current_ttvfig
->INFO
->TECHNONAME
= namealloc ("spice");
1445 current_ttvfig
->INFO
->TECHNOVERSION
= namealloc ("1.0");
1446 current_ttvfig
->INFO
->SLOPE
= (long)(TTVSLOPE
*1e12
*TTV_UNIT
);
1447 current_ttvfig
->INFO
->CAPAOUT
= (long)(TTVCAPA
*1e12
);
1448 current_ttvfig
->INFO
->STHHIGH
= V_FLOAT_TAB
[__SIM_VTH_HIGH
].VALUE
;
1449 current_ttvfig
->INFO
->STHLOW
= V_FLOAT_TAB
[__SIM_VTH_LOW
].VALUE
;
1450 current_ttvfig
->INFO
->DTH
= V_FLOAT_TAB
[__SIM_VTH
].VALUE
;
1451 current_ttvfig
->INFO
->TEMP
= V_FLOAT_TAB
[__SIM_TEMP
].VALUE
;
1452 current_ttvfig
->INFO
->VDD
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1454 if (TTVFLAGS
& TTV_DRIVE_DTX
)
1456 ttv_drittv (current_ttvfig
, filetype
, (long)0, NULL
);
1457 stm_drivecell(current_ttvfig
->INSNAME
);
1460 if ((TTVFLAGS
& TTV_INSTANCE_MODE
)==0 && TTV_FORCED_NAME
==NULL
)
1461 TTV_BASE_LOFIG
->USER
=addptype(TTV_BASE_LOFIG
->USER
, TTV_DONE_PTYPE
, current_ttvfig
);
1463 current_dup_lofig
->LOINS
=(loins_list
*)append((chain_list
*)current_dup_lofig
->LOINS
, (chain_list
*)loins_removed
);
1464 current_dup_lofig
->LOSIG
=(losig_list
*)append((chain_list
*)current_dup_lofig
->LOSIG
, (chain_list
*)losig_removed
);
1467 CALLED_TTV_FUNCTION
=0;
1468 TTV_BASE_LOFIG
=NULL
;
1469 TTV_FUNCTIONS_FILE
= NULL
;
1470 ALL_ADDED_NODES
=NULL
;
1471 current_dup_lofig
=NULL
;
1472 TTV_FORCED_NAME
=NULL
;
1475 IFGNS( ALL_MY_TTV
=addchain(ALL_MY_TTV
, current_ttvfig
); )
1478 //avt_restorecontext ();
1482 ttvfig_list
*ttv_FinishTimingFigure()
1485 if (CheckFirstCallForThisModel()) return NULL
;
1487 ttv_API_Action_Terminate();
1491 void ttv_DriveTimingFigure(ttvfig_list
*tvf
, char *filename
, char *format
)
1493 if (tvf
==NULL
) return;
1494 ttv_disablecache(tvf
);
1495 if (strcasecmp(format
,"dtx")==0)
1496 ttv_drittv (tvf
, TTV_FILE_DTX
, (long)0, filename
);
1497 else if (strcasecmp(format
,"ttx")==0)
1498 ttv_drittv (tvf
, TTV_FILE_TTX
, (long)0, filename
);
1501 avt_errmsg(TTV_API_ERRMSG
, "010", AVT_ERROR
, format
, filename
);
1502 // avt_error("ttvapi", 4, AVT_ERR, "unknown file format '%s' for timing file '%s'\n", format, filename);
1506 stm_drivecell(tvf
->INFO
->FIGNAME
);
1508 void ttv_BuildTiming()
1510 if (CheckFirstCallForThisModel()) return;
1511 ttv_API_Action_Terminate();
1514 void ttv_TasBuiltTiming(lofig_list
*lf
)
1521 //avt_savecontext();
1523 yagenv(tas_yaginit
);
1525 YAG_CONTEXT
->YAG_GENIUS
=FALSE
;
1526 cnsf
=yagDisassemble(lf
->NAME
, lf
, 0);
1528 TAS_CONTEXT
->TAS_LOFIG
=lf
;
1529 TAS_CONTEXT
->TAS_FIND_MIN
= 'Y';
1530 tas_TechnoParameters();
1534 elpLofigAddCapas ( lf
, elpTYPICAL
);
1536 tas_detectinout (cnsf
);
1538 tas_initcnsfigalloc (cnsf
);
1539 tvf
=tas_builtfig(lf
);
1540 tas_loconorient(lf
,tvf
);
1542 tas_timing (cnsf
, lf
, tvf
);
1543 tvf
=tas_cns2ttv(cnsf
, tvf
, lf
);
1544 ttv_setttvdate (tvf
, TTV_DATE_LOCAL
);
1545 tvf
->INFO
->TOOLNAME
= namealloc ("ttv_API_subtas");
1546 tvf
->INFO
->TOOLVERSION
= namealloc ("1.0");
1547 tvf
->INFO
->TECHNONAME
= namealloc ("tas");
1548 tvf
->INFO
->TECHNOVERSION
= namealloc ("1.0");
1549 tvf
->INFO
->SLOPE
= (long)(TTVSLOPE
*1e12
);
1550 tvf
->INFO
->CAPAOUT
= (long)(TTVCAPA
*1e12
);
1552 if (TTVFLAGS
& TTV_DRIVE_DTX
)
1554 ttv_drittv (tvf
, TTV_FILE_DTX
, (long)0, NULL
);
1555 stm_drivecell(tvf
->INSNAME
);
1557 CNS_HEADCNSFIG
= delcnsfig(CNS_HEADCNSFIG
, cnsf
);
1559 ALL_MY_TTV
=addchain(ALL_MY_TTV
, tvf
);
1562 //avt_restorecontext();
1565 void ttv_API_TopLevel(long list
) // commentaire pour desactiver l'ajout de token
1567 chain_list
*cl
=(chain_list
*)list
;
1576 if ((TTVFLAGS
& TTV_INSTANCE_MODE
)==0)
1578 myttvfigs
=addht(1024);
1579 for (ch
=ALL_MY_TTV
; ch
!=NULL
; ch
=ch
->NEXT
)
1581 tvf
=(ttvfig_list
*)ch
->DATA
;
1582 addhtitem(myttvfigs
, tvf
->INSNAME
, (long)tvf
);
1586 for (cl
=(chain_list
*)list
; cl
!=NULL
; cl
=cl
->NEXT
)
1588 li
=(loins_list
*)cl
->DATA
;
1589 if ((TTVFLAGS
& TTV_INSTANCE_MODE
)!=0 || gethtitem(myttvfigs
, li
->INSNAME
)!=EMPTYHT
)
1591 li
->FIGNAME
=li
->INSNAME
;
1595 if ((TTVFLAGS
& TTV_INSTANCE_MODE
)==0)
1600 for (ch
=ALL_MY_TTV
; ch
!=NULL
; ch
=ch
->NEXT
)
1602 tvf
=(ttvfig_list
*)ch
->DATA
;
1604 for (cl
=(chain_list
*)list
; cl
!=NULL
; cl
=cl
->NEXT
)
1606 if (((loins_list
*)cl
->DATA
)->FIGNAME
==tvf
->INSNAME
) break;
1610 ttv_unlockttvfig(tvf
);
1611 if((cell
= stm_getcell(tvf
->INFO
->FIGNAME
)) != NULL
){
1612 stm_freecell(tvf
->INFO
->FIGNAME
) ;
1615 ttv_freeallttvfig(tvf
);
1619 for (cl
=(chain_list
*)list
; cl
!=NULL
; cl
=cl
->NEXT
)
1621 li
=(loins_list
*)cl
->DATA
;
1622 for (lc
=li
->LOCON
; lc
!=NULL
; lc
=lc
->NEXT
)
1624 dir
=mbk_rc_are_internal(li
, lc
);
1627 if (getptype(lc
->SIG
->USER
, TAS_SIG_NORCDELAY
)==NULL
)
1628 lc
->SIG
->USER
=addptype(lc
->SIG
->USER
, TAS_SIG_NORCDELAY
, NULL
);
1635 freechain(ALL_MY_TTV
);
1642 if (TTV_COM
==NULL
) return 0;
1643 if (TTV_COM(TTV_getdelaytype
, &state
)) return 0;
1644 if (state
==TTV_getdelaytype_min
) return 1;
1651 if (TTV_COM
==NULL
) return 0;
1652 if (TTV_COM(TTV_getdelaytype
, &state
)) return 0;
1653 if (state
==TTV_getdelaytype_max
) return 1;
1658 void ASSOCIATE_TIMING(void *func
)
1660 APICallFunc
*cf
=(APICallFunc
*)func
;
1662 HierLofigInfo
*hli
=gethierlofiginfo(CUR_HIER_LOFIG
);
1664 if (TTVFLAGS
& TTV_INSTANCE_MODE
|| hli
->BUILD_TTV
==NULL
)
1666 // ajout a la lofig hierarchique de l'info
1669 if (APIExecAPICallFunc(APIGetExecutionContext(), cf
, &ret
, 0)) EXIT(1);
1677 APIFreeTARGS(cf
->ARGS
);
1682 void ttv_SetLineCommand(ttvline_list
*tl
, char *max_command
, char *min_command
, char *dir
)
1687 if (tl
==NULL
) return;
1689 ttv_dir_to_index(dir
, &a
, &b
);
1690 if (min_command
==NULL
) min_command
=max_command
, b
=a
;
1693 avt_errmsg(TTV_API_ERRMSG
, "009", AVT_ERROR
, gen_info(), dir
);
1694 // avt_error("ttvapi", 3, AVT_ERR, "%s: invalid direction '%s', timing line command creation ignored\n", gen_info(), dir);
1697 if (tl
->ROOT
->ROOT
->TYPE
& TTV_SIG_L
)
1699 tvs
=ttv_AddCommand(max_command
);
1700 ttv_addcmd(tl
, TTV_LINE_CMDMAX
, &tvs
->NODE
[a
]) ;
1701 tvs
=ttv_AddCommand(min_command
);
1702 ttv_addcmd(tl
, TTV_LINE_CMDMIN
, &tvs
->NODE
[b
]) ;
1706 void ttv_SetLineModel(ttvline_list
*tl
, char *modelname
, char *where
)
1711 if (tl
==NULL
) return;
1713 if (strstr(where
,"slope")!=NULL
) slope
=1;
1715 if (strstr(where
,"max")!=NULL
) max
=1;
1723 a
[slope
][max
]=namealloc(modelname
);
1725 if ((tl
->TYPE
& (TTV_LINE_O
|TTV_LINE_U
))==0
1726 || (tl
->TYPE
& TTV_LINE_A
)==TTV_LINE_A
)
1727 ttv_addcaracline(tl
, a
[0][1], a
[0][0], a
[1][1], a
[1][0]);
1729 ttv_addcaracline(tl
, a
[0][1], a
[0][0], NULL
, NULL
);
1732 void ttv_SetTimingFigureName( ttvfig_list
*tvf
, char *name
)
1735 if( !tvf
|| !name
) return ;
1736 aname
= namealloc( name
);
1737 ttv_delhtmodel( tvf
);
1738 if( !stm_renamecell( tvf
->INFO
->FIGNAME
, aname
) ) {
1739 printf( "can't rename stm model\n" );
1741 tvf
->INFO
->FIGNAME
= aname
;
1742 tvf
->INSNAME
= aname
;
1743 ttv_addhtmodel( tvf
);
1746 void ttv_CreateTimingTableModel(ttvfig_list
*tvf
, char *name
, chain_list
*input_slope
, chain_list
*output_capa
, chain_list
*values
, char *type
)
1748 int nbs
, nbc
, slope
, i
, j
;
1749 timing_model
*model
= NULL
;
1750 chain_list
*cl
, *ch
;
1754 IFGNS( if (tvf
==NULL
) tvf
=current_ttvfig
; )
1756 if (tvf
==NULL
) return;
1758 nbs
=countchain(input_slope
);
1759 nbc
=countchain(output_capa
);
1760 if (strcasecmp(type
,"slope-slope")==0) u1
=u2
=1e12
, t1
=t2
=STM_INPUT_SLEW
;
1761 else if (strcasecmp(type
,"slope-ckslope")==0) u1
=u2
=1e12
, t1
=STM_INPUT_SLEW
, t2
=STM_CLOCK_SLEW
;
1762 else if (strcasecmp(type
,"slope-capa")==0) u1
=1e12
, u2
=1e15
, t1
=STM_INPUT_SLEW
, t2
=STM_LOAD
;
1765 avt_errmsg(TTV_API_ERRMSG
, "050", AVT_ERROR
, type
);
1769 if ((i
=countchain(values
))!=nbs
)
1771 avt_errmsg(TTV_API_ERRMSG
, "049", AVT_ERROR
, i
, nbs
);
1775 for (ch
=values
; ch
!=NULL
; ch
=ch
->NEXT
)
1776 if ((i
=countchain((chain_list
*)ch
->DATA
))!=nbc
)
1778 avt_errmsg(TTV_API_ERRMSG
, "049", AVT_ERROR
, i
, nbc
);
1782 name
=namealloc(name
);
1788 stm_addconstmodel(tvf
->INFO
->FIGNAME
, name
, (*(float *)&((chain_list
*)values
->DATA
)->DATA
*1e12
));
1792 model
= stm_addtblmodel (tvf
->INFO
->FIGNAME
, name
, nbc
, 0, t2
, STM_NOTYPE
);
1793 for (cl
=output_capa
, i
=0; i
<nbc
; i
++, cl
=cl
->NEXT
)
1795 stm_modtbl_setXrangeval(model
->UMODEL
.TABLE
, i
, (*(float *)&cl
->DATA
)*u2
);
1797 for (ch
=values
; ch
!=NULL
; ch
=ch
->NEXT
)
1798 for (cl
=(chain_list
*)ch
->DATA
, i
=0; cl
!=NULL
; cl
=cl
->NEXT
, i
++)
1799 stm_modtbl_set1Dval (model
->UMODEL
.TABLE
, i
, (*(float *)&cl
->DATA
)*1e12
);
1804 model
= stm_addtblmodel (tvf
->INFO
->FIGNAME
, name
, nbs
, 0, t1
, STM_NOTYPE
);
1805 for (cl
=input_slope
, i
=0; i
<nbs
; i
++, cl
=cl
->NEXT
)
1807 stm_modtbl_setXrangeval(model
->UMODEL
.TABLE
, i
, (*(float *)&cl
->DATA
)*u1
);
1809 for (cl
=values
, i
=0; cl
!=NULL
; cl
=cl
->NEXT
, i
++)
1810 for (ch
=(chain_list
*)cl
->DATA
; ch
!=NULL
; ch
=ch
->NEXT
)
1811 stm_modtbl_set1Dval (model
->UMODEL
.TABLE
, i
, (*(float *)&ch
->DATA
)*1e12
);
1815 model
= stm_addtblmodel (tvf
->INFO
->FIGNAME
, name
, nbs
, nbc
, t1
, t2
);
1816 for (cl
=input_slope
, i
=0; i
<nbs
; i
++, cl
=cl
->NEXT
)
1818 stm_modtbl_setXrangeval(model
->UMODEL
.TABLE
, i
, (*(float *)&cl
->DATA
)*u1
);
1820 for (cl
=output_capa
, i
=0; i
<nbc
; i
++, cl
=cl
->NEXT
)
1822 stm_modtbl_setYrangeval(model
->UMODEL
.TABLE
, i
, (*(float *)&cl
->DATA
)*u2
);
1824 for (ch
=values
, i
=0; i
<nbs
; i
++, ch
=ch
->NEXT
)
1825 for (j
=0, cl
=(chain_list
*)ch
->DATA
; j
<nbc
; j
++, cl
=cl
->NEXT
)
1827 stm_modtbl_set2Dval(model
->UMODEL
.TABLE
, i
, j
, (*(float *)&cl
->DATA
)*1e12
);
1832 void ttv_CreateEnergyTableModel(ttvfig_list
*tvf
, char *name
, chain_list
*input_slope
, chain_list
*output_capa
, chain_list
*values
, char *type
)
1834 int nbs
, nbc
, slope
, i
, j
;
1835 timing_model
*model
= NULL
;
1836 chain_list
*cl
, *ch
;
1840 IFGNS( if (tvf
==NULL
) tvf
=current_ttvfig
; )
1842 if (tvf
==NULL
) return;
1844 nbs
=countchain(input_slope
);
1845 nbc
=countchain(output_capa
);
1846 if (strcasecmp(type
,"slope-slope")==0) u1
=u2
=1e12
, t1
=t2
=STM_INPUT_SLEW
;
1847 else if (strcasecmp(type
,"slope-ckslope")==0) u1
=u2
=1e12
, t1
=STM_INPUT_SLEW
, t2
=STM_CLOCK_SLEW
;
1848 else if (strcasecmp(type
,"slope-capa")==0) u1
=1e12
, u2
=1e15
, t1
=STM_INPUT_SLEW
, t2
=STM_LOAD
;
1851 avt_errmsg(TTV_API_ERRMSG
, "050", AVT_ERROR
, type
);
1855 if ((i
=countchain(values
))!=nbs
)
1857 avt_errmsg(TTV_API_ERRMSG
, "049", AVT_ERROR
, i
, nbs
);
1861 for (ch
=values
; ch
!=NULL
; ch
=ch
->NEXT
)
1862 if ((i
=countchain((chain_list
*)ch
->DATA
))!=nbc
)
1864 avt_errmsg(TTV_API_ERRMSG
, "049", AVT_ERROR
, i
, nbc
);
1868 name
=namealloc(name
);
1870 model
=stm_getmodel(tvf
->INFO
->FIGNAME
, name
);
1876 model
->ENERGYTYPE
= STM_ENERGY_TABLE
;
1877 model
->ENERGYMODEL
.ETABLE
= stm_modtbl_create(0, 0, STM_NOTYPE
, STM_NOTYPE
);
1878 stm_modtbl_setconst (model
->ENERGYMODEL
.ETABLE
, (*(float *)&((chain_list
*)values
->DATA
)->DATA
));
1882 model
->ENERGYTYPE
= STM_ENERGY_TABLE
;
1883 model
->ENERGYMODEL
.ETABLE
= stm_modtbl_create(nbc
, 0, t2
, STM_NOTYPE
);
1884 for (cl
=output_capa
, i
=0; i
<nbc
; i
++, cl
=cl
->NEXT
)
1886 stm_modtbl_setXrangeval(model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&cl
->DATA
)*u2
);
1888 for (ch
=values
; ch
!=NULL
; ch
=ch
->NEXT
)
1889 for (cl
=(chain_list
*)ch
->DATA
, i
=0; cl
!=NULL
; cl
=cl
->NEXT
, i
++)
1890 stm_modtbl_set1Dval (model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&cl
->DATA
));
1895 model
->ENERGYTYPE
= STM_ENERGY_TABLE
;
1896 model
->ENERGYMODEL
.ETABLE
= stm_modtbl_create(nbs
, 0, t1
, STM_NOTYPE
);
1897 for (cl
=input_slope
, i
=0; i
<nbs
; i
++, cl
=cl
->NEXT
)
1899 stm_modtbl_setXrangeval(model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&cl
->DATA
)*u1
);
1901 for (cl
=values
, i
=0; cl
!=NULL
; cl
=cl
->NEXT
, i
++)
1902 for (ch
=(chain_list
*)cl
->DATA
; ch
!=NULL
; ch
=ch
->NEXT
)
1903 stm_modtbl_set1Dval (model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&ch
->DATA
));
1907 model
->ENERGYTYPE
= STM_ENERGY_TABLE
;
1908 model
->ENERGYMODEL
.ETABLE
= stm_modtbl_create(nbs
, nbc
, t1
, t2
);
1909 for (cl
=input_slope
, i
=0; i
<nbs
; i
++, cl
=cl
->NEXT
)
1911 stm_modtbl_setXrangeval(model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&cl
->DATA
)*u1
);
1913 for (cl
=output_capa
, i
=0; i
<nbc
; i
++, cl
=cl
->NEXT
)
1915 stm_modtbl_setYrangeval(model
->ENERGYMODEL
.ETABLE
, i
, (*(float *)&cl
->DATA
)*u2
);
1917 for (ch
=values
, i
=0; i
<nbs
; i
++, ch
=ch
->NEXT
)
1918 for (j
=0, cl
=(chain_list
*)ch
->DATA
; j
<nbc
; j
++, cl
=cl
->NEXT
)
1920 stm_modtbl_set2Dval(model
->ENERGYMODEL
.ETABLE
, i
, j
, (*(float *)&cl
->DATA
));
1926 chain_list
*ttv_CharacTimingLineModel(ttvfig_list
*tvf
, char *name
, chain_list
*input_slope
, chain_list
*output_capa
, char *type
)
1928 int nbs
, nbc
, slope
, i
, j
, cst
=0;
1929 timing_model
*model
= NULL
;
1930 chain_list
*cl
, *ch
, *res
, *res1
;
1931 float si
, sc
, u1
, u2
, val
;
1935 IFGNS( if (tvf
==NULL
) tvf
=current_ttvfig
; )
1937 if (tvf
==NULL
) return NULL
;
1939 nbs
=countchain(input_slope
);
1940 nbc
=countchain(output_capa
);
1941 if (strcasecmp(type
,"slope-slope")==0) u1
=u2
=1e12
, cst
=1;
1942 else if (strcasecmp(type
,"slope-capa:delay")==0) u1
=u2
=1e12
, cst
=2;
1943 else if (strcasecmp(type
,"slope-capa:slope")==0) u1
=1e12
, u2
=1e15
;
1946 avt_errmsg(TTV_API_ERRMSG
, "050", AVT_ERROR
, type
);
1950 name
=namealloc(name
);
1951 cellname
=tvf
->INFO
->FIGNAME
;
1954 for (ch
=input_slope
; ch
!=NULL
; ch
=ch
->NEXT
)
1956 si
=(*(float *)&ch
->DATA
)*u1
;
1958 for (cl
=output_capa
; cl
!=NULL
; cl
=cl
->NEXT
)
1960 sc
=(*(float *)&cl
->DATA
)*u2
;
1962 val
=stm_getconstraint(cellname
, name
, si
, sc
);
1964 val
=stm_getdelay(cellname
, name
, sc
, si
, NULL
, NULL
);
1966 val
=stm_getslew(cellname
, name
, sc
, si
, NULL
, NULL
, NULL
);
1967 res1
=addchain(res1
, NULL
);
1968 *(float *)&res1
->DATA
=val
*1e-12;
1970 res
=addchain(res
, reverse(res1
));
1976 int ttv_LoadSSTAResults(ttvfig_list
*tvf
, chain_list
*filenames
, chain_list
*order
)
1979 if (tvf
==NULL
) return 0;
1980 for (cl
=order
; cl
!=NULL
; cl
=cl
->NEXT
)
1982 if (countchain((chain_list
*)cl
->DATA
)!=2)
1984 avt_errmsg(TTV_API_ERRMSG
, "053", AVT_ERROR
);
1988 return ttv_ssta_loadresults(tvf
, filenames
, order
);
1991 int ttv_SetSSTARunNumber(ttvfig_list
*tvf
, int num
)
1993 return ttv_ssta_set_run_number(tvf
, num
-1);
1996 int ttv_BuildSSTALineStats(ttvfig_list
*tvf
)
1998 return ttv_ssta_buildlinestat(tvf
);