Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / ttv / ttv_propagation.c
1
2 #include "ttv.h"
3
4 #define TTV_PROPAGATE_IF_DIFFERENT 1
5 //#define TTV_PROPAGATE_IF_DIFFERENT 2
6 #define SAMESLOPELIMIT 0.01
7
8 long TTV_PROPAGATE_FORCED_SLOPE=TTV_NOTIME;
9 float TTV_PROPAGATE_FORCED_CAPA=-1;
10 static int TTV_STOP_AFTER_GATE_1=0, useheap=0;
11
12 typedef struct propagate_cache
13 {
14 struct propagate_cache *next;
15 long slope;
16 float capa;
17 long res_slope, res_delay;
18 } propagate_cache;
19
20 static HeapAlloc propagate_heap;
21
22 static inline int ttv_get_propagate_cache_delay_slope(ttvline_list *tl, long slope, float capa, long *res_slope, long *res_delay)
23 {
24 ptype_list *pt;
25 propagate_cache *pc;
26 if (useheap)
27 {
28 if ((pt=getptype(tl->USER, TTV_NODE_PROPINFO_CACHE))==NULL) return 0;
29 pc=(propagate_cache *)pt->DATA;
30 while (pc!=NULL && (pc->slope!=slope || pc->capa!=capa)) pc=pc->next;
31 if (pc!=NULL)
32 {
33 *res_slope=pc->res_slope;
34 *res_delay=pc->res_delay;
35 return 1;
36 }
37 }
38 return 0;
39 }
40
41 static inline void ttv_add_propagate_cache_delay_slope(ttvline_list *tl, long slope, float capa, long res_slope, long res_delay)
42 {
43 propagate_cache *npc;
44 if (useheap)
45 {
46 ptype_list *pt;
47 if ((pt=getptype(tl->USER, TTV_NODE_PROPINFO_CACHE))==NULL)
48 pt=tl->USER=addptype(tl->USER, TTV_NODE_PROPINFO_CACHE, NULL);
49
50 npc=(propagate_cache *)AddHeapItem(&propagate_heap);
51 npc->slope=slope;
52 npc->capa=capa;
53 npc->res_slope=res_slope;
54 npc->res_delay=res_delay;
55 npc->next=(propagate_cache *)pt->DATA;
56 pt->DATA=npc;
57 }
58 }
59
60
61 void ttv_experim_setstopaftergate1(int val)
62 {
63 TTV_STOP_AFTER_GATE_1=val;
64 }
65
66 ttvline_list *ttv_CreateContactLine(ttvevent_list *node, ttvevent_list *root)
67 {
68 ttvline_list *tvl;
69 tvl=(ttvline_list *)mbkalloc(sizeof(ttvline_list));
70 tvl->USER=NULL;
71 tvl->NODE=node;
72 tvl->ROOT=root;
73 tvl->FIG=NULL;
74 return tvl;
75 }
76
77 static void initprop(ttvpropinfo_list *prop, long slope)
78 {
79 prop->CTK.PWL=NULL;
80 prop->CTK.SLEW=slope;
81 prop->CTK.DELAY=0;
82 prop->CTK.R=-1;
83 if (prop->REF!=NULL)
84 {
85 prop->REF->PWL=NULL;
86 prop->REF->SLEW=slope;
87 prop->REF->DELAY=0;
88 prop->REF->R=-1;
89 }
90 }
91
92 static ttvpropinfo_list *createpropinfo(ttvevent_list *a, int usectk)
93 {
94 ttvpropinfo_list *prop;
95 prop=(ttvpropinfo_list *)mbkalloc(sizeof(ttvpropinfo_list)); //<= par heap
96 prop->CTK.PWL=NULL;
97 prop->CTK.SLEW=TTV_NOSLOPE;
98 prop->CTK.DELAY=TTV_NOTIME;
99 prop->CTK.R=-1;
100 prop->CTK.C1=-1;
101 prop->CTK.C2=-1;
102 prop->CTK.RDRIVER=-1;
103 prop->CTK.CAPA=-1;
104 if (usectk)
105 {
106 prop->REF=(ttv_onepropinfo *)mbkalloc(sizeof(ttv_onepropinfo));
107 prop->REF->PWL=NULL;
108 prop->REF->SLEW=TTV_NOSLOPE;
109 prop->REF->DELAY=TTV_NOTIME;
110 prop->REF->R=-1;
111 prop->REF->C1=-1;
112 prop->REF->C2=-1;
113 prop->REF->RDRIVER=-1;
114 prop->REF->CAPA=-1;
115 }
116 else
117 prop->REF=NULL;
118 a->USER=addptype(a->USER, TTV_NODE_PROPINFO, prop);
119 return prop;
120 }
121
122 ttvpropinfo_list *ttv_get_prop_info(ttvevent_list *node)
123 {
124 ptype_list *pt;
125 if ((pt=getptype(node->USER, TTV_NODE_PROPINFO))!=NULL)
126 return (ttvpropinfo_list *)pt->DATA;
127 return NULL;
128 }
129
130 ttvpropinfo_list *givepropinfo(ttvevent_list *a, int usectk)
131 {
132 ttvpropinfo_list *prop;
133
134 if ((prop=ttv_get_prop_info(a))!=NULL)
135 return prop;
136
137 return createpropinfo(a, usectk);
138 }
139
140 static void cleanpropinfo(ttvevent_list *a)
141 {
142 ptype_list *pt;
143 ttvpropinfo_list *prop;
144
145 if ((pt=getptype(a->USER, TTV_NODE_PROPINFO))!=NULL)
146 {
147 prop=(ttvpropinfo_list *)pt->DATA;
148 if (prop->REF!=NULL)
149 {
150 mbkfree(prop->REF);
151 }
152 mbkfree(prop);
153 a->USER=delptype(a->USER, TTV_NODE_PROPINFO);
154 }
155 }
156
157 static int ttv_sameslope(long a, long b)
158 {
159 long diff;
160 if (a==TTV_NOSLOPE || b==TTV_NOSLOPE) return 0;
161 if (a!=b) return 0;
162 /* diff=abs(a-b);
163 if (((float)diff)/b>SAMESLOPELIMIT || ((float)diff)/a>SAMESLOPELIMIT) return 0;
164 */
165 return 1;
166 }
167
168 void ttv_RecomputeLineDelayAndSlope(ttvfig_list *tvf, ttvline_list *line, ttvpropinfo_list *input0, ttvpropinfo_list *output0, float capa, long type, int doref)
169 {
170 timing_model *modelmin, *modelmax ;
171 float vtmin=0, vtmax=0 ;
172 float vfmin=0, vfmax=0 ;
173 float vfrcmin=0, vfrcmax=0 ;
174 float vddmin=0, vddmax=0 ;
175 float vthmin=0, vthmax=0 ;
176 long *dmin1 = NULL, *fmin1 = NULL, *dmax1 = NULL, *fmax1 = NULL;
177 stm_pwl **fmin1_pwl = NULL, **fmax1_pwl = NULL;
178 double *rmin=NULL, *c1min=NULL, *c2min=NULL, vsatmin=-1, rlinmin=-1 ;
179 double *rmax=NULL, *c1max=NULL, *c2max=NULL, vsatmax=-1, rlinmax=-1 ;
180 double r=0, c1=0, c2=0;
181 lofig_list *lofig ;
182 locon_list *locon ;
183 stm_pwl *pwlmin=NULL, *pwlmax=NULL;
184 long smin=0, smax=0;
185 ttvline_list *previous_line=input0->PREVIOUS_LINE;
186 ttv_onepropinfo *input, *output;
187 float *nrjmin = NULL,*nrjmax = NULL;
188
189
190 if (doref)
191 {
192 input=input0->REF, output=output0->REF;
193 }
194 else
195 {
196 input=&input0->CTK, output=&output0->CTK;
197 }
198
199 if (type & TTV_FIND_MIN)
200 {
201 pwlmin=input->PWL;
202 smin=input->SLEW;
203 dmin1=&output->DELAY;
204 fmin1=&output->SLEW;
205 if (0/*V_BOOL_TAB[__STM_USE_MSC].VALUE*/)
206 fmin1_pwl=&output->PWL;
207 else
208 fmin1_pwl=NULL;
209 rmin=&r;
210 c1min=&c1;
211 c2min=&c2;
212 *rmin = input->RDRIVER;
213 *c1min = 1000.0*input->CAPA;
214 nrjmin = &output->ENERGY;
215 }
216 else
217 {
218 pwlmax=input->PWL;
219 smax=input->SLEW;
220 dmax1=&output->DELAY;
221 fmax1=&output->SLEW;
222 if (0/*V_BOOL_TAB[__STM_USE_MSC].VALUE*/)
223 fmax1_pwl=&output->PWL;
224 else
225 fmax1_pwl=NULL;
226 rmax=&r;
227 c1max=&c1;
228 c2max=&c2;
229 *rmax = input->RDRIVER;
230 *c1max = 1000.0*input->CAPA;
231 nrjmax = &output->ENERGY;
232 }
233
234 modelmax = NULL;
235 modelmin = NULL;
236
237 if((line->TYPE & TTV_LINE_RC) == TTV_LINE_RC)
238 {
239 if (type & TTV_FIND_MIN)
240 {
241 if (previous_line)
242 modelmin = stm_getmodel(previous_line->FIG->INFO->FIGNAME,previous_line->MDMIN) ;
243 vtmin = stm_mod_vt(modelmin);
244 vfmin = stm_mod_vf(modelmin);
245 vthmin = stm_mod_vth(modelmin);
246 vddmin = stm_mod_vdd(modelmin);
247 if (input->R>=0)
248 {
249 vsatmin = stm_mod_vsat(modelmin);
250 rlinmin = stm_mod_rlin(modelmin);
251 }
252 }
253 else
254 {
255 if (previous_line)
256 modelmax = stm_getmodel(previous_line->FIG->INFO->FIGNAME,previous_line->MDMAX) ;
257 vtmax = stm_mod_vt(modelmax);
258 vfmax = stm_mod_vf(modelmax);
259 vthmax = stm_mod_vth(modelmax);
260 vddmax = stm_mod_vdd(modelmax);
261 if (input->R>=0)
262 {
263 vsatmax = stm_mod_vsat(modelmax);
264 rlinmax = stm_mod_rlin(modelmax);
265 }
266 }
267 if (modelmax==NULL && modelmin==NULL && (line->NODE->ROOT->TYPE & TTV_SIG_C)!=0)
268 {
269 float low, high;
270 ttv_get_signal_swing(tvf, line->NODE->ROOT, &low, &high);
271 vddmax=high-low;
272 vthmax=vddmax/2;
273 vfmax=vddmax;
274 vtmax=0.2*vddmax;
275 }
276
277 r=input->R; c1=input->C1; c2=input->C2;
278
279 if((line->ROOT->TYPE & TTV_NODE_UP) == TTV_NODE_UP)
280 {
281 vfrcmin = vddmin;
282 vfrcmax = vddmax;
283 }
284 else
285 {
286 vfrcmin = 0.0;
287 vfrcmax = 0.0;
288 }
289
290
291 ttv_calclinedelayslope(line,smin,smax,pwlmin,pwlmax,vtmin,vtmax,vfrcmin,vfrcmax,vddmin,vddmax,vthmin,vthmax,capa,dmin1,fmin1,fmin1_pwl,dmax1,fmax1,fmax1_pwl,0,vsatmin,rlinmin,rmin,c1min,c2min,vsatmax,rlinmax,rmax,c1max,c2max,NULL,NULL);
292
293 output->R=-1;
294 output->RDRIVER = input->RDRIVER;
295 output->CAPA = input->CAPA;
296 output->ENERGY = 0.0;
297 }
298 else
299 {
300 if (type & TTV_FIND_MIN)
301 {
302 modelmin = stm_getmodel(line->FIG->INFO->FIGNAME,line->MDMIN) ;
303 vtmin = stm_mod_vt(modelmin);
304 vfmin = stm_mod_vf(modelmin);
305 vthmin = stm_mod_vth(modelmin);
306 vddmin = stm_mod_vdd(modelmin);
307 }
308 else
309 {
310 modelmax = stm_getmodel(line->FIG->INFO->FIGNAME,line->MDMAX) ;
311 vtmax = stm_mod_vt(modelmax);
312 vfmax = stm_mod_vf(modelmax);
313 vthmax = stm_mod_vth(modelmax);
314 vddmax = stm_mod_vdd(modelmax);
315 }
316
317 lofig = ttv_getrcxlofig( line->ROOT->ROOT->ROOT ) ;
318 if( lofig )
319 {
320 locon = rcx_gethtrcxcon( NULL, lofig, line->ROOT->ROOT->NAME ) ;
321 if( locon )
322 {
323 rcx_rcnload_reset( locon->SIG );
324 }
325 }
326
327 ttv_calclinedelayslope(line,smin,smax,pwlmin,pwlmax,vtmin,vtmax,vfrcmin,vfrcmax,vddmin,vddmax,vthmin,vthmax,capa,dmin1,fmin1,fmin1_pwl,dmax1,fmax1,fmax1_pwl,0,vsatmin,rlinmin,rmin,c1min,c2min,vsatmax,rlinmax,rmax,c1max,c2max,nrjmin,nrjmax);
328
329 output->R=r;
330 output->C1=c1;
331 output->C2=c2;
332 if (type & TTV_FIND_MIN)
333 {
334 modelmin = stm_getmodel(line->FIG->INFO->FIGNAME,line->MDMIN) ;
335 output->RDRIVER = stm_mod_rlin( modelmin );
336 }
337 else
338 {
339 modelmax = stm_getmodel(line->FIG->INFO->FIGNAME,line->MDMAX) ;
340 output->RDRIVER = stm_mod_rlin( modelmax );
341 }
342 }
343
344 if( r > 0.0 && c2 > 0.0 )
345 output->CAPA = c1+c2 ;
346 else
347 output->CAPA = c1 ;
348 }
349
350 static int mustpropagate_tmalike(ttvline_list *prevline, chain_list *cur, chain_list *start)
351 {
352 ttvline_list *curl, *nextl;
353 if (cur==start || (cur==start->NEXT && (prevline->TYPE & TTV_LINE_RC) == TTV_LINE_RC)) return 1;
354 curl=(ttvline_list *)cur->DATA;
355 if (cur->NEXT==NULL && (curl->ROOT->ROOT->TYPE & (TTV_SIG_N|TTV_SIG_C)) != 0) return 1;
356 if (cur->NEXT!=NULL && cur->NEXT->NEXT==NULL)
357 {
358 nextl=(ttvline_list *)cur->NEXT->DATA;
359 if ((nextl->TYPE & TTV_LINE_RC) == TTV_LINE_RC && (nextl->ROOT->ROOT->TYPE & (TTV_SIG_N|TTV_SIG_C)) != 0) return 1;
360 }
361 return 0;
362 }
363
364 static inline int ttvprop_islastgaterc(chain_list *cl)
365 {
366 ttvline_list *curl, *nextl;
367 if (cl->NEXT==NULL) return 1;
368 if (cl->NEXT->NEXT!=NULL) return 0;
369 nextl=(ttvline_list *)cl->NEXT->DATA;
370 if ((nextl->TYPE & TTV_LINE_RC) != TTV_LINE_RC) return 0;
371 return 1;
372 }
373
374 long ttv_RecomputeLineChain(ttvfig_list *tvf, ttvfig_list *tvi, chain_list *ordered_line_list, long inputSLEW, long *outputSLEW, float *energy, float capa, long type, long mode, int doref)
375 {
376 chain_list *cl;
377 ttvline_list *tl;
378 ttvpropinfo_list *res;
379 ttvevent_list *startnode;
380 float thiscapa;
381 ttvpropinfo_list *input=NULL;
382 long totaldelay=0, totaldelayref=0, outdelay, oldslope, justlast=0, val;
383 ttvline_list *prevline;
384 stbfig_list *sf=NULL;
385 ctk_exchange ctkinfo;
386 int lastmode, trig=0;
387
388 if ((type & TTV_FIND_ACCESS)==0) trig=1;
389
390 *energy = 0.0;
391
392 if (doref) sf=stb_getstbfig(tvf);
393
394 if (ordered_line_list==NULL) { *outputSLEW=0; return 0; }
395
396 if ((mode & TTV_PROPAGATE_IF_DIFFERENT)!=0) doref=0;
397
398 prevline=NULL;
399 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
400 {
401 tl=(ttvline_list *)cl->DATA;
402 if (input==NULL)
403 {
404 input=givepropinfo(tl->NODE, doref);
405 if ((mode & TTV_PROPAGATE_IF_DIFFERENT)!=0 && ttv_sameslope(input->CTK.SLEW, inputSLEW)) justlast=1;
406 initprop(input, inputSLEW);
407 }
408
409 if (prevline!=NULL && prevline->FIG==NULL) prevline=NULL; // contact line
410 input->PREVIOUS_LINE=prevline;
411
412 res=givepropinfo(tl->ROOT, doref); //?
413
414 if (tl->FIG!=NULL)
415 {
416 if (cl!=ordered_line_list && prevline==NULL) // pas d'access
417 {
418 ttv_getnodeslope(tvf,tvi,tl->ROOT,&oldslope,type);
419 initprop(input, oldslope);
420 }
421 if((tl->ROOT->ROOT->TYPE & (TTV_SIG_N|TTV_SIG_C)) != 0
422 && (cl->NEXT==NULL || (cl->NEXT->NEXT==NULL && (((ttvline_list *)cl->NEXT->DATA)->TYPE & TTV_LINE_RC)!=0))
423 )
424 {
425 if (capa>=0)
426 thiscapa=capa;
427 else
428 thiscapa=ttv_get_signal_output_capacitance(tvf, tl->ROOT->ROOT);
429 }
430 else
431 thiscapa=0;
432
433 oldslope=res->CTK.SLEW;
434
435 if (justlast==0 || (justlast==1 && ttvprop_islastgaterc(cl)))
436 {
437 if (doref && sf!=NULL)
438 {
439 lastmode=rcx_crosstalkactive(RCX_MILLER); //?
440 if((tl->TYPE & TTV_LINE_RC) == TTV_LINE_RC)
441 stb_set_ctk_information(sf, tl->NODE, type, &ctkinfo);
442 else
443 stb_set_ctk_information(sf, tl->ROOT, type, &ctkinfo);
444 }
445 if (TTV_STOP_AFTER_GATE_1 && !mustpropagate_tmalike(prevline, cl, ordered_line_list))
446 {
447 if ((type & TTV_FIND_MIN)!=0)
448 res->CTK.DELAY=tl->VALMIN, res->CTK.SLEW=tl->FMIN;
449 else
450 res->CTK.DELAY=tl->VALMAX, res->CTK.SLEW=tl->FMAX;
451 }
452 else
453 {
454 if (ttv_get_propagate_cache_delay_slope(tl, input->CTK.SLEW, thiscapa, &res->CTK.SLEW, &res->CTK.DELAY)==0)
455 {
456 ttv_RecomputeLineDelayAndSlope(tvf, tl, input, res, thiscapa, type, 0);
457 ttv_add_propagate_cache_delay_slope(tl, input->CTK.SLEW, thiscapa, res->CTK.SLEW, res->CTK.DELAY);
458 }
459 }
460 if (doref && sf!=NULL)
461 {
462 stb_release_ctk_information(&ctkinfo);
463 rcx_crosstalkactive(lastmode); // ?
464 }
465 }
466 if (doref)
467 {
468 lastmode=rcx_crosstalkactive(RCX_NOCROSSTALK);
469 if (TTV_STOP_AFTER_GATE_1 && !mustpropagate_tmalike(prevline, cl, ordered_line_list))
470 {
471 if ((type & TTV_FIND_MIN)!=0)
472 res->REF->DELAY=tl->VALMIN, res->REF->SLEW=tl->FMIN;
473 else
474 res->REF->DELAY=tl->VALMAX, res->REF->SLEW=tl->FMAX;
475 }
476 else ttv_RecomputeLineDelayAndSlope(tvf, tl, input, res, thiscapa, type, 1);
477 rcx_crosstalkactive(lastmode);
478 }
479
480 if ((mode & TTV_PROPAGATE_IF_DIFFERENT)!=0 && ttv_sameslope(oldslope, res->CTK.SLEW)) justlast=1;
481
482 if ((tl->TYPE & TTV_LINE_A) != 0)
483 {
484 if ((val=stb_gettruncatedaccess(tl->ROOT, tl->NODE, (type & TTV_FIND_MAX)==TTV_FIND_MAX?1:0))!=TTV_NOTIME)
485 {
486 if (res->CTK.DELAY>val) res->CTK.DELAY=val;
487 if (doref && res->REF->DELAY>val) res->REF->DELAY=val;
488 }
489 }
490
491 totaldelay+=res->CTK.DELAY;
492 if (doref) totaldelayref+=res->REF->DELAY;
493 if (trig==0 && (tl->ROOT->ROOT->TYPE & (TTV_SIG_L|TTV_SIG_R))!=0) trig=1;
494 if (trig)
495 *energy += res->CTK.ENERGY;
496 }
497
498 input=res;
499 prevline=tl;
500 }
501
502 outdelay=totaldelay;
503
504 if ((mode & TTV_PROPAGATE_IF_DIFFERENT)==0)
505 {
506 if (0/*V_BOOL_TAB[__STM_USE_MSC].VALUE*/)
507 {
508 // clean pwl
509 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
510 {
511 tl=(ttvline_list *)cl->DATA;
512 input=givepropinfo(tl->NODE, doref);
513 if (input->CTK.PWL!=NULL) stm_pwl_destroy(input->CTK.PWL);
514 if (doref && input->REF->PWL!=NULL) stm_pwl_destroy(input->REF->PWL);
515 }
516 if (ordered_line_list!=NULL && ((ttvline_list *)ordered_line_list->DATA)->NODE!=tl->ROOT)
517 {
518 input=givepropinfo(tl->ROOT, doref);
519 if (input->CTK.PWL!=NULL) stm_pwl_destroy(input->CTK.PWL);
520 if (doref && input->REF->PWL!=NULL) stm_pwl_destroy(input->REF->PWL);
521 }
522 }
523
524 if ((type & TTV_FIND_DUAL)==TTV_FIND_DUAL)
525 {
526 totaldelay=0;
527 totaldelayref=0;
528 tl=(ttvline_list *)ordered_line_list->DATA;
529 input=givepropinfo(tl->NODE, doref);
530 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
531 {
532 tl=(ttvline_list *)cl->DATA;
533 input->CTK.FIND_DELAY=totaldelay;
534 res=givepropinfo(tl->ROOT, doref);
535 totaldelay+=res->CTK.DELAY;
536 if (doref)
537 {
538 input->REF->FIND_DELAY=totaldelayref;
539 totaldelayref+=res->REF->DELAY;
540 }
541 input=res;
542 }
543 res->CTK.FIND_DELAY=totaldelay;
544 if (doref) res->REF->FIND_DELAY=totaldelayref;
545 }
546 else
547 {
548 tl=(ttvline_list *)ordered_line_list->DATA;
549 startnode=tl->NODE;
550 input=givepropinfo(tl->NODE, doref);
551
552 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
553 {
554 tl=(ttvline_list *)cl->DATA;
555 input->CTK.FIND_DELAY=totaldelay;
556 res=givepropinfo(tl->ROOT, doref);
557 totaldelay-=res->CTK.DELAY;
558 if (doref)
559 {
560 input->REF->FIND_DELAY=totaldelayref;
561 totaldelayref-=res->REF->DELAY;
562 }
563 input=res;
564 }
565 if (startnode!=tl->ROOT)
566 {
567 res->CTK.FIND_DELAY=totaldelay; // 0 ?
568 if (doref) res->REF->FIND_DELAY=totaldelayref;
569 }
570 }
571 }
572 *outputSLEW=res->CTK.SLEW;
573 return outdelay;
574 }
575
576 void ttv_RecomputeCleanLineChain(chain_list *ordered_line_list)
577 {
578 chain_list *cl;
579 ttvline_list *tl;
580
581 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
582 {
583 tl=(ttvline_list *)cl->DATA;
584 cleanpropinfo(tl->NODE);
585 if (useheap) tl->USER=testanddelptype(tl->USER, TTV_NODE_PROPINFO_CACHE);
586 }
587 if (ordered_line_list!=NULL) cleanpropinfo(tl->ROOT);
588 }
589
590 void ttv_RecomputeFreeLineChain(chain_list *ordered_line_list)
591 {
592 chain_list *cl;
593 ttvline_list *tl;
594 for (cl=ordered_line_list; cl!=NULL; cl=cl->NEXT)
595 {
596 tl=(ttvline_list *)cl->DATA;
597 if (tl->FIG==NULL) mbkfree(tl);
598 }
599 freechain(ordered_line_list);
600 }
601
602 chain_list *ttv_BuildLineList(ttvfig_list *ttvfig, ttvevent_list *root, ttvevent_list *node, long type, int *doref)
603 {
604 ttvevent_list *nodex ;
605 ptype_list *ptype ;
606 chain_list *line_list;
607
608 nodex = node ;
609 *doref=0;
610 line_list=NULL;
611
612 if((type & TTV_FIND_DUAL) != TTV_FIND_DUAL)
613 {
614 if((nodex->FIND->OUTLINE == NULL) &&
615 ((ptype = getptype(nodex->USER,TTV_NODE_LATCH)) != NULL))
616 {
617 line_list=addchain(line_list, ttv_CreateContactLine(nodex, (ttvevent_list *)ptype->DATA));
618 nodex = (ttvevent_list *)ptype->DATA ;
619 }
620
621 while(nodex->FIND->OUTLINE != NULL)
622 {
623 line_list=addchain(line_list, nodex->FIND->OUTLINE);
624 if (*doref==0 && ttv_getlinedelay(nodex->FIND->OUTLINE)!=NULL) *doref=1;
625 nodex = nodex->FIND->OUTLINE->ROOT ;
626 if((nodex->FIND->OUTLINE == NULL) &&
627 ((ptype = getptype(nodex->USER,TTV_NODE_LATCH)) != NULL))
628 {
629 line_list=addchain(line_list, ttv_CreateContactLine(nodex, (ttvevent_list *)ptype->DATA));
630 nodex = (ttvevent_list *)ptype->DATA ;
631 }
632 if(nodex == root) break ;
633 }
634 line_list=reverse(line_list);
635 }
636 else
637 {
638 while(nodex->FIND->OUTLINE != NULL)
639 {
640 if (*doref==0 && ttv_getlinedelay(nodex->FIND->OUTLINE)!=NULL) *doref=1;
641 line_list=addchain(line_list, nodex->FIND->OUTLINE);
642 nodex = nodex->FIND->OUTLINE->NODE ;
643 if(nodex == root) break ;
644 }
645 }
646
647 return(line_list) ;
648 }
649
650 chain_list *ttv_DoPropagation_PRECISION_LEVEL1(ttvfig_list *tvf, ttvfig_list *tvi, ttvevent_list *node, ttvevent_list *root, long type)
651 {
652 chain_list *line_list;
653 long inslope, res;
654 int doref;
655 float energy;
656
657 if ((type & TTV_FIND_PATH)==TTV_FIND_PATH) return NULL;
658
659 line_list=ttv_BuildLineList(tvf, root, node, type, &doref);
660
661 if (TTV_PROPAGATE_FORCED_SLOPE!=TTV_NOTIME)
662 inslope=TTV_PROPAGATE_FORCED_SLOPE;
663 else
664 {
665 if ((type & TTV_FIND_DUAL)!=TTV_FIND_DUAL)
666 ttv_getnodeslope(tvf, tvi, node, &inslope, type);
667 else
668 ttv_getnodeslope(tvf, tvi, root, &inslope, type);
669 }
670
671 ttv_RecomputeLineChain(tvf, tvi, line_list, inslope, &res, &energy, TTV_PROPAGATE_FORCED_CAPA, type, 0, doref);
672 #if 0
673 {
674 ttvpropinfo_list *input;
675 long oslop;
676 char *n1, *n2;
677 double rat;
678 // if ((type & TTV_FIND_DUAL)!=TTV_FIND_DUAL)
679 input=givepropinfo(node, doref);
680 /* else
681 input=givepropinfo(root, doref);*/
682
683 if ((type & TTV_FIND_DUAL)!=TTV_FIND_DUAL)
684 n1=node->ROOT->NAME, n2=root->ROOT->NAME;
685 else
686 n1=root->ROOT->NAME, n2=node->ROOT->NAME;
687 line_list=reverse(line_list);
688 if ((type & TTV_FIND_MIN)!=0) oslop=((ttvline_list *)line_list->DATA)->FMIN;
689 else oslop=((ttvline_list *)line_list->DATA)->FMAX;
690 rat=((float)(input->CTK.FIND_DELAY-node->FIND->DELAY))*100.0/node->FIND->DELAY;
691 avt_fprintf(stderr,"%s%s %s is:%ld od:%ld os:%ld -> od:%ld os:%ld (%+.1f%%)¤.\n",fabs(rat)<5?"":fabs(rat)<10?"¤4":"¤6", n1, n2, inslope,node->FIND->DELAY,oslop,input->CTK.FIND_DELAY,res,rat);
692 line_list=reverse(line_list);
693 }
694 #endif
695 return line_list;
696 }
697
698 void ttv_CleanPropagation_PRECISION_LEVEL1(chain_list *line_list)
699 {
700 ttv_RecomputeCleanLineChain(line_list);
701 ttv_RecomputeFreeLineChain(line_list);
702 }
703
704 long ttv_GET_FINDDELAY(ttvevent_list *node, int ref)
705 {
706 ttvpropinfo_list *propinfo=NULL;
707
708 if (V_INT_TAB[__TTV_PRECISION_LEVEL].VALUE!=0)
709 propinfo = ttv_get_prop_info(node);
710
711 if(propinfo){
712 if (ref && propinfo->REF!=NULL)
713 return(propinfo->REF->FIND_DELAY);
714 return(propinfo->CTK.FIND_DELAY);
715 }
716 return node->FIND->DELAY;
717 }
718
719 long ttv_GET_LINE_DELAY(ttvline_list *line, long type, int ref)
720 {
721 ttvpropinfo_list *propinfo=NULL;
722 long val, ret;
723
724 if (V_INT_TAB[__TTV_PRECISION_LEVEL].VALUE!=0)
725 propinfo = ttv_get_prop_info(line->ROOT);
726
727 if(propinfo){
728 if (ref && propinfo->REF!=NULL)
729 ret=propinfo->REF->DELAY;
730 else
731 ret=propinfo->CTK.DELAY;
732 }
733 else {
734 if ((type & TTV_FIND_MAX) == TTV_FIND_MAX)
735 ret=line->VALMAX;
736 else
737 ret=line->VALMIN;
738 }
739 if ((line->TYPE & TTV_LINE_A) != 0)
740 {
741 if ((val=stb_gettruncatedaccess(line->ROOT, line->NODE, (type & TTV_FIND_MAX)==TTV_FIND_MAX?1:0))!=TTV_NOTIME && ret>val) ret=val;
742 }
743 return ret;
744 }
745
746 long ttv_GET_LINE_SLEW(ttvline_list *line, long type, int ref)
747 {
748 ttvpropinfo_list *propinfo=NULL;
749
750 if (V_INT_TAB[__TTV_PRECISION_LEVEL].VALUE!=0)
751 propinfo= ttv_get_prop_info(line->ROOT);
752
753 if(propinfo){
754 if (ref && propinfo->REF!=NULL)
755 return(propinfo->REF->SLEW);
756 return(propinfo->CTK.SLEW);
757 }
758 if ((type & TTV_FIND_MAX) == TTV_FIND_MAX)
759 return(line->FMAX);
760 else
761 return(line->FMIN);
762 }
763
764 void ttv_DoCharacPropagation(ttvfig_list *tvf, ttvfig_list *tvi, ttvevent_list *node, ttvevent_list *root, long type, chain_list *slope_list, chain_list *capa_list, chain_list **resd, chain_list **ress, chain_list **rese, chain_list *inputlinelist)
765 {
766 chain_list *line_list;
767 long inslope, res, delay, resen;
768 int doref=0;
769 chain_list *slopes, *capas;
770 float capa;
771
772 *resd=NULL;
773 *ress=NULL;
774 *rese=NULL;
775 if (inputlinelist)
776 line_list=inputlinelist;
777 else
778 line_list=ttv_BuildLineList(tvf, root, node, type, &doref);
779
780 useheap=1;
781 CreateHeap(sizeof(propagate_cache), 1000, &propagate_heap);
782
783 for (slopes=slope_list; slopes!=NULL; slopes=slopes->NEXT)
784 {
785 inslope=(long)slopes->DATA;
786 if (inslope==TTV_NOTIME)
787 {
788 if ((type & TTV_FIND_DUAL)!=TTV_FIND_DUAL)
789 ttv_getnodeslope(tvf, tvi, node, &inslope, type);
790 else
791 ttv_getnodeslope(tvf, tvi, root, &inslope, type);
792 }
793
794 for (capas=capa_list; capas!=NULL; capas=capas->NEXT)
795 {
796 capa=*(float *)&capas->DATA;
797 delay=ttv_RecomputeLineChain(tvf, tvi, line_list, inslope, &res, (float*)&resen, capa, type, TTV_PROPAGATE_IF_DIFFERENT, doref);
798 *resd=addchain(*resd, (void *)delay);
799 *ress=addchain(*ress, (void *)res);
800 if(( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 1 )
801 ||( V_INT_TAB[ __AVT_POWER_CALCULATION ].VALUE == 5 )){
802 *rese=addchain(*rese, (void *)resen);
803 }
804 }
805 }
806
807 DeleteHeap(&propagate_heap);
808 ttv_RecomputeCleanLineChain(line_list);
809 ttv_RecomputeFreeLineChain(line_list);
810 *resd=reverse(*resd);
811 *ress=reverse(*ress);
812 *rese=reverse(*rese);
813 useheap=0;
814 }