Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stb / stb_clocks.c
1 #include <stdlib.h>
2
3 #include MUT_H
4 #include STB_H
5
6 #include "stb_util.h"
7 #include "stb_error.h"
8 #include "stb_init.h"
9 #include "stb_transfer.h"
10 #include "stb_overlap.h"
11 #include "stb_clock_tree.h"
12
13 typedef struct
14 {
15 long min, max;
16 } d_minmax;
17
18 typedef struct
19 {
20 d_minmax delays[2];
21 ttvsig_list *master;
22 } d_minmax_rf;
23
24
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)
26 {
27 chain_list *clocks;
28 ptype_list *pt, *cmdlist;
29 ttvpath_list *path, *rpath;
30 ttvevent_list *cmdevent;
31 int i, minmax;
32 long thisdelay, find;
33 char buf0[1024], buf1[1024];
34 stb_propagated_clock_to_clock *spctc;
35
36 result->master=source;
37 for (i=0; i<2; i++)
38 result->delays[i].min=result->delays[i].max=TTV_NOTIME;
39
40 if ((pt=getptype(dest->USER, STB_IS_CLOCK))!=NULL)
41 {
42 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
43 if (spctc->haslatency)
44 {
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;
49 return 1;
50 }
51 }
52
53 if (getptype (source->USER, STB_IDEAL_CLOCK)!=NULL || getptype (source->USER, STB_VIRTUAL_CLOCK)!=NULL) return 0;
54
55 clocks=addchain(NULL, source);
56
57 if ((dest->TYPE & TTV_SIG_L)!=0)
58 {
59 for (i=0; i<2; i++)
60 {
61 for (minmax=0; minmax<2; minmax++)
62 {
63 if (minmax==0) find=TTV_FIND_MIN; else find=TTV_FIND_MAX;
64
65 cmdlist = ttv_getlatchaccess(tvf,&dest->NODE[i],find) ;
66
67 for(pt=cmdlist ; pt!=NULL ; pt=pt->NEXT)
68 {
69 cmdevent = (ttvevent_list *)pt->DATA ;
70
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);
74
75 for (rpath=path; rpath!=NULL; rpath=rpath->NEXT)
76 {
77 if (rpath->ROOT==cmdevent && (rpath->NODE->TYPE & start_event[i])!=0) break;
78 }
79
80 if (rpath!=NULL)
81 {
82 thisdelay=rpath->DELAY;
83 if (minmax==0)
84 {
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;
87 }
88 else
89 {
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;
92 }
93 }
94 ttv_freepathlist(path);
95 }
96 freeptype(cmdlist);
97 }
98 }
99 }
100 else
101 {
102 int maxperiod ;
103 maxperiod = V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE ;
104 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE = 0 ;
105
106 for (minmax=0; minmax<2; minmax++)
107 {
108 if (minmax==0) find=TTV_FIND_MIN; else find=TTV_FIND_MAX;
109
110 ttv_search_mode(1, TTV_MORE_OPTIONS_MUST_BE_CLOCK);
111 TTV_QUIET_MODE=1;
112 path = ttv_getaccess (tvf, NULL, dest, NULL, clocks, TTV_DELAY_MAX, TTV_DELAY_MIN, TTV_FIND_SIG | find | TTV_FIND_CMD | type);
113 TTV_QUIET_MODE=0;
114 ttv_search_mode(0, TTV_MORE_OPTIONS_MUST_BE_CLOCK);
115
116 for (i=0; i<2; i++)
117 {
118 for (rpath=path; rpath!=NULL; rpath=rpath->NEXT)
119 {
120 if (rpath->ROOT==&dest->NODE[i] && rpath->NODE->ROOT==source && (rpath->NODE->TYPE & start_event[i])!=0) break;
121 }
122
123 if (rpath!=NULL)
124 {
125 thisdelay=rpath->DELAY;
126 if (minmax==0)
127 {
128 if (result->delays[i].min==TTV_NOTIME || thisdelay<result->delays[i].min) result->delays[i].min=thisdelay;
129 }
130 else
131 {
132 if (result->delays[i].max==TTV_NOTIME || thisdelay<result->delays[i].max) result->delays[i].max=thisdelay;
133 }
134 }
135 }
136 ttv_freepathlist(path);
137 }
138 V_INT_TAB[__TTV_MAX_PATH_PERIOD].VALUE = maxperiod ;
139 }
140
141 avt_log(LOGSTABILITY,2, "Paths from '%s' to '%s'\n",ttv_getsigname(tvf,buf0,source), ttv_getsigname(tvf,buf1,dest));
142 for (i=0; i<2; i++)
143 {
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");
151 }
152
153 freechain(clocks);
154 return 1;
155 }
156
157 void stb_get_clock_local_latency(ttvsig_list *tvs, long *rmin, long *rmax, long *fmin, long *fmax)
158 {
159 d_minmax_rf *cur;
160 ptype_list *pt0;
161 *rmin=*rmax=*fmin=*fmax=0;
162
163 if ((pt0=getptype(tvs->USER, STB_CLOCK_LOCAL_LATENCY))!=NULL)
164 {
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;
170 }
171 }
172
173 static void recur_compute_clock_latency(ttvsig_list *tvs, d_minmax_rf *sum)
174 {
175 int i;
176 ptype_list *pt0;
177 d_minmax_rf *cur;
178
179 if ((pt0=getptype(tvs->USER, STB_CLOCK_LOCAL_LATENCY))!=NULL)
180 {
181 cur=(d_minmax_rf *)pt0->DATA;
182 for (i=0; i<2; i++)
183 {
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;
186 }
187 if (cur->master!=NULL) recur_compute_clock_latency(cur->master, sum);
188 }
189 }
190
191 int stb_compute_clock_latency(stbfig_list *sb, long type)
192 {
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;
199 int i;
200 stbnode *n;
201 char buf0[1024], buf1[1024];
202
203 for (cl=sb->CLOCK; cl!=NULL; cl=cl->NEXT)
204 {
205 tvs=(ttvsig_list *)cl->DATA;
206 if ((pt=getptype(tvs->USER, STB_IS_CLOCK))!=NULL)
207 {
208 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
209 if (spctc->master!=NULL)
210 {
211 clock=NULL;
212
213 chain=addchain(NULL, spctc->master);
214 for (chainsig=sb->CLOCK; chainsig!=NULL; chainsig=chainsig->NEXT)
215 {
216 clock=(ttvsig_list *)chainsig->DATA;
217 if (getptype(clock->USER, STB_VIRTUAL_CLOCK)==NULL)
218 {
219 if (ttv_testnetnamemask(sb->FIG, clock, chain)) break;
220 }
221 else
222 {
223 if (mbk_TestREGEX(clock->NETNAME, spctc->master)) break;
224 }
225 }
226 freechain(chain);
227 if (chain==NULL) clock=NULL;
228
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;
231
232 if (getptype(tvs->USER, STB_INVERTED_CLOCK)!=NULL)
233 {
234 long l;
235 l=start_event[0];
236 start_event[0]=start_event[1];
237 start_event[1]=l;
238 }
239
240 if (clock!=NULL)
241 {
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;
244 else
245 {
246 dmrf_tmp=(d_minmax_rf *)mbkalloc(sizeof(d_minmax_rf));
247 tvs->USER=addptype(tvs->USER, STB_CLOCK_LOCAL_LATENCY, dmrf_tmp);
248 }
249 memcpy(dmrf_tmp, &dmrf, sizeof(d_minmax_rf));
250 }
251 else
252 {
253 spctc->master=NULL;
254 }
255 }
256 }
257 }
258
259 for (cl=sb->CLOCK; cl!=NULL; cl=cl->NEXT)
260 {
261 tvs=(ttvsig_list *)cl->DATA;
262 for (i=0; i<2; i++)
263 {
264 dmrf.delays[i].min=dmrf.delays[i].max=0;
265 }
266 recur_compute_clock_latency(tvs, &dmrf);
267
268 if ((pt=getptype(tvs->USER, STB_IS_CLOCK))!=NULL)
269 {
270 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
271 if (spctc->master!=NULL)
272 {
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);
275
276 if ((pt=getptype(tvs->USER, STB_IS_CLOCK))!=NULL)
277 {
278 spctc=(stb_propagated_clock_to_clock *)pt->DATA;
279 for (i=0; i<2; i++)
280 {
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;
286 }
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);
288
289 }
290 }
291 }
292 }
293
294
295 return 0;
296 }
297
298 chain_list *get_clock_latency_tree(ttvevent_list *tve, long type, chain_list *cl)
299 {
300 int i, mask;
301 ptype_list *pt;
302 d_minmax_rf *cur;
303 long delay, date;
304 stb_propagated_clock_to_clock *spctc;
305 stbnode *n;
306 stb_clock_latency_information *scli;
307
308 if ((pt=getptype(tve->ROOT->USER, STB_IS_CLOCK))!=NULL)
309 {
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)
313 {
314 if (mask==1) mask=2; else mask=1;
315 }
316 if ((pt=getptype(tve->ROOT->USER, STB_CLOCK_LOCAL_LATENCY))!=NULL)
317 {
318 cur=(d_minmax_rf *)pt->DATA;
319
320 if (cur->master!=NULL)
321 {
322 if (type & TTV_FIND_MAX) delay=cur->delays[i].max; else delay=cur->delays[i].min;
323 if (delay==TTV_NOTIME) delay=0;
324
325 if ((spctc->edges & mask)!=0) mask=1; else mask=0;
326 if (cl==NULL)
327 {
328 n=stb_getstbnode(tve);
329 if (i==0)
330 {
331 if (type & TTV_FIND_MAX) date=n->CK->SDNMAX; else date=n->CK->SDNMIN;
332 }
333 else
334 {
335 if (type & TTV_FIND_MAX) date=n->CK->SUPMAX; else date=n->CK->SUPMIN;
336 }
337 scli=(stb_clock_latency_information *)mbkalloc(sizeof(stb_clock_latency_information));
338 scli->date=date;
339 scli->delay=TTV_NOTIME;
340 scli->period=n->CK->PERIOD;
341 scli->clock_event=tve;
342 cl=addchain(cl, scli);
343 }
344
345 n=stb_getstbnode(&cur->master->NODE[mask]);
346 if (mask==0)
347 {
348 if (type & TTV_FIND_MAX) date=n->CK->SDNMAX; else date=n->CK->SDNMIN;
349 }
350 else
351 {
352 if (type & TTV_FIND_MAX) date=n->CK->SUPMAX; else date=n->CK->SUPMIN;
353 }
354 scli=(stb_clock_latency_information *)mbkalloc(sizeof(stb_clock_latency_information));
355 scli->date=date;
356 scli->delay=delay;
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);
361 }
362 }
363 else
364 {
365 n=stb_getstbnode(tve);
366 if (mask==0)
367 {
368 if (type & TTV_FIND_MAX) date=n->CK->SDNMAX, delay=spctc->latencies.SDNMAX;
369 else date=n->CK->SDNMIN, delay=spctc->latencies.SDNMIN;
370 }
371 else
372 {
373 if (type & TTV_FIND_MAX) date=n->CK->SUPMAX, delay=spctc->latencies.SUPMAX;
374 else date=n->CK->SUPMIN, delay=spctc->latencies.SUPMIN;
375 }
376
377 if (delay!=0)
378 {
379 scli=(stb_clock_latency_information *)mbkalloc(sizeof(stb_clock_latency_information));
380 scli->date=date-delay;
381 scli->delay=delay;
382 scli->period=n->CK->PERIOD;
383 scli->clock_event=tve;
384 cl=addchain(cl, scli);
385 }
386 }
387 }
388 return cl;
389 }
390
391
392 ptype_list *stb_build_generated_clock_info(chain_list *clocklist)
393 {
394 int i;
395 ptype_list *pt=NULL;
396 ttvsig_list *tvs;
397 chain_list *min, *max;
398 while (clocklist!=NULL)
399 {
400 tvs=(ttvsig_list *)clocklist->DATA;
401 for (i=0; i<2; i++)
402 {
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
406 }
407 clocklist=clocklist->NEXT;
408 }
409 return pt;
410 }
411
412 void stb_free_built_generated_clock_info(ptype_list *geneclockinfo)
413 {
414 int i;
415 ptype_list *pt;
416 ttvsig_list *tvs;
417 chain_list *cl, *ch;
418 for (pt=geneclockinfo; pt!=NULL; pt=pt->NEXT)
419 {
420 cl=(chain_list *)pt->DATA;
421 while (cl!=NULL)
422 {
423 for (ch=(chain_list *)cl->DATA; ch!=NULL; ch=ch->NEXT)
424 mbkfree(ch->DATA);
425 freechain((chain_list *)cl->DATA);
426 cl=delchain(cl, cl);
427 }
428 }
429 freeptype(geneclockinfo);
430 }
431
432 long stb_get_generated_clock_skew(ptype_list *geneclockinfo, ttvevent_list *tve0, ttvevent_list *tve1, ttvevent_list **common_node)
433 {
434 ptype_list *pt;
435 chain_list *c0, *c1;
436 long minmax=TTV_NOTIME;
437 stb_clock_latency_information *scli0, *scli1;
438 *common_node=NULL;
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)
446 {
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;
450 else break;
451 c0=c0->NEXT;
452 c1=c1->NEXT;
453 }
454 return minmax;
455 }
456
457