9 #include "stb_transfer.h"
10 #include "stb_overlap.h"
11 #include "stb_clock_tree.h"
25 int stb_find_path_from_clock_to_clock(ttvfig_list
*tvf
, ttvsig_list
*source
, ttvsig_list
*dest
, long type
, int start_event
[2], d_minmax_rf
*result
)
28 ptype_list
*pt
, *cmdlist
;
29 ttvpath_list
*path
, *rpath
;
30 ttvevent_list
*cmdevent
;
33 char buf0
[1024], buf1
[1024];
34 stb_propagated_clock_to_clock
*spctc
;
36 result
->master
=source
;
38 result
->delays
[i
].min
=result
->delays
[i
].max
=TTV_NOTIME
;
40 if ((pt
=getptype(dest
->USER
, STB_IS_CLOCK
))!=NULL
)
42 spctc
=(stb_propagated_clock_to_clock
*)pt
->DATA
;
43 if (spctc
->haslatency
)
45 result
->delays
[0].min
=spctc
->latencies
.SDNMIN
;
46 result
->delays
[0].max
=spctc
->latencies
.SDNMAX
;
47 result
->delays
[1].min
=spctc
->latencies
.SUPMIN
;
48 result
->delays
[1].max
=spctc
->latencies
.SUPMAX
;
53 if (getptype (source
->USER
, STB_IDEAL_CLOCK
)!=NULL
|| getptype (source
->USER
, STB_VIRTUAL_CLOCK
)!=NULL
) return 0;
55 clocks
=addchain(NULL
, source
);
57 if ((dest
->TYPE
& TTV_SIG_L
)!=0)
61 for (minmax
=0; minmax
<2; minmax
++)
63 if (minmax
==0) find
=TTV_FIND_MIN
; else find
=TTV_FIND_MAX
;
65 cmdlist
= ttv_getlatchaccess(tvf
,&dest
->NODE
[i
],find
) ;
67 for(pt
=cmdlist
; pt
!=NULL
; pt
=pt
->NEXT
)
69 cmdevent
= (ttvevent_list
*)pt
->DATA
;
71 ttv_search_mode(1, TTV_MORE_OPTIONS_MUST_BE_CLOCK
);
72 path
= ttv_getpathnocross (tvf
, NULL
, cmdevent
->ROOT
, clocks
, TTV_DELAY_MAX
, TTV_DELAY_MIN
, TTV_FIND_SIG
|find
| TTV_FIND_CMD
| type
);
73 ttv_search_mode(0, TTV_MORE_OPTIONS_MUST_BE_CLOCK
);
75 for (rpath
=path
; rpath
!=NULL
; rpath
=rpath
->NEXT
)
77 if (rpath
->ROOT
==cmdevent
&& (rpath
->NODE
->TYPE
& start_event
[i
])!=0) break;
82 thisdelay
=rpath
->DELAY
;
85 if (pt
->TYPE
!=0) thisdelay
+=((ttvline_list
*)pt
->TYPE
)->VALMIN
;
86 if (result
->delays
[i
].min
==TTV_NOTIME
|| thisdelay
<result
->delays
[i
].min
) result
->delays
[i
].min
=thisdelay
;
90 if (pt
->TYPE
!=0) thisdelay
+=((ttvline_list
*)pt
->TYPE
)->VALMAX
;
91 if (result
->delays
[i
].max
==TTV_NOTIME
|| thisdelay
<result
->delays
[i
].max
) result
->delays
[i
].max
=thisdelay
;
94 ttv_freepathlist(path
);
103 maxperiod
= V_INT_TAB
[__TTV_MAX_PATH_PERIOD
].VALUE
;
104 V_INT_TAB
[__TTV_MAX_PATH_PERIOD
].VALUE
= 0 ;
106 for (minmax
=0; minmax
<2; minmax
++)
108 if (minmax
==0) find
=TTV_FIND_MIN
; else find
=TTV_FIND_MAX
;
110 ttv_search_mode(1, TTV_MORE_OPTIONS_MUST_BE_CLOCK
);
112 path
= ttv_getaccess (tvf
, NULL
, dest
, NULL
, clocks
, TTV_DELAY_MAX
, TTV_DELAY_MIN
, TTV_FIND_SIG
| find
| TTV_FIND_CMD
| type
);
114 ttv_search_mode(0, TTV_MORE_OPTIONS_MUST_BE_CLOCK
);
118 for (rpath
=path
; rpath
!=NULL
; rpath
=rpath
->NEXT
)
120 if (rpath
->ROOT
==&dest
->NODE
[i
] && rpath
->NODE
->ROOT
==source
&& (rpath
->NODE
->TYPE
& start_event
[i
])!=0) break;
125 thisdelay
=rpath
->DELAY
;
128 if (result
->delays
[i
].min
==TTV_NOTIME
|| thisdelay
<result
->delays
[i
].min
) result
->delays
[i
].min
=thisdelay
;
132 if (result
->delays
[i
].max
==TTV_NOTIME
|| thisdelay
<result
->delays
[i
].max
) result
->delays
[i
].max
=thisdelay
;
136 ttv_freepathlist(path
);
138 V_INT_TAB
[__TTV_MAX_PATH_PERIOD
].VALUE
= maxperiod
;
141 avt_log(LOGSTABILITY
,2, "Paths from '%s' to '%s'\n",ttv_getsigname(tvf
,buf0
,source
), ttv_getsigname(tvf
,buf1
,dest
));
144 avt_log(LOGSTABILITY
,2, "\t%s-%s : min=",(start_event
[i
] & TTV_NODE_UP
)!=0?"rise":"fall", i
?"rise":"fall");
145 if (result
->delays
[i
].min
==TTV_NOTIME
) avt_log(LOGSTABILITY
,2,"NOT FOUND");
146 else avt_log(LOGSTABILITY
,2,"%g",result
->delays
[i
].min
*1e-12/TTV_UNIT
);
147 avt_log(LOGSTABILITY
,2, " max=");
148 if (result
->delays
[i
].max
==TTV_NOTIME
) avt_log(LOGSTABILITY
,2,"NOT FOUND");
149 else avt_log(LOGSTABILITY
,2,"%g",result
->delays
[i
].max
*1e-12/TTV_UNIT
);
150 avt_log(LOGSTABILITY
,2, "\n");
157 void stb_get_clock_local_latency(ttvsig_list
*tvs
, long *rmin
, long *rmax
, long *fmin
, long *fmax
)
161 *rmin
=*rmax
=*fmin
=*fmax
=0;
163 if ((pt0
=getptype(tvs
->USER
, STB_CLOCK_LOCAL_LATENCY
))!=NULL
)
165 cur
=(d_minmax_rf
*)pt0
->DATA
;
166 if (cur
->delays
[0].min
!=TTV_NOTIME
) *fmin
=cur
->delays
[0].min
;
167 if (cur
->delays
[0].max
!=TTV_NOTIME
) *fmax
=cur
->delays
[0].max
;
168 if (cur
->delays
[1].min
!=TTV_NOTIME
) *rmin
=cur
->delays
[1].min
;
169 if (cur
->delays
[1].max
!=TTV_NOTIME
) *rmax
=cur
->delays
[1].max
;
173 static void recur_compute_clock_latency(ttvsig_list
*tvs
, d_minmax_rf
*sum
)
179 if ((pt0
=getptype(tvs
->USER
, STB_CLOCK_LOCAL_LATENCY
))!=NULL
)
181 cur
=(d_minmax_rf
*)pt0
->DATA
;
184 if (cur
->delays
[i
].min
!=TTV_NOTIME
) sum
->delays
[i
].min
+=cur
->delays
[i
].min
;
185 if (cur
->delays
[i
].max
!=TTV_NOTIME
) sum
->delays
[i
].max
+=cur
->delays
[i
].max
;
187 if (cur
->master
!=NULL
) recur_compute_clock_latency(cur
->master
, sum
);
191 int stb_compute_clock_latency(stbfig_list
*sb
, long type
)
193 chain_list
*cl
, *chain
, *chainsig
;
194 int start_event
[2]={TTV_NODE_UP
, TTV_NODE_UP
};
195 ptype_list
*pt
, *pt0
;
196 ttvsig_list
*tvs
, *clock
;
197 d_minmax_rf dmrf
, *dmrf_tmp
;
198 stb_propagated_clock_to_clock
*spctc
;
201 char buf0
[1024], buf1
[1024];
203 for (cl
=sb
->CLOCK
; cl
!=NULL
; cl
=cl
->NEXT
)
205 tvs
=(ttvsig_list
*)cl
->DATA
;
206 if ((pt
=getptype(tvs
->USER
, STB_IS_CLOCK
))!=NULL
)
208 spctc
=(stb_propagated_clock_to_clock
*)pt
->DATA
;
209 if (spctc
->master
!=NULL
)
213 chain
=addchain(NULL
, spctc
->master
);
214 for (chainsig
=sb
->CLOCK
; chainsig
!=NULL
; chainsig
=chainsig
->NEXT
)
216 clock
=(ttvsig_list
*)chainsig
->DATA
;
217 if (getptype(clock
->USER
, STB_VIRTUAL_CLOCK
)==NULL
)
219 if (ttv_testnetnamemask(sb
->FIG
, clock
, chain
)) break;
223 if (mbk_TestREGEX(clock
->NETNAME
, spctc
->master
)) break;
227 if (chain
==NULL
) clock
=NULL
;
229 if ((spctc
->edges
& 2)!=0) start_event
[1]=TTV_NODE_UP
; else start_event
[1]=TTV_NODE_DOWN
;
230 if ((spctc
->edges
& 1)!=0) start_event
[0]=TTV_NODE_UP
; else start_event
[0]=TTV_NODE_DOWN
;
232 if (getptype(tvs
->USER
, STB_INVERTED_CLOCK
)!=NULL
)
236 start_event
[0]=start_event
[1];
242 stb_find_path_from_clock_to_clock(sb
->FIG
, clock
, tvs
, type
, start_event
, &dmrf
);
243 if ((pt0
=getptype(tvs
->USER
, STB_CLOCK_LOCAL_LATENCY
))!=NULL
) dmrf_tmp
=(d_minmax_rf
*)pt0
->DATA
;
246 dmrf_tmp
=(d_minmax_rf
*)mbkalloc(sizeof(d_minmax_rf
));
247 tvs
->USER
=addptype(tvs
->USER
, STB_CLOCK_LOCAL_LATENCY
, dmrf_tmp
);
249 memcpy(dmrf_tmp
, &dmrf
, sizeof(d_minmax_rf
));
259 for (cl
=sb
->CLOCK
; cl
!=NULL
; cl
=cl
->NEXT
)
261 tvs
=(ttvsig_list
*)cl
->DATA
;
264 dmrf
.delays
[i
].min
=dmrf
.delays
[i
].max
=0;
266 recur_compute_clock_latency(tvs
, &dmrf
);
268 if ((pt
=getptype(tvs
->USER
, STB_IS_CLOCK
))!=NULL
)
270 spctc
=(stb_propagated_clock_to_clock
*)pt
->DATA
;
271 if (spctc
->master
!=NULL
)
273 avt_log(LOGSTABILITY
,2, "Latency computed from '%s' to '%s'", spctc
->master
, ttv_getsigname(sb
->FIG
,buf1
,tvs
));
274 avt_log(LOGSTABILITY
,2, ": RISE(%g,%g) FALL(%g,%g)\n",dmrf
.delays
[1].min
*1e-12/TTV_UNIT
,dmrf
.delays
[1].max
*1e-12/TTV_UNIT
,dmrf
.delays
[0].min
*1e-12/TTV_UNIT
,dmrf
.delays
[0].max
*1e-12/TTV_UNIT
);
276 if ((pt
=getptype(tvs
->USER
, STB_IS_CLOCK
))!=NULL
)
278 spctc
=(stb_propagated_clock_to_clock
*)pt
->DATA
;
281 n
= stb_getstbnode(tvs
->NODE
+i
);
282 n
->CK
->SUPMAX
=spctc
->original_waveform
.SUPMAX
+dmrf
.delays
[1].max
;
283 n
->CK
->SUPMIN
=spctc
->original_waveform
.SUPMIN
+dmrf
.delays
[1].min
;
284 n
->CK
->SDNMAX
=spctc
->original_waveform
.SDNMAX
+dmrf
.delays
[0].max
;
285 n
->CK
->SDNMIN
=spctc
->original_waveform
.SDNMIN
+dmrf
.delays
[0].min
;
287 avt_log(LOGSTABILITY
,2, "\tNew waveform: RISE(%g,%g) FALL(%g,%g)\n",n
->CK
->SUPMIN
*1e-12/TTV_UNIT
, n
->CK
->SUPMAX
*1e-12/TTV_UNIT
, n
->CK
->SDNMIN
*1e-12/TTV_UNIT
, n
->CK
->SDNMAX
*1e-12/TTV_UNIT
);
298 chain_list
*get_clock_latency_tree(ttvevent_list
*tve
, long type
, chain_list
*cl
)
304 stb_propagated_clock_to_clock
*spctc
;
306 stb_clock_latency_information
*scli
;
308 if ((pt
=getptype(tve
->ROOT
->USER
, STB_IS_CLOCK
))!=NULL
)
310 spctc
=(stb_propagated_clock_to_clock
*)pt
->DATA
;
311 if (tve
->TYPE
& TTV_NODE_UP
) { i
=1; mask
=2; } else { i
=0; mask
=1; }
312 if (getptype(tve
->ROOT
->USER
, STB_INVERTED_CLOCK
)!=NULL
)
314 if (mask
==1) mask
=2; else mask
=1;
316 if ((pt
=getptype(tve
->ROOT
->USER
, STB_CLOCK_LOCAL_LATENCY
))!=NULL
)
318 cur
=(d_minmax_rf
*)pt
->DATA
;
320 if (cur
->master
!=NULL
)
322 if (type
& TTV_FIND_MAX
) delay
=cur
->delays
[i
].max
; else delay
=cur
->delays
[i
].min
;
323 if (delay
==TTV_NOTIME
) delay
=0;
325 if ((spctc
->edges
& mask
)!=0) mask
=1; else mask
=0;
328 n
=stb_getstbnode(tve
);
331 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SDNMAX
; else date
=n
->CK
->SDNMIN
;
335 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SUPMAX
; else date
=n
->CK
->SUPMIN
;
337 scli
=(stb_clock_latency_information
*)mbkalloc(sizeof(stb_clock_latency_information
));
339 scli
->delay
=TTV_NOTIME
;
340 scli
->period
=n
->CK
->PERIOD
;
341 scli
->clock_event
=tve
;
342 cl
=addchain(cl
, scli
);
345 n
=stb_getstbnode(&cur
->master
->NODE
[mask
]);
348 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SDNMAX
; else date
=n
->CK
->SDNMIN
;
352 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SUPMAX
; else date
=n
->CK
->SUPMIN
;
354 scli
=(stb_clock_latency_information
*)mbkalloc(sizeof(stb_clock_latency_information
));
357 scli
->period
=n
->CK
->PERIOD
;
358 scli
->clock_event
=&cur
->master
->NODE
[mask
];
359 cl
=addchain(cl
, scli
);
360 cl
=get_clock_latency_tree(&cur
->master
->NODE
[mask
], type
, cl
);
365 n
=stb_getstbnode(tve
);
368 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SDNMAX
, delay
=spctc
->latencies
.SDNMAX
;
369 else date
=n
->CK
->SDNMIN
, delay
=spctc
->latencies
.SDNMIN
;
373 if (type
& TTV_FIND_MAX
) date
=n
->CK
->SUPMAX
, delay
=spctc
->latencies
.SUPMAX
;
374 else date
=n
->CK
->SUPMIN
, delay
=spctc
->latencies
.SUPMIN
;
379 scli
=(stb_clock_latency_information
*)mbkalloc(sizeof(stb_clock_latency_information
));
380 scli
->date
=date
-delay
;
382 scli
->period
=n
->CK
->PERIOD
;
383 scli
->clock_event
=tve
;
384 cl
=addchain(cl
, scli
);
392 ptype_list
*stb_build_generated_clock_info(chain_list
*clocklist
)
397 chain_list
*min
, *max
;
398 while (clocklist
!=NULL
)
400 tvs
=(ttvsig_list
*)clocklist
->DATA
;
403 min
=get_clock_latency_tree(&tvs
->NODE
[i
], TTV_FIND_MIN
, NULL
);
404 max
=get_clock_latency_tree(&tvs
->NODE
[i
], TTV_FIND_MAX
, NULL
);
405 pt
=addptype(pt
, (long)&tvs
->NODE
[i
], addchain(addchain(NULL
, max
), min
)); //min puis max
407 clocklist
=clocklist
->NEXT
;
412 void stb_free_built_generated_clock_info(ptype_list
*geneclockinfo
)
418 for (pt
=geneclockinfo
; pt
!=NULL
; pt
=pt
->NEXT
)
420 cl
=(chain_list
*)pt
->DATA
;
423 for (ch
=(chain_list
*)cl
->DATA
; ch
!=NULL
; ch
=ch
->NEXT
)
425 freechain((chain_list
*)cl
->DATA
);
429 freeptype(geneclockinfo
);
432 long stb_get_generated_clock_skew(ptype_list
*geneclockinfo
, ttvevent_list
*tve0
, ttvevent_list
*tve1
, ttvevent_list
**common_node
)
436 long minmax
=TTV_NOTIME
;
437 stb_clock_latency_information
*scli0
, *scli1
;
439 for (pt
=geneclockinfo
; pt
!=NULL
&& pt
->TYPE
!=(long)tve0
; pt
=pt
->NEXT
) ;
440 if (pt
==NULL
) return TTV_NOTIME
;
441 c0
=(chain_list
*)((chain_list
*)pt
->DATA
)->DATA
; // min
442 for (pt
=geneclockinfo
; pt
!=NULL
&& pt
->TYPE
!=(long)tve1
; pt
=pt
->NEXT
) ;
443 if (pt
==NULL
) return TTV_NOTIME
;
444 c1
=(chain_list
*)((chain_list
*)pt
->DATA
)->NEXT
->DATA
; // max
445 while (c0
!=NULL
&& c1
!=NULL
)
447 scli0
=(stb_clock_latency_information
*)c0
->DATA
;
448 scli1
=(stb_clock_latency_information
*)c1
->DATA
;
449 if (scli0
->clock_event
==scli1
->clock_event
) minmax
=scli1
->date
-scli0
->date
, *common_node
=scli1
->clock_event
;