5 #include "stb_transfer.h"
7 #include "stb_directives.h"
8 #include "stb_falseslack.h"
9 #include "stb_relaxation_correction.h"
10 #include "stb_debug.h"
12 typedef struct node_path_info_per_phase
14 struct node_path_info_per_phase
*next
;
15 long delaymax
, delaymin
;
16 long movemax
, movemin
;
17 long startmin
, startmax
;
19 } node_path_info_per_phase
;
21 typedef struct node_path_info
23 struct node_path_info
*next
;
24 node_path_info_per_phase
*PP
;
26 ttvevent_list
*start
, *cmd
;
30 static node_path_info
*create_node_path_info()
33 npi
=(node_path_info
*)mbkalloc(sizeof(node_path_info
));
35 npi
->output_phase
=STB_NO_INDEX
;
41 static node_path_info_per_phase
*create_node_path_info_PP()
43 node_path_info_per_phase
*npipp
;
44 npipp
=(node_path_info_per_phase
*)mbkalloc(sizeof(node_path_info_per_phase
));
45 npipp
->movemax
=npipp
->movemin
=0;
46 npipp
->startmin
=npipp
->startmax
=0;
47 npipp
->delaymin
=npipp
->delaymax
=TTV_NOTIME
;
48 npipp
->phase
=STB_NO_INDEX
;
52 static valid_range_info
*give_valid_range_info(ttvline_list
*tl
, int nbindex
)
55 valid_range_info
*vri
;
58 if ((pt
=getptype(tl
->USER
, STB_TRANSFERT_CORRECTION_PTYPE
))!=NULL
)
59 return (valid_range_info
*)pt
->DATA
;
61 vri
=(valid_range_info
*)mbkalloc(sizeof(valid_range_info
)*nbindex
);
62 for (i
=0; i
<nbindex
; i
++)
64 // vri[i].validmin=vri[i].validmax=TTV_NOTIME;
68 tl
->USER
=addptype(tl
->USER
, STB_TRANSFERT_CORRECTION_PTYPE
, vri
);
72 valid_range_info
*get_valid_range_info(ttvline_list
*tl
)
76 if ((pt
=getptype(tl
->USER
, STB_TRANSFERT_CORRECTION_PTYPE
))!=NULL
)
77 return (valid_range_info
*)pt
->DATA
;
83 void stb_clean_relax_correction_info (stbfig_list
*stbfig
)
90 valid_range_info
*vri
;
93 for (cl
=stbfig
->NODE
; cl
!=NULL
; cl
=cl
->NEXT
)
95 event
=(ttvevent_list
*)cl
->DATA
;
96 if ((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
97 level
= stbfig
->FIG
->INFO
->LEVEL
;
99 level
= event
->ROOT
->ROOT
->INFO
->LEVEL
;
101 if (stbfig
->GRAPH
== STB_RED_GRAPH
)
103 ttv_expfigsig (stbfig
->FIG
, event
->ROOT
, level
, stbfig
->FIG
->INFO
->LEVEL
,
104 TTV_STS_CL_PJT
, TTV_FILE_TTX
);
105 line
= event
->INPATH
;
109 ttv_expfigsig (stbfig
->FIG
, event
->ROOT
, level
, stbfig
->FIG
->INFO
->LEVEL
,
110 TTV_STS_CLS_FED
, TTV_FILE_DTX
);
111 line
= event
->INLINE
;
114 for (; line
; line
= line
->NEXT
)
116 if ((pt
=getptype(line
->USER
, STB_TRANSFERT_CORRECTION_PTYPE
))!=NULL
)
118 vri
=(valid_range_info
*)pt
->DATA
;
119 for (i
=0; i
<(int)stbfig
->PHASENUMBER
; i
++)
121 stb_freestbpair(vri
[i
].realpair
);
124 line
->USER
=delptype(line
->USER
, STB_TRANSFERT_CORRECTION_PTYPE
);
130 void stb_clean_relax_correction_path_info (stbfig_list
*stbfig
)
132 ttvevent_list
*event
;
134 node_path_info
*npi
, *nnpi
;
135 node_path_info_per_phase
*npipp
, *nnpipp
;
139 for (cl
=stbfig
->NODE
; cl
!=NULL
; cl
=cl
->NEXT
)
141 event
=(ttvevent_list
*)cl
->DATA
;
142 if ((pt
=getptype(event
->USER
, STB_PATH_LIST
))!=NULL
)
144 for (npi
=(node_path_info
*)pt
->DATA
; npi
!=NULL
; npi
=nnpi
)
147 for (npipp
=npi
->PP
; npipp
!=NULL
; npipp
=nnpipp
)
154 event
->USER
=delptype(event
->USER
, STB_PATH_LIST
);
159 node_path_info
*stb_assign_paths(stbfig_list
*stbfig
, ttvevent_list
*tve
)
162 int oldprecisionlevel
;
163 ttvpath_list
*path
, *scanpath
;
166 node_path_info
*pathl
=NULL
, *npi
;
167 node_path_info_per_phase
*npipp
;
170 ttvevent_list
*start
;
171 ttvpath_stb_stuff
*tps
;
174 if ((pt
=getptype(tve
->USER
, STB_PATH_LIST
))!=NULL
) return (node_path_info
*)pt
->DATA
;
177 ttv_search_mode(1, TTV_MORE_OPTIONS_KEEP_PHASE_INFO
);
179 oldprecisionlevel
=ttv_SetPrecisionLevel(0);
183 if(stbfig
->GRAPH
== STB_RED_GRAPH
)
184 find
= TTV_FIND_PATH
;
186 find
= TTV_FIND_LINE
;
188 if (tve
->TYPE
& TTV_NODE_UP
)
189 find
|= TTV_FIND_NOT_UPDW
| TTV_FIND_NOT_DWDW
;
191 find
|= TTV_FIND_NOT_UPUP
| TTV_FIND_NOT_DWUP
;
193 if (stbfig
->CLOCK
&& (stbfig
->FLAGS
& STB_HAS_FALSE_ACCESS
)!=0 && V_BOOL_TAB
[__STB_HANDLE_FALSE_ACCESS
].VALUE
)
195 if(ttv_canbeinfalsepath(tve
, 'o'))
197 if (ttv_hasaccessfalsepath(stbfig
->FIG
, tve
, stbfig
->CLOCK
))
199 ttv_set_ttv_getpath_clock_list(stbfig
->CLOCK
);
200 ttv_activate_path_and_access_mode(1);
201 find
|=TTV_FIND_ACCESS
;
206 path
= ttv_getpathnocross_v2(stbfig
->FIG
,NULL
,tve
->ROOT
,NULL
, TTV_DELAY_MAX
,TTV_DELAY_MIN
,TTV_FIND_MAX
|find
,0) ;
208 for(scanpath
= path
; scanpath
!= NULL
; scanpath
= scanpath
->NEXT
)
210 if ((scanpath
->TYPE
& TTV_FIND_HZ
) == TTV_FIND_HZ
) continue ;
211 if (scanpath
->LATCH
==NULL
&& getptype(scanpath
->NODE
->ROOT
->USER
, STB_IS_CLOCK
)!=NULL
212 && (scanpath
->TTV_MORE_SEARCH_OPTIONS
& TTV_MORE_OPTIONS_FLAG_THRU_FILTER_FOUND
)==0)
215 if ((scanpath
->ROOT
->ROOT
->TYPE
& TTV_SIG_R
) != 0)
217 ptype
=getptype(scanpath
->USER
, TTV_PATH_PREVIOUS_NODE
);
218 scanpath
->CMD
=(ttvevent_list
*)ptype
->DATA
;
221 start
=scanpath
->LATCH
?scanpath
->LATCH
:scanpath
->NODE
;
222 if ((l
=gethtitem(startht
, start
))!=EMPTYHT
)
224 for (cl
=(chain_list
*)l
; cl
!=NULL
&& (npi
=(node_path_info
*)cl
->DATA
)->cmd
!=scanpath
->CMD
; cl
=cl
->NEXT
) ;
225 if (cl
!=NULL
) continue;
230 npi
=create_node_path_info();
232 npi
->cmd
=scanpath
->CMD
;
235 addhtitem(startht
, start
, (long)addchain(cl
, npi
));
236 if ((pt
=getptype(scanpath
->USER
, TTV_PATH_OUTPUT_PHASE
))!=NULL
)
238 if ((ophase
=(char)(long)pt
->DATA
)==TTV_NO_PHASE
) ophase
=STB_NO_INDEX
;
239 npi
->output_phase
=ophase
;
241 else npi
->output_phase
=STB_NO_INDEX
;
243 pt
=getptype(scanpath
->USER
,TTV_PATH_PHASE_INFO
);
246 for (tps
=(ttvpath_stb_stuff
*)pt
->DATA
; tps
!=NULL
; tps
=tps
->NEXT
)
248 npipp
=create_node_path_info_PP();
251 npipp
->phase
=tps
->STARTPHASE
;
252 npipp
->startmax
=tps
->STARTTIME
;
253 npipp
->delaymax
=scanpath
->DELAY
-scanpath
->CLOCKPATHDELAY
;
254 npipp
->movemax
=tps
->PERIOD_CHANGE
;
256 ttv_freepathstblist((ttvpath_stb_stuff
*)pt
->DATA
);
260 npipp
=create_node_path_info_PP();
263 npipp
->phase
=STB_NO_INDEX
;
264 npipp
->startmax
=TTV_NOTIME
;
265 npipp
->delaymax
=scanpath
->DELAY
-scanpath
->CLOCKPATHDELAY
;
269 ttv_freepathlist(path
) ;
271 path
= ttv_getpathnocross_v2(stbfig
->FIG
,NULL
,tve
->ROOT
,NULL
, TTV_DELAY_MAX
,TTV_DELAY_MIN
,TTV_FIND_MIN
|find
,0) ;
273 for(scanpath
= path
; scanpath
!= NULL
; scanpath
= scanpath
->NEXT
)
275 if((scanpath
->TYPE
& TTV_FIND_HZ
) == TTV_FIND_HZ
) continue ;
276 if (scanpath
->LATCH
==NULL
&& getptype(scanpath
->NODE
->ROOT
->USER
, STB_IS_CLOCK
)!=NULL
277 && (scanpath
->TTV_MORE_SEARCH_OPTIONS
& TTV_MORE_OPTIONS_FLAG_THRU_FILTER_FOUND
)==0)
280 if ((scanpath
->ROOT
->ROOT
->TYPE
& TTV_SIG_R
) != 0)
282 ptype
=getptype(scanpath
->USER
, TTV_PATH_PREVIOUS_NODE
);
283 scanpath
->CMD
=(ttvevent_list
*)ptype
->DATA
;
286 start
=scanpath
->LATCH
?scanpath
->LATCH
:scanpath
->NODE
;
287 if ((l
=gethtitem(startht
, start
))!=EMPTYHT
)
289 for (cl
=(chain_list
*)l
; cl
!=NULL
&& (npi
=(node_path_info
*)cl
->DATA
)->cmd
!=scanpath
->CMD
; cl
=cl
->NEXT
) ;
290 // if (cl==NULL) exit(60);
296 npi
=create_node_path_info();
299 if (l
!=EMPTYHT
) cl
=(chain_list
*)l
;
300 addhtitem(startht
, start
, (long)addchain(cl
, npi
));
301 if ((pt
=getptype(scanpath
->USER
, TTV_PATH_OUTPUT_PHASE
))!=NULL
)
303 if ((ophase
=(char)(long)pt
->DATA
)==TTV_NO_PHASE
) ophase
=STB_NO_INDEX
;
304 npi
->output_phase
=ophase
;
306 else npi
->output_phase
=STB_NO_INDEX
;
308 npi
->cmd
=scanpath
->CMD
;
311 pt
=getptype(scanpath
->USER
,TTV_PATH_PHASE_INFO
);
315 for (tps
=(ttvpath_stb_stuff
*)pt
->DATA
; tps
!=NULL
; tps
=tps
->NEXT
)
317 for (npipp
=npi
->PP
; npipp
!=NULL
&& npipp
->phase
!=tps
->STARTPHASE
; npipp
=npipp
->next
) ;
320 npipp
=create_node_path_info_PP();
323 npipp
->phase
=tps
->STARTPHASE
;
325 npipp
->startmin
=tps
->STARTTIME
;
326 npipp
->delaymin
=scanpath
->DELAY
-scanpath
->CLOCKPATHDELAY
;
327 npipp
->movemin
=tps
->PERIOD_CHANGE
;
329 ttv_freepathstblist((ttvpath_stb_stuff
*)pt
->DATA
);
333 for (npipp
=npi
->PP
; npipp
!=NULL
&& npipp
->phase
!=STB_NO_INDEX
; npipp
=npipp
->next
) ;
336 npipp
=create_node_path_info_PP();
339 npipp
->phase
=STB_NO_INDEX
;
341 npipp
->startmin
=TTV_NOTIME
;
342 npipp
->delaymin
=scanpath
->DELAY
-scanpath
->CLOCKPATHDELAY
;
347 ttv_freepathlist(path
) ;
349 ttv_search_mode(0, TTV_MORE_OPTIONS_KEEP_PHASE_INFO
);
351 cl
=GetAllHTElems(startht
);
354 freechain((chain_list
*)cl
->DATA
);
359 ttv_SetPrecisionLevel(oldprecisionlevel
);
360 tve
->USER
=addptype(tve
->USER
, STB_PATH_LIST
, pathl
);
361 ttv_set_ttv_getpath_clock_list(NULL
);
362 ttv_activate_path_and_access_mode(0);
367 static int stb_inrelax
=0;
369 void stb_set_relax(int val
)
374 #ifdef RELAX_CORRECT_DEBUG
375 #define DISPDIR(x) ((x->TYPE & TTV_NODE_UP)!=0?'u':'d')
378 void stb_compute_falsepath_and_falseslack_effect(stbfig_list
*sf
, stbnode
*node
, ttvline_list
*line
, ttvevent_list
*linecmd
, stbck
*nodeck
, int flags
)
381 valid_range_info
*vri
;
384 int i
, res
, startindex
;
385 // long validmin, validmax;
386 stbpair_list
*STBTAB
[256], *STBHZ
[256], *ptstbpair
, *pair
;
388 long periodeSetup
, periodeHold
, output_periode
, input_periode
;
389 int nb0
, nb1
, first
=0;
391 node_path_info_per_phase
*npipp
, *backupnpipp
;
392 #ifdef RELAX_CORRECT_DEBUG
394 if (strcmp(node
->EVENT
->ROOT
->NAME
,"F2171467")==0 && (node
->EVENT
->TYPE
& TTV_NODE_UP
)==0) deb
=1;
397 if (node
->EVENT
->ROOT
->TYPE
& TTV_SIG_R
)
400 if (!stb_inrelax
&& get_valid_range_info(line
)!=NULL
) return;
402 vri
=give_valid_range_info(line
, node
->NBINDEX
);
404 npi
=stb_assign_paths(sf
, node
->EVENT
);
407 if (npi
->cmd
==linecmd
)
409 startnode
=stb_getstbnode(npi
->start
);
415 #ifdef RELAX_CORRECT_DEBUG
416 if (strcmp(npi
->start
->ROOT
->NAME
,"F1867251")==0)
419 for (i
=0; i
<node
->NBINDEX
; i
++) STBHZ
[i
]=NULL
, STBTAB
[i
]=NULL
;
421 if (getptype(npi
->start
->ROOT
->USER
, STB_IS_CLOCK
)!=NULL
)
422 create_clock_stability(startnode
, STBTAB
);
423 else if (!stb_inrelax
/*(startnode->FLAG & STB_NODE_DONE)==0*/)
425 for (i
=0; i
<node
->NBINDEX
; i
++) STBTAB
[i
]=stb_dupstbpairlist(startnode
->STBTAB
[i
]);
428 stb_transferstbline (sf
, npi
->start
, startnode
, STBTAB
, STBHZ
, 0, 1, NULL
, ck
, 1, 0) ;
431 for (ckindex
=0; ckindex
<node
->NBINDEX
&& STBTAB
[ckindex
]==NULL
; ckindex
++) ;
433 ckindex
=(int)ck
->CKINDEX
;
435 if (ckindex
<node
->NBINDEX
)
439 if (STBTAB
[startindex
]!=NULL
)
441 for (npipp
=npi
->PP
, backupnpipp
=NULL
; npipp
!=NULL
&& npipp
->phase
!=startindex
; npipp
=npipp
->next
)
442 if (npipp
->phase
==STB_NO_INDEX
) backupnpipp
=npipp
;
444 if (npipp
==NULL
) npipp
=backupnpipp
;
448 if (stb_hasfalseslack(sf
, node
->EVENT
))
450 ttvevent_list
*startclock
, *endclocksetup
, *endclockhold
;
453 stb_getslacktopclocks(NULL
, node
, 0, ck
, nodeck
, &startclock
, &endclocksetup
, &endclockhold
);
454 if (startclock
!=NULL
&& endclocksetup
!=NULL
)
455 fs
=stb_isfalseslack(sf
, startclock
, npi
->start
, node
->EVENT
, endclocksetup
, INF_FALSESLACK_SETUP
);
457 if (startclock
!=NULL
&& endclockhold
!=NULL
)
458 fh
=stb_isfalseslack(sf
, startclock
, npi
->start
, node
->EVENT
, endclockhold
, INF_FALSESLACK_HOLD
);
459 if ((fs
& INF_FALSESLACK_NOTHZ
)!=0 && (fh
& INF_FALSESLACK_NOTHZ
)!=0) res
=1;
461 printf("found %s -> %s\n", npi->start->ROOT->NETNAME, node->EVENT->ROOT->NETNAME);*/
462 #ifdef RELAX_CORRECT_DEBUG
463 if (deb
&& stb_hasfalseslack(sf
, node
->EVENT
))
464 printf(" [FS %d] %s(%c) %s(%c) %s(%c) %s(%c)", res
, startclock
?startclock
->ROOT
->NAME
:"?", DISPDIR(startclock
),
465 npi
->start
->ROOT
->NAME
, DISPDIR(npi
->start
),
466 node
->EVENT
->ROOT
->NAME
, DISPDIR(node
->EVENT
),
467 endclocksetup
?endclocksetup
->ROOT
->NAME
:"?", endclocksetup
?DISPDIR(endclocksetup
):'x');
470 if (npipp
->delaymin
==TTV_NOTIME
) npipp
->delaymin
=npipp
->delaymax
;
471 if (npipp
->delaymax
==TTV_NOTIME
) npipp
->delaymax
=npipp
->delaymin
;
472 if (npipp
->delaymin
>npipp
->delaymax
) npipp
->delaymin
=npipp
->delaymax
;
474 if (npi
->output_phase
!=STB_NO_INDEX
) // filtre
475 ckindex
=npi
->output_phase
;
481 ick
=stb_getclock(sf
, startindex
, NULL
, &ckedge
, NULL
);
482 if (ick
!=NULL
) input_periode
=ick
->PERIOD
;
484 output_periode
=input_periode
;
487 ick
=stb_getclock(sf
, nodeck
->CKINDEX
, NULL
, &ckedge
, NULL
);
488 if (ick
!=NULL
) output_periode
=ick
->PERIOD
;
491 if ((flags
& STB_TRANSFERT_NOFILTERING
)==0)
492 stb_getmulticycleperiod(npi
->start
, node
->EVENT
, input_periode
, output_periode
, &periodeSetup
, &periodeHold
, &nb0
, &nb1
);
494 periodeSetup
=periodeHold
=0;
496 // if (periodeSetup!=0)
499 dmax
=npipp
->delaymax
-periodeSetup
-npipp
->movemax
;
500 dmin
=npipp
->delaymin
-periodeSetup
-npipp
->movemin
;
508 pair
= stb_dupstbpairlist (STBTAB
[startindex
]);
509 pair
= stb_clippair( pair
, npipp
->startmin
, npipp
->startmax
);
510 // stb_assign_phase_to_stbpair(pair, startindex);
511 #ifdef RELAX_CORRECT_DEBUG
514 printf(" this[%d %d]", pair
->D
+dmin
, pair
->U
+dmax
);
519 stb_freestbpair(vri
[ckindex
].realpair
);
520 vri
[ckindex
].realpair
=NULL
;
522 vri
[ckindex
].realpair
= stb_transferstbpair (pair
, vri
[ckindex
].realpair
, dmax
, dmin
, 0, 0);
523 if ((sf
->ANALYSIS
== STB_GLOB_ANALYSIS
) && vri
[ckindex
].realpair
!=NULL
&& vri
[ckindex
].realpair
->NEXT
!=NULL
)
526 vri
[ckindex
].realpair
= stb_globalstbpair(sbp
=vri
[ckindex
].realpair
);
527 stb_freestbpair(sbp
);
530 #ifdef RELAX_CORRECT_DEBUG
533 ptstbpair
= stb_globalstbpair(STBTAB
[startindex
]);
534 printf(" MC: startstab from %s (%c): [%ld %ld] (mcs=%ld) move:(%ld/%ld) totstab: \n", npi
->start
->ROOT
->NAME
, (npi
->start
->TYPE
& TTV_NODE_UP
)!=0?'u':'d', ptstbpair
->D
, ptstbpair
->U
, periodeSetup
, npipp
->movemin
, npipp
->movemax
);
536 for (pair
=vri
[ckindex
].realpair
; pair
!=NULL
; pair
=pair
->NEXT
)
537 printf("[%ld %ld]", pair
->D
, pair
->U
);
539 stb_freestbpair(ptstbpair
);
544 #ifdef RELAX_CORRECT_DEBUG
552 stb_freestbtabpair(STBTAB
, node
->NBINDEX
);
553 stb_freestbtabpair(STBHZ
, node
->NBINDEX
);
563 int path_false_slack_check(ttvpath_list
*tp
, ttvevent_list
*opencmd
, ttvevent_list
*topopenclock
)
565 ttvevent_list
*startclock
, *endclocksetup
, *endclockhold
;
572 if (tp
->LATCH
==NULL
) return 0;
574 node
=stb_getstbnode(tp
->ROOT
);
575 if (node
==NULL
) return 0;
577 for (nodeck
=node
->CK
; nodeck
!=NULL
&& nodeck
->CMD
!=opencmd
; nodeck
=nodeck
->NEXT
) ;
579 if (nodeck
==NULL
) return 0;
581 sf
=stb_getstbfig(tp
->NODE
->ROOT
->ROOT
);
582 stb_getslacktopclocks(NULL
, node
, 0, NULL
, nodeck
, &startclock
, &endclocksetup
, &endclockhold
);
583 if (endclocksetup
!=NULL
&& (topopenclock
==NULL
|| endclocksetup
->ROOT
==topopenclock
->ROOT
))
584 fs
=stb_isfalseslack(sf
, tp
->NODE
, tp
->LATCH
, node
->EVENT
, endclocksetup
, INF_FALSESLACK_SETUP
);
586 if (endclockhold
!=NULL
&& (topopenclock
==NULL
|| endclockhold
->ROOT
==topopenclock
->ROOT
))
587 fh
=stb_isfalseslack(sf
, tp
->NODE
, tp
->LATCH
, node
->EVENT
, endclockhold
, INF_FALSESLACK_HOLD
);
588 if ((fs
& INF_FALSESLACK_NOTHZ
)!=0 && (fh
& INF_FALSESLACK_NOTHZ
)!=0) return 1;