14 #define API_USE_REAL_TYPES
15 #include "ttv_API_LOCAL.h"
17 #include "ttv_API_display.h"
18 #include "ttv_API_util.h"
21 static void recur_run(ttvfig_list
*tvf
, long slopein
, ttvevent_list
*a
, chain_list
*nextnodelist
, chain_list
**lst
, chain_list
**config
, char dirend
, long minmax
, chain_list
**allsearch
)
23 ttvpath_list
*path_list
, *pth
;
24 ttvsig_list
*tvsend
, *tvs2
;
25 long slopeout
, findcmd
=0, savelastslope
;
28 chain_list
*cl
, *savenodelist
, *ch
;
30 dir
[0]=ttv_GetTimingEventDirection(a
);
32 if (nextnodelist
!=NULL
)
34 savelastslope
=TTV_PROPAGATE_FORCED_SLOPE
;
35 if (slopein
!=0) TTV_PROPAGATE_FORCED_SLOPE
=slopein
;
37 cl
=(chain_list
*)nextnodelist
->DATA
;
38 nextnodelist
=nextnodelist
->NEXT
;
39 if (cl
!=NULL
&& cl
->DATA
==NULL
) doaccess
=1, cl
=cl
->NEXT
;
44 tvsend
=(ttvsig_list
*)cl
->DATA
;
47 if (doaccess
&& nextnodelist
!=NULL
&& (tvsend
->TYPE
& (TTV_SIG_L
|TTV_SIG_B
))!=0)
49 savenodelist
=nextnodelist
;
50 ch
=(chain_list
*)nextnodelist
->DATA
;
51 nextnodelist
=nextnodelist
->NEXT
;
52 if (ch
!=NULL
&& ch
->DATA
==NULL
) ch
=ch
->NEXT
;
56 tvs2
=(ttvsig_list
*)ch
->DATA
;
58 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
60 a
->ROOT
->NODE
->TYPE
|= TTV_NODE_STOP
;
61 (a
->ROOT
->NODE
+1)->TYPE
|= TTV_NODE_STOP
;
62 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
63 TTV_MORE_SEARCH_OPTIONS
|=TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
65 if ((a
->ROOT
->TYPE
& TTV_SIG_Q
) != 0)
68 // pour que les falsepaths s'appliquent
69 if ((tvs2
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
71 tvs2
->NODE
->TYPE
|=TTV_NODE_STOP
;
72 (tvs2
->NODE
+1)->TYPE
|=TTV_NODE_STOP
;
76 path_list
=ttv_getsigaccesslist (tvf
, tvsend
, tvs2
, a
->ROOT
, dir
, 0, minmax
|findcmd
, 0, 0);
79 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
81 a
->ROOT
->NODE
->TYPE
&= ~TTV_NODE_STOP
;
82 (a
->ROOT
->NODE
+1)->TYPE
&= ~TTV_NODE_STOP
;
83 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
84 TTV_MORE_SEARCH_OPTIONS
&=~TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
87 // pour que les falsepaths s'appliquent
88 if ((tvs2
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
90 tvs2
->NODE
->TYPE
&=~TTV_NODE_STOP
;
91 (tvs2
->NODE
+1)->TYPE
&=~TTV_NODE_STOP
;
97 *allsearch
=addchain(*allsearch
, path_list
);
99 for (pth
=path_list
; pth
!=NULL
; pth
=pth
->NEXT
)
101 if (!(nextnodelist
!=NULL
&& ttv_PathIsHZ(pth
)))
103 *lst
=addchain(*lst
, pth
);
106 recur_run(tvf
, slopeout
, pth
->ROOT
, nextnodelist
, lst
, config
, dirend
, minmax
, allsearch
);
108 *lst
=delchain(*lst
, *lst
);
114 nextnodelist
=savenodelist
;
120 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
122 a
->ROOT
->NODE
->TYPE
|= TTV_NODE_STOP
;
123 (a
->ROOT
->NODE
+1)->TYPE
|= TTV_NODE_STOP
;
124 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
125 TTV_MORE_SEARCH_OPTIONS
|=TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
127 if ((a
->ROOT
->TYPE
& TTV_SIG_Q
) != 0)
128 findcmd
=TTV_FIND_CMD
;
130 // pour que les falsepaths s'appliquent
131 if ((tvsend
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
133 tvsend
->NODE
->TYPE
|=TTV_NODE_STOP
;
134 (tvsend
->NODE
+1)->TYPE
|=TTV_NODE_STOP
;
137 path_list
=ttv_getcritic_pathlist (tvf
, a
->ROOT
, tvsend
, dir
, 0, minmax
|findcmd
, 0, 0, 0);
139 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
141 a
->ROOT
->NODE
->TYPE
&= ~TTV_NODE_STOP
;
142 (a
->ROOT
->NODE
+1)->TYPE
&= ~TTV_NODE_STOP
;
143 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
144 TTV_MORE_SEARCH_OPTIONS
&=~TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
147 // pour que les falsepaths s'appliquent
148 if ((tvsend
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
150 tvsend
->NODE
->TYPE
&=~TTV_NODE_STOP
;
151 (tvsend
->NODE
+1)->TYPE
&=~TTV_NODE_STOP
;
156 *allsearch
=addchain(*allsearch
, path_list
);
158 for (pth
=path_list
; pth
!=NULL
; pth
=pth
->NEXT
)
160 if (!(nextnodelist
!=NULL
&& ttv_PathIsHZ(pth
)))
162 *lst
=addchain(*lst
, pth
);
165 recur_run(tvf
, slopeout
, pth
->ROOT
, nextnodelist
, lst
, config
, dirend
, minmax
, allsearch
);
167 *lst
=delchain(*lst
, *lst
);
174 TTV_PROPAGATE_FORCED_SLOPE
=savelastslope
;
178 if (dirend
=='?' || dirend
==dir
[0])
179 *config
=addchain(*config
, reverse(dupchainlst(*lst
)));
183 // renvoie le front d'ouverture le plus tard ou tot selon le type de recherche
184 static ttvevent_list
*getgoodclockevent(stbfig_list
*stbfig
, ttvevent_list
*latch
, long type
)
186 long lastopen
, open
, move
;
187 ttvevent_list
*tve
=NULL
, *cmd
;
190 chain_list
*cmds
=NULL
, *cl
;
192 node
=stb_getstbnode(latch
);
195 // stb_getlatchslope modifie la structure donc on garde une liste a part
196 for (ck
=node
->CK
; ck
!=NULL
; ck
=ck
->NEXT
) cmds
=addchain(cmds
, ck
->CMD
);
198 for (cl
=cmds
; cl
!=NULL
; cl
=cl
->NEXT
)
200 cmd
=(ttvevent_list
*)cl
->DATA
;
203 if ((type
& TTV_FIND_MAX
)==TTV_FIND_MAX
)
205 stb_getlatchslope(stbfig
,latch
,cmd
,&open
,NULL
,NULL
,NULL
,NULL
,1,STB_NO_INDEX
,&move
);
206 if (tve
==NULL
|| lastopen
<open
) lastopen
=open
, tve
=cmd
;
210 stb_getlatchslope(stbfig
,latch
,cmd
,NULL
,&open
,NULL
,NULL
,NULL
,1,STB_NO_INDEX
,&move
);
211 if (tve
==NULL
|| open
>lastopen
) lastopen
=open
, tve
=cmd
;
220 #define CLIPCTK 0x0fab1
221 #define CLIPREF 0x0fab2
223 static void performstbclipping(ttvfig_list
*tvf
, chain_list
*head
, long type
)
226 long lastopen
=TTV_NOTIME
, lastclose
;
227 long openmax
, openmin
, closemax
, closemin
, period
, deltaref
, deltactk
, open
, close
, move
;
228 long timeref
=0, timectk
=0, err
;
230 ttvevent_list
*tve
, *newtve
;
231 stbfig_list
*stbfig
=NULL
;
234 if ((stbfig
=stb_getstbfig(tvf
))==NULL
) return;
236 for (cl
=head
; cl
!=NULL
&& cl
->NEXT
!=NULL
; cl
=cl
->NEXT
)
238 tph
=(ttvpath_list
*)cl
->DATA
;
240 timeref
+=tph
->REFDELAY
;
243 if ((tve
=ttv_GetPathCommand(tph
))!=NULL
)
245 if ((newtve
=getgoodclockevent(stbfig
, tph
->ROOT
, type
))!=NULL
)
247 stb_getlatchslope(stbfig
,tph
->ROOT
,tve
,&openmax
,&openmin
,&closemax
,&closemin
,&period
,1,STB_NO_INDEX
,&move
);
248 if ((type
& TTV_FIND_MAX
)==0) openmax
=openmin
, closemax
=closemin
;
250 if (lastopen
==TTV_NOTIME
)
256 if (openmax
<lastopen
)
258 open
=openmax
+period
-lastopen
, close
=closemax
+period
-lastopen
;
262 open
=openmax
-lastopen
, close
=closemax
-lastopen
;
264 if (timeref
<open
) deltaref
=open
-timeref
; else deltaref
=0;
265 if (timectk
<open
) deltactk
=open
-timectk
; else deltactk
=0;
266 if (timeref
>close
|| timectk
>close
)
269 if (timectk
-close
>err
) err
=timectk
-close
;
270 avt_errmsg(TTV_API_ERRMSG
, "033", AVT_WARNING
, ttv_GetFullSignalName_COND(tvf
, tph
->ROOT
->ROOT
), err
/TTV_UNIT
);
271 // avt_error("ttvapi", -1, AVT_WAR, "stability error found at node %s: data too late by %.1fps\n", ttv_GetFullSignalName_COND(tvf, tph->ROOT->ROOT), err/TTV_UNIT);
272 if (timeref
>close
) timeref
=close
;
273 if (timectk
>close
) timectk
=close
;
275 if ((pt
=getptype(tph
->USER
, CLIPCTK
))==NULL
) pt
=tph
->USER
=addptype(tph
->USER
, CLIPCTK
, 0);
276 pt
->DATA
=(void *)deltactk
;
277 if ((pt
=getptype(tph
->USER
, CLIPREF
))==NULL
) pt
=tph
->USER
=addptype(tph
->USER
, CLIPREF
, 0);
278 pt
->DATA
=(void *)deltaref
;
280 timeref
=timeref
+deltaref
-open
;
281 timectk
=timectk
+deltactk
-open
;
290 static long getdatadelta(ttvpath_list
*pth
, long type
)
293 if ((pt
=getptype(pth
->USER
, type
))!=NULL
)
294 return (long)pt
->DATA
;
298 // retourne le delay total ref ou normal
299 static double getconfigdelay(chain_list
*head
, char type
, double *slope
)
304 for (cl
=head
; cl
!=NULL
; cl
=cl
->NEXT
)
306 tph
=(ttvpath_list
*)cl
->DATA
;
309 case 'n': delay
+=ttv_GetPathDelay(tph
)+getdatadelta(tph
, CLIPCTK
)*1e-12/TTV_UNIT
; break;
310 case 'r': delay
+=ttv_GetPathRefDelay(tph
)+getdatadelta(tph
, CLIPREF
)*1e-12/TTV_UNIT
; break;
315 case 'n': *slope
=ttv_GetPathSlope(tph
); break;
316 case 'r': *slope
=ttv_GetPathRefSlope(tph
); break;
321 // recupere le min ou max des paths pour une config de l'e/s
322 static void removebadconfig(chain_list
*headconfig
, char dirstart
, char dirend
, long search
)
324 chain_list
*lastconfig
=NULL
, *cl
, *ch
;
325 double lastdelay
, thisdelay
, slope
;
326 ttvpath_list
*tph
, *lastfirstpath
=NULL
, *fpt
;
329 if ((search
& TTV_FIND_MAX
)!=0) max
=1; else max
=0;
331 for (cl
=headconfig
; cl
!=NULL
; cl
=cl
->NEXT
)
335 ch
=(chain_list
*)cl
->DATA
;
336 fpt
=tph
=(ttvpath_list
*)ch
->DATA
;
337 if (ttv_GetPathStartDirection(tph
)==dirstart
)
339 while (ch
->NEXT
!=NULL
) ch
=ch
->NEXT
;
340 tph
=(ttvpath_list
*)ch
->DATA
;
341 if (ttv_GetPathEndDirection(tph
)==dirend
)
343 thisdelay
=getconfigdelay((chain_list
*)cl
->DATA
, 'n', &slope
);
344 if (lastconfig
==NULL
|| (max
&& thisdelay
>lastdelay
) || (!max
&& thisdelay
<lastdelay
))
346 if (lastconfig
!=NULL
) { freechain((chain_list
*)lastconfig
->DATA
); lastconfig
->DATA
=NULL
; }
356 // cree un path global pour une config
357 static ttvpath_list
*buildconfigpath(chain_list
*config
, ttvpath_list
*last
)
360 double delay
, delayref
, slope
, sloperef
;
361 ttvpath_list
*pt
, *newpth
, *ptend
;
364 pt
=(ttvpath_list
*)ch
->DATA
;
365 while (ch
->NEXT
!=NULL
) ch
=ch
->NEXT
;
366 ptend
=(ttvpath_list
*)ch
->DATA
;
368 delay
=getconfigdelay(config
, 'n', &slope
);
369 delayref
=getconfigdelay(config
, 'n', &sloperef
);
371 newpth
=ttv_allocpath(last
,
383 mbk_long_round(delayref
*1e12
*TTV_UNIT
),
384 mbk_long_round(sloperef
*1e12
*TTV_UNIT
),
385 mbk_long_round(delay
*1e12
*TTV_UNIT
),
386 mbk_long_round(slope
*1e12
*TTV_UNIT
),
399 // cree un detail global pour une config
400 static ttvcritic_list
*buildconfigdetail(chain_list
*config
)
404 ttvcritic_list
*tc
, *newtc
=NULL
, *emptytc
;
406 for (ch
=config
; ch
!=NULL
; ch
=ch
->NEXT
)
408 pt
=(ttvpath_list
*)ch
->DATA
;
409 for (tc
=pt
->CRITIC
; tc
!=NULL
; tc
=tc
->NEXT
)
411 if (!(ch
!=config
&& tc
==pt
->CRITIC
))
413 emptytc
=ttv_alloccritic(
428 if ((emptytc
->NODE_FLAG
& TTV_NODE_FLAG_NOALLOC
)==0)
430 mbkfree(emptytc
->NAME
);
431 mbkfree(emptytc
->NETNAME
);
433 memcpy(emptytc
, tc
, sizeof(*tc
));
437 emptytc
->DELAY
+=getdatadelta(pt
, CLIPCTK
);
438 emptytc
->REFDELAY
+=getdatadelta(pt
, CLIPREF
);
440 if ((tc
->NODE_FLAG
& TTV_NODE_FLAG_NOALLOC
)==0)
442 emptytc
->NAME
=mbkstrdup(tc
->NAME
);
443 emptytc
->NETNAME
=mbkstrdup(tc
->NETNAME
);
450 return (ttvcritic_list
*)reverse((chain_list
*)newtc
);
453 static chain_list
*filterpath(chain_list
*lst
, int max
)
460 for(cl
=lst
, i
=1; i
<max
&& cl
!=NULL
; cl
=cl
->NEXT
, i
++) ;
463 ttv_FreePathList(cl
->NEXT
);
471 static void freedoublechain(chain_list
*cl
)
475 freechain((chain_list
*)cl
->DATA
);
480 chain_list
*ttv_ProbeDelay_sub(ttvfig_list
*tvf
, double slopein
, chain_list
*nodenamelist
, char *dir
, int nbpath
, char *path_or_access
, char *minmax
, int nosync
, int noprop
)
482 chain_list
*cl
, *mask
, *nodelist
, *ch
, *allsearch
=NULL
, *ch0
;
483 ttvpath_list
*path_list
, *pth
;
486 chain_list
*config
=NULL
, *nlist
;
487 char *oldmode
, d0
, d1
;
488 int oldprop
, path
, cnt
;
489 long lastslope
=mbk_long_round(slopein
*1e12
*TTV_UNIT
);
490 long oldexstart
, oldexend
, mode
;
492 API_TEST_TOKEN_SUB(TMA_API
,"tma")
494 if (nbpath
<0) nbpath
=0;
496 if (!strcasecmp (minmax
, "max")) minmax_i
= TTV_FIND_MAX
;
497 else if (!strcasecmp (minmax
, "min")) minmax_i
= TTV_FIND_MIN
;
500 avt_errmsg(TTV_API_ERRMSG
, "022", AVT_ERROR
);
501 // fprintf (stderr, "ttv_ProbeDelay: error: available values for 'minmax' are 'min' or 'max'\n");
505 if (!strcasecmp (path_or_access
, "path")) path
=1;
506 else if (!strcasecmp (path_or_access
, "access")) path
=0;
507 else if (strcasecmp (path_or_access
, "-")!=0)
509 avt_errmsg(TTV_API_ERRMSG
, "024", AVT_ERROR
);
510 // fprintf (stderr, "ttv_ProbeDelay: error: available values for 'path_or_access' are 'path' or 'access'\n");
515 if (path
==1 && countchain(nodenamelist
)<2)
517 avt_errmsg(TTV_API_ERRMSG
, "035", AVT_ERROR
, 2);
518 //fprintf (stderr, "ttv_ProbeDelay: at least 2 node names are required for the function to run\n");
522 if (path
==0 && countchain(nodenamelist
)<3)
524 avt_errmsg(TTV_API_ERRMSG
, "035", AVT_ERROR
, 3);
525 // fprintf (stderr, "ttv_ProbeDelay: at least 3 node names are required for the function to run\n");
529 if (tvf
==NULL
) return NULL
;
531 // ttv_checkinfchange(tvf);
532 if ((ttv_getloadedfigtypes(tvf
) & TTV_FILE_DTX
)==TTV_FILE_DTX
) mode
=TTV_FILE_DTX
;
533 else mode
=TTV_FILE_TTX
;
535 for (cl
=nodenamelist
, nodelist
=NULL
; cl
!=NULL
; cl
=cl
->NEXT
)
537 char *var
=(char *)cl
->DATA
;
538 unsigned int i
, access
=0;
539 const char *as
="-access";
551 if (strncasecmp(var
,as
,strlen(as
))==0) { var
=&var
[strlen(as
)]; access
=1; }
552 if (path
==0 && cl
==nodenamelist
->NEXT
) access
=1;
553 if (cl
==nodenamelist
|| cl
->NEXT
==NULL
) access
=0;
555 for (i
=0; i
<sizeof(pref
)/sizeof(*pref
); i
++)
557 if (strncasecmp(var
,pref
[i
],strlen(pref
[i
]))==0) { var
=&var
[strlen(pref
[i
])]; break; }
559 if (i
>=sizeof(pref
)/sizeof(*pref
) && access
) var
=(char *)cl
->DATA
;
560 if (i
>=sizeof(pref
)/sizeof(*pref
) || i
==0 || i
==4) stype
=(access
==0)?TTV_SIG_TYPEALL
:TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
;
561 if (i
==1) stype
=TTV_SIG_L
;
562 if (i
==2) stype
=TTV_SIG_R
;
563 if (i
==3) stype
=TTV_SIG_C
;
564 if ((i
==5 || i
>=sizeof(pref
)/sizeof(*pref
)) && cl
!=nodenamelist
&& cl
->NEXT
!=NULL
) stype
=TTV_SIG_L
;
566 tvs
=ttv_GetTimingSignal(tvf
, var
);
569 if (i
>=sizeof(pref
)/sizeof(*pref
) || (tvs
->TYPE
& stype
)!=0) ch
=addchain(NULL
, tvs
);
574 if (i
>=sizeof(pref
)/sizeof(*pref
) && !mbk_isregex_name(var
))
575 stype
=(access
==0)?TTV_SIG_TYPEALL
:TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
;
577 ch
=ttv_getsigbytype_and_netname(tvf
,NULL
,stype
,mask
=addchain(NULL
, namealloc(var
)));
581 for (ch0
=ch
; ch0
!=NULL
; ch0
=ch0
->NEXT
)
583 tvs
=(ttvsig_list
*)ch0
->DATA
;
584 if ((tvs
->TYPE
& (TTV_SIG_C
|TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
))!=0 || ttv_isgateoutput(tvf
, tvs
, mode
))
585 nlist
=addchain(nlist
, tvs
);
590 if (access
&& ch
!=NULL
) ch
=addchain(ch
,NULL
);
593 avt_errmsg(TTV_API_ERRMSG
, "034", AVT_ERROR
, (char *)cl
->DATA
);
595 freedoublechain(nodelist
);
598 if ((cnt
=countchain(ch
))>10000)
599 avt_errmsg(TTV_API_ERRMSG
, "047", AVT_ERROR
, (char *)cl
->DATA
, cnt
);
600 nodelist
=addchain(nodelist
, ch
);
602 nodelist
=reverse(nodelist
);
604 if (lastslope
<=0 || noprop
)
607 ttv_setsearchexclude(0, 0, &oldexstart
, &oldexend
);
609 oldprop
=ttv_SetPrecisionLevel(1);
610 oldmode
=ttv_AutomaticDetailBuild("on");
613 d0
=ttv_getUorD(dir
[0]);
614 d1
=ttv_getUorD(dir
[1]);
616 for (cl
=(chain_list
*)nodelist
->DATA
; cl
!=NULL
; cl
=cl
->NEXT
)
618 tvs
=(ttvsig_list
*)cl
->DATA
;
619 if (d0
=='d' || d0
=='?')
620 recur_run(tvf
, lastslope
, tvs
->NODE
, nodelist
->NEXT
, &mask
, &config
, d1
, minmax_i
, &allsearch
);
621 if (d0
=='u' || d0
=='?')
622 recur_run(tvf
, lastslope
, tvs
->NODE
+1, nodelist
->NEXT
, &mask
, &config
, d1
, minmax_i
, &allsearch
);
625 freedoublechain(nodelist
);
626 ttv_AutomaticDetailBuild(oldmode
);
628 ttv_SetPrecisionLevel(oldprop
);
629 ttv_setsearchexclude(oldexstart
, oldexend
, &oldexstart
, &oldexend
);
631 // creation des details
632 if (countchain(nodenamelist
)==2)
634 config
=reverse(config
);
636 for (cl
=config
, ch
=NULL
; cl
!=NULL
; cl
=cl
->NEXT
)
638 path_list
=((chain_list
*)(cl
->DATA
))->DATA
;
639 path_list
->USER
=addptype(path_list
->USER
, CLIPCTK
, NULL
);
641 if (ch
==NULL
) path_list
->NEXT
=NULL
;
642 else path_list
->NEXT
=(ttvpath_list
*)ch
->DATA
;
643 ch
=addchain(ch
, path_list
);
644 freechain((chain_list
*)cl
->DATA
);
650 pth
=(ttvpath_list
*)allsearch
->DATA
;
651 if (getptype(pth
->USER
, CLIPCTK
)==NULL
)
654 ttv_freepathlist(pth
);
657 pth
->USER
=delptype(pth
->USER
, CLIPCTK
);
658 allsearch
=delchain(allsearch
, allsearch
);
661 path_list
=ttv_classpath(path_list
, minmax_i
);
664 while (path_list
!=NULL
)
666 ch
=addchain(ch
, path_list
);
667 path_list
=path_list
->NEXT
;
675 /* removebadconfig(config, 'u', 'u', minmax_i);
676 removebadconfig(config, 'u', 'd', minmax_i);
677 removebadconfig(config, 'd', 'u', minmax_i);
678 removebadconfig(config, 'd', 'd', minmax_i);*/
681 for (cl
=config
; cl
!=NULL
; cl
=cl
->NEXT
)
685 if (!nosync
) performstbclipping(tvf
, (chain_list
*)cl
->DATA
, minmax_i
);
686 path_list
=buildconfigpath((chain_list
*)cl
->DATA
, path_list
);
687 path_list
->CRITIC
=buildconfigdetail((chain_list
*)cl
->DATA
);
690 path_list
=ttv_classpath(path_list
, minmax_i
);
691 while (path_list
!=NULL
)
693 ch
=addchain(ch
, path_list
);
694 path_list
=path_list
->NEXT
;
699 for (cl
=config
; cl
!=NULL
; cl
=cl
->NEXT
)
702 freechain((chain_list
*)cl
->DATA
);
705 for (cl
=allsearch
; cl
!=NULL
; cl
=cl
->NEXT
)
707 for (path_list
=(ttvpath_list
*)cl
->DATA
; path_list
!=NULL
; path_list
=path_list
->NEXT
)
709 path_list
->USER
=testanddelptype(path_list
->USER
, CLIPCTK
);
710 path_list
->USER
=testanddelptype(path_list
->USER
, CLIPREF
);
712 ttv_freepathlist((ttvpath_list
*)cl
->DATA
);
714 freechain(allsearch
);
717 ch
=filterpath(ch
, nbpath
);
721 // ------------------------------------------ V2 -----------------------------------------------------------------
722 static int allow_signal(chain_list
*lst
, ttvsig_list
*tvs
, int depth
)
726 for (cl
=lst
; cl
!=NULL
; cl
=cl
->NEXT
)
728 pth
=(ttvpath_list
*)cl
->DATA
;
729 if (pth
->NODE
->ROOT
==tvs
) return 0;
730 // if (pth->ROOT->ROOT==tvs) return 0;
735 static void recur_run_v2(ttvfig_list
*tvf
, long slopein
, ttvevent_list
*a
, ttvsig_list
*end
, chain_list
**lst
, chain_list
**config
, char dirend
, long minmax
, chain_list
**allsearch
, int depth
)
737 ttvpath_list
*path_list
, *pth
;
738 long slopeout
, findcmd
=0, savelastslope
;
741 if (depth
>0 && a
->ROOT
==end
)
743 if (dirend
=='?' || dirend
==ttv_GetTimingEventDirection(pth
->ROOT
))
745 *config
=addchain(*config
, reverse(dupchainlst(*lst
)));
750 if (depth
>10) return;
752 if (!allow_signal(*lst
, a
->ROOT
, depth
)) return;
755 dir
[0]=ttv_GetTimingEventDirection(a
);
757 savelastslope
=TTV_PROPAGATE_FORCED_SLOPE
;
758 if (slopein
!=0) TTV_PROPAGATE_FORCED_SLOPE
=slopein
;
761 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
763 a
->ROOT
->NODE
->TYPE
|= TTV_NODE_STOP
;
764 (a
->ROOT
->NODE
+1)->TYPE
|= TTV_NODE_STOP
;
765 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
766 TTV_MORE_SEARCH_OPTIONS
|=TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
768 if ((a
->ROOT
->TYPE
& TTV_SIG_Q
) != 0)
769 findcmd
=TTV_FIND_CMD
;
771 // pour que les falsepaths s'appliquent
772 if ((end
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
774 end
->NODE
->TYPE
|=TTV_NODE_STOP
;
775 (end
->NODE
+1)->TYPE
|=TTV_NODE_STOP
;
779 path_list
=ttv_getsigaccesslist (tvf
, a
->ROOT
, NULL
, a
->ROOT
, dir
, 0, minmax
|findcmd
, 0, 0);
782 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
784 a
->ROOT
->NODE
->TYPE
&= ~TTV_NODE_STOP
;
785 (a
->ROOT
->NODE
+1)->TYPE
&= ~TTV_NODE_STOP
;
786 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
787 TTV_MORE_SEARCH_OPTIONS
&=~TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
790 // pour que les falsepaths s'appliquent
791 if ((end
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
793 end
->NODE
->TYPE
&=~TTV_NODE_STOP
;
794 (end
->NODE
+1)->TYPE
&=~TTV_NODE_STOP
;
800 *allsearch
=addchain(*allsearch
, path_list
);
802 for (pth
=path_list
; pth
!=NULL
; pth
=pth
->NEXT
)
804 if (pth
->ROOT
->ROOT
==end
|| !ttv_PathIsHZ(pth
))
806 *lst
=addchain(*lst
, pth
);
809 recur_run_v2(tvf
, slopeout
, pth
->ROOT
, end
, lst
, config
, dirend
, minmax
, allsearch
, depth
+1);
811 *lst
=delchain(*lst
, *lst
);
817 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
819 a
->ROOT
->NODE
->TYPE
|= TTV_NODE_STOP
;
820 (a
->ROOT
->NODE
+1)->TYPE
|= TTV_NODE_STOP
;
821 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
822 TTV_MORE_SEARCH_OPTIONS
|=TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
824 if ((a
->ROOT
->TYPE
& TTV_SIG_Q
) != 0)
825 findcmd
=TTV_FIND_CMD
;
827 // pour que les falsepaths s'appliquent
828 if ((end
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
830 end
->NODE
->TYPE
|=TTV_NODE_STOP
;
831 (end
->NODE
+1)->TYPE
|=TTV_NODE_STOP
;
834 path_list
=ttv_getcritic_pathlist (tvf
, a
->ROOT
, NULL
, dir
, 0, minmax
|findcmd
, 0, 0, 0);
836 if((a
->ROOT
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
838 a
->ROOT
->NODE
->TYPE
&= ~TTV_NODE_STOP
;
839 (a
->ROOT
->NODE
+1)->TYPE
&= ~TTV_NODE_STOP
;
840 if ((a
->ROOT
->TYPE
& TTV_SIG_N
) != 0)
841 TTV_MORE_SEARCH_OPTIONS
&=~TTV_MORE_OPTIONS_ENABLE_STOP_ON_TTV_SIG_N
;
844 // pour que les falsepaths s'appliquent
845 if ((end
->TYPE
& (TTV_SIG_C
| TTV_SIG_L
| TTV_SIG_R
| TTV_SIG_B
)) == 0)
847 end
->NODE
->TYPE
&=~TTV_NODE_STOP
;
848 (end
->NODE
+1)->TYPE
&=~TTV_NODE_STOP
;
853 *allsearch
=addchain(*allsearch
, path_list
);
855 for (pth
=path_list
; pth
!=NULL
; pth
=pth
->NEXT
)
857 if (pth
->ROOT
->ROOT
==end
|| ((pth
->ROOT
->ROOT
->TYPE
& (TTV_SIG_R
|TTV_SIG_Q
))==0 && !ttv_PathIsHZ(pth
)))
859 *lst
=addchain(*lst
, pth
);
862 recur_run_v2(tvf
, slopeout
, pth
->ROOT
, end
, lst
, config
, dirend
, minmax
, allsearch
, depth
+1);
864 *lst
=delchain(*lst
, *lst
);
869 TTV_PROPAGATE_FORCED_SLOPE
=savelastslope
;
873 chain_list
*ttv_ProbeDelay_v2(ttvfig_list
*tvf
, double slopein
, char *start
, char *end
, char *dir
, int nbpath
, char *minmax
)
875 chain_list
*cl
, *mask
, *ch
, *allsearch
=NULL
;
876 ttvpath_list
*path_list
;
877 ttvsig_list
*tvs_start
, *tvs_end
;
879 chain_list
*config
=NULL
;
880 char *oldmode
, d0
, d1
;
882 long lastslope
=mbk_long_round(slopein
*1e12
*TTV_UNIT
);
883 long oldexstart
, oldexend
;
885 if (nbpath
<0) nbpath
=0;
887 if (!strcasecmp (minmax
, "max")) minmax_i
= TTV_FIND_MAX
;
888 else if (!strcasecmp (minmax
, "min")) minmax_i
= TTV_FIND_MIN
;
891 avt_errmsg(TTV_API_ERRMSG
, "022", AVT_ERROR
);
892 // fprintf (stderr, "ttv_ProbeDelay: error: available values for 'minmax' are 'min' or 'max'\n");
896 tvs_start
=ttv_GetTimingSignal(tvf
, start
);
897 tvs_end
=ttv_GetTimingSignal(tvf
, end
);
901 avt_errmsg(TTV_API_ERRMSG
, "034", AVT_ERROR
, start
);
902 // avt_error("ttvapi", -1, AVT_ERR, "ttv_ProbeDelay: could not find node '%s'\n", start);
907 avt_errmsg(TTV_API_ERRMSG
, "034", AVT_ERROR
, end
);
908 //avt_error("ttvapi", -1, AVT_ERR, "ttv_ProbeDelay: could not find node '%s'\n", end);
915 // ttv_checkinfchange(tvf);
917 ttv_setsearchexclude(0, 0, &oldexstart
, &oldexend
);
918 oldprop
=ttv_SetPrecisionLevel(1);
919 oldmode
=ttv_AutomaticDetailBuild("on");
922 d0
=ttv_getUorD(dir
[0]);
923 d1
=ttv_getUorD(dir
[1]);
925 if (d0
=='d' || d0
=='?')
926 recur_run_v2(tvf
, lastslope
, tvs_start
->NODE
, tvs_end
, &mask
, &config
, d1
, minmax_i
, &allsearch
, 0);
927 if (d0
=='u' || d0
=='?')
928 recur_run_v2(tvf
, lastslope
, tvs_start
->NODE
+1, tvs_end
, &mask
, &config
, d1
, minmax_i
, &allsearch
, 0);
930 ttv_AutomaticDetailBuild(oldmode
);
931 ttv_SetPrecisionLevel(oldprop
);
932 ttv_setsearchexclude(oldexstart
, oldexend
, &oldexstart
, &oldexend
);
937 for (cl
=config
; cl
!=NULL
; cl
=cl
->NEXT
)
941 performstbclipping(tvf
, (chain_list
*)cl
->DATA
, minmax_i
);
942 path_list
=buildconfigpath((chain_list
*)cl
->DATA
, path_list
);
943 path_list
->CRITIC
=buildconfigdetail((chain_list
*)cl
->DATA
);
946 path_list
=ttv_classpath(path_list
, minmax_i
);
947 while (path_list
!=NULL
)
949 ch
=addchain(ch
, path_list
);
950 path_list
=path_list
->NEXT
;
955 for (cl
=config
; cl
!=NULL
; cl
=cl
->NEXT
)
958 freechain((chain_list
*)cl
->DATA
);
961 for (cl
=allsearch
; cl
!=NULL
; cl
=cl
->NEXT
)
963 for (path_list
=(ttvpath_list
*)cl
->DATA
; path_list
!=NULL
; path_list
=path_list
->NEXT
)
965 path_list
->USER
=testanddelptype(path_list
->USER
, CLIPCTK
);
966 path_list
->USER
=testanddelptype(path_list
->USER
, CLIPREF
);
968 ttv_freepathlist((ttvpath_list
*)cl
->DATA
);
970 freechain(allsearch
);
972 ch
=filterpath(ch
, nbpath
);
976 chain_list
*ttv_CharacPaths(ttvfig_list
*tf
, double slopein
, char *start
, char *end
, char *dir
, long number
, char *all
, char *path
, char *minmax
, double capaout
, int propagate
)
978 int oldprop
=ttv_SetPrecisionLevel(propagate
!=0?1:0);
979 long lastslope
=mbk_long_round(slopein
*1e12
*TTV_UNIT
);
985 API_TEST_TOKEN_SUB(TMA_API
,"tma")
986 // ttv_checkinfchange(tf);
989 ttv_experim_setstopaftergate1(1);
994 oldmode
=ttv_AutomaticDetailBuild("on");
995 savelastslope
=TTV_PROPAGATE_FORCED_SLOPE
;
996 savelastcapa
=TTV_PROPAGATE_FORCED_CAPA
;
997 if (lastslope
!=0) TTV_PROPAGATE_FORCED_SLOPE
=lastslope
;
998 TTV_PROPAGATE_FORCED_CAPA
=capaout
*1e15
;
999 res
=ttv_GetPaths_sub(tf
, start
, start
, end
, dir
, number
, all
, path
, minmax
);
1000 TTV_PROPAGATE_FORCED_CAPA
=savelastcapa
;
1001 TTV_PROPAGATE_FORCED_SLOPE
=savelastslope
;
1002 ttv_SetPrecisionLevel(oldprop
);
1004 ttv_AutomaticDetailBuild(oldmode
);
1006 ttv_experim_setstopaftergate1(0);
1011 static chain_list
*converttodoublelist(chain_list
*val
, int nbx
)
1013 chain_list
*cl
, *ch
=NULL
;
1019 for (i
=0;i
<nbx
&& val
!=NULL
;i
++)
1021 cl
=addchain(cl
, val
->DATA
);
1022 val
=delchain(val
,val
);
1024 ch
=addchain(ch
, reverse(cl
));
1028 chain_list
*ttv_CharacPathTables(ttvpath_list
*pth
, chain_list
*slopes
, chain_list
*capas
, int propagate
)
1030 // int oldprop=ttv_SetPrecisionLevel(propagate!=0?1:0);
1032 chain_list
*res
, *cl
;
1033 chain_list
*slopes_in
=NULL
, *capas_in
=NULL
, *delays_out
, *slopes_out
, *energy
;
1036 API_TEST_TOKEN_SUB(TMA_API
,"tma")
1037 // ttv_checkinfchange(tf);
1039 type
=(pth
->TYPE
& (~TTV_FIND_PATH
)) | TTV_FIND_LINE
;
1041 /* if (propagate==2)
1042 ttv_experim_setstopaftergate1(1);
1044 if (slopes
==NULL
) slopes_in
=addchain(NULL
, (void *)TTV_NOTIME
);
1047 for (cl
=slopes
; cl
!=NULL
; cl
=cl
->NEXT
)
1049 val
=*(float *)&cl
->DATA
;
1051 slopes_in
=addchain(slopes_in
, (void *)mbk_long_round(val
*1e12
*TTV_UNIT
));
1053 slopes_in
=addchain(slopes_in
, (void *)TTV_NOTIME
);
1057 if (capas
==NULL
) capas_in
=addchain(NULL
, 0), *(float *)&capas_in
->DATA
=-1.0;
1060 for (cl
=capas
; cl
!=NULL
; cl
=cl
->NEXT
)
1062 val
=*(float *)&cl
->DATA
;
1063 capas_in
=addchain(capas_in
, NULL
);
1064 *(float *)&capas_in
->DATA
=val
*1e15
;
1068 slopes_in
=reverse(slopes_in
);
1069 capas_in
=reverse(capas_in
);
1071 ttv_activate_search_charac_mode(slopes_in
, capas_in
);
1073 if (pth
->ROOT
==pth
->NODE
&& pth
->DELAY
==0)
1076 nbx
=countchain(slopes_in
);
1077 nby
=countchain(capas_in
);
1081 for (cl
=slopes_in
; cl
!=NULL
; cl
=cl
->NEXT
)
1082 for (i
=0; i
<nby
; i
++)
1084 delays_out
=addchain(delays_out
, (void *)pth
->DELAY
);
1085 slopes_out
=addchain(slopes_out
, cl
->DATA
);
1086 energy
=addchain(energy
, NULL
);
1087 *(float *)&energy
->DATA
=0;
1092 long sTTV_MORE_SEARCH_OPTIONS
=TTV_MORE_SEARCH_OPTIONS
;
1093 TTV_MORE_SEARCH_OPTIONS
=pth
->TTV_MORE_SEARCH_OPTIONS
;
1094 if ((pth
->TYPE
& TTV_FIND_ALL
)==0)
1095 ttv_getcritic(ttv_GetTopTimingFigure(pth
->FIG
),pth
->FIG
, pth
->ROOT
, pth
->NODE
, pth
->LATCH
, pth
->CMDLATCH
, type
);
1097 ttv_getcriticpara(ttv_GetTopTimingFigure(pth
->FIG
), pth
->FIG
, pth
->ROOT
, pth
->NODE
, pth
->DELAY
, type
, NULL
, pth
->TTV_MORE_SEARCH_OPTIONS
);
1098 ttv_retreive_search_charac_results(&delays_out
, &slopes_out
, &energy
);
1099 TTV_MORE_SEARCH_OPTIONS
=sTTV_MORE_SEARCH_OPTIONS
;
1102 for (cl
=delays_out
; cl
!=NULL
; cl
=cl
->NEXT
)
1103 val
=((long)cl
->DATA
)*1e-12/TTV_UNIT
, *(float *)&cl
->DATA
=val
;
1105 for (cl
=slopes_out
; cl
!=NULL
; cl
=cl
->NEXT
)
1106 val
=((long)cl
->DATA
)*1e-12/TTV_UNIT
, *(float *)&cl
->DATA
=val
;
1109 cl
=addchain(NULL
, converttodoublelist(energy
, countchain(capas_in
)));
1111 cl
=addchain(NULL
, NULL
);
1112 cl
=addchain(cl
, converttodoublelist(slopes_out
, countchain(capas_in
)));
1113 cl
=addchain(cl
, converttodoublelist(delays_out
, countchain(capas_in
)));
1115 ttv_activate_search_charac_mode(NULL
, NULL
);
1116 freechain(capas_in
);
1117 freechain(slopes_in
);