25 #define API_USE_REAL_TYPES
27 #include "../ttv/ttv_API_LOCAL.h"
29 #include "../ttv/ttv_API_display.h"
30 #include "../ttv/ttv_API_util.h"
31 #include "stb_LOCAL.h"
40 return mbk_vect(mbk_decodeanyvector(name
), '[', ']');
44 static char dirconv(char dir
)
46 if (dir
=='u') return 'R';
47 else if (dir
=='d') return 'F';
51 static void stb_get_path_info(ttvsig_list
*tvs
, int setup
, ttvsig_list
**start
, ttvsig_list
**latch
)
63 lastmode
=stbsetdebugflag(STB_DIFFERENTIATE_INPUT_EVENTS
);
65 val
=getsetuphold(tvs
,setup
,2,NULL
, NULL
, NULL
, &shi
);
69 val=___findworst(tvs, &max, stb_GetSetup);
71 val=___findworst(tvs, &max, stb_GetHold);
75 inssig
=stb_GetPathInputSignal(max
);
77 sprintf(search
, "?%c", shi
.latch_event
);
78 ttv_activate_path_and_access_mode(1);
79 if (setup
) list
=ttv_internal_GetAccess(inssig
, tvs
, "*", search
, 1); //max
80 else list
=ttv_internal_GetAccess(inssig
, tvs
, "*", search
, 0); // min
81 ttv_activate_path_and_access_mode(0);
83 list
=ttv_internal_filterpathbycommand(list
, max
->CMD_EVENT
, max
->SIG1_EVENT
, 1);
87 pth
=(ttvpath_list
*)list
->DATA
;
88 if (pth
->LATCH
!=NULL
) *latch
=pth
->LATCH
->ROOT
;
89 *start
=pth
->NODE
->ROOT
;
91 ttv_FreePathList(list
);
94 stbsetdebugflag(lastmode
);
98 void stb_DisplayErroneousSignals (FILE *f
, chain_list
*errorlist
)
101 ttvsig_list
*sig
, *start
, *latch
;
102 char *name
, buf1
[15];
107 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayErroneousSignals");
111 b
=Board_CreateBoard();
113 Board_SetSize(b
, COL_INDEX
, 5, 'r');
114 _ttv_Board_SetSize(STAB_CONFIG_SHOW
, COL_START
, b
, COL_START
, 10, 'l');
115 _ttv_Board_SetSize(STAB_CONFIG_SHOW
, COL_LATCH
, b
, COL_LATCH
, 10, 'l');
116 _ttv_Board_SetSep(STAB_CONFIG_SHOW
, COL_START
, b
, COL_ERRL_SEP0
);
117 _ttv_Board_SetSep(STAB_CONFIG_SHOW
, COL_LATCH
, b
, COL_ERRL_SEP1
);
118 Board_SetSize(b
, COL_NAME
, 10, 'l');
119 Board_SetSize(b
, COL_SETUP
, 7, DISPLAY_number_justify
);
120 Board_SetSize(b
, COL_HOLD
, 7, DISPLAY_number_justify
);
121 Board_SetSep(b
, COL_ERRL_SEP2
);
122 Board_SetSep(b
, COL_ERRL_SEP3
);
125 Board_SetValue(b
, COL_NAME
, "To Node");
126 sprintf(buf1
,"Setup");
127 Board_SetValue(b
, COL_SETUP
, buf1
);
128 sprintf(buf1
,"Hold");
129 Board_SetValue(b
, COL_HOLD
, buf1
);
130 _ttv_Board_SetValue(STAB_CONFIG_SHOW
, COL_START
, b
, COL_START
, "From node");
131 _ttv_Board_SetValue(STAB_CONFIG_SHOW
, COL_LATCH
, b
, COL_LATCH
, "Thru node");
133 Board_NewSeparation(b
);
135 for (i
=0,ch
=errorlist
; ch
; ch
=ch
->NEXT
, i
++)
138 sig
= (ttvsig_list
*)ch
->DATA
;
139 name
= ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(sig
), sig
);
140 setup
= __stb_GetSignalSetup(sig
, '?'); //stb_GetErroneousSignalSetup (sig);
141 hold
= __stb_GetSignalHold(sig
, '?'); //stb_GetErroneousSignalHold (sig);
143 sprintf(buf1
,"%d",i
+1);
144 Board_SetValue(b
, COL_INDEX
, buf1
);
146 if (setup
==-1) strcpy(buf1
,"none"); else sprintf(buf1
,DISPLAY_time_format
,setup
*DISPLAY_time_unit
);
147 Board_SetValue(b
, COL_SETUP
, buf1
);
149 if (hold
==-1) strcpy(buf1
,"none"); else sprintf(buf1
,DISPLAY_time_format
,hold
*DISPLAY_time_unit
);
150 Board_SetValue(b
, COL_HOLD
, buf1
);
152 Board_SetValue(b
, COL_NAME
, name
);
154 if (setup
==-1) { if (hold
!=-1) who
=0; }
155 else if (hold
==-1) { if (setup
!=-1) who
=1; }
156 else if (setup
!=-1 && hold
!=-1) { if (hold
<setup
) who
=0; else who
=1; }
158 if (who
!=-1 && (STAB_CONFIG_SHOW
[COL_START
] || STAB_CONFIG_SHOW
[COL_LATCH
]))
160 stb_get_path_info(sig
, who
, &start
, &latch
);
161 _ttv_Board_SetValue(STAB_CONFIG_SHOW
, COL_START
, b
, COL_START
, ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(start
), start
));
163 _ttv_Board_SetValue(STAB_CONFIG_SHOW
, COL_LATCH
, b
, COL_LATCH
, ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(latch
), latch
));
167 Board_NewSeparation(b
);
169 avt_fprintf(f
, " *** Error report (unit:[%s]) ***\n\n", DISPLAY_time_string
);
171 Board_Display(f
, b
, "");
174 avt_fprintf(f
, "\n");
177 void stb_DisplayErrorList (FILE *f
, stbfig_list
*stbfig
, double margin
, int nberror
)
184 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayErrorList");
185 if (stbfig
==NULL
) return;
187 if (margin
>1e-3) margin
=1e-3;
189 errlist
= stb_geterrorlist (stbfig
, (long)(margin
*1e12
), nberror
, &minsetup
, &minhold
, &errnum
);
190 stb_DisplayErroneousSignals (f
, errlist
);
196 static void stb_DisplayRanges (FILE *f
, chain_list
*ranges
, double period
)
200 char buf
[20], buf1
[20];
202 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayRanges");
205 for (ch
=ranges
; ch
; ch
=ch
->NEXT
) {
206 start
= stb_GetInstabilityRangeStart((stbpair_list
*)ch
->DATA
);
209 end
= stb_GetInstabilityRangeEnd((stbpair_list
*)ch
->DATA
);
212 fprintf (f
, "___[%s %s]___", FormaT(start
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT(end
*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
216 void stb_DisplayInputInstabilityRanges (FILE *f
, stbdebug_list
*input
)
222 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayInputInstabilityRanges");
225 period
= stb_GetClockPeriod (input
);
226 range
= stb_GetInputInstabilityRanges(input
, 'm');
227 sg
=stb_GetPathInputSignal(input
);
228 fprintf (f
, DEC
"Input (%s) : ", ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(sg
), sg
));
229 stb_DisplayRanges (f
, range
, period
);
234 void stb_DisplayOutputInstabilityRanges (FILE *f
, stbdebug_list
*input
)
240 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayOutputInstabilityRanges");
243 period
= stb_GetClockPeriod (input
);
244 range
= stb_GetOutputInstabilityRanges (input
, 'm');
245 sg
=stb_GetPathOutputSignal(input
);
246 fprintf (f
, DEC
"Output (%s) : ", ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(sg
), sg
));
247 stb_DisplayRanges (f
, range
, period
);
252 void stb_DisplayClock (FILE *f
, stbdebug_list
*input
, int clock
)
254 double ckup_time
, ckdn_time
, ckup_delta
, ckdn_delta
;
255 char buf
[20], buf1
[20];
257 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayClock");
260 ckup_time
= stb_GetClockTime (input
, clock
, 'u');
261 ckdn_time
= stb_GetClockTime (input
, clock
, 'd');
262 if ((ckup_time
==-1)||(ckdn_time
==-1))
264 ckup_delta
= stb_GetClockDelta (input
, clock
, 'u');
265 ckdn_delta
= stb_GetClockDelta (input
, clock
, 'd');
268 case INPUT_CLOCK
: fprintf (f
, DEC0
"input clock : "); break;
269 case OUTPUT_CLOCK
: fprintf (f
, DEC0
"output clock : "); break;
270 case MAIN_CLOCK
: fprintf (f
, DEC0
"clock (%s) : ", stb_GetClockName (input
)); break;
274 fprintf (f
, "RISE (%s:%s), ", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckup_time
+ckup_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
276 fprintf (f
, "RISE %s, ", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
279 fprintf (f
, "FALL (%s:%s) ", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckdn_time
+ckdn_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
281 fprintf (f
, "FALL %s ", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
284 if (clock
== MAIN_CLOCK
)
285 fprintf (f
, ", PERIOD = %s", FormaT(stb_GetClockPeriod (input
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
290 void stb_DisplayOutputSpecificationRanges (FILE *f
, stbdebug_list
*input
)
295 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayOutputSpecificationRanges");
298 if ((range
=stb_GetOutputSpecificationRanges (input
, 'm'))) {
299 period
= stb_GetClockPeriod (input
);
300 fprintf (f
, DEC
"Specs : ");
301 stb_DisplayRanges (f
, range
, period
);
307 void stb_DisplayInfos (FILE *f
, stbdebug_list
*input
)
310 char buf
[1024], *str
;
312 ttvsig_list
*isg
, *osg
;
314 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayInfos");
317 if ((str
= stb_GetCommandName (input
)))
318 sprintf (buf
, " (%s) ", str
);
322 isg
=stb_GetPathInputSignal(input
);
323 osg
=stb_GetPathOutputSignal(input
);
324 fprintf (f
, "%s%s-> %s :", ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(isg
), isg
), buf
, ttv_GetFullSignalName_COND (ttv_GetSignalTopTimingFigure(osg
), osg
));
325 if ((s
=stb_GetSetup (input
))!=-1) fprintf (f
, " setup = %s", FormaT(s
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
326 if ((s
=stb_GetHold (input
))!=-1) fprintf (f
, " hold = %s", FormaT(s
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
327 if ((margin
= stb_GetSetupMargin (input
)) > 0)
328 fprintf (f
, " setup margin = %s", FormaT(margin
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
329 if ((margin
= stb_GetHoldMargin (input
)) > 0)
330 fprintf (f
, " hold margin = %s", FormaT(margin
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
335 void stb_DisplayInputInfos (FILE *f
, stbdebug_list
*input
)
337 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayInputInfos");
338 stb_DisplayInfos (f
, input
);
339 stb_DisplayClock (f
, input
, MAIN_CLOCK
);
340 stb_DisplayClock (f
, input
, INPUT_CLOCK
);
341 stb_DisplayInputInstabilityRanges (f
, input
);
342 stb_DisplayClock (f
, input
, OUTPUT_CLOCK
);
343 stb_DisplayOutputInstabilityRanges (f
, input
);
344 stb_DisplayOutputSpecificationRanges (f
, input
);
348 void stb_DisplaySetupTimeReport (FILE *f
, stbdebug_list
*max
, char datadir
)
350 double ckup_time
, ckdn_time
, ckup_delta
, ckdn_delta
, val
=DBL_MAX
, v
, add
;
351 double maxdd
=-DBL_MAX
;
354 char buf
[20], buf1
[20];
355 char *rise
="RISE", *fall
="FALL", *ckname
;
362 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplaySetupTimeReport");
363 if (max
==NULL
|| f
==NULL
) return;
365 tvs
=stb_GetPathOutputSignal(max
);
367 if ((val
=stb_GetSetup(max
))==-1) val
=DBL_MAX
; //val=___findworst(tvs, &max, stb_GetSetup);
369 cl
=stb_GetOutputInstabilityRanges(max
,'m');
370 for (ch
=cl
; ch
!=NULL
; ch
=ch
->NEXT
)
372 v
=stb_GetInstabilityRangeEnd((stbpair_list
*)ch
->DATA
);
373 if (v
>maxdd
) { maxdd
=v
; }
377 if (maxdd
==-DBL_MAX
) return;
379 v
=stb_GetClockPeriod (max
);
381 ckup_time
= stb_GetClockTime (max
, MAIN_CLOCK
, 'u');
382 ckdn_time
= stb_GetClockTime (max
, MAIN_CLOCK
, 'd');
384 if (!(ckup_time
==-1 || ckdn_time
==-1))
386 ckup_time
+=stb_periodmove('x', max
);
387 ckdn_time
+=stb_periodmove('x', max
);
388 ckup_delta
= stb_GetClockDelta (max
, MAIN_CLOCK
, 'u');
389 ckdn_delta
= stb_GetClockDelta (max
, MAIN_CLOCK
, 'd');
391 avt_fprintf(f
, DEC
"CLOCK %-5s :", stb_GetClockName (max
));
392 if (ckup_delta
>0) avt_fprintf (f
, " RISE = (%s:%s)", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckup_time
+ckup_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
393 else avt_fprintf (f
, " RISE = %s", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
394 if (ckdn_delta
>0) avt_fprintf (f
, " FALL = (%s:%s)", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckdn_time
+ckdn_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
395 else avt_fprintf (f
, " FALL = %s", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
396 avt_fprintf (f
, " PERIOD = %s", FormaT(stb_GetClockPeriod(max
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
400 ckup_time
= stb_GetClockTime (max
, OUTPUT_CLOCK
, 'u');
401 ckdn_time
= stb_GetClockTime (max
, OUTPUT_CLOCK
, 'd');
403 if (!(ckup_time
==-1 || ckdn_time
==-1))
405 ckup_time
+=stb_periodmove('u', max
);
406 ckdn_time
+=stb_periodmove('d', max
);
407 ckup_delta
= stb_GetClockDelta (max
, OUTPUT_CLOCK
, 'u');
408 ckdn_delta
= stb_GetClockDelta (max
, OUTPUT_CLOCK
, 'd');
410 if (max
->CMD_EVENT
!=NULL
)
412 tvf
=ttv_GetSignalTopTimingFigure(max
->CMD_EVENT
->ROOT
);
413 if (datadir
=='d') tve
=stb_GetPathOutputSignal(max
)->NODE
;
414 else tve
=stb_GetPathOutputSignal(max
)->NODE
+1;
415 ckname
=ttv_GetFullSignalName_COND(tvf
, max
->CMD_EVENT
->ROOT
);
416 node
=stb_getstbnode(tve
);
419 sb
= stb_getstbfig(tvf
);
420 stb_getgoodclock_and_status(sb
, node
->CK
, max
->CMD_EVENT
, tve
, &inverted
);
421 if (inverted
) rise
="FALL", fall
="RISE";
425 avt_fprintf(f
, DEC
"CLOCK %-5s :", ckname
);
426 avt_fprintf (f
, " %s = %s [MIN]", rise
, FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
427 avt_fprintf (f
, " %s = %s [MIN]", fall
, FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
431 if (stb_GetSetupMargin(max
)!=-1) add
=stb_GetSetupMargin(max
); else add
=0;
432 avt_fprintf(f
, DEC
"DATA DELAY : %s [MAX]", FormaT((maxdd
+add
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
434 avt_fprintf(f
, " (%s + %s)", FormaT((maxdd
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
), FormaT(add
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
435 avt_fprintf(f
, "\n");
438 avt_fprintf(f
, DEC
"SETUP : %s%s¤.\n", val
<0?"¤6":"", FormaT(val
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
440 avt_fprintf(f
, DEC
"SETUP : none\n");
443 void stb_DisplayHoldTimeReport (FILE *f
, stbdebug_list
*max
, char datadir
)
445 double ckup_time
, ckdn_time
, ckup_delta
, ckdn_delta
, val
=DBL_MAX
, v
, sub
;
446 double mindd
=DBL_MAX
;
449 char buf
[20], buf1
[20];
450 char *rise
="RISE", *fall
="FALL", *ckname
;
457 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayHoldTimeReport");
458 if (max
==NULL
|| f
==NULL
) return;
460 tvs
=stb_GetPathOutputSignal(max
);
462 if ((val
=stb_GetHold(max
))==-1) val
=DBL_MAX
; // val=___findworst(tvs, &max, stb_GetHold);
464 cl
=stb_GetOutputInstabilityRanges(max
, 'm');
465 for (ch
=cl
; ch
!=NULL
; ch
=ch
->NEXT
)
467 v
=stb_GetInstabilityRangeStart((stbpair_list
*)ch
->DATA
);
468 if (v
<mindd
) { mindd
=v
; }
472 if (mindd
==DBL_MAX
) return;
474 v
=stb_GetClockPeriod (max
);
476 ckup_time
= stb_GetClockTime (max
, MAIN_CLOCK
, 'u');
477 ckdn_time
= stb_GetClockTime (max
, MAIN_CLOCK
, 'd');
478 if (!(ckup_time
==-1 || ckdn_time
==-1))
480 ckup_time
+=-v
+stb_periodmove('x', max
);
481 ckdn_time
+=-v
+stb_periodmove('x', max
);
483 ckup_delta
= stb_GetClockDelta (max
, MAIN_CLOCK
, 'u');
484 ckdn_delta
= stb_GetClockDelta (max
, MAIN_CLOCK
, 'd');
486 avt_fprintf(f
, DEC
"CLOCK %-5s :", stb_GetClockName (max
));
487 if (ckup_delta
>0) avt_fprintf (f
, " RISE = (%s:%s)", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckup_time
+ckup_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
488 else avt_fprintf (f
, " RISE = %s", FormaT(ckup_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
489 if (ckdn_delta
>0) avt_fprintf (f
, " FALL = (%s:%s)", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
), FormaT((ckdn_time
+ckdn_delta
)*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
));
490 else avt_fprintf (f
, " FALL = %s", FormaT(ckdn_time
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
491 avt_fprintf (f
, " PERIOD = %s", FormaT(stb_GetClockPeriod(max
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
495 ckup_time
= stb_GetClockTime (max
, OUTPUT_CLOCK
, 'u');
496 ckdn_time
= stb_GetClockTime (max
, OUTPUT_CLOCK
, 'd');
498 if (!(ckup_time
==-1 || ckdn_time
==-1))
500 ckup_time
+=-v
+stb_periodmove('u', max
);
501 ckdn_time
+=-v
+stb_periodmove('d', max
);
502 ckup_delta
= stb_GetClockDelta (max
, OUTPUT_CLOCK
, 'u');
503 ckdn_delta
= stb_GetClockDelta (max
, OUTPUT_CLOCK
, 'd');
505 if (max
->CMD_EVENT
!=NULL
)
507 tvf
=ttv_GetSignalTopTimingFigure(max
->CMD_EVENT
->ROOT
);
508 if (datadir
=='d') tve
=stb_GetPathOutputSignal(max
)->NODE
;
509 else tve
=stb_GetPathOutputSignal(max
)->NODE
+1;
510 ckname
=ttv_GetFullSignalName_COND(tvf
, max
->CMD_EVENT
->ROOT
);
511 node
=stb_getstbnode(tve
);
514 sb
= stb_getstbfig(tvf
);
515 stb_getgoodclock_and_status(sb
, node
->CK
, max
->CMD_EVENT
, tve
, &inverted
);
516 if (inverted
) rise
="FALL", fall
="RISE";
520 avt_fprintf(f
, DEC
"CLOCK %-5s :", ckname
);
521 avt_fprintf (f
, " %s = %s [MAX]", rise
, FormaT((ckup_time
+ckup_delta
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
522 avt_fprintf (f
, " %s = %s [MAX]", fall
, FormaT((ckdn_time
+ckdn_delta
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
526 if (stb_GetHoldMargin(max
)!=-1) sub
=stb_GetHoldMargin(max
); else sub
=0;
527 avt_fprintf(f
, DEC
"DATA DELAY : %s [MIN]", FormaT((mindd
-sub
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
529 avt_fprintf(f
, " (%s - %s)", FormaT(mindd
*DISPLAY_time_unit
, buf1
, DISPLAY_time_format
), FormaT(sub
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
530 avt_fprintf(f
, "\n");
532 avt_fprintf(f
, DEC
"HOLD : %s%s¤.\n", val
<0?"¤6":"", FormaT(val
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
534 avt_fprintf(f
, DEC
"HOLD : none\n");
537 void stb_DisplayClockRoute(FILE *f
, stbdebug_list
*max
, char type
)
542 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayClockRoute");
544 if (type
!='s' && type
!='h')
546 avt_errmsg(STB_API_ERRMSG
, "005", AVT_ERROR
);
547 //avt_fprintf(f, "valid values for type is 's' (setup) or 'h' (hold)");
553 tvs
=stb_GetPathOutputSignal(max
);
555 if (max
->CMD_EVENT
==NULL
) {avt_fprintf(f
, "¤6<no path to clock found, unknown command node>¤."); return; }
557 if (max
->CMD_EVENT
->TYPE
& TTV_NODE_UP
) tve
=max
->CMD_EVENT
->ROOT
->NODE
;
558 else tve
=max
->CMD_EVENT
->ROOT
->NODE
+1;
560 ttv_DisplayRoute(f
, tve
, type
=='s'?'m':'M', NULL
, 0);
563 void stb_DisplayDataRoute(FILE *f
, stbdebug_list
*max
, char type
, char datadir
)
565 ttvsig_list
*inssig
, *tvs
;
566 chain_list
*cl
, *list
;
567 chain_list
*detail
, *detailbase
;
569 char *nodename
, *col
, *_type
;
573 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplayDataRoute");
574 if (max
==NULL
|| f
==NULL
) return;
578 tvs
=stb_GetPathOutputSignal(max
);
580 if (type
!='s' && type
!='h')
583 avt_errmsg(STB_API_ERRMSG
, "005", AVT_ERROR
);
584 // avt_fprintf(f, "valid values for type is 's' (setup) or 'h' (hold), ");
589 inssig
=stb_GetPathInputSignal(max
);
591 sprintf(search
,"?%c",datadir
);
593 ttv_activate_path_and_access_mode(1);
594 if (type
=='s') list
=ttv_internal_GetAccess(inssig
, tvs
, "*", search
, 1); //max
595 else list
=ttv_internal_GetAccess(inssig
, tvs
, "*", search
, 0); // min
596 ttv_activate_path_and_access_mode(0);
598 list
=ttv_internal_filterpathbycommand(list
, max
->CMD_EVENT
, max
->SIG1_EVENT
, 1);
604 pth
=(ttvpath_list
*)cl
->DATA
;
605 detailbase
=detail
=ttv_GetPathDetail(pth
);
609 tc
=(ttvcritic_list
*)detail
->DATA
;
610 if (detail
==detailbase
|| !(DISPLAY_nodemode
==0 && strcasecmp(ttv_GetDetailType(tc
),"rc")==0))
612 if (detail
!=detailbase
) avt_fprintf(f
, " - ");
613 nodename
=ttv_GetDetailSignalName_COND(tc
);
615 _type
=ttv_GetDetailSignalType(tc
);
616 if (strstr(_type
,"latch")!=NULL
|| strstr(_type
,"flip-flop")!=NULL
) col
="¤4";
618 avt_fprintf(f
, "%s%s¤.(%c)", col
, nodename
, dirconv(ttv_GetDetailDirection(tc
)));
624 ttv_FreePathDetail(detailbase
);
625 freechain(detailbase
);
628 avt_fprintf(f
, "¤6<access not found>¤.");
629 ttv_FreePathList(list
);
632 else avt_fprintf(f
, "¤6<not found>¤.");
636 void stb_DisplaySignalStabilityReport (FILE *f
, stbfig_list
*stbfig
, char *name
)
644 avt_errmsg(STB_API_ERRMSG
, "007", AVT_WARNING
, "stb_DisplaySignalStabilityReport");
647 tvs
= ttv_getsig(stbfig
->FIG
, vecname(name
));
649 if (tvs
==NULL
|| f
==NULL
) return;
650 lastmode
=stbsetdebugflag(STB_DIFFERENTIATE_INPUT_EVENTS
);
652 avt_fprintf(f
,"¤2Signal '%s'¤. (unit:[%s])\n", ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(tvs
), tvs
), DISPLAY_time_string
);
654 val
=getsetuphold(tvs
,1,2,NULL
, NULL
, NULL
, &shi
);
656 // val=___findworst(tvs, &max, stb_GetSetup);
657 if (stb_GetSetup(max
)==-1)
658 avt_fprintf(f
," [¤+No Setup Time Available¤.]\n");
659 else if (val
!=DBL_MAX
&& val
>=0)
660 avt_fprintf(f
," [Setup Time]\n");
662 avt_fprintf(f
," [¤6Setup Time Error¤.]\n");
665 avt_fprintf(f
, DEC0
"Data route : ");
666 if (max
!=NULL
) { stb_DisplayDataRoute(f
, max
, 's', shi
.latch_event
); avt_fprintf(f
, "\n"); }
667 avt_fprintf(f
, DEC0
"Closing Clock route : ");
668 if (max
!=NULL
) { stb_DisplayClockRoute(f
, max
, 's'); avt_fprintf(f
, "\n"); }
669 avt_fprintf(f
, "\n");
670 stb_DisplaySetupTimeReport (f
, max
, shi
.latch_event
);
672 avt_fprintf(f
, "\n");
674 val
=getsetuphold(tvs
,0,2,NULL
, NULL
, NULL
, &shi
);
676 // val=___findworst(tvs, &max, stb_GetHold);
677 if (stb_GetHold(max
)==-1)
678 avt_fprintf(f
," [¤+No Hold Time Available¤.]\n");
679 else if (val
!=DBL_MAX
&& val
>=0)
680 avt_fprintf(f
," [Hold Time]\n");
682 avt_fprintf(f
," [¤6Hold Time Error¤.]\n");
685 avt_fprintf(f
, DEC0
"Data route : ");
686 if (max
!=NULL
) { stb_DisplayDataRoute(f
, max
, 'h', shi
.latch_event
); avt_fprintf(f
, "\n"); }
687 avt_fprintf(f
, DEC0
"Closing Clock route : ");
688 if (max
!=NULL
) { stb_DisplayClockRoute(f
, max
, 'h'); avt_fprintf(f
, "\n"); }
689 avt_fprintf(f
, "\n");
690 stb_DisplayHoldTimeReport (f
, max
, shi
.latch_event
);
691 avt_fprintf(f
, "\n");
692 stbsetdebugflag(lastmode
);
695 static int isclock(ttvsig_list
*ts
)
697 if (getptype(ts
->USER
, TTV_SIG_CLOCK
)!=NULL
) return 1;
701 void ttv_CheckTransformToIdeal(ttvpath_list
* tp
)
706 int latchideal
=0, clockideal
=0, mode
=0;
708 if (tp
==NULL
) return;
710 if (tp
->LATCH
&& getptype(tp
->LATCH
->ROOT
->USER
, STB_IDEAL_CLOCK
)!=NULL
) latchideal
=1;
711 if (getptype(tp
->NODE
->ROOT
->USER
, STB_IDEAL_CLOCK
)!=NULL
) clockideal
=1;
713 ch
=cl
=ttv_GetPathDetail(tp
);
717 tc
=(ttvcritic_list
*)cl
->DATA
;
720 if (tc
->NODE_FLAG
& TTV_NODE_FLAG_ISLATCH_ACCESS
)
722 if (!latchideal
) break;
725 else if ((mode
==0 && clockideal
) || (mode
==1 && latchideal
))
727 sub
+=tc
->DELAY
; tc
->DELAY
=0;
728 subr
+=tc
->REFDELAY
; tc
->REFDELAY
=0;
729 if (tc
->SIMDELAY
!=TTV_NOTIME
) tc
->SIMDELAY
=0;
737 //tp->USER=addptype(tp->USER, STB_IDEAL_CLOCK, NULL);
741 static char *typeconv(char *type
)
743 if (strstr(type
,"connector")!=NULL
) return "S";
744 if (strstr(type
,"latch")!=NULL
) return "L";
745 if (strstr(type
,"precharge")!=NULL
) return "N";
746 if (strstr(type
,"flip-flop")!=NULL
) return "F";
747 if (strstr(type
,"breakpoint")!=NULL
) return "B";
748 if (strstr(type
,"command")!=NULL
) return "K";
752 static int slacksort(const void *a0
, const void *b0
)
755 slackinfo
*a
=(slackinfo
*)a0
, *b
=(slackinfo
*)b0
;
756 if (a
->slack
<b
->slack
) return -1;
757 if (a
->slack
>b
->slack
) return 1;
758 if ((res
=mbk_casestrcmp(a
->debugl
.SIG2
->NAME
, b
->debugl
.SIG2
->NAME
))<0) return -1;
759 else if (res
>0) return 1;
760 else if ((res
=mbk_casestrcmp(a
->debugl
.SIG1
->NAME
, b
->debugl
.SIG1
->NAME
))<0) return -1;
761 else if (res
>0) return 1;
765 static ttvevent_list
*stb_getpathstart(ttvfig_list
*tvf
, ttvevent_list
*inev
, char *start
, int dirin
, int *access
, unsigned char phase
, ttvevent_list
*startcmd
, int notanaccess
, ttvevent_list
*startclock
)
767 ttvevent_list
*input
=NULL
, *testev
;
771 ptype_list
*pt
, *pt0
;
773 if (notanaccess
|| (inev
->ROOT
->TYPE
& (TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
))==0 || (startcmd
==NULL
&& ttv_IsClock(inev
->ROOT
)))
776 if ((inev
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
778 if ((dirin
==2 || checkdir
==dirin
) && mbk_TestREGEX(ttv_GetFullSignalName(tvf
, inev
->ROOT
), start
))
781 else if ((inev
->ROOT
->TYPE
& TTV_SIG_B
)!=0)
783 pt
=ttv_getlatchaccess(tvf
, inev
, TTV_FIND_MAX
);
784 for (pt0
=pt
; pt0
!=NULL
; pt0
=pt0
->NEXT
)
786 node
=stb_getstbnode((ttvevent_list
*)pt0
->DATA
);
791 if (ck
->ORIGINAL_CLOCK
!=NULL
) testev
=ck
->ORIGINAL_CLOCK
;
792 else if (stb_getclocknode(stb_getstbfig(tvf
), ck
->CKINDEX
, NULL
, &testev
, NULL
)==NULL
)
797 if ((testev
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
799 if ((dirin
==2 || checkdir
==dirin
) && mbk_TestREGEX(ttv_GetFullSignalName(tvf
, testev
->ROOT
), start
))
804 if (pt0
!=NULL
&& testev
!=NULL
) input
=testev
, *access
=1;
805 else input
=inev
, *access
=0;
809 // recherche de la clock
811 if (startclock
!=NULL
&& (inev
->ROOT
->TYPE
& TTV_SIG_R
)==0)
813 if ((startclock
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
815 if ((dirin
==2 || checkdir
==dirin
) && mbk_TestREGEX(ttv_GetFullSignalName(tvf
, startclock
->ROOT
), start
))
822 node
=stb_getstbnode(inev
);
823 for (ck
=node
->CK
; ck
!=NULL
; ck
=ck
->NEXT
)
825 if (phase
!=STB_NO_INDEX
&& ck
->CKINDEX
!=phase
) continue;
826 if (ck
->ORIGINAL_CLOCK
!=NULL
)
827 testev
=ck
->ORIGINAL_CLOCK
;
828 else if (stb_getclocknode(stb_getstbfig(tvf
), ck
->CKINDEX
, NULL
, &testev
, NULL
)==NULL
)
833 if ((testev
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
835 if ((dirin
==2 || checkdir
==dirin
) && mbk_TestREGEX(ttv_GetFullSignalName(tvf
, testev
->ROOT
), start
))
837 if ((ck
->FLAGS
& (STBCK_MAX_EDGE_HZ
|STBCK_MIN_EDGE_HZ
))!=0)
838 *access
=0, testev
=inev
;
839 else if ((ck
->FLAGS
& (STBCK_FAKE_DOWN
|STBCK_FAKE_UP
))!=0)
842 if (ck
->CMD
!=NULL
) tve
=ck
->CMD
;
845 if ((pt
=getptype(node
->EVENT
->USER
, STB_BREAK_TEST_EVENT
))!=NULL
)
846 tve
=(ttvevent_list
*)pt
->DATA
;
850 if ((inev
->ROOT
->TYPE
& TTV_SIG_L
)!=0 && (tve
->TYPE
& TTV_NODE_UP
)!=(ck
->ORIGINAL_CLOCK
->TYPE
& TTV_NODE_UP
))
851 checkdir
=(checkdir
+1) & 1;
852 if ((checkdir
==0 && (ck
->FLAGS
& STBCK_FAKE_DOWN
)!=0)
853 || (checkdir
==1 && (ck
->FLAGS
& STBCK_FAKE_UP
)!=0))
854 *access
=0, testev
=inev
;
868 static inline int stb_could_enter_range(ttvsig_list
*tvs
, int setuphold
, double top
, int nb
, int max
)
874 if (!V_BOOL_TAB
[__STB_SETUP_HOLD_UPDATE
].VALUE
) return 1;
875 if (nb
<max
) return 1;
877 for(i
= 0 ; i
< 2 ; i
++)
879 if((ptnode
= stb_getstbnode(tvs
->NODE
+i
)) == NULL
)
882 if (setuphold
&& ptnode
->SETUP
!=STB_NO_TIME
)
884 val
=ptnode
->SETUP
*1e-12/TTV_UNIT
;
886 else if (!setuphold
&& ptnode
->HOLD
!=STB_NO_TIME
)
888 val
=ptnode
->HOLD
*1e-12/TTV_UNIT
;
891 if (val
!=-1 && val
<top
) return 1;
896 static int checkkeepslack(int flag
, int forced
)
898 if ((flag
& STB_DEBUG_HZPATH
)==0 && forced
==TTV_API_ONLY_HZ
) return 0;
899 if ((flag
& STB_DEBUG_HZPATH
)!=0 && forced
==TTV_API_ONLY_NOTHZ
) return 0;
903 static chain_list
*getslackinfo_grab(ttvfig_list
*tvf
, ttvsig_list
*sig
, int setup
, char *start
, char *end
, int dirin
, int dirout
, double margin
, chain_list
*old
, double *top
, int *nb
, int max
, int forced
, char *thru
)
905 stbdebug_list
*dbl
, *savedbl
;
908 Setup_Hold_Computation_Detail_INFO
*detail
;
910 ttvsig_list
*inputsig
;
911 ttvevent_list
*path_start_sig
;
914 chain_list
*lst
, *ch
;
916 if (!stb_could_enter_range(sig
, setup
, *top
, *nb
, max
)) return old
;
918 if (mbk_TestREGEX(ttv_GetFullSignalName(tvf
, sig
), end
) || mbk_TestREGEX(ttv_GetFullSignalNetName(tvf
, sig
), end
))
920 lst
=stb_internal_GetSignalStabilityPaths(sig
, setup
?STB_COMPUTE_SETUP_ONLY
:STB_COMPUTE_HOLD_ONLY
);
921 for (ch
=lst
; ch
!=NULL
; ch
=ch
->NEXT
)
923 dbl
=(stbdebug_list
*)ch
->DATA
;
926 if (dirout
==2 || dirout
==i
)
928 if (setup
) detail
=&dbl
->detail
[i
].setup
;
929 else detail
=&dbl
->detail
[i
].hold
;
931 val
=detail
->VALUE
*1e-12/TTV_UNIT
;
932 if (detail
->VALUE
!=STB_NO_TIME
&& val
<=margin
&& (*nb
<max
|| val
<*top
) && checkkeepslack(detail
->flags
, forced
))
935 if ((path_start_sig
=stb_getpathstart(tvf
, dbl
->SIG1_EVENT
, start
, dirin
, &access
, detail
->phase_origin
, dbl
->START_CMD_EVENT
, 0, dbl
->START_CLOCK
))!=NULL
)
938 || (!access
&& (mbk_TestREGEX(ttv_GetFullSignalName(tvf
, path_start_sig
->ROOT
), thru
) || mbk_TestREGEX(ttv_GetFullSignalNetName(tvf
, path_start_sig
->ROOT
), thru
)))
939 || (access
&& (mbk_TestREGEX(ttv_GetFullSignalName(tvf
, dbl
->SIG1
), thru
) || mbk_TestREGEX(ttv_GetFullSignalNetName(tvf
, dbl
->SIG1
), thru
)))
942 d_valid
=detail
->instab
+detail
->data_margin
;
944 d_req
=detail
->clock
+detail
->clock_margin
-detail
->margin
+detail
->skew
-detail
->uncertainty
;
947 d_req
=detail
->clock
+detail
->clock_margin
+detail
->margin
-detail
->period
-detail
->skew
+detail
->uncertainty
;
948 d_valid
+=detail
->misc
;
951 // correction pour multicycle sur le required
952 /*d_valid+=detail->mc_setup_period-detail->mc_hold_period;
953 d_req+=detail->mc_setup_period-detail->mc_hold_period;*/
954 d_valid
+=-detail
->datamoved
-detail
->mc_hold_period
;
955 d_req
+=-detail
->datamoved
-detail
->mc_hold_period
;
959 if (dbl
->CKREFUP_MAX
<dbl
->CKREFDN_MAX
)
960 ckt
=(dbl
->CKREFUP_MAX
/TTV_UNIT
)*1e-12, ckdir
='u';
962 ckt
=(dbl
->CKREFDN_MAX
/TTV_UNIT
)*1e-12, ckdir
='d';
966 if (dbl
->CKREFUP_MIN
<dbl
->CKREFDN_MIN
)
967 ckt
=(dbl
->CKREFUP_MIN
/TTV_UNIT
)*1e-12, ckdir
='u';
969 ckt
=(dbl
->CKREFDN_MIN
/TTV_UNIT
)*1e-12, ckdir
='d';
972 si
=(slackinfo
*)mbkalloc(sizeof(slackinfo
));
974 si
->slack
=detail
->VALUE
*1e-12/TTV_UNIT
;
976 si
->datavalid
=(d_valid
/TTV_UNIT
)*1e-12;
977 /* if ((detail->flags & STB_DEBUG_DIRECTIVE)==0)
979 if (dbl->CKREFUP_MAX==STB_NO_TIME)
980 si->datavalidclock=-1;
982 si->datavalidclock=ckt;
983 si->datavalidclockdir=ckdir;
987 si->datavalidclock=0; // a faire
988 si->datavalidclockdir='u';
991 if (dbl
->PERIODE
==STB_NO_TIME
)
994 si
->period
=(dbl
->PERIODE
/TTV_UNIT
)*1e-12;
995 si
->datareq
=(d_req
/TTV_UNIT
)*1e-12;
998 si
->lag
=(detail
->lag
/TTV_UNIT
)*1e-12;
999 /* if (detail->flags & STB_DEBUG_DIRECTIVE_FALLING) si->dirin=0;
1000 else if (detail->flags & STB_DEBUG_DIRECTIVE_RISING) si->dirin=1;
1001 else */si
->dirin
=(path_start_sig
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
?1:0;
1003 si
->hzpath
=(detail
->flags
& STB_DEBUG_HZPATH
)!=0?1:0;
1004 si
->phase
=detail
->phase_origin
;
1005 si
->flags
=detail
->flags
;
1008 memcpy(savedbl
=&si
->debugl
, dbl
, sizeof(stbdebug_list
));
1010 /* if (savedbl->CHRONO!=NULL)
1012 savedbl->CHRONO=mbkalloc(sizeof(stbchrono_list));
1013 memcpy(savedbl->CHRONO, dbl->CHRONO, sizeof(stbchrono_list));
1014 savedbl->CHRONO->SPECS=stb_dupstbpairlist(dbl->CHRONO->SPECS);
1015 savedbl->CHRONO->SPECS_U=stb_dupstbpairlist(dbl->CHRONO->SPECS_U);
1016 savedbl->CHRONO->SPECS_D=stb_dupstbpairlist(dbl->CHRONO->SPECS_D);
1019 old
=addchain(old
, si
);
1021 if (val
>*top
) *top
=val
;
1033 static chain_list
*stb_get_directive_paths(ttvfig_list
*tf
, int max
, ttvsig_list
*sig
, int sigdir
, int clock
, int retrypath
, long thisarrival
, ttvevent_list
**tve
, chain_list
*speedinput
)
1035 chain_list
*cl
, *ch
, *clks
, *ret
=NULL
;
1041 ttv_activate_multi_cmd_critic_mode(1);
1042 ttv_activate_multi_end_cmd_critic_mode(1);
1043 ch
=addchain(NULL
, sig
);
1046 clks
=ttv_getclocksiglist(tf
);
1047 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_CLOCK_START
);
1051 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_DATA_START
);
1054 cl
=ttv_internal_GetPaths_EXPLICIT(tf
, NULL
, clks
, ch
, "??", 0, "critic", clock
?"path":retrypath
?"path":"access", max
?"max":"min");
1055 if (clks
!=speedinput
) freechain(clks
);
1057 ttv_search_mode(0, TTV_MORE_OPTIONS_USE_CLOCK_START
|TTV_MORE_OPTIONS_USE_DATA_START
);
1058 ttv_activate_multi_end_cmd_critic_mode(0);
1059 ttv_activate_multi_cmd_critic_mode(0);
1061 for (ch
=cl
; ch
!=NULL
; ch
=ch
->NEXT
)
1063 tp
=(ttvpath_list
*)ch
->DATA
;
1064 if ((tp
->ROOT
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
1067 ((tp
->NODE
->ROOT
->TYPE
& TTV_SIG_C
)==0
1068 || ttv_IsClock(tp
->NODE
->ROOT
))
1070 if (ttv_PathIsHZ(tp
)) continue;
1072 if (checkdir
==sigdir
)
1074 arrival
=tp
->DELAY
+tp
->DATADELAY
;
1075 if (tp
->CROSSMINDELAY
!=TTV_NOTIME
)
1076 arrival
+=tp
->CROSSMINDELAY
;
1078 arrival
+=tp
->DELAYSTART
;
1079 if ((clock
&& getptype(tp
->NODE
->ROOT
->USER
, STB_IDEAL_CLOCK
)!=NULL
) || arrival
==thisarrival
)
1081 ret
=addchain(ret
, tp
);
1088 if (!retrypath
&& !clock
&& ret
==NULL
)
1089 ret
=stb_get_directive_paths(tf
, max
, sig
, sigdir
, clock
, 1, thisarrival
, tve
, speedinput
);
1091 if (!retrypath
&& ret
==NULL
&& (sig
->TYPE
& TTV_SIG_C
)!=0)
1093 *tve
=&sig
->NODE
[sigdir
];
1096 ttv_FreePathList(cl
);
1102 static ttvpath_list
*change_path_start_considering_start_phase(ttvfig_list
*tf
, ttvpath_list
*tp
, char phase
, chain_list
**list
)
1105 start
=ttv_getinittime(tf
,tp
->NODE
,STB_NO_INDEX
,tp
->TYPE
,phase
,NULL
) ;
1106 if (start
!=tp
->DELAYSTART
)
1109 tp
->DELAYSTART
=start
;
1110 *list
=addchain(*list
, tp
);
1115 static int stb_assoc_start_mode(slackinfo
*a
)
1117 if (a
->access
) return 2; // clock mode
1118 if (ttv_IsClock(a
->debugl
.SIG1
))
1120 if (a
->debugl
.START_CMD_EVENT
==NULL
) return 2; // clock mode
1121 else return 1; //data mode
1125 static chain_list
*stb_associate_paths(ttvfig_list
*tf
, char *dir
, int setuphold
, char *start
, int dirin
, slackinfo
*tab
, int cur
, int tot
, chain_list
*allpaths
, chain_list
*speedinput
)
1127 chain_list
*cl
, *ch
, *clks
;
1128 int i
, access
, checkdir
, specinmode
=0, sm
;
1131 ttvevent_list
*path_start_ev
;
1133 if (tab
[cur
].path
==NULL
)
1135 ttv_activate_multi_cmd_critic_mode(1);
1136 ttv_activate_multi_end_cmd_critic_mode(1);
1137 ttv_search_mode(1, TTV_MORE_OPTIONS_DONT_FILTER_ENDING_NODE
);
1138 ch
=addchain(NULL
, tab
[cur
].debugl
.SIG2
);
1139 if (tab
[cur
].access
)
1141 clks
=ttv_getclocksiglist(tf
);
1142 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_CLOCK_START
);
1143 if (tab
[cur
].debugl
.SIG2
==tab
[cur
].debugl
.SIG1
&& (tab
[cur
].debugl
.SIG2
->TYPE
& TTV_SIG_C
)!=0)
1144 ttv_search_mode(1, TTV_MORE_OPTIONS_MOST_DIRECT_ACCESS
);
1147 sm
=stb_assoc_start_mode(&tab
[cur
]);
1148 if (sm
==1) ttv_search_mode(1, TTV_MORE_OPTIONS_USE_DATA_START
);
1149 else if (sm
==2) ttv_search_mode(1, TTV_MORE_OPTIONS_USE_CLOCK_START
);
1151 cl
=ttv_internal_GetPaths_EXPLICIT(tf
, clks
, speedinput
, ch
, dir
, 0, "critic", tab
[cur
].access
?"access":"path", setuphold
?"max":"min");
1154 ttv_search_mode(0, TTV_MORE_OPTIONS_DONT_FILTER_ENDING_NODE
);
1155 ttv_search_mode(0, TTV_MORE_OPTIONS_MOST_DIRECT_ACCESS
);
1159 node
=stb_getstbnode(tab
[cur
].debugl
.SIG1_EVENT
);
1160 if (node
->SPECIN
!=NULL
)
1162 cl
=addchain(NULL
, ttv_create_one_node_path(tf
, tf
, tab
[cur
].debugl
.SIG1_EVENT
, setuphold
?TTV_FIND_MAX
:TTV_FIND_MIN
));
1166 ttv_search_mode(0, TTV_MORE_OPTIONS_USE_CLOCK_START
|TTV_MORE_OPTIONS_USE_DATA_START
);
1167 ttv_activate_multi_end_cmd_critic_mode(0);
1168 ttv_activate_multi_cmd_critic_mode(0);
1170 sort_by_absolute_time(cl);
1171 if (setuphold==0) cl=reverse(cl);
1173 for (i
=cur
; i
<tot
; i
+=tab
[i
].jump
)
1175 if (tab
[i
].path
!=NULL
) continue;
1176 // if (tab[i].flags & STB_DEBUG_DIRECTIVE) continue;
1177 if (tab
[i
].access
==tab
[cur
].access
&& tab
[i
].debugl
.SIG2
==tab
[cur
].debugl
.SIG2
&& stb_assoc_start_mode(&tab
[i
])==sm
)
1179 path_start_ev
=stb_getpathstart(tf
, tab
[i
].debugl
.SIG1_EVENT
, start
, dirin
, &access
, tab
[i
].phase
, tab
[i
].debugl
.START_CMD_EVENT
, !tab
[i
].access
, tab
[i
].debugl
.START_CLOCK
);
1180 for (ch
=cl
; ch
!=NULL
; ch
=ch
->NEXT
)
1182 tp
=(ttvpath_list
*)ch
->DATA
;
1183 if ((tp
->ROOT
->TYPE
& TTV_NODE_UP
)==TTV_NODE_UP
) checkdir
=1;
1185 if (ttv_PathIsHZ(tp
)) checkhz
=1; else checkhz
=0;
1187 if ((specinmode
|| checkdir
==tab
[i
].dirout
) && checkhz
==tab
[i
].hzpath
)
1189 if (tab
[cur
].access
==0)
1191 if (tp
->NODE
==tab
[i
].debugl
.SIG1_EVENT
)
1193 tab
[i
].path
=change_path_start_considering_start_phase(tf
, tp
, tab
[i
].phase
, &cl
);
1200 if (tp
->LATCH
==tab
[i
].debugl
.SIG1_EVENT
&& tp
->NODE
==path_start_ev
1201 && ((tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)!=0 || tp
->CMD
==tab
[i
].debugl
.CMD_EVENT
)
1202 && ((tp
->LATCH
->ROOT
->TYPE
& (TTV_SIG_R
|TTV_SIG_B
))!=0 || tp
->CMDLATCH
==tab
[i
].debugl
.START_CMD_EVENT
)
1205 tab
[i
].path
=change_path_start_considering_start_phase(tf
, tp
, tab
[i
].phase
, &cl
);
1214 for (ch
=cl
; ch
!=NULL
; ch
=ch
->NEXT
)
1216 tp
=(ttvpath_list
*)ch
->DATA
;
1217 if (tp
->MD
!=NULL
) allpaths
=addchain(allpaths
, tp
), ch
->DATA
=NULL
;
1219 ttv_FreePathList(cl
);
1225 #define ZINAPS_TEMP_TYPE 0xfab70228
1227 static slackinfo
*__stb_getslacklist(stbfig_list
*sbf
, int setuphold
, char *start
, char *end
, int dirin
, int dirout
, double margin
, int maxnb
, int *total
, int forced
, char *thru
)
1229 int tot
, max
, nbtot
=0;
1231 chain_list
*cl
, *chainsig
, *chain
, *all
, *prev
;
1236 if (sbf
==NULL
) { *total
=0; return NULL
; }
1239 chainsig
= ttv_getsigbytype(sbf
->FIG
, NULL
, TTV_SIG_TYPEALL
, NULL
) ;
1240 for(chain
= chainsig
; chain
; chain
= chain
->NEXT
)
1242 tvs
=(ttvsig_list
*)chain
->DATA
;
1243 all
=getslackinfo_grab(sbf
->FIG
, tvs
, setuphold
, start
, end
, dirin
, dirout
, margin
, all
, &topval
, &nbtot
, maxnb
, forced
, thru
);
1244 if (maxnb
!=INT_MAX
&& nbtot
>maxnb
*2)
1246 tab
=(slackinfo
*)mbkalloc(sizeof(slackinfo
)*nbtot
);
1247 for (tot
=0, cl
=all
; tot
<nbtot
&& cl
!=NULL
; tot
++, cl
=cl
->NEXT
)
1249 memcpy(&tab
[tot
], cl
->DATA
, sizeof(slackinfo
));
1252 qsort(tab
, tot
, sizeof(slackinfo
), slacksort
);
1254 for (tot
=0, cl
=all
; tot
<maxnb
; tot
++, cl
=cl
->NEXT
)
1257 memcpy(cl
->DATA
, &tab
[tot
], sizeof(slackinfo
));
1263 cl
=delchain(cl
, cl
);
1265 topval
=tab
[maxnb
-1].slack
;
1270 freechain(chainsig
);
1272 max
=countchain(all
);
1273 tab
=(slackinfo
*)mbkalloc(sizeof(slackinfo
)*max
);
1274 for (tot
=0; all
!=NULL
; all
=delchain(all
, all
))
1276 memcpy(&tab
[tot
], all
->DATA
, sizeof(slackinfo
));
1281 qsort(tab
, tot
, sizeof(slackinfo
), slacksort
);
1285 for (max
=0; max
<tot
; max
++)
1287 if ((pt
=getptype(tab
[max
].debugl
.SIG2
->USER
, ZINAPS_TEMP_TYPE
))==NULL
)
1288 tab
[max
].debugl
.SIG2
->USER
=addptype(tab
[max
].debugl
.SIG2
->USER
, ZINAPS_TEMP_TYPE
, (void *)(long)max
);
1291 tab
[(int)(long)pt
->DATA
].jump
=max
-(int)(long)pt
->DATA
;
1292 pt
->DATA
=(void *)(long)max
;
1296 for (max
=0; max
<tot
; max
++)
1298 if ((pt
=getptype(tab
[max
].debugl
.SIG2
->USER
, ZINAPS_TEMP_TYPE
))!=NULL
)
1300 tab
[(int)(long)pt
->DATA
].jump
=tot
-(int)(long)pt
->DATA
;
1301 tab
[max
].debugl
.SIG2
->USER
=delptype(tab
[max
].debugl
.SIG2
->USER
, ZINAPS_TEMP_TYPE
);
1308 static chain_list
*__stb_getslackpaths(ttvfig_list
*tvf
, slackinfo
*tab
, char *start
, int dirin
, char *direction
, int setuphold
, int i
, int tot
, chain_list
*allpaths
, chain_list
**requiredpath
, chain_list
*speedinput
)
1310 Setup_Hold_Computation_Detail_INFO
*detail
;
1313 ttvevent_list
*clockcon
, *pathcmd
;
1316 /* if (tab[i].flags & STB_DEBUG_DIRECTIVE)
1317 allpaths=stb_associate_directive_paths(tvf, setuphold, tab, i, tot, allpaths, (tab[i].flags & STB_DEBUG_DIRECTIVE_DATA_IS_CLOCK)?1:0, 0, speedinput);
1319 allpaths
=stb_associate_paths(tvf
, direction
, setuphold
, start
, dirin
, tab
, i
, tot
, allpaths
, speedinput
);
1322 if (ttv_GetPathEndDirection(tab
[i
].path
)=='u') dir
=1; else dir
=0;
1323 if (setuphold
) detail
=&tab
[i
].debugl
.detail
[dir
].setup
;
1324 else detail
=&tab
[i
].debugl
.detail
[dir
].hold
;
1326 tab
[i
].path
->CMD
=tab
[i
].debugl
.CMD_EVENT
;
1328 if (!(tab
[i
].flags
& STB_DEBUG_SPECOUTMODE
) && !(tab
[i
].flags
& STB_DEBUG_DIRECTIVE_DELAYMODE
))
1330 if (tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)
1332 chain
=stb_get_directive_paths(tvf
, !setuphold
, tab
[i
].debugl
.CMD_EVENT
->ROOT
, (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_RISING
)?1:0,(tab
[i
].flags
& STB_DEBUG_DIRECTIVE_CLOCK_IS_DATA
)?0:1, 0, detail
->clock
-detail
->moved_clock_period
, &clockcon
, speedinput
);
1335 chain
=ttv_GetClockPath(tab
[i
].path
, &clockcon
, &pathcmd
);
1336 if (chain
==NULL
&& clockcon
!=NULL
)
1338 if ((tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)==0 || (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_CLOCK_IS_DATA
)==0)
1339 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_CLOCK_START
);
1341 ttv_search_mode(1, TTV_MORE_OPTIONS_USE_DATA_START
);
1343 chain
=addchain(NULL
, ttv_create_one_node_path(tab
[i
].path
->FIG
, tab
[i
].path
->FIG
, clockcon
, (tab
[i
].path
->TYPE
& TTV_FIND_MAX
)!=0?TTV_FIND_MIN
:TTV_FIND_MAX
));
1344 ttv_search_mode(0, TTV_MORE_OPTIONS_USE_CLOCK_START
|TTV_MORE_OPTIONS_USE_DATA_START
);
1348 *requiredpath
=chain
;
1354 static ttvpath_list
*stb_GetSlackPath(slackobject
*so
, char which
)
1356 // which=0 data_valid else data_required
1357 chain_list
*allpaths
, *chain
;
1358 Setup_Hold_Computation_Detail_INFO
*detail
;
1360 if (so
->SI
.path
==NULL
)
1362 int oldttvmode
=TTV_QUIET_MODE
, oldprecisionlevel
;
1364 oldprecisionlevel
=ttv_SetPrecisionLevel(0);
1366 allpaths
=__stb_getslackpaths(ttv_GetSignalTopTimingFigure(so
->SI
.debugl
.SIG2
), &so
->SI
, "*", 2, "??", so
->setuphold
, 0, 1, NULL
, &chain
, NULL
);
1367 so
->data_required
=chain
!=NULL
?chain
->DATA
:NULL
;
1369 so
->data_valid
=so
->SI
.path
;
1370 for (chain
=allpaths
; chain
!=NULL
&& chain
->DATA
!=so
->SI
.path
; chain
=chain
->NEXT
) ;
1371 if (chain
!=NULL
) chain
->DATA
=NULL
;
1372 ttv_FreePathList(allpaths
);
1373 freechain(allpaths
);
1375 ttv_SetPrecisionLevel(oldprecisionlevel
);
1376 TTV_QUIET_MODE
=oldttvmode
;
1378 if (so
->setuphold
) detail
=&so
->SI
.debugl
.detail
[(int)so
->SI
.dirout
].setup
;
1379 else detail
=&so
->SI
.debugl
.detail
[(int)so
->SI
.dirout
].hold
;
1381 // if (so->data_valid!=NULL) so->data_valid->DELAYSTART+=detail->datamoved+detail->misc;
1383 if (so
->data_required
!=NULL
)
1386 pm=detail->moved_clock_period;
1387 if (so->setuphold==0) pm-=detail->period;
1388 so->data_required->DELAYSTART+=pm;*/
1389 so
->data_required
->DELAYSTART
+=-detail
->datamoved
-detail
->misc
+detail
->moved_clock_period
;
1390 if (so
->setuphold
==0) so
->data_required
->DELAYSTART
-=detail
->period
;
1392 if (so
->data_valid
) ttv_CheckTransformToIdeal(so
->data_valid
);
1393 if (so
->data_required
) ttv_CheckTransformToIdeal(so
->data_required
);
1395 if (which
=='v') return so
->data_valid
;
1396 return so
->data_required
;
1399 static void stb_GetAllSlackPath(chain_list
*sl
)
1401 chain_list
*cl
, *chain
, *allpaths
, *speedinput
;
1404 int nb
, setuphold
, i
;
1407 for (nb
=0, cl
=sl
; cl
!=NULL
; cl
=cl
->NEXT
)
1409 so
=(slackobject
*)cl
->DATA
;
1410 setuphold
=so
->setuphold
;
1411 tvf
=so
->SI
.debugl
.SIG2
->ROOT
;
1412 if (so
->SI
.path
==NULL
) nb
++;
1417 tab
=(slackinfo
*)mbkalloc(nb
*sizeof(slackinfo
));
1418 for (nb
=0, cl
=sl
; cl
!=NULL
; cl
=cl
->NEXT
)
1420 so
=(slackobject
*)cl
->DATA
;
1421 if (so
->SI
.path
==NULL
)
1422 memcpy(&tab
[nb
++], &so
->SI
, sizeof(slackinfo
));
1424 tvf
=ttv_GetTopTimingFigure(tvf
);
1425 speedinput
= ttv_getsigbytype_and_netname(tvf
,NULL
,TTV_SIG_C
|TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
,NULL
) ;
1427 for (i
=0, cl
=sl
; cl
!=NULL
; cl
=cl
->NEXT
)
1429 so
=(slackobject
*)cl
->DATA
;
1430 if (so
->SI
.path
==NULL
)
1432 allpaths
=__stb_getslackpaths(tvf
, tab
, "*", 2, "??", setuphold
, i
, nb
, allpaths
, &chain
, speedinput
);
1433 so
->data_required
=chain
!=NULL
?ttv_duppath((ttvpath_list
*)chain
->DATA
):NULL
;
1435 so
->data_valid
=ttv_duppath(tab
[i
].path
);
1439 freechain(speedinput
);
1440 for (chain
=allpaths
; chain
!=NULL
; chain
=chain
->NEXT
)
1442 pth
=(ttvpath_list
*)chain
->DATA
;
1443 if (pth
!=NULL
) pth
->MD
=NULL
;
1445 ttv_FreePathList(allpaths
);
1446 freechain(allpaths
);
1451 static void __stb_DisplaySlackReport_grab(FILE *f
, stbfig_list
*stbfig
, char *start
, char *end
, char *direction
, int setuphold
, double margin
, int sumaonly
, int maxnb
, int addit
, char *thru
, chain_list
*given_objects
, int simple
)
1453 char *startsig
, *endsig
;
1455 char startdir
, enddir
;
1457 int count
=1, tot
, max
, i
, dir
, dirin
, dirout
, access
, countfree
;
1460 slackobject
**sotab
=NULL
;
1462 Setup_Hold_Computation_Detail_INFO
*detail
;
1463 chain_list
*chain
, *allpaths
, *speedinput
=NULL
;
1464 ttvevent_list
*path_start_ev
;
1466 long old0
, old1
, save_req
;
1471 ttv_DirectionStringToIndices(direction
, &dirin
, &dirout
);
1472 forced
=ttv_DirectionStringToIndicesHZ(direction
);
1474 lastmode
=stbsetdebugflag(STB_DIFFERENTIATE_INPUT_EVENTS
);
1475 ttv_setsearchexclude(0,0,&old0
, &old1
);
1477 b
=Board_CreateBoard();
1479 Board_SetSize(b
, COL_INDEX
, 5, 'r');
1480 Board_SetSize(b
, COL_SLACK
, 7, DISPLAY_number_justify
);
1481 Board_SetSize(b
, COL_DV_TIME
, 7, DISPLAY_number_justify
);
1482 Board_SetSize(b
, COL_DV_REL
, 7, DISPLAY_number_justify
);
1483 Board_SetSize(b
, COL_DR_TIME
, 7, DISPLAY_number_justify
);
1484 Board_SetSize(b
, COL_DR_REL
, 7, DISPLAY_number_justify
);
1485 Board_SetSize(b
, COL_STARTEND
, 3, 'c');
1486 Board_SetSize(b
, COL_FROMNODE
, 20, 'l');
1487 Board_SetSize(b
, COL_FROMNODEDIR
, 3, 'l');
1488 Board_SetSize(b
, COL_TONODE
, 20, 'l');
1489 Board_SetSize(b
, COL_TONODEDIR
, 4, 'l');
1492 Board_SetSize(b
, COL_THRUDEBUG
, 20, 'l');
1496 Board_SetSize(b
, COL_DATAPATHMARGIN
, 6, DISPLAY_number_justify
);
1497 Board_SetSize(b
, COL_CLOCKPATHMARGIN
, 6, DISPLAY_number_justify
);
1498 Board_SetSize(b
, COL_INTRINSIC_MARGIN
, 10, DISPLAY_number_justify
);
1499 Board_SetSep(b
, COL_SLACK_SEP6
);
1502 Board_SetSep(b
, COL_SLACK_SEP0
);
1503 Board_SetSep(b
, COL_SLACK_SEP1
);
1504 Board_SetSep(b
, COL_SLACK_SEP2
);
1505 Board_SetSep(b
, COL_SLACK_SEP3
);
1506 Board_SetSep(b
, COL_SLACK_SEP4
);
1507 Board_SetSep(b
, COL_SLACK_SEP5
);
1511 Board_SetValue(b
, COL_INDEX
, "Path");
1512 Board_SetValue(b
, COL_SLACK
, "Slack");
1513 Board_SetValue(b
, COL_DV_TIME
, "éData");
1514 Board_SetValue(b
, COL_DV_REL
, "èvalid");
1515 Board_SetValue(b
, COL_DR_TIME
, "éData");
1516 Board_SetValue(b
, COL_DR_REL
, "èrequired");
1517 Board_SetValue(b
, COL_FROMNODE
, "From_node");
1518 Board_SetValue(b
, COL_TONODE
, "To_node");
1522 Board_SetValue(b
, COL_DATAPATHMARGIN
, "D-Margin");
1523 Board_SetValue(b
, COL_CLOCKPATHMARGIN
, "C-Margin");
1524 Board_SetValue(b
, COL_INTRINSIC_MARGIN
, "IntrMargin");
1527 Board_SetValue(b
, COL_THRUDEBUG
, "Thru_node");
1529 Board_NewSeparation(b
);
1532 tab
=__stb_getslacklist(stbfig
, setuphold
, start
, end
, dirin
, dirout
, margin
, maxnb
, &tot
, forced
,thru
);
1535 tot
=countchain(given_objects
);
1538 tab
=mbkalloc(sizeof(slackinfo
)*tot
);
1539 sotab
=mbkalloc(sizeof(slackobject
*)*tot
);
1540 for (chain
=given_objects
, i
=0; chain
!=NULL
; chain
=chain
->NEXT
, i
++)
1542 sotab
[i
]=(slackobject
*)chain
->DATA
;
1543 memcpy(&tab
[i
], &((slackobject
*)chain
->DATA
)->SI
, sizeof(slackinfo
));
1548 for (i
=0; i
<tot
&& i
<maxnb
; i
++)
1551 sprintf(buf
,"%d", count
);
1552 Board_SetValue(b
, COL_INDEX
, buf
);
1555 if (sotab
[i
]->SI
.path
!=NULL
)
1556 path_start_ev
=sotab
[i
]->SI
.path
->NODE
;
1558 path_start_ev
=stb_getpathstart(ttv_GetSignalTopTimingFigure(sotab
[i
]->SI
.debugl
.SIG2
), sotab
[i
]->SI
.debugl
.SIG1_EVENT
, "*", (int)sotab
[i
]->SI
.dirin
, &access
, sotab
[i
]->SI
.phase
, sotab
[i
]->SI
.debugl
.START_CMD_EVENT
, !sotab
[i
]->SI
.access
, sotab
[i
]->SI
.debugl
.START_CLOCK
);
1561 path_start_ev
=stb_getpathstart(stbfig
->FIG
, tab
[i
].debugl
.SIG1_EVENT
, start
, dirin
, &access
, tab
[i
].phase
,tab
[i
].debugl
.START_CMD_EVENT
, !tab
[i
].access
, tab
[i
].debugl
.START_CLOCK
);
1563 sg
=path_start_ev
->ROOT
;
1564 startsig
=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(sg
), sg
);
1566 sg
=tab
[i
].debugl
.SIG2
;
1567 endsig
=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(sg
), sg
);
1569 startdir
=dirconv(tab
[i
].dirin
?'u':'d');
1570 enddir
=dirconv(tab
[i
].dirout
?'u':'d');
1571 sprintf(buf
,"(%c)",startdir
);
1572 Board_SetValue(b
, COL_FROMNODEDIR
, buf
);
1575 if (tab
[i
].hzpath
) {strcpy(&buf
[2],"Z)");}
1576 else {strcpy(&buf
[2],")"); }
1577 Board_SetValue(b
, COL_TONODEDIR
, buf
);
1578 Board_SetValue(b
, COL_FROMNODE
, startsig
);
1579 Board_SetValue(b
, COL_TONODE
, endsig
);
1581 if (/*(tab[i].flags & STB_DEBUG_DIRECTIVE)==0 && */(tab
[i
].access
|| (tab
[i
].debugl
.SIG1_EVENT
->ROOT
->TYPE
& TTV_SIG_C
)==0))
1585 if (tab
[i
].debugl
.START_CMD_EVENT
!=NULL
)
1587 startsig
=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(tab
[i
].debugl
.START_CMD_EVENT
->ROOT
), tab
[i
].debugl
.START_CMD_EVENT
->ROOT
);
1588 sprintf(buf1
, " cmd: %s (%c)", startsig
, dirconv(ttv_GetTimingEventDirection(tab
[i
].debugl
.START_CMD_EVENT
)));
1590 else strcpy(buf1
,"");
1591 startsig
=ttv_GetFullSignalName_COND(ttv_GetSignalTopTimingFigure(tab
[i
].debugl
.SIG1_EVENT
->ROOT
), tab
[i
].debugl
.SIG1_EVENT
->ROOT
);
1592 sprintf(buf
, "%s (%c)%s", startsig
, dirconv(ttv_GetTimingEventDirection(tab
[i
].debugl
.SIG1_EVENT
)), buf1
);
1593 Board_SetValue(b
, COL_THRUDEBUG
, buf
);
1596 if (tab
[i
].datavalid
<1)
1598 Board_SetValue(b
, COL_DV_TIME
, FormaT(tab
[i
].datavalid
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1599 if ((tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)==0)
1603 sprintf(buf
, "[%s lag]", FormaT(tab
[i
].lag
*DISPLAY_time_unit
, buf0
, DISPLAY_time_format
));
1606 Board_SetValue(b
, COL_DV_REL
, buf
);
1611 Board_SetValue(b
, COL_DV_TIME
, "void");
1612 // Board_SetValue(b, COL_DV_REL, "void");
1614 Board_SetValue(b
, COL_DR_TIME
, FormaT(tab
[i
].datareq
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1615 /* if ((tab[i].flags & STB_DEBUG_DIRECTIVE)==0)
1617 if (tab[i].period>0)
1618 sprintf(buf, "%s B%c", FormaT(fmod(tab[i].datavalidclock-tab[i].datareq, tab[i].period)*DISPLAY_time_unit, buf, DISPLAY_time_format), tab[i].datavalidclockdir=='u'?'R':'F');
1621 Board_SetValue(b, COL_DR_REL, buf);
1623 if (tab
[i
].datavalid
<1)
1625 Board_SetValue(b
, COL_SLACK
, FormaT(tab
[i
].slack
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1627 else Board_SetValue(b
, COL_SLACK
, "void");
1629 if ((tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)==0)
1631 if (isclock(path_start_ev
->ROOT
))
1635 startsig
=typeconv(ttv_GetSignalType(path_start_ev
->ROOT
));
1636 // if (strcmp(startsig, "S")==0) startsig="s";
1639 if (isclock(tab
[i
].debugl
.SIG2
))
1642 endsig
=typeconv(ttv_GetSignalType(tab
[i
].debugl
.SIG2
));
1646 if (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_DATA_IS_CLOCK
)
1650 if (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_DELAYMODE
)
1652 else if (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_CLOCK_IS_DATA
)
1658 sprintf(buf
,"%s-%s", startsig
, endsig
);
1660 Board_SetValue(b
, COL_STARTEND
, buf
);
1664 if (setuphold
) detail
=&tab
[i
].debugl
.detail
[(int)tab
[i
].dirout
].setup
;
1665 else detail
=&tab
[i
].debugl
.detail
[(int)tab
[i
].dirout
].hold
;
1666 Board_SetValue(b
, COL_DATAPATHMARGIN
, FormaT((detail
->data_margin
*1e-12/TTV_UNIT
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1667 Board_SetValue(b
, COL_CLOCKPATHMARGIN
, FormaT((detail
->clock_margin
*1e-12/TTV_UNIT
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1668 Board_SetValue(b
, COL_INTRINSIC_MARGIN
, FormaT((detail
->margin
*1e-12/TTV_UNIT
)*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1674 avt_fprintf(f
, " *** %s Slack report (unit:[%s]) ***\n\n",setuphold
?"Setup":"Hold", DISPLAY_time_string
);
1676 Board_Display(f
, b
, "");
1679 avt_fprintf(f
, "\n\n");
1684 olddetmode
=ttv_AutomaticDetailBuild("on");
1688 speedinput
= ttv_getsigbytype_and_netname(stbfig
->FIG
,NULL
,TTV_SIG_C
|TTV_SIG_L
|TTV_SIG_R
|TTV_SIG_B
,NULL
) ;
1690 stb_GetAllSlackPath(given_objects
);
1692 for (i
=0; i
<tot
&& i
<maxnb
; i
++)
1696 allpaths
=__stb_getslackpaths(stbfig
->FIG
, tab
, start
, dirin
, direction
, setuphold
, i
, tot
, allpaths
, &chain
, speedinput
);
1699 if (sotab
[i
]->SI
.path
==NULL
)
1700 stb_GetSlackPath(sotab
[i
], 'v');
1701 tab
[i
].path
=sotab
[i
]->SI
.path
;
1707 int oldmode
=detail_forced_mode
;
1709 if (ttv_GetPathEndDirection(tab
[i
].path
)=='u') dir
=1; else dir
=0;
1710 if (setuphold
) detail
=&tab
[i
].debugl
.detail
[dir
].setup
;
1711 else detail
=&tab
[i
].debugl
.detail
[dir
].hold
;
1713 detail_forced_mode
=NOSUPINFO_DETAIL
;
1714 // if (getptype(tab[i].path->NODE->ROOT->USER, STB_IDEAL_CLOCK)!=NULL)
1716 if (!sotab
|| sotab
[i
]->custom
==0)
1717 ttv_CheckTransformToIdeal(tab
[i
].path
);
1718 // detail_forced_mode|=IDEAL_CLOCK;
1721 avt_fprintf(f
, "Path (%d) : Slack of %s\n", i
+1, FormaT(tab
[i
].slack
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1722 avt_fprintf(f
, " DATA VALID:\n");
1724 tab
[i
].path
->CMD
=tab
[i
].debugl
.CMD_EVENT
;
1726 tab[i].path->USER=addptype(tab[i].path->USER, DEBUG_PTYPE, &tab[i].debugl);*/
1729 if (detail
->data_margin
!=0)
1731 PATH_MORE_INFO
.add
[max
].label
="[PATH MARGIN]";
1732 PATH_MORE_INFO
.add
[max
].val
=(detail
->data_margin
*1e-12/TTV_UNIT
);
1733 PATH_MORE_INFO
.add
[max
].noacc
=0;
1737 PATH_MORE_INFO
.add
[max
].label
=NULL
;
1738 PATH_MORE_INFO
.enabled
=1;
1739 ttv_DisplayPathDetail(f
, -1, tab
[i
].path
);
1740 PATH_MORE_INFO
.enabled
=0;
1741 // tab[i].path->USER=testanddelptype(tab[i].path->USER, DEBUG_PTYPE);
1742 tab
[i
].path
->USER
=testanddelptype(tab
[i
].path
->USER
, MORE_PTYPE
);
1744 // detail_forced_mode&=~IDEAL_CLOCK;
1746 if (chain
!=NULL
|| (sotab
&& (detail
->flags
& STB_DEBUG_SPECOUTMODE
)==0 && (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_DELAYMODE
)==0))
1749 pth
=(ttvpath_list
*)chain
->DATA
;
1751 pth
=stb_GetSlackPath(sotab
[i
], 'r');
1755 sh_m
=(detail
->margin
*1e-12/TTV_UNIT
);
1756 if (detail
->clock_margin
!=0)
1758 PATH_MORE_INFO
.add
[max
].label
="[PATH MARGIN]";
1759 PATH_MORE_INFO
.add
[max
].val
=(detail
->clock_margin
*1e-12/TTV_UNIT
);
1760 PATH_MORE_INFO
.add
[max
].noacc
=0;
1763 if (detail
->margin
!=0)
1765 char *labelsetup
, *labelhold
;
1766 if ((tab
[i
].flags
& STB_DEBUG_DIRECTIVE
)==0)
1767 labelsetup
="[INTRINSIC SETUP]", labelhold
="[INTRINSIC HOLD]";
1769 labelsetup
="[SETUP MARGIN]", labelhold
="[HOLD MARGIN]";
1772 PATH_MORE_INFO
.add
[max
].label
=labelsetup
, PATH_MORE_INFO
.add
[max
].val
=-(detail
->margin
*1e-12/TTV_UNIT
);
1774 PATH_MORE_INFO
.add
[max
].label
=labelhold
, PATH_MORE_INFO
.add
[max
].val
=(detail
->margin
*1e-12/TTV_UNIT
);
1775 PATH_MORE_INFO
.add
[max
].noacc
=0;
1778 if (detail
->skew
!=0)
1780 PATH_MORE_INFO
.add
[max
].label
="[SKEW COMPENSATION]";
1782 PATH_MORE_INFO
.add
[max
].val
=detail
->skew
/TTV_UNIT
*1e-12;
1784 PATH_MORE_INFO
.add
[max
].val
=-detail
->skew
/TTV_UNIT
*1e-12;
1785 PATH_MORE_INFO
.add
[max
].noacc
=0;
1788 if (detail
->uncertainty
!=0)
1790 PATH_MORE_INFO
.add
[max
].label
="[CLOCK UNCERTAINTY]";
1792 PATH_MORE_INFO
.add
[max
].val
=-detail
->uncertainty
/TTV_UNIT
*1e-12;
1794 PATH_MORE_INFO
.add
[max
].val
=detail
->uncertainty
/TTV_UNIT
*1e-12;
1795 PATH_MORE_INFO
.add
[max
].noacc
=0;
1800 if (detail
->mc_setup_period
!=0)
1802 sprintf(buf
, "[SETUP MULTICYCLE %d]", detail
->nb_setup_cycle
);
1803 PATH_MORE_INFO
.add
[max
].label
=sensitive_namealloc(buf
);
1804 PATH_MORE_INFO
.add
[max
].val
=(detail
->mc_setup_period
*1e-12/TTV_UNIT
);
1805 PATH_MORE_INFO
.add
[max
].noacc
=1;
1808 if (!setuphold
&& detail
->mc_hold_period
!=0)
1810 sprintf(buf
, "[HOLD MULTICYCLE %d]", detail
->nb_hold_cycle
);
1811 PATH_MORE_INFO
.add
[max
].label
=sensitive_namealloc(buf
);
1812 PATH_MORE_INFO
.add
[max
].val
=-(detail
->mc_hold_period
*1e-12/TTV_UNIT
);
1813 PATH_MORE_INFO
.add
[max
].noacc
=1;
1817 pm
=-(detail
->datamoved
+detail
->mc_setup_period
)+detail
->moved_clock_period
;
1818 if (setuphold
==0) pm
-=detail
->period
;
1822 PATH_MORE_INFO
.add
[max
].label
="[NEXT PERIOD]";
1824 PATH_MORE_INFO
.add
[max
].label
="[PREVIOUS PERIOD]";
1825 PATH_MORE_INFO
.add
[max
].val
=pm
/TTV_UNIT
*1e-12;
1826 PATH_MORE_INFO
.add
[max
].noacc
=1;
1831 PATH_MORE_INFO
.add
[max
].label
=NULL
;
1832 if (max
!=0) PATH_MORE_INFO
.enabled
=1;
1833 avt_fprintf(f
, " DATA REQUIRED:\n");
1834 // if (getptype(pth->NODE->ROOT->USER, STB_IDEAL_CLOCK)!=NULL)
1836 if (!sotab
|| sotab
[i
]->custom
==0)
1837 ttv_CheckTransformToIdeal(pth
);
1838 // detail_forced_mode|=IDEAL_CLOCK;
1841 save_req
=pth
->DELAYSTART
;
1842 if (sotab
&& !simple
)
1844 pth
->DELAYSTART
-=detail
->moved_clock_period
-detail
->datamoved
+detail
->misc
;
1845 if (setuphold
==0) pth
->DELAYSTART
+=detail
->period
;
1847 else if (!sotab
&& simple
)
1849 pth
->DELAYSTART
+=-detail
->datamoved
-detail
->misc
+detail
->moved_clock_period
;
1850 if (!setuphold
) pth
->DELAYSTART
-=detail
->period
;
1854 ttv_DisplayPathDetail(f
, -1, pth
);
1856 pth
->DELAYSTART
=save_req
;
1858 PATH_MORE_INFO
.enabled
=0;
1860 else if (tab
[i
].flags
& STB_DEBUG_DIRECTIVE_DELAYMODE
)
1862 avt_fprintf(f
, " -> Specification: Must be stable %s %s\n\n", setuphold
?"after":"before", FormaT(tab
[i
].datareq
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1866 ttv_GetNodeSpecout(tab
[i
].path
->ROOT
, DISPLAY_time_unit
, DISPLAY_time_format
, buf
, &tab
[i
].debugl
, tab
[i
].path
, setuphold
, -detail
->datamoved
-detail
->misc
+detail
->moved_clock_period
);
1869 avt_fprintf(f
, " -> Specification: %s\n\n", buf
);
1872 ttv_FreePathList(chain
);
1874 detail_forced_mode
=oldmode
;
1879 if (tab
[i
].path
->MD
==NULL
)
1884 chain_list
*temp
=allpaths
;
1886 for (chain
=temp
; chain
!=NULL
; chain
=chain
->NEXT
)
1888 pth
=(ttvpath_list
*)chain
->DATA
;
1892 ttv_freepathlist(pth
);
1894 else allpaths
=addchain(allpaths
, pth
);
1904 avt_fprintf(f
, "Path (%d) : Slack of %s\n", i
+1, FormaT(tab
[i
].slack
*DISPLAY_time_unit
, buf
, DISPLAY_time_format
));
1905 avt_fprintf(f
, " DATA VALID: *** FAILED TO RETRIEVE PATH ***\n\n");
1911 freechain(speedinput
);
1912 for (chain
=allpaths
; chain
!=NULL
; chain
=chain
->NEXT
)
1914 pth
=(ttvpath_list
*)chain
->DATA
;
1915 if (pth
!=NULL
) pth
->MD
=NULL
;
1917 ttv_FreePathList(allpaths
);
1918 freechain(allpaths
);
1920 ttv_AutomaticDetailBuild(olddetmode
);
1924 /* for (i=0; i<tot; i++)
1926 if (tab[i].debugl.CHRONO!=NULL)
1929 stb_freestbpair(tab[i].debugl.CHRONO->SPECS);
1930 stb_freestbpair(tab[i].debugl.CHRONO->SPECS_U);
1931 stb_freestbpair(tab[i].debugl.CHRONO->SPECS_D);
1932 mbkfree(tab[i].debugl.CHRONO);
1933 tab[i].debugl.CHRONO = NULL;
1939 if (sotab
) mbkfree(sotab
);
1941 ttv_setsearchexclude(old0
, old1
, &old0
, &old1
);
1942 stbsetdebugflag(lastmode
);
1946 void stb_DisplaySlackReport_sub(FILE *f
, stbfig_list
*stbfig
, char *start
, char *end
, char *dir
, int number
, char *mode
, double margin
)
1948 int setup
=0, hold
=0, sum
=0;
1951 int oldttvmode
=TTV_QUIET_MODE
;
1952 int oldprecisionlevel
, addit
=0, simple
=0;
1953 long stbmode
=stb_SUPMODE
;
1957 tok
=strtok_r(buf
, " ", &c
);
1961 if (strcasecmp(tok
,"setup")==0) setup
=1;
1962 else if (strcasecmp(tok
,"hold")==0) hold
=1;
1963 else if (strcasecmp(tok
,"all")==0) {setup
=hold
=1;}
1964 else if (strcasecmp(tok
,"summary")==0) sum
=1;
1965 else if (strcasecmp(tok
,"margins")==0) addit
|=1;
1966 else if (strcasecmp(tok
,"thru")==0) addit
|=2;
1967 else if (strcasecmp(tok
,"simple")==0) simple
=1;
1968 else if (strcasecmp(tok
,"noprechlag")==0) stb_SUPMODE
|=STB_REMOVE_LAGGING_PRECHARGES
;
1969 else if (strncasecmp(tok
,"thru=",5)==0) thru
=&tok
[5];
1970 else //avt_error("stbapi", 2, AVT_ERR, "stb_DisplaySlackReport: unknown mode '%s'\n", tok);
1971 avt_errmsg(STB_API_ERRMSG
, "002", AVT_ERROR
, tok
);
1972 tok
=strtok_r(NULL
, " ", &c
);
1975 if (f
==NULL
) return;
1978 ttv_DumpHeader(f
, stbfig
->FIG
);
1981 avt_errmsg(STB_API_ERRMSG
, "003", AVT_ERROR
);
1982 // avt_error("stbapi", 2, AVT_ERR, "stb_DisplaySlackReport: NULL stbfig\n");
1988 oldprecisionlevel
=ttv_SetPrecisionLevel(0);
1990 if (number
<=0) number
=INT_MAX
;
1994 __stb_DisplaySlackReport_grab(f
, stbfig
, start
, end
, dir
, 1, margin
, sum
, number
, addit
,thru
, NULL
, simple
);
1998 __stb_DisplaySlackReport_grab(f
, stbfig
, start
, end
, dir
, 0, margin
, sum
, number
, addit
,thru
, NULL
, simple
);
2001 ttv_SetPrecisionLevel(oldprecisionlevel
);
2003 TTV_QUIET_MODE
=oldttvmode
;
2004 stb_SUPMODE
=stbmode
;
2005 if (setup
==0 && hold
==0)
2006 avt_errmsg(STB_API_ERRMSG
, "004", AVT_ERROR
, mode
);
2007 // avt_error("stbapi", 1, AVT_ERR, "stb_DisplaySlackReport: unknown or incomplete mode '%s'. Required: 'setup', 'hold' or 'all'\n", mode);
2010 void stb_FreeSlackList(chain_list
*cl
)
2015 so
=(slackobject
*)cl
->DATA
;
2016 if (so
->data_valid
!=NULL
) { so
->data_valid
->NEXT
=NULL
; so
->data_valid
->MD
=NULL
; ttv_freepathlist(so
->data_valid
); }
2017 if (so
->data_required
!=NULL
) { so
->data_required
->NEXT
=NULL
; so
->data_required
->MD
=NULL
; ttv_freepathlist(so
->data_required
); }
2023 chain_list
*stb_GetSlacks_sub(stbfig_list
*stbfig
, char *start
, char *end
, char *dir
, int number
, char *mode
, double margin
, char *thru
, int nolagprech
)
2026 int oldprecisionlevel
;
2027 int oldttvmode
=TTV_QUIET_MODE
;
2028 int tot
, i
, dirin
, dirout
;
2031 chain_list
*cl
, *ch
;
2033 long stbmode
=stb_SUPMODE
;
2035 ttv_DirectionStringToIndices(dir
, &dirin
, &dirout
);
2036 forced
=ttv_DirectionStringToIndicesHZ(dir
);
2038 if (strcasecmp(mode
,"setup")==0) setuphold
=1;
2039 else if (strcasecmp(mode
,"hold")==0) setuphold
=0;
2042 avt_errmsg(STB_API_ERRMSG
, "002", AVT_ERROR
, mode
);
2046 if (nolagprech
) stb_SUPMODE
|=STB_REMOVE_LAGGING_PRECHARGES
;
2047 if (number
<=0) number
=INT_MAX
;
2048 if (thru
==NULL
|| strcmp(thru
,"*")==0) thru
=NULL
;
2051 oldprecisionlevel
=ttv_SetPrecisionLevel(0);
2052 tab
=__stb_getslacklist(stbfig
, setuphold
, start
, end
, dirin
, dirout
, margin
, number
, &tot
, forced
, thru
);
2055 for (i
=0; i
<tot
; i
++)
2057 so
=(slackobject
*)mbkalloc(sizeof(slackobject
));
2058 memcpy(&so
->SI
, &tab
[i
], sizeof(slackinfo
));
2059 so
->setuphold
=setuphold
;
2061 so
->data_valid
=so
->data_required
=NULL
;
2063 cl
=addchain(cl
, so
);
2065 ch
=addchain(ch
, so
);
2068 stb_FreeSlackList(ch
);
2070 ttv_SetPrecisionLevel(oldprecisionlevel
);
2071 TTV_QUIET_MODE
=oldttvmode
;
2072 stb_SUPMODE
=stbmode
;
2077 static ptype_list
*fitdouble(double val
)
2080 pt
=addptype(NULL
, TYPE_DOUBLE
, NULL
);
2081 *(float *)&pt
->DATA
=(float)val
;
2084 Property
*stb_GetSlackProperty (slackobject
*so
, char *property
)
2087 Setup_Hold_Computation_Detail_INFO
*detail
;
2090 sprintf (buf
, "error_null_stabilityslack");
2091 return addptype (NULL
, TYPE_CHAR
, strdup (buf
));
2094 if (!strcasecmp (property
, "TYPE"))
2095 return addptype (NULL
, TYPE_CHAR
, strdup(so
->setuphold
?"setup":"hold"));
2097 if (!strcasecmp (property
, "DATA_REQUIRED_PATH"))
2098 return addptype (NULL
, TYPE_TIMING_PATH
, stb_GetSlackPath(so
, 'r'));
2100 if (!strcasecmp (property
, "DATA_VALID_PATH"))
2101 return addptype (NULL
, TYPE_TIMING_PATH
, stb_GetSlackPath(so
, 'v'));
2103 if (!strcasecmp (property
, "DATA_REQUIRED"))
2104 return fitdouble(so
->SI
.datareq
);
2106 if (!strcasecmp (property
, "DATA_VALID"))
2107 return fitdouble(so
->SI
.datavalid
);
2109 if (!strcasecmp (property
, "START_EVENT"))
2111 ttvevent_list
*path_start_ev
;
2113 path_start_ev
=stb_getpathstart(ttv_GetSignalTopTimingFigure(so
->SI
.debugl
.SIG2
), so
->SI
.debugl
.SIG1_EVENT
, "*", (int)so
->SI
.dirin
, &access
, so
->SI
.phase
, so
->SI
.debugl
.START_CMD_EVENT
, !so
->SI
.access
, so
->SI
.debugl
.START_CLOCK
);
2114 return addptype (NULL
, TYPE_TIMING_EVENT
, path_start_ev
);
2117 if (!strcasecmp (property
, "THRU_EVENT"))
2119 ttvevent_list
*thru
=NULL
;
2120 if (so
->SI
.access
) thru
=so
->SI
.debugl
.SIG1_EVENT
;
2121 return addptype (NULL
, TYPE_TIMING_EVENT
, thru
);
2124 if (!strcasecmp (property
, "THRU_COMMAND_EVENT"))
2126 ttvevent_list
*thrucmd
=NULL
;
2127 if (so
->SI
.access
) thrucmd
=so
->SI
.debugl
.START_CMD_EVENT
;
2128 return addptype (NULL
, TYPE_TIMING_EVENT
, thrucmd
);
2131 if (!strcasecmp (property
, "END_EVENT"))
2132 return addptype (NULL
, TYPE_TIMING_EVENT
, &so
->SI
.debugl
.SIG2
->NODE
[(int)so
->SI
.dirout
]);
2134 if (!strcasecmp (property
, "IS_HZ"))
2136 return addptype (NULL
, TYPE_CHAR
, strdup(so
->SI
.hzpath
?"yes":"no"));
2139 if (!strcasecmp (property
, "VALUE"))
2140 return fitdouble(so
->SI
.slack
);
2142 if (so
->setuphold
) detail
=&so
->SI
.debugl
.detail
[(int)so
->SI
.dirout
].setup
;
2143 else detail
=&so
->SI
.debugl
.detail
[(int)so
->SI
.dirout
].hold
;
2145 if (!strcasecmp (property
, "DATA_REQUIRED_PATH_MARGIN"))
2146 return fitdouble(detail
->clock_margin
*1e-12/TTV_UNIT
);
2148 if (!strcasecmp (property
, "DATA_VALID_PATH_MARGIN"))
2149 return fitdouble(detail
->data_margin
*1e-12/TTV_UNIT
);
2151 if (!strcasecmp (property
, "INTRINSIC_MARGIN"))
2154 return fitdouble(-detail
->margin
*1e-12/TTV_UNIT
);
2156 return fitdouble(detail
->margin
*1e-12/TTV_UNIT
);
2159 if (!strcasecmp (property
, "UNCERTAINTY"))
2162 return fitdouble(-detail
->uncertainty
*1e-12/TTV_UNIT
);
2164 return fitdouble(detail
->uncertainty
*1e-12/TTV_UNIT
);
2167 if (!strcasecmp (property
, "SKEW_COMPENSATION"))
2170 return fitdouble(detail
->skew
/TTV_UNIT
*1e-12);
2172 return fitdouble(-detail
->skew
/TTV_UNIT
*1e-12);
2175 avt_errmsg(STB_API_ERRMSG
, "006", AVT_FATAL
, property
);
2176 // fprintf (stderr, "error: unknown property %s\n", property);
2180 static int stb_path_is_clockpath(ttvpath_list
*pth
)
2186 if ((pth
->TTV_MORE_SEARCH_OPTIONS
& TTV_MORE_OPTIONS_MUST_BE_CLOCK
)!=0
2187 || (pth
->TTV_MORE_SEARCH_OPTIONS
& TTV_MORE_OPTIONS_USE_CLOCK_START
)!=0
2189 if ((pth
->TTV_MORE_SEARCH_OPTIONS
& TTV_MORE_OPTIONS_USE_DATA_START
)!=0) return 1;
2190 if (pth
->LATCH
==NULL
) ev
=pth
->NODE
;
2193 if (ttv_IsClock(ev
->ROOT
)) return 1;
2194 n
=stb_getstbnode(ev
);
2195 pair
=stb_globalstbtab(n
->STBTAB
, n
->NBINDEX
);
2196 stb_freestbpair(pair
) ;
2198 if (n
->CK
!=NULL
) return 1;
2202 slackobject
*stb_ComputeOneSlack(int setup
, ttvpath_list
*data
, ttvpath_list
*clock
, double margin
, int nextcycle
, int nosync
)
2204 char phase_data
, phase_clock
;
2205 int clockisdata
=0, dataisclock
=0,dirout
;
2206 long oc
,od
, cs
, ds
, val
, lmargin
, d_valid
, d_req
, css
, dss
, movedck
,pper
;
2211 Setup_Hold_Computation_Detail_INFO
*detail
;
2212 Extended_Setup_Hold_Computation_Data_Item eshdi
;
2213 int flags
=STB_DEBUG_DIRECTIVE
;
2216 tf
=ttv_GetSignalTopTimingFigure(data
->NODE
->ROOT
);
2218 sf
=stb_getstbfig(tf
);
2220 if (sf
==NULL
) return NULL
;
2222 ifl
=getloadedinffig(tf
->INFO
->FIGNAME
);
2224 phase_data
=data
->PHASE
;
2225 phase_clock
=clock
->PHASE
;
2226 if (stb_path_is_clockpath(data
)) dataisclock
=1, flags
|=STB_DEBUG_DIRECTIVE_DATA_IS_CLOCK
;
2227 if (!stb_path_is_clockpath(clock
)) clockisdata
=1, flags
|=STB_DEBUG_DIRECTIVE_CLOCK_IS_DATA
;
2229 if (ifl
!=NULL
&& ifl
->LOADED
.INF_FALSESLACK
!=NULL
)
2232 res
=stb_isfalseslack(sf
, data
->LATCH
?data
->NODE
:NULL
, data
->LATCH
?data
->LATCH
:data
->NODE
, data
->ROOT
, clock
->NODE
, setup
?INF_FALSESLACK_SETUP
:INF_FALSESLACK_HOLD
);
2233 if ((ttv_PathIsHZ(data
) && (res
& INF_FALSESLACK_HZ
)!=0) || (!ttv_PathIsHZ(data
) && (res
& INF_FALSESLACK_NOTHZ
)!=0)) return NULL
;
2236 so
=mbkalloc(sizeof(slackobject
));
2237 so
->setuphold
=setup
;
2239 so
->data_valid
=ttv_duppath(data
);
2240 so
->data_required
=ttv_duppath(clock
);
2241 ttv_CheckTransformToIdeal(so
->data_valid
);
2242 ttv_CheckTransformToIdeal(so
->data_required
);
2243 if (so
->data_valid
->ROOT
->TYPE
& TTV_NODE_UP
) dirout
=1; else dirout
=0;
2245 if (setup
) detail
=&si
->debugl
.detail
[dirout
].setup
;
2246 else detail
=&si
->debugl
.detail
[dirout
].hold
;
2249 ttv_get_path_margins(tf
, so
->data_valid
, so
->data_required
, &eshdi
.data_margin
, &eshdi
.clock_margin
, &oc
, &od
, clockisdata
, dataisclock
);
2250 eshdi
.common
=NULL
; eshdi
.same_origin
=0;
2251 eshdi
.value
=abs(oc
-od
);
2255 eshdi
.clock_uncertainty
=0;
2258 if (phase_data
!=STB_NO_INDEX
) od
=stb_getperiod(sf
, phase_data
); else od
=0;
2259 if (phase_clock
!=STB_NO_INDEX
) oc
=stb_getperiod(sf
, phase_clock
); else oc
=0;
2261 stb_getmulticycleperiod(so
->data_valid
->LATCH
?so
->data_valid
->LATCH
:so
->data_valid
->NODE
, so
->data_valid
->ROOT
, od
, oc
, &detail
->mc_setup_period
, &detail
->mc_hold_period
, &detail
->nb_setup_cycle
, &detail
->nb_hold_cycle
);
2262 if (setup
) detail
->mc_hold_period
=0;
2264 detail
->datamoved
=-detail
->mc_setup_period
;
2269 if (phase_data
!=STB_NO_INDEX
&& phase_clock
!=STB_NO_INDEX
)
2271 if (stb_cmpphase(sf
, phase_clock
, phase_data
)<=0/*phase_clock<=phase_data*/)
2273 detail
->datamoved
-=stb_synchronize_slopes(sf
, phase_data
, phase_clock
, oc
, 0);
2274 // detail->datamoved-=oc;
2276 else if (phase_clock
==phase_data
&& nextcycle
)
2281 if (setup
&& -detail
->datamoved
+movedck
!=0) eshdi
.value
=0;
2282 else if (!setup
&& -detail
->datamoved
+detail
->mc_hold_period
+movedck
!=0) eshdi
.value
=0;
2286 if (((so
->data_valid
->ROOT
->ROOT
->TYPE
& (TTV_SIG_L
|TTV_SIG_B
))!=0) && ((so
->data_required
->ROOT
->ROOT
->TYPE
& (TTV_SIG_Q
|TTV_SIG_B
))!=0)
2287 && ((so
->data_valid
->TYPE
& (TTV_FIND_MAX
|TTV_FIND_MIN
))|(so
->data_required
->TYPE
& (TTV_FIND_MAX
|TTV_FIND_MIN
)))==(TTV_FIND_MAX
|TTV_FIND_MIN
))
2289 margin
=ttv_GetLatchIntrinsicQuick(tf
, so
->data_valid
->ROOT
, so
->data_required
->ROOT
, setup
,NULL
);
2295 lmargin
=_DOUBLE_TO_LONG(margin
);
2297 if (so
->data_required
->CROSSMINDELAY
!=TTV_NOTIME
) cs
=so
->data_required
->CROSSMINDELAY
; else cs
=so
->data_required
->DELAYSTART
;
2299 cs
+=so
->data_required
->DELAY
+so
->data_required
->DATADELAY
+movedck
;
2300 if (so
->data_valid
->CROSSMINDELAY
!=TTV_NOTIME
) ds
=so
->data_valid
->CROSSMINDELAY
; else ds
=so
->data_valid
->DELAYSTART
;
2302 ds
+=so
->data_valid
->DELAY
+so
->data_valid
->DATADELAY
+detail
->datamoved
;
2304 val
=(cs
+eshdi
.clock_margin
-eshdi
.clock_uncertainty
)-(ds
+eshdi
.data_margin
)-lmargin
+eshdi
.value
;
2306 val
=(ds
+eshdi
.data_margin
)+detail
->mc_hold_period
-(cs
+eshdi
.clock_margin
+lmargin
-pper
+eshdi
.clock_uncertainty
)+eshdi
.value
;
2308 stb_setdetail(detail
, val
, ds
, cs
, lmargin
, setup
?0:pper
, setup
?0:detail
->mc_hold_period
, &eshdi
, flags
, phase_data
, movedck
);
2310 si
->debugl
.SIG1_EVENT
=so
->data_valid
->LATCH
?so
->data_valid
->LATCH
:so
->data_valid
->NODE
;
2311 si
->debugl
.SIG1
=si
->debugl
.SIG1_EVENT
->ROOT
;
2312 si
->debugl
.SIG2
=so
->data_valid
->ROOT
->ROOT
;
2313 si
->debugl
.PERIODE
=oc
;
2314 si
->debugl
.CKNAME
=si
->debugl
.CMDNAME
=NULL
;
2315 si
->debugl
.CMD_EVENT
=so
->data_valid
->CMD
;
2316 si
->debugl
.MARGESETUP
=si
->debugl
.MARGEHOLD
=lmargin
;
2317 si
->debugl
.SETUP
=setup
?val
:STB_NO_TIME
;
2318 si
->debugl
.HOLD
=!setup
?val
:STB_NO_TIME
;
2319 si
->debugl
.START_CMD_EVENT
=so
->data_valid
->CMDLATCH
?so
->data_valid
->CMDLATCH
:NULL
;
2320 si
->debugl
.HOLDPERIOD
=detail
->mc_hold_period
+oc
;
2322 d_valid
=detail
->instab
+detail
->data_margin
;
2324 d_req
=detail
->clock
+detail
->clock_margin
-detail
->margin
+detail
->skew
;
2327 d_req
=detail
->clock
+detail
->clock_margin
+detail
->margin
-detail
->period
-detail
->skew
;
2328 d_valid
+=detail
->misc
;
2331 // correction pour multicycle sur le required
2332 d_valid
+=-detail
->datamoved
-detail
->mc_hold_period
;
2333 d_req
+=-detail
->datamoved
-detail
->mc_hold_period
;
2335 si
->slack
=_LONG_TO_DOUBLE(detail
->VALUE
);
2337 si
->datavalid
=_LONG_TO_DOUBLE(d_valid
);
2338 si
->lag
=_LONG_TO_DOUBLE(data
->DATADELAY
);
2339 /* if (ttv_IsClock(so->data_valid->NODE->ROOT)) si->datavalidclock=dss; else si->datavalidclock=-1;
2340 si->datavalidclockdir=(so->data_valid->NODE->TYPE==TTV_NODE_UP)?1:0;*/
2342 if (si
->debugl
.PERIODE
==STB_NO_TIME
) si
->period
=-1; else si
->period
=_LONG_TO_DOUBLE(si
->debugl
.PERIODE
);
2343 si
->datareq
=_LONG_TO_DOUBLE(d_req
);
2344 si
->path
=so
->data_valid
;
2346 si
->dirin
=(so
->data_valid
->NODE
->TYPE
& TTV_NODE_UP
)?1:0;
2347 si
->access
=so
->data_valid
->LATCH
?1:0;
2348 si
->hzpath
=ttv_PathIsHZ(so
->data_valid
)?1:0;
2349 si
->phase
=phase_data
;
2350 si
->flags
=detail
->flags
;
2352 so
->data_required
->DELAYSTART
+=-detail
->datamoved
-detail
->misc
+detail
->moved_clock_period
;
2353 if (!setup
) so
->data_required
->DELAYSTART
-=detail
->period
;
2357 void stb_DisplaySlackReport_sub2(FILE *f
, chain_list
*solist
, int number
, char *mode
)
2359 int setup
=1, hold
=1, sum
=0, simple
=0;
2363 chain_list
*cl
, *ch
;
2365 if (f
==NULL
) return;
2367 if (number
<=0) number
=INT_MAX
;
2369 if (ftello(f
)==0 && solist
!=NULL
)
2372 tvf
=ttv_GetSignalTopTimingFigure(((slackobject
*)solist
->DATA
)->SI
.debugl
.SIG2
);
2373 ttv_DumpHeader(f
, tvf
);
2377 tok
=strtok_r(buf
, " ", &c
);
2381 if (strcasecmp(tok
,"setup")==0) hold
=0;
2382 else if (strcasecmp(tok
,"hold")==0) setup
=0;
2383 else if (strcasecmp(tok
,"all")==0) setup
=hold
=1;
2384 else if (strcasecmp(tok
,"summary")==0) sum
=1;
2385 else if (strcasecmp(tok
,"margins")==0) addit
|=1;
2386 else if (strcasecmp(tok
,"thru")==0) addit
|=2;
2387 else if (strcasecmp(tok
,"simple")==0) simple
=1;
2388 else //avt_error("stbapi", 2, AVT_ERR, "stb_DisplaySlackReport: unknown mode '%s'\n", tok);
2389 avt_errmsg(STB_API_ERRMSG
, "002", AVT_ERROR
, tok
);
2390 tok
=strtok_r(NULL
, " ", &c
);
2396 for (cl
=solist
; cl
!=NULL
; cl
=cl
->NEXT
)
2397 if (((slackobject
*)cl
->DATA
)->setuphold
) ch
=addchain(ch
, cl
->DATA
);
2400 __stb_DisplaySlackReport_grab(f
, NULL
, NULL
, NULL
, "??", 1, 0, sum
, number
, addit
,0, ch
, simple
);
2407 for (cl
=solist
; cl
!=NULL
; cl
=cl
->NEXT
)
2408 if (!((slackobject
*)cl
->DATA
)->setuphold
) ch
=addchain(ch
, cl
->DATA
);
2411 __stb_DisplaySlackReport_grab(f
, NULL
, NULL
, NULL
, "??", 0, 0, sum
, number
, addit
,0, ch
, simple
);
2416 void stb_DisplayCoverage_sub(FILE *f
, stbfig_list
*sf
, int detail
)
2433 int totsig
, totsetup
, tothold
, totevent
;
2434 int totrise
, totfall
, minus
, realtot
;
2437 char *label
[___LAST
]={"Latchs","Precharges","Directives","Breakpoints","Outputs"};
2444 #define DC_COL_DIR 0
2445 #define DC_COL_NAME 1
2446 #define DC_COL_SETUP 2
2447 #define DC_COL_HOLD 3
2448 #define DC_COL_DATA 4
2449 #define DC_COL_CLOCK 5
2450 #define DC_COL_SPECOUT 6
2452 if (f
==NULL
) return;
2455 ttv_DumpHeader(f
, sf
->FIG
);
2457 fprintf(f
," *** Coverage Report ***\n\n");
2459 for (a
=0; a
<___LAST
; a
++)
2460 res
[a
].totsig
=res
[a
].totsetup
=res
[a
].tothold
=res
[a
].totevent
=res
[a
].totrise
=res
[a
].totfall
=res
[a
].minus
=res
[a
].realtot
=0;
2462 for (cl
=sf
->NODE
; cl
!=NULL
; cl
=cl
->NEXT
)
2464 tve
=(ttvevent_list
*)cl
->DATA
;
2465 sn
=stb_getstbnode(tve
);
2467 if (tve
->ROOT
->TYPE
& TTV_SIG_R
)
2469 else if (tve
->ROOT
->TYPE
& TTV_SIG_L
)
2471 else if ((tve
->ROOT
->TYPE
& TTV_SIG_C
)!=0
2472 && (tve
->ROOT
->TYPE
& TTV_SIG_CI
)!=TTV_SIG_CI
2473 && (tve
->ROOT
->TYPE
& TTV_SIG_CX
)!=TTV_SIG_CX
2476 else if ((tve
->ROOT
->TYPE
& TTV_SIG_B
)!=0)
2479 if (a
!=-1 && (tve
->TYPE
& TTV_NODE_UP
)!=0)
2484 if (sn
->SPECOUT
==NULL
) k
=sn
->NBINDEX
;
2486 for (k
=0; k
<sn
->NBINDEX
&& sn
->SPECOUT
[k
]==NULL
; k
++) ;
2490 else if (a
==___BREAK
)
2492 if (getptype(tve
->ROOT
->NODE
[0].USER
, STB_BREAK_TEST_EVENT
)==NULL
2493 && getptype(tve
->ROOT
->NODE
[1].USER
, STB_BREAK_TEST_EVENT
)==NULL
)
2500 if (tve
->TYPE
& TTV_NODE_UP
) res
[a
].totsig
++;
2502 if (sn
->SETUP
!=STB_NO_TIME
&& sn
->HOLD
!=STB_NO_TIME
)
2504 if (tve
->TYPE
& TTV_NODE_UP
) res
[a
].totrise
++;
2505 else res
[a
].totfall
++;
2508 if (sn
->SETUP
!=STB_NO_TIME
|| sn
->HOLD
!=STB_NO_TIME
)
2510 if (sn
->SETUP
!=STB_NO_TIME
) res
[a
].totsetup
++;
2511 if (sn
->HOLD
!=STB_NO_TIME
) res
[a
].tothold
++;
2517 if ((sd
=ttv_get_directive(tve
->ROOT
))!=NULL
)
2519 while (sd
!=NULL
&& sd
->filter
) sd
=sd
->next
;
2520 if (sd
!=NULL
) a
=___DIRECT
;
2525 if (tve
->TYPE
& TTV_NODE_UP
) res
[a
].totsig
++;
2527 if (sn
->SETUP
!=STB_NO_TIME
&& sn
->HOLD
!=STB_NO_TIME
)
2529 if (tve
->TYPE
& TTV_NODE_UP
) res
[a
].totrise
++;
2530 else res
[a
].totfall
++;
2533 if (sn
->SETUP
!=STB_NO_TIME
|| sn
->HOLD
!=STB_NO_TIME
)
2535 if (sn
->SETUP
!=STB_NO_TIME
) res
[a
].totsetup
++;
2536 if (sn
->HOLD
!=STB_NO_TIME
) res
[a
].tothold
++;
2542 for (i
=0; i
<___LAST
; i
++)
2545 fprintf(f
,"\n_________ %s coverage\n", label
[i
]);
2546 if (i
==___PRECH
) nbev
=res
[i
].totsig
;
2547 else nbev
=res
[i
].totsig
*2;
2548 fprintf(f
," total = %d signals\n", res
[i
].realtot
);
2549 fprintf(f
," total to check = %d signals (%d events)\n", res
[i
].totsig
, nbev
);
2550 if (res
[i
].totsig
>0)
2552 fprintf(f
," event setups = %d (%.1f%%)\n", res
[i
].totsetup
, res
[i
].totsetup
*100.0/nbev
);
2553 fprintf(f
," event holds = %d (%.1f%%)\n", res
[i
].tothold
, res
[i
].tothold
*100.0/nbev
);
2555 fprintf(f
," event rising = %d (%.1f%%)\n", res
[i
].totrise
, res
[i
].totrise
*100.0/res
[i
].totsig
);
2557 fprintf(f
," event falling = %d (%.1f%%)\n", res
[i
].totfall
, res
[i
].totfall
*100.0/res
[i
].totsig
);
2561 fprintf(f
,"\n ** DETAIL **\n");
2562 b
=Board_CreateBoard();
2563 Board_SetSize(b
, DC_COL_DIR
, 4, 'l');
2564 Board_SetSize(b
, DC_COL_NAME
, 5, 'l');
2565 Board_SetSize(b
, DC_COL_SETUP
, 8, 'r');
2566 Board_SetSize(b
, DC_COL_HOLD
, 8, 'r');
2567 Board_SetSize(b
, DC_COL_DATA
, 8, 'r');
2568 Board_SetSize(b
, DC_COL_CLOCK
, 8, 'r');
2569 if (i
==___OUTPUT
|| i
==___BREAK
) Board_SetSize(b
, DC_COL_SPECOUT
, 8, 'r');
2570 // Board_SetValue(b, DC_COL_DIR, 4, 'l');
2572 Board_SetValue(b
, DC_COL_NAME
, "Node Name");
2573 Board_SetValue(b
, DC_COL_SETUP
, "Setup");
2574 Board_SetValue(b
, DC_COL_HOLD
, "Hold");
2575 Board_SetValue(b
, DC_COL_DATA
, "Data");
2576 Board_SetValue(b
, DC_COL_CLOCK
, "Clock");
2577 Board_SetValue(b
, DC_COL_SPECOUT
, i
==___OUTPUT
?"OutSpec":"Constraint");
2579 Board_NewSeparation(b
);
2580 for (cl
=sf
->NODE
; cl
!=NULL
; cl
=cl
->NEXT
)
2582 tve
=(ttvevent_list
*)cl
->DATA
;
2583 if (i
==___PRECH
&& (tve
->TYPE
& TTV_NODE_UP
)!=0) continue;
2584 sn
=stb_getstbnode(tve
);
2586 if (tve
->ROOT
->TYPE
& TTV_SIG_R
)
2588 else if (tve
->ROOT
->TYPE
& TTV_SIG_L
)
2590 else if ((tve
->ROOT
->TYPE
& TTV_SIG_C
)!=0
2591 && (tve
->ROOT
->TYPE
& TTV_SIG_CI
)!=TTV_SIG_CI
2592 && (tve
->ROOT
->TYPE
& TTV_SIG_CX
)!=TTV_SIG_CX
2595 else if (tve
->ROOT
->TYPE
& TTV_SIG_B
&&
2596 (getptype(tve
->ROOT
->NODE
[0].USER
, STB_BREAK_TEST_EVENT
)!=NULL
2597 || getptype(tve
->ROOT
->NODE
[1].USER
, STB_BREAK_TEST_EVENT
)!=NULL
))
2600 if (i
==___DIRECT
&& ttv_get_directive(tve
->ROOT
)!=NULL
)
2603 if (a
==i
&& (sn
->SETUP
==STB_NO_TIME
|| sn
->HOLD
==STB_NO_TIME
))
2606 dir
=dirconv(tve
->TYPE
& TTV_NODE_UP
?'u':'d');
2607 sprintf(buf
,"(%c)",dir
);
2609 Board_SetValue(b
, DC_COL_DIR
, buf
);
2610 Board_SetValue(b
, DC_COL_NAME
, ttv_GetFullSignalName_COND (sf
->FIG
, tve
->ROOT
));
2611 Board_SetValue(b
, DC_COL_SETUP
, sn
->SETUP
!=STB_NO_TIME
?"yes":"no");
2612 Board_SetValue(b
, DC_COL_HOLD
, sn
->HOLD
!=STB_NO_TIME
?"yes":"no");
2613 Board_SetValue(b
, DC_COL_CLOCK
, sn
->CK
!=NULL
?"yes":"no");
2614 if (sn
->STBTAB
==NULL
) k
=sn
->NBINDEX
;
2616 for (k
=0; k
<sn
->NBINDEX
&& sn
->STBTAB
[k
]==NULL
; k
++) ;
2617 Board_SetValue(b
, DC_COL_DATA
, k
>=sn
->NBINDEX
?"no":"yes");
2621 if (sn
->SPECOUT
==NULL
) k
=sn
->NBINDEX
;
2623 for (k
=0; k
<sn
->NBINDEX
&& sn
->SPECOUT
[k
]==NULL
; k
++) ;
2624 Board_SetValue(b
, DC_COL_SPECOUT
, k
>=sn
->NBINDEX
?"no":"yes");
2628 Board_SetValue(b
, DC_COL_SPECOUT
, getptype(tve
->USER
, STB_BREAK_TEST_EVENT
)==NULL
?"no":"yes");
2632 Board_NewSeparation(b
);
2633 Board_Display(f
, b
, " ");