1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Fichier : stm_API_cache.c */
7 /* © copyright 2003 AVERTEC */
8 /* Tous droits reserves */
10 /* Auteur(s) : Antony PINTO */
12 /****************************************************************************/
14 #include "stm_API_cache.h"
16 static double THRESHOLD
= 120.0;
17 static stm_tree4cache
*APISTM_TREE
= NULL
;
18 static stm_current
*CURRENT
= NULL
;
20 static int stm_gettimingfunction_and_signalcapa(char *out
, timing_function
**fct
, double *capa
);
22 static stm_current
*stm_getCurrent(timing_function
*fct
);
24 void stm_createCache(void);
25 double stm_getSlope (double inslope
, double outload
);
26 double stm_getDelay (double inslope
, double outload
);
27 void stm_storeSlope (double inslope
, double outload
, double slope
);
28 void stm_storeDelay (double inslope
, double outload
, double delay
);
29 int stm_delayThresholdOK(double inslope
, double outload
, double threshold
);
30 int stm_slopeThresholdOK(double inslope
, double outload
, double threshold
);
32 void stm_displayRange(timing_table
*table
);
34 static void stm_storeInTable(timing_table
**table
, double inslope
, double outload
, double delay
, int mode
);
35 static int stm_thresholdOK(timing_table
*table
, double inslope
, double outload
, double threshold
);
36 static int stm_getBeforeAndAfter(float *range
, int max
, double value
, int *before
, int *after
);
37 static double stm_thresholdTest(double x0
, double x1
, double x
, double y0
, double y1
);
38 static void stm_getVar(timing_table
*table
, double *x0
, double *x1
, double *y0
, double *y1
, int bx
, int ax
, int by
, int ay
, int mode
) ;
39 static int stm_findIndex(float *range
, double value
, int size
);
40 static int stm_copyRangeAndInsert(float *range
, float *new, double value
, int size
);
42 static int isEqual(float a
, float b
);
43 static int isInf(float a
, float b
);
45 static stm_tree4cache
*stm_newTree(stm_tree4cache
*head
);
46 static stm_tree4cache
*stm_freeTree(stm_tree4cache
*tree
);
47 static stm_tree4cache
*stm_freeAllTree(stm_tree4cache
*tree
);
48 static stm_tree4cache
*stm_addTree(stm_tree4cache
*current
, char *orig
, char *dest
, char *type
);
50 static void stm_setDelayNSlope(stm_tree4cache
*tree
, double delay
, double slope
);
51 static void stm_updateCacheFromTree(stm_tree4cache
*tree
, double inslope
);
52 static double stm_getTreeSlope(stm_tree4cache
*tree
, char *orig
);
53 static void stm_applyTree(double inslope
);
54 static double stm_interpol(timing_table
*table
, double inslope
, double outload
, float (*func
)(timing_table
*, float, float), long type
);
55 static double stm_getValue(timing_table
*table
, double inslope
, double outload
, float (*func
)(timing_table
*, float, float));
57 static void stm_fillFindUpnDown(timing_table
*tbl
, int xind
, int yind
, int *up
, int *down
);
58 static void stm_fillCol(timing_table
*tbl
, int up
, int down
, int xind
);
59 static void stm_fillNewLine(timing_table
*tbl
,int yind
);
60 static void stm_fillFindLeftnRight(timing_table
*tbl
, int xind
, int yind
, int *beg
, int *end
);
61 static void stm_fillLine(timing_table
*tbl
, int beg
, int end
, int yind
);
62 static void stm_fillNewCol(timing_table
*tbl
,int xind
);
63 static void stm_fillTbl(timing_table
*tbl
, int xind
, int yind
, char type
);
65 void stm_test_threshold(void);
67 /****************************************************************************/
68 /*{{{ stm_API_ActionTerminate() */
71 /****************************************************************************/
72 void stm_API_ActionTerminate() // commentaire pour desactiver l'ajout de token
74 APISTM_TREE
= stm_freeAllTree(APISTM_TREE
);
76 /*}}}************************************************************************/
77 /*{{{ Tree Management */
78 /****************************************************************************/
79 /*{{{ stm_newTree() */
82 /****************************************************************************/
83 static stm_tree4cache
*stm_newTree(stm_tree4cache
*head
)
87 res
= mbkalloc(sizeof(struct stm_tree4cache
));
95 /*}}}************************************************************************/
96 /*{{{ stm_freeTree() */
99 /****************************************************************************/
100 static stm_tree4cache
*stm_freeTree(stm_tree4cache
*tree
)
107 /*}}}************************************************************************/
108 /*{{{ stm_freeAllTree() */
111 /****************************************************************************/
112 static stm_tree4cache
*stm_freeAllTree(stm_tree4cache
*tree
)
116 tree
->NEXT
= stm_freeAllTree(tree
->NEXT
);
117 tree
= stm_freeTree(tree
);
122 /*}}}************************************************************************/
123 /*{{{ stm_addTree() */
126 /****************************************************************************/
127 static stm_tree4cache
*stm_addTree(stm_tree4cache
*current
, char *orig
,
128 char *dest
, char *type
)
130 stm_tree4cache treex
, *res
= NULL
;
132 orig
= namealloc(orig
);
133 dest
= namealloc(dest
);
134 type
= namealloc(type
);
135 treex
.NEXT
= current
;
138 for ( ; treex
.NEXT
; treex
= *(treex
.NEXT
))
139 if (treex
.ORIG
== orig
&& treex
.DEST
== dest
&& treex
.DIRECTION
== type
)
146 res
= stm_newTree(treex
.NEXT
);
151 res
->DIRECTION
= type
;
157 /*}}}************************************************************************/
158 /*{{{ stm_setDelayNSlope() */
161 /****************************************************************************/
162 static void stm_setDelayNSlope(stm_tree4cache
*tree
, double delay
,
169 /*}}}************************************************************************/
170 /*{{{ stm_updateCacheFromTree() */
173 /****************************************************************************/
174 static void stm_updateCacheFromTree(stm_tree4cache
*tree
,double inslope
)
176 stm_tree4cache
*treex
;
178 for (treex
= tree
; tree
; tree
= tree
->NEXT
)
182 timing_function
*fct
;
188 switch (stm_gettimingfunction_and_signalcapa(treex
->DEST
,&fct
,&capa
))
192 cur
= stm_getCurrent(fct
);
193 slope
= stm_getTreeSlope(tree
,treex
->ORIG
);
194 inslope
= (slope
> 0.0) ? slope
: inslope
;
196 mode
= stm_thresholdOK(tbl
,inslope
,capa
, 20);
197 stm_storeInTable(&tbl
, inslope
, capa
, treex
->DELAY
, mode
);
200 stm_storeInTable(&tbl
, inslope
, capa
, treex
->SLOPE
, mode
);
209 /*}}}************************************************************************/
210 /*{{{ stm_getTreeSlope() */
213 /****************************************************************************/
214 static double stm_getTreeSlope(stm_tree4cache
*tree
, char *orig
)
216 for ( ; tree
; tree
= tree
->NEXT
)
217 if (tree
->DEST
== orig
)
222 /*}}}************************************************************************/
223 /*{{{ SET_DELAY_AND_SLOPE() */
226 /****************************************************************************/
227 void SET_DELAY_AND_SLOPE(char *in
, char *out
, char *direction
, double delay
,
232 res
= stm_addTree(APISTM_TREE
,in
,out
,direction
);
233 stm_setDelayNSlope(res
,delay
,slope
);
238 /*}}}************************************************************************/
239 /*{{{ stm_applyTree() */
242 /****************************************************************************/
243 static void stm_applyTree(double inslope
)
245 stm_updateCacheFromTree(APISTM_TREE
,inslope
);
246 APISTM_TREE
= stm_freeAllTree(APISTM_TREE
);
249 /*}}}************************************************************************/
250 /*}}}************************************************************************/
251 /*{{{ Extern Funtions */
252 /****************************************************************************/
253 /*{{{ High Level Functions */
255 /* CURRENT VSLOPE represents input slope setted by stm_thresholdOK */
256 /* CURRENT VLOAD represents output capa setted by stm_thresholdOK */
258 /****************************************************************************/
259 void stm_sup_storeDelay(double delay
)
261 stm_storeDelay(CURRENT
->VSLOPE
,CURRENT
->VLOAD
,delay
);
262 stm_applyTree(CURRENT
->VSLOPE
);
265 void stm_sup_storeSlope(double slope
)
267 stm_storeSlope(CURRENT
->VSLOPE
,CURRENT
->VLOAD
,slope
);
268 stm_applyTree(CURRENT
->VSLOPE
);
271 double stm_sup_getDelay()
273 return stm_getDelay(CURRENT
->VSLOPE
,CURRENT
->VLOAD
);
276 double stm_sup_getSlope()
278 return stm_getSlope(CURRENT
->VSLOPE
,CURRENT
->VLOAD
);
281 /*}}}************************************************************************/
283 /*{{{ stm_freeCurrent() */
286 /****************************************************************************/
287 static void stm_freeCurrent(void *x
)
289 stm_current
*current
;
294 stm_freeCurrent(current
->NEXT
);
295 stm_modtbl_destroy(current
->DELAY
);
296 stm_modtbl_destroy(current
->SLOPE
);
297 current
->NEXT
= NULL
;
302 /*}}}************************************************************************/
303 /*{{{ stm_newCurrent() */
306 /****************************************************************************/
307 stm_current
*stm_newCurrent(stm_current
*head
, char *insname
)
309 stm_current
*current
;
311 current
= mbkalloc(sizeof(struct stm_current
));
312 current
->NEXT
= head
;
313 current
->INS
= insname
;
314 current
->DELAY
= NULL
;
315 current
->SLOPE
= NULL
;
316 current
->VSLOPE
= 0.0;
317 current
->VLOAD
= 0.0;
318 current
->VDELAY
= 0.0;
319 current
->TRESRES
= 0;
324 /*}}}************************************************************************/
325 /*{{{ stm_getCurrentByName() */
328 /****************************************************************************/
329 stm_current
*stm_getCurrentByName(ptype_list
*ptype
, char *name
)
333 for (cur
= ptype
->DATA
; cur
&& cur
->INS
!= name
; cur
= cur
->NEXT
)
337 ptype
->DATA
= stm_newCurrent(ptype
->DATA
,name
);
344 /*}}}************************************************************************/
345 /*{{{ stm_getCurrent() */
348 /****************************************************************************/
349 stm_current
*stm_getCurrent(timing_function
*fct
)
354 ptypex
= stm_modfct_getSharedType(fct
,STM_CURRENT_TYPE
);
357 cur
= stm_modfct_addSharedType(fct
,STM_CURRENT_TYPE
,
358 stm_newCurrent(NULL
,fct
->INS
),
359 stm_freeCurrent
) -> DATA
;
361 cur
= stm_getCurrentByName(ptypex
,fct
->INS
);
366 /*}}}************************************************************************/
367 /*{{{ stm_createCache() */
370 /****************************************************************************/
371 void stm_createCache()
373 CURRENT
= stm_getCurrent(stm_get_current_arc());
375 printf("instance : %s\n",CURRENT
->INS
);
376 stm_displayTable("slope",CURRENT
->SLOPE
);
377 stm_displayTable("delay",CURRENT
->DELAY
);
381 /*}}}************************************************************************/
382 /*{{{ stm_delayThresholdOK() */
385 /****************************************************************************/
386 int stm_delayThresholdOK(double inslope
, double outload
, double threshold
)
391 printf("computing delay for slope %4.3g, load %4.3g\n",inslope
,outload
);
393 CURRENT
->TYPE
= STM_MODE_DELAY
;
394 CURRENT
->VSLOPE
= inslope
;
395 CURRENT
->VLOAD
= outload
;
396 CURRENT
->TRESRES
= stm_thresholdOK(CURRENT
->DELAY
,inslope
,outload
,
399 if (CURRENT
->TRESRES
&STM_THRESHOLD_NOMATCH
)
404 // printf("delai ok\n");
406 return CURRENT
->TRESRES
;
410 /*}}}************************************************************************/
411 /*{{{ stm_slopeThresholdOK() */
414 /****************************************************************************/
415 int stm_slopeThresholdOK(double inslope
, double outload
, double threshold
)
420 printf("computing slope for slope %g, load %g\n",inslope
,outload
);
422 CURRENT
->TYPE
= STM_MODE_SLOPE
;
423 CURRENT
->VSLOPE
= inslope
;
424 CURRENT
->VLOAD
= outload
;
425 CURRENT
->TRESRES
= stm_thresholdOK(CURRENT
->SLOPE
,inslope
,outload
,
428 if (CURRENT
->TRESRES
& STM_THRESHOLD_NOMATCH
)
433 printf("slope ok\n");
435 return CURRENT
->TRESRES
;
439 /*}}}************************************************************************/
440 /*{{{ stm_storeDelay() */
443 /****************************************************************************/
444 void stm_storeDelay(double inslope
, double outload
, double delay
)
446 stm_storeInTable( &(CURRENT
->DELAY
),inslope
,outload
,delay
,
447 (CURRENT
->TRESRES
)&STM_THRESHOLD_MATCH_XY
);
449 stm_displayTable(CURRENT
->DELAY
);
453 /*}}}************************************************************************/
454 /*{{{ stm_storeSlope() */
457 /****************************************************************************/
458 void stm_storeSlope(double inslope
, double outload
, double slope
)
461 printf("inserting %g,%g,%g\n",inslope
,outload
,slope
);
463 stm_storeInTable(&(CURRENT
->SLOPE
),inslope
,outload
,slope
,
464 (CURRENT
->TRESRES
)&STM_THRESHOLD_MATCH_XY
);
466 stm_displayTable(CURRENT
->SLOPE
);
470 /*}}}************************************************************************/
471 /*{{{ stm_getDelay() */
474 /****************************************************************************/
475 double stm_getDelay(double inslope
, double outload
)
477 return stm_getValue(CURRENT
->DELAY
,inslope
,outload
,stm_modtbl_delay
);
480 /*}}}************************************************************************/
481 /*{{{ stm_getSlope() */
484 /****************************************************************************/
485 double stm_getSlope(double inslope
, double outload
)
487 return stm_getValue(CURRENT
->SLOPE
,inslope
,outload
,stm_modtbl_slew
);
490 /*}}}************************************************************************/
491 /*{{{ stm_printVariation() */
494 /****************************************************************************/
495 void stm_printVariation(FILE *fp
, double real
, double found
)
497 fprintf(fp
,"real : %g",real
);
498 fprintf(fp
,",found : %g",found
);
499 fprintf(fp
,",variation : %3.1f%%\n",100*(real
-found
)/real
);
502 /*}}}************************************************************************/
503 /*}}}************************************************************************/
504 /*{{{ Static functions */
505 /****************************************************************************/
506 /*{{{ stm_getValue() */
509 /****************************************************************************/
510 static double stm_getValue(timing_table
*table
, double inslope
,
512 float (*func
)(timing_table
*, float, float))
514 // stm_displayTable(table);
515 if (CURRENT
->TRESRES
== STM_THRESHOLD_MATCH_XY
)
518 x
= stm_findIndex(table
->XRANGE
,inslope
,table
->NX
);
519 y
= stm_findIndex(table
->YRANGE
,outload
,table
->NY
);
520 return table
->SET2D
[x
][y
];
523 return stm_interpol(table
,inslope
,outload
,func
,CURRENT
->TRESRES
);
526 /*}}}************************************************************************/
527 /*{{{ stm_interpol() */
530 /****************************************************************************/
531 static double stm_interpol(timing_table
*table
, double inslope
,
533 float (*func
)(timing_table
*, float, float),
536 float **set2D
, set1D
[1024], res
, *xrange
;
537 int nx
, x
= -1, y
= -1, i
;
540 set2D
= table
->SET2D
;
542 xrange
= table
->XRANGE
;
545 y
= (table
->NY
== 1) ? 0 : (type
&STM_THRESHOLD_MATCH_Y
)
546 ? stm_findIndex(table
->YRANGE
,outload
,table
->NY
): y
;
547 x
= (table
->NX
== 1) ? 0 : (type
&STM_THRESHOLD_MATCH_X
)
548 ? stm_findIndex(table
->XRANGE
,inslope
,table
->NX
) : x
;
552 for (i
= 0; i
< table
->NX
; i
++)
553 set1D
[i
] = set2D
[i
][y
];
555 table
->SET1D
= set1D
;
560 table
->SET1D
= set2D
[x
];
561 table
->NX
= table
->NY
;
562 table
->XRANGE
= table
->YRANGE
;
563 table
->XTYPE
= STM_LOAD
;
566 res
= (*func
)(table
,outload
,inslope
);
567 table
->SET2D
= set2D
;
570 table
->XRANGE
= xrange
;
577 for (i = 0; i < table->NX; i ++)
578 set1D[i] = set2D[i][0];
580 table->SET1D = set1D;
582 else if (table->NX == 1)
585 table->SET1D = set2D[0];
586 table->NX = table->NY;
588 res = (*func)(table,outload,inslope);
589 table->SET2D = set2D;
598 /*}}}************************************************************************/
599 /*{{{ stm_thresholdOK() */
602 /****************************************************************************/
603 static int stm_thresholdOK(timing_table
*table
, double inslope
,
604 double outload
, double threshold
)
606 int bx
, ax
, by
, ay
, x
, y
, res
;
607 double x0
, x1
, y0
, y1
;
611 x
= stm_getBeforeAndAfter(table
->XRANGE
,table
->NX
,inslope
,&bx
,&ax
);
612 y
= stm_getBeforeAndAfter(table
->YRANGE
,table
->NY
,outload
,&by
,&ay
);
618 res
= STM_THRESHOLD_MATCH_XY
;
619 if (table
->SET2D
[bx
][by
] == STM_NOVALUE
)
620 res
|= STM_THRESHOLD_NOMATCH
;
624 res
|= STM_THRESHOLD_MATCH_X
;
625 if (ay
== table
->NY
|| by
== -1)
626 res
|= STM_THRESHOLD_NOMATCH
;
629 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,0);
630 if ( stm_thresholdTest(x0
,x1
,outload
,y0
,y1
) > threshold
)
631 res
|= STM_THRESHOLD_NOMATCH
;
633 res
|= STM_THRESHOLD_MATCH
;
638 res
|= STM_THRESHOLD_MATCH_Y
;
639 if (ax
== table
->NX
|| bx
== -1)
640 res
|= STM_THRESHOLD_NOMATCH
;
643 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,1);
644 if ( stm_thresholdTest(x0
,x1
,inslope
,y0
,y1
) > threshold
)
645 res
|= STM_THRESHOLD_NOMATCH
;
647 res
|= STM_THRESHOLD_MATCH
;
653 if (ax
== table
->NX
|| ay
== table
->NY
|| by
== -1 || bx
== -1)
654 res
= STM_THRESHOLD_NOMATCH
;
657 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,0);
658 if ( stm_thresholdTest(x0
,x1
,outload
,y0
,y1
) > threshold
)
659 res
= STM_THRESHOLD_NOMATCH
;
662 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,1);
663 if ( stm_thresholdTest(x0
,x1
,inslope
,y0
,y1
) > threshold
)
664 res
= STM_THRESHOLD_NOMATCH
;
667 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,2);
668 if ( stm_thresholdTest(x0
,x1
,outload
,y0
,y1
) > threshold
)
669 res
= STM_THRESHOLD_NOMATCH
;
672 stm_getVar(table
,&x0
,&x1
,&y0
,&y1
,bx
,ax
,by
,ay
,3);
673 if ( stm_thresholdTest(x0
,x1
,inslope
,y0
,y1
) > threshold
)
674 res
= STM_THRESHOLD_NOMATCH
;
676 res
|= STM_THRESHOLD_MATCH
;
684 res
= STM_THRESHOLD_NOMATCH
;
687 printf("test res = %x\n",res
);
692 /*}}}************************************************************************/
693 /*{{{ stm_getVar() */
696 /****************************************************************************/
697 static void stm_getVar(timing_table
*table
, double *x0
, double *x1
,
698 double *y0
, double *y1
, int bx
, int ax
, int by
,
704 *x0
= table
->YRANGE
[by
];
705 *x1
= table
->YRANGE
[ay
];
706 *y0
= table
->SET2D
[bx
][by
];
707 *y1
= table
->SET2D
[bx
][ay
];
710 *x0
= table
->XRANGE
[bx
];
711 *x1
= table
->XRANGE
[ax
];
712 *y0
= table
->SET2D
[bx
][by
];
713 *y1
= table
->SET2D
[ax
][by
];
716 *x0
= table
->YRANGE
[by
];
717 *x1
= table
->YRANGE
[ay
];
718 *y0
= table
->SET2D
[ax
][by
];
719 *y1
= table
->SET2D
[ax
][ay
];
722 *x0
= table
->XRANGE
[bx
];
723 *x1
= table
->XRANGE
[ax
];
724 *y0
= table
->SET2D
[bx
][ay
];
725 *y1
= table
->SET2D
[ax
][ay
];
730 /*}}}************************************************************************/
731 /*{{{ stm_thresholdTest() */
734 /****************************************************************************/
735 static double stm_thresholdTest(double x0
, double x1
, double x
,
736 double y0
, double y1
)
738 double res
, angle
,X0
, Y0
, X
, Y
, a
;
740 if (y0
== STM_NOVALUE
|| y1
== STM_NOVALUE
)
749 angle
= atan(a
)/(M_PI
/2);
750 Y
= log(pow(angle
,2));
751 X
= (2*(x
-x0
)/(x1
-x0
) - 1) * Y
;
752 res
= exp(-pow(X
,2)) * 100 * sqrt(angle
);
754 printf("angle : %4.2f° ",angle
*90);
755 printf("threshold : %4.2f%%\n",res
);
761 /*}}}************************************************************************/
762 /*{{{ stm_getBeforeAndAfter() */
765 /****************************************************************************/
766 static int stm_getBeforeAndAfter(float *range
, int max
, double value
,
767 int *before
, int *after
)
774 for (i
= 0; i
< max
; i
++)
776 if (isInf(value
,range
[i
]))
779 if ((res
= isEqual(range
[i
],value
)))
785 printf("value %g, before %d %g, after %d %g %s\n",value
,
786 *before
,range
[*before
],*after
,range
[*after
],(res
)?"OK":"NOT OK");
792 /*}}}************************************************************************/
793 /*{{{ stm_storeInTable() */
796 /****************************************************************************/
797 static void stm_storeInTable(timing_table
**curtable
, double inslope
,
798 double outload
, double delay
, int mode
)
800 timing_table
*restable
, *table
;
801 int i
, j
, x
, y
, dx
, dy
;
807 if (table == CURRENT->SLOPE)
809 printf("before adding------------------------------------------------\n");
810 stm_displayTable(table);
813 if (mode
== STM_THRESHOLD_MATCH_XY
)
815 x
= stm_findIndex(table
->XRANGE
,inslope
, table
->NX
);
816 y
= stm_findIndex(table
->YRANGE
,outload
, table
->NY
);
817 table
->SET2D
[x
][y
] = delay
;
820 // stm_fillTbl(restable,x,y,type);
826 case STM_THRESHOLD_MATCH_X
:
827 restable
= stm_modtbl_create(table
->NX
,table
->NY
+ 1,
828 STM_INPUT_SLEW
,STM_LOAD
);
829 x
= stm_findIndex(table
->XRANGE
,inslope
, table
->NX
);
830 y
= stm_copyRangeAndInsert(table
->YRANGE
, restable
->YRANGE
,
831 outload
,restable
->NY
);
833 restable
->XRANGE
= table
->XRANGE
;
834 table
->XRANGE
= NULL
;
836 case STM_THRESHOLD_MATCH_Y
:
837 restable
= stm_modtbl_create(table
->NX
+ 1,table
->NY
,
838 STM_INPUT_SLEW
,STM_LOAD
);
839 x
= stm_copyRangeAndInsert(table
->XRANGE
, restable
->XRANGE
,
840 inslope
,restable
->NX
);
841 y
= stm_findIndex(table
->YRANGE
,outload
, table
->NY
);
843 restable
->YRANGE
= table
->YRANGE
;
844 table
->YRANGE
= NULL
;
847 restable
= stm_modtbl_create(table
->NX
+ 1,table
->NY
+ 1,
848 STM_INPUT_SLEW
,STM_LOAD
);
849 x
= stm_copyRangeAndInsert(table
->XRANGE
,
851 inslope
,restable
->NX
);
852 y
= stm_copyRangeAndInsert(table
->YRANGE
,
854 outload
,restable
->NY
);
860 for (j
= 0; j
< restable
->NY
; j
++)
863 if (j
== y
&& mode
!= STM_THRESHOLD_MATCH_Y
)
868 for (i
= 0; i
< restable
->NX
; i
++)
870 if (i
== x
&& mode
!= STM_THRESHOLD_MATCH_X
)
875 restable
->SET2D
[i
][j
] = table
->SET2D
[i
- dx
][j
- dy
];
878 restable
->SET2D
[x
][y
] = delay
;
879 // stm_fillTbl(restable,x,y,type);
880 stm_modtbl_destroy(table
);
884 restable
= stm_modtbl_create(STM_CACHE_SIZE
,STM_CACHE_SIZE
,
885 STM_INPUT_SLEW
,STM_LOAD
);
886 stm_modtbl_setXrangeval(restable
,0,inslope
);
887 stm_modtbl_setYrangeval(restable
,0,outload
);
888 stm_modtbl_set2Dval(restable
,0,0,delay
);
890 *curtable
= restable
;
893 if (table == CURRENT->SLOPE)
895 printf("after complete\n");
896 stm_displayTable(restable);
897 printf("-------------------------------------------------------------\n");
902 /*}}}************************************************************************/
903 /*{{{ stm_findIndex() */
906 /****************************************************************************/
907 static int stm_findIndex(float *range
, double value
, int size
)
911 for (i
= 0; i
< size
; i
++)
912 if (isEqual(range
[i
],value
))
918 /*}}}************************************************************************/
919 /*{{{ stm_copyRangeAndInsert() */
921 /* return index of new value */
923 /****************************************************************************/
924 static int stm_copyRangeAndInsert(float *range
, float *new, double value
,
929 for (i
= 0; i
< size
-1 && range
[i
] < value
; i
++)
933 for (i
= res
+ 1; i
< size
; i
++)
939 /*}}}************************************************************************/
940 /*{{{ stm_getarcdef() */
943 /****************************************************************************/
944 static char *stm_getarcdef(char *ins
, char *local
)
948 sprintf(temp
,"%s.%s",ins
, local
);
950 return namealloc(temp
);
953 /*}}}************************************************************************/
954 /*{{{ stm_gettimingfunction_and_signalcapa() */
957 /****************************************************************************/
958 static int stm_gettimingfunction_and_signalcapa(char *output
,
959 timing_function
**tf
,
962 timing_function
*fct
;
964 timing_model
*tmodel
;
967 fct
= stm_get_current_arc();
968 modelname
= stm_getarcdef(fct
->INS
, fct
->LOCALNAME
);
970 tmodel
= stm_getmodel (LATEST_GNS_RUN
->FIGNAME
, modelname
);
973 avt_errmsg(STM_API_ERRMSG
, "001", AVT_ERROR
, modelname
);
974 //fprintf(stderr,"stm model '%s' does not exist\n",modelname);
977 if (tmodel
->UTYPE
!= STM_MOD_MODFCT
)
979 avt_errmsg(STM_API_ERRMSG
, "002", AVT_ERROR
, modelname
);
980 // fprintf(stderr,"stm model '%s' is not a function\n",modelname);
983 *tf
= tmodel
->UMODEL
.FUNCTION
;
984 ls
= gen_corresp_sig(gen_makesignalname(output
),CUR_CORRESP_TABLE
);
990 if (ls
->PRCN
!= NULL
)
991 *capa
= ls
->PRCN
->RCCAPA
*1e3
;
998 /*}}}************************************************************************/
999 /*{{{ Filling tables utilities */
1000 /****************************************************************************/
1001 /*{{{ stm_fillTbl() */
1004 /****************************************************************************/
1005 static void stm_fillTbl(timing_table
*tbl
, int xind
, int yind
, char type
)
1007 int beg
, end
, up
,down
;
1012 stm_fillFindLeftnRight(tbl
,xind
,yind
,&beg
,&end
);
1013 stm_fillLine(tbl
,beg
,xind
,yind
);
1014 stm_fillLine(tbl
,xind
,end
,yind
);
1015 stm_fillNewCol(tbl
,xind
);
1018 stm_fillFindUpnDown(tbl
,xind
,yind
,&up
,&down
);
1019 stm_fillCol(tbl
,up
,yind
,xind
);
1020 stm_fillCol(tbl
,yind
,down
,xind
);
1021 stm_fillNewLine(tbl
,yind
);
1024 stm_fillNewCol(tbl
,xind
);
1025 stm_fillNewLine(tbl
,yind
);
1028 stm_fillFindLeftnRight(tbl
,xind
,yind
,&beg
,&end
);
1029 stm_fillLine(tbl
,beg
,xind
,yind
);
1030 stm_fillLine(tbl
,xind
,end
,yind
);
1031 stm_fillFindUpnDown(tbl
,xind
,yind
,&up
,&down
);
1032 stm_fillCol(tbl
,up
,yind
,xind
);
1033 stm_fillCol(tbl
,yind
,down
,xind
);
1038 /*}}}************************************************************************/
1039 /*{{{ stm_fillFindUpnDown() */
1042 /****************************************************************************/
1043 static void stm_fillFindUpnDown(timing_table
*tbl
, int xind
, int yind
,
1050 for (i
= 0; i
< tbl
->NY
; i
++)
1051 if (tbl
->SET2D
[xind
][i
] != STM_NOVALUE
)
1063 /*}}}************************************************************************/
1064 /*{{{ stm_fillCol() */
1066 /* fill a line like this : X */
1071 /****************************************************************************/
1072 static void stm_fillCol(timing_table
*tbl
, int up
, int down
, int xind
)
1074 if (up
!= -1 && down
!= -1)
1076 float x0
, x1
, y0
, y1
, x
;
1079 x0
= tbl
->YRANGE
[up
];
1080 y0
= tbl
->SET2D
[xind
][up
];
1081 x1
= tbl
->YRANGE
[down
];
1082 y1
= tbl
->SET2D
[xind
][down
];
1083 for (i
= up
; i
< down
; i
++)
1086 if (stm_thresholdTest(x0
,x1
,x
,y0
,y1
) < THRESHOLD
)
1087 tbl
->SET2D
[xind
][i
] = stm_modtbl_interpol1DCalc(x0
,x1
,y0
,y1
,x
);
1093 /*}}}************************************************************************/
1094 /*{{{ stm_fillNewLine() */
1096 /* fill a new column like this : XXX */
1100 /****************************************************************************/
1101 static void stm_fillNewLine(timing_table
*tbl
,int yind
)
1103 if (yind
!= 0 && yind
!= tbl
->NY
-1)
1105 float x0
, x1
, y0
, y1
, x
;
1108 for (i
= 0; i
< tbl
->NX
; i
++)
1109 if ( tbl
->SET2D
[i
][yind
-1] != STM_NOVALUE
1110 && tbl
->SET2D
[i
][yind
+1] != STM_NOVALUE
)
1112 x0
= tbl
->YRANGE
[yind
-1];
1113 y0
= tbl
->SET2D
[i
][yind
-1];
1114 x1
= tbl
->YRANGE
[yind
+1];
1115 y1
= tbl
->SET2D
[i
][yind
+1];
1117 if (stm_thresholdTest(x0
,x1
,x
,y0
,y1
) < THRESHOLD
)
1118 tbl
->SET2D
[i
][yind
] = stm_modtbl_interpol1DCalc(x0
,x1
,y0
,y1
,x
);
1123 /*}}}************************************************************************/
1124 /*{{{ stm_fillFindLeftnRight() */
1127 /****************************************************************************/
1128 static void stm_fillFindLeftnRight(timing_table
*tbl
, int xind
, int yind
,
1135 for (i
= 0; i
< tbl
->NX
; i
++)
1136 if (tbl
->SET2D
[i
][yind
] != STM_NOVALUE
)
1148 /*}}}************************************************************************/
1149 /*{{{ stm_fillLine() */
1151 /* fill a line like this : X.....X */
1153 /****************************************************************************/
1154 static void stm_fillLine(timing_table
*tbl
, int beg
, int end
, int yind
)
1156 if (beg
!= -1 && end
!= -1)
1158 float x0
, x1
, y0
, y1
, x
;
1161 x0
= tbl
->XRANGE
[beg
];
1162 y0
= tbl
->SET2D
[beg
][yind
];
1163 x1
= tbl
->XRANGE
[end
];
1164 y1
= tbl
->SET2D
[end
][yind
];
1165 for (i
= beg
; i
< end
; i
++)
1168 if (stm_thresholdTest(x0
,x1
,x
,y0
,y1
) < THRESHOLD
)
1169 tbl
->SET2D
[i
][yind
] = stm_modtbl_interpol1DCalc(x0
,x1
,y0
,y1
,x
);
1175 /*}}}************************************************************************/
1176 /*{{{ stm_fillNewCol() */
1178 /* fill a new column like this : X.X */
1181 /****************************************************************************/
1182 static void stm_fillNewCol(timing_table
*tbl
,int xind
)
1184 if (xind
!= 0 && xind
!= tbl
->NX
-1)
1186 float x0
, x1
, y0
, y1
, x
;
1189 for (i
= 0; i
< tbl
->NY
; i
++)
1190 if ( tbl
->SET2D
[xind
-1][i
] != STM_NOVALUE
1191 && tbl
->SET2D
[xind
+1][i
] != STM_NOVALUE
)
1193 x0
= tbl
->XRANGE
[xind
-1];
1194 y0
= tbl
->SET2D
[xind
-1][i
];
1195 x1
= tbl
->XRANGE
[xind
+1];
1196 y1
= tbl
->SET2D
[xind
+1][i
];
1198 if (stm_thresholdTest(x0
,x1
,x
,y0
,y1
) < THRESHOLD
)
1199 tbl
->SET2D
[xind
][i
] = stm_modtbl_interpol1DCalc(x0
,x1
,y0
,y1
,x
);
1204 /*}}}************************************************************************/
1205 /*}}}************************************************************************/
1206 /*}}}************************************************************************/
1207 /*{{{ stm_displayRange() */
1210 /****************************************************************************/
1211 void stm_displayRange(timing_table
*table
)
1215 int i
, j
, k
, nb
= 8, x
;
1217 for (k
= 0; k
<= (table
->NX
)/nb
; k
++)
1219 x
= k
*nb
+ ((k
< (table
->NX
)/nb
) ? nb
: (table
->NX
- k
*nb
)%nb
);
1220 printf("| delay |");
1221 for (i
= k
*nb
; i
< x
; i
++)
1222 printf(" %+e",table
->XRANGE
[i
]);
1226 for (j
= 0; j
< table
->NY
; j
++)
1227 printf(" %+e",table
->YRANGE
[j
]);
1233 /*}}}************************************************************************/
1234 /*{{{ stm_test_threshold() */
1237 /****************************************************************************/
1238 void stm_test_threshold()
1240 double res
, y
, x0
, x1
, y0
, y1
, x
, X
, Y
, nb
;
1243 f
= fopen("plot.dat","wt");
1250 for (y
= y0
; y
<= y1
; y
+= (y1
-y0
)/nb
)
1252 for (x
= x0
; x
<= x1
; x
+= (x1
-x0
)/nb
)
1255 // Y = log(pow(Y,(1.0-1/y)));
1257 X
= (2*(x
-x0
)/(x1
-x0
) - 1);
1259 res
= exp(-pow(X
,2)) * 100 * pow(y
/90,1.0/3);
1260 // fprintf(f,"%4.3g %4.1f %7.2f\n",x,y,res);
1269 /*}}}************************************************************************/
1270 /*{{{ Math Function */
1271 /****************************************************************************/
1272 /*{{{ stm_arround() */
1275 /****************************************************************************/
1276 double stm_arround(double a
, double pres
)
1282 cut
= (long)(res
+ 0.5);
1288 /*}}}************************************************************************/
1292 /****************************************************************************/
1293 static int isEqual(float a
, float b
)
1299 return ( fabs((b
/a
) - 1) < STM_ACCURACY
);
1301 return ( fabs((a
/b
) - 1) < STM_ACCURACY
);
1304 /*}}}************************************************************************/
1308 /****************************************************************************/
1309 static int isInf(float a
, float b
)
1317 /*}}}************************************************************************/
1318 /*}}}************************************************************************/