1 /*
2  *   Copyright (C) 1989-1991 Yale University
3  *   Copyright (C) 2015 Staf Verhaegen <staf@stafverhaegen.be>
4  *
5  *   This work is distributed in the hope that it will be useful; you can
6  *   redistribute it and/or modify it under the terms of the
7  *   GNU General Public License as published by the Free Software Foundation;
8  *   either version 2 of the License,
9  *   or any later version, on the following conditions:
10  *
11  *   (a) YALE MAKES NO, AND EXPRESSLY DISCLAIMS
12  *   ALL, REPRESENTATIONS OR WARRANTIES THAT THE MANUFACTURE, USE, PRACTICE,
13  *   SALE OR
14  *   OTHER DISPOSAL OF THE SOFTWARE DOES NOT OR WILL NOT INFRINGE UPON ANY
15  *   PATENT OR
16  *   OTHER RIGHTS NOT VESTED IN YALE.
17  *
18  *   (b) YALE MAKES NO, AND EXPRESSLY DISCLAIMS ALL, REPRESENTATIONS AND
19  *   WARRANTIES
20  *   WHATSOEVER WITH RESPECT TO THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
21  *   INCLUDING,
22  *   BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
23  *   PARTICULAR
24  *   PURPOSE.
25  *
26  *   (c) LICENSEE SHALL MAKE NO STATEMENTS, REPRESENTATION OR WARRANTIES
27  *   WHATSOEVER TO
28  *   ANY THIRD PARTIES THAT ARE INCONSISTENT WITH THE DISCLAIMERS BY YALE IN
29  *   ARTICLE
30  *   (a) AND (b) above.
31  *
32  *   (d) IN NO EVENT SHALL YALE, OR ITS TRUSTEES, DIRECTORS, OFFICERS,
33  *   EMPLOYEES AND
34  *   AFFILIATES BE LIABLE FOR DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR
35  *   INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER YALE SHALL BE
36  *   ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE
37  *   POSSIBILITY OF THE FOREGOING.
38  *
39  */
40 
41 /* -----------------------------------------------------------------
42 FILE:	    feedest.c
43 DESCRIPTION:feedthru estimation.
44 CONTENTS:   feedest()
45 	    re_estimate_feed_penalty( )
46 	    estimate_pass_thru_penalty( row1 , row2 )
47 		INT row1 , row2 ;
48 	    update_feedest( net )
49 		INT net ;
50 	    free_up_feedest_malloc()
51 	    update_segment_data( segptr )
52 		SEGBOXPTR segptr ;
53 	    PINBOXPTR makeSTpt( net , ptr1 , ptr2 )
54 		INT net ;
55 		PINBOXPTR ptr1 , ptr2 ;
56 	    SEGBOXPTR makeseg( lowptr , highptr )
57 		PINBOXPTR lowptr , highptr ;
58 	    dbg_cost()
59 DATE:	    Mar 27, 1989
60 REVISIONS:  Sat Dec 15 22:08:21 EST 1990 - modified pinloc values
61 		so that it will always be positive.
62 	    Tue Mar 12 17:08:44 CST 1991 - added back missing
63 		computation.
64 ----------------------------------------------------------------- */
65 
66 #define FEEDS_VARS
67 
68 #include <string.h>
69 #include "standard.h"
70 #include "groute.h"
71 #include "feeds.h"
72 #include "main.h"
73 
74 /* global definitions */
75 INT *rowfeed_penaltyG ;
76 
77 extern BOOL absolute_minimum_feedsG ;
78 
79 /* static definitions */
80 static DOUBLE *fd_estimateS ;
81 static INT *min_feedS ;
82 static INT *row_flagS ;
83 static INT chip_width_penaltyS ;
84 static INT *est_min_ratioS ;
85 
86 void estimate_pass_thru_penalty(INT row1 , INT row2 );
87 
feedest()88 void feedest()
89 {
90 
91   DOUBLE ratio ;
92   INT net , row , toprow , botrow, maxdesire ;
93   DBOXPTR dimptr ;
94   PINBOXPTR ptr ;
95 
96   fd_estimateS = (DOUBLE *)Ysafe_calloc( numChansG + 1, sizeof(DOUBLE) ) ;
97   min_feedS = (INT *)Ysafe_calloc( numChansG + 1, sizeof(INT) ) ;
98   row_flagS = (INT *)Ysafe_calloc( numChansG + 1, sizeof(INT) ) ;
99   rowfeed_penaltyG = (INT *)Ysafe_malloc( ( numChansG + 1 ) * sizeof(INT) ) ;
100   memset(rowfeed_penaltyG, 0, ( numChansG + 1 ) * sizeof(INT) ); // FIXME: If not clearing, result is non-determinsitic. Figure out why
101   est_min_ratioS = (INT *)Ysafe_malloc( numChansG * sizeof(INT) ) ;
102 
103   maxdesire = barrayG[1]->desire ;
104   for( row = 2 ; row <= numRowsG ; row++ ) {
105     if( maxdesire < barrayG[row]->desire ) {
106       maxdesire = barrayG[row]->desire ;
107     }
108   }
109 
110   ratio = (DOUBLE)(maxdesire) / (DOUBLE)( barrayG[numRowsG]->bycenter -
111       barrayG[1]->bycenter + rowHeightG ) ;
112   ratio = 1.0 / ratio ;  /* to fix Kai-Win's bug */
113 
114   if( absolute_minimum_feedsG ) {
115     if( ratio >= 1.0 ) {
116       chip_width_penaltyS = barrayG[numRowsG]->bycenter -
117         barrayG[1]->bycenter + rowHeightG ;
118     } else {
119       chip_width_penaltyS = maxdesire ;
120     }
121   } else {
122     /* chip_width_penaltyS = 2.0 * (DOUBLE) rowHeightG ; */
123     chip_width_penaltyS = 6.9 * (DOUBLE) rowHeightG ;
124   }
125 
126 
127 
128   if( !absolute_minimum_feedsG ) {
129     add_Lcorner_feedG = TRUE ;
130     /* Carl */
131     for( row = 1 ; row <= numRowsG ; row++ ) {
132       if( FeedInRowG[row] == 0 ) {
133         add_Lcorner_feedG = FALSE ;
134         break ;
135       }
136     }
137     /* Carl */
138   } else {
139     add_Lcorner_feedG = FALSE ;
140   }
141   for( net = 1 ; net <= numnetsG ; net++ ) {
142     dimptr = netarrayG[net] ;
143     if( !(dimptr->pins) ) {
144       continue ;
145     }
146     switch( dimptr->numpins ) {
147       case 0 :
148       case 1 :
149         break ;
150       case 2 :
151         ptr = dimptr->pins ;
152         toprow = ptr->row ;
153         botrow = ptr->next->row ;
154         if( toprow > botrow ) {
155           for( row = botrow + 1 ; row < toprow ; row++ ) {
156             fd_estimateS[row]++ ;
157             min_feedS[row]++ ;
158           }
159           if( ABS( ptr->xpos - ptr->next->xpos ) >=
160               average_feed_sepG ) {
161             fd_estimateS[botrow] += 0.5 ;
162             fd_estimateS[toprow] += 0.5 ;
163           }
164         } else if( toprow < botrow ) {
165           for( row = toprow + 1 ; row < botrow ; row++ ) {
166             fd_estimateS[row]++ ;
167             min_feedS[row]++ ;
168           }
169           if( ABS( ptr->xpos - ptr->next->xpos ) >=
170               average_feed_sepG ) {
171             fd_estimateS[botrow] += 0.5 ;
172             fd_estimateS[toprow] += 0.5 ;
173           }
174         }
175         row_flagS[botrow] = 0 ;
176         row_flagS[toprow] = 0 ;
177         break ;
178       case 3 :
179       case 4 :
180       case 5 :
181         ptr = dimptr->pins ;
182         toprow = botrow = ptr->row ;
183         row_flagS[toprow] = 1 ;
184         for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
185           row = ptr->row ;
186           if( row < botrow ) {
187             botrow = row ;
188           }
189           if( row > toprow ) {
190             toprow = row ;
191           }
192           row_flagS[row] = 1 ;
193         }
194         for( row = botrow + 1 ; row < toprow ; row++ ) {
195           if( row_flagS[row] ) {
196             fd_estimateS[row]++ ;
197             row_flagS[row] = 0 ;
198           } else {
199             fd_estimateS[row] += 1.5 ;
200             min_feedS[row]++ ;
201           }
202         }
203         if( toprow > botrow ) {
204           fd_estimateS[botrow] += 0.5 ;
205           fd_estimateS[toprow] += 0.5 ;
206         }
207         row_flagS[botrow] = 0 ;
208         row_flagS[toprow] = 0 ;
209         break ;
210       default :
211         ptr = dimptr->pins ;
212         toprow = botrow = ptr->row ;
213         row_flagS[toprow] = 1 ;
214         for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
215           row = ptr->row ;
216           if( row < botrow ) {
217             botrow = row ;
218           }
219           if( row > toprow ) {
220             toprow = row ;
221           }
222           row_flagS[row] = 1 ;
223         }
224         for( row = botrow + 1 ; row < toprow ; row++ ) {
225           if( row_flagS[row] ) {
226             fd_estimateS[row]++ ;
227             row_flagS[row] = 0 ;
228           } else {
229             fd_estimateS[row] += 1.5 ;
230             min_feedS[row]++ ;
231           }
232         }
233         if( toprow > botrow ) {
234           fd_estimateS[botrow]++ ;
235           fd_estimateS[toprow]++ ;
236         }
237         row_flagS[botrow] = 0 ;
238         row_flagS[toprow] = 0 ;
239         break ;
240     }
241   }
242 
243   estimate_pass_thru_penalty( 1 , numRowsG ) ;
244 
245 }
246 
re_estimate_feed_penalty()247 void re_estimate_feed_penalty()
248 {
249 
250   INT i , n , row , row_rite , excess_fd , *old_penalty ;
251   DOUBLE ratio , factor ;
252   FEED_DATA *feedptr ;
253   CBOXPTR cellptr ;
254 
255   old_penalty = (INT *)Ysafe_malloc( numChansG * sizeof(INT) ) ;
256   for( row = 1 ; row <= numRowsG ; row++ ) {
257     old_penalty[row] = rowfeed_penaltyG[row] ;
258     feedptr = feedpptrG[row] ;
259     n = 0 ;
260     for( i = 1 ; i <= chan_node_noG ; i++ ) {
261       n += feedptr[i]->needed ;
262     }
263     fd_estimateS[row] = n ;
264   }
265   estimate_pass_thru_penalty( 1 , numRowsG ) ;
266 
267   if( !enough_built_in_feedG ) {
268     goto out ;
269   }
270   for( row = 1 ; row <= numRowsG ; row++ ) {
271     rowfeed_penaltyG[row] =
272       ( 2 * old_penalty[row] + 3 * rowfeed_penaltyG[row] ) / 5 ;
273     cellptr = carrayG[ pairArrayG[row][ pairArrayG[row][0] ] ] ;
274     row_rite = cellptr->cxcenter + cellptr->tileptr->right ;
275     if( fdWidthG > 0 ) {
276       excess_fd = fdcel_addedG[row] + 1 -
277         ( right_most_in_classG[ row_rite_classG[row] ] - row_rite ) /
278         fdWidthG;
279     } else {
280       excess_fd = fdcel_addedG[row] + 1 -
281         ( right_most_in_classG[ row_rite_classG[row] ] - row_rite ) ;
282     }
283     if( excess_fd <= 0 ) {
284       continue ;
285     }
286     ratio = (DOUBLE)(fdcel_addedG[row]) / (DOUBLE)(FeedInRowG[row]) ;
287     if( ratio <= 0.01 ) {
288       factor = 4 ;
289     } else if( ratio <= 0.03 ) {
290       factor = 8 ;
291     } else if( ratio <= 0.05 ) {
292       factor = 15 ;
293     } else if( ratio <= 0.08 ) {
294       factor = 25 ;
295     } else if( ratio <= 0.10 ) {
296       factor = 30 ;
297     } else if( ratio <= 0.20 ) {
298       factor = 40 ;
299     } else {
300       factor = 50 ;
301     }
302     rowfeed_penaltyG[row] += factor * ratio * (DOUBLE)(rowHeightG) ;
303   }
304   /*
305      fp = TWOPEN("vcost.dat", "a", ABORT ) ;
306      fprintf(fp, " row newcost oldcost\n" ) ;
307      for( row = 1 ; row <= numRowsG ; row++ ) {
308      fprintf(fp," %3d %7d %7d\n", row,
309      rowfeed_penaltyG[row], old_penalty[row] ) ;
310      }
311      TWCLOSE(fp) ;
312    */
313 out:
314   Ysafe_free( old_penalty );
315 }
316 
317 #ifdef Carl
estimate_pass_thru_penalty(INT row1,INT row2)318 void estimate_pass_thru_penalty(INT row1 , INT row2 )
319 {
320 
321   INT row ;
322   DOUBLE ratio ;
323   if( row1 < 1 ) {
324     row1 = 1 ;
325   }
326   if( row2 > numRowsG ) {
327     row2 = numRowsG ;
328   }
329   ratio = (DOUBLE) implicit_feed_count / (DOUBLE) TotRegPins ;
330   if( ratio > 0.0 ) {
331     ratio += 0.1 ;
332   }
333   if( ratio > 1.0 ) {
334     ratio = 1.0 ;
335   }
336   for( row = row1 ; row <= row2 ; row++ ) {
337     if( !absolute_minimum_feeds ) {
338       rowfeed_penaltyG[row] = (2.0 - ratio * 1.2) * rowHeightG ;
339     } else {
340       rowfeed_penaltyG[row] = chip_width_penaltyS ;
341     }
342   }
343 }
344 #else
345 
estimate_pass_thru_penalty(INT row1,INT row2)346 void estimate_pass_thru_penalty(INT row1 , INT row2 )
347 {
348 
349   INT row ;
350   DOUBLE actual , estimate , act_est_ratio ;
351   if( row1 < 1 ) {
352     row1 = 1 ;
353   }
354   if( row2 > numRowsG ) {
355     row2 = numRowsG ;
356   }
357 
358   for( row = row1 ; row <= row2 ; row++ ) {
359     actual = FeedInRowG[row] ;
360     estimate = fd_estimateS[row] ;
361     if( actual > min_feedS[row] && !absolute_minimum_feedsG ) {
362       if( estimate > 0.0 ) {
363         act_est_ratio = actual / estimate ;
364       } else {
365         act_est_ratio = INT_MAX ;
366         /*  fix by Carl 1/25/89  */
367       }
368       if( act_est_ratio >= 4 ) {
369         rowfeed_penaltyG[row] = rowHeightG * 0.3 ;
370       } else if( act_est_ratio >= 1.0 ) {
371         rowfeed_penaltyG[row] =
372           ( 0.9 - 0.2 * ( act_est_ratio - 1.0 ) ) * rowHeightG ;
373       } else if( act_est_ratio <= 0.5 ) {
374         rowfeed_penaltyG[row] = 6.9 * rowHeightG ;
375       } else {
376         rowfeed_penaltyG[row] =
377           ( 0.9 + 12.0 * ( 1.0 - act_est_ratio ) ) * rowHeightG ;
378       }
379     } else {
380       rowfeed_penaltyG[row] = chip_width_penaltyS ;
381     }
382   }
383 }
384 #endif
385 
386 
update_feedest(net)387 void update_feedest( net )
388   INT net ;
389 {
390 
391   DBOXPTR dimptr ;
392   SEGBOXPTR seg ;
393   PINBOXPTR ptr ;
394   INT row , toprow , botrow , row1 , row2 ;
395 
396 
397   dimptr = netarrayG[net] ;
398   if( !(dimptr->pins) ) {
399     return ;
400   }
401   switch( dimptr->numpins ) {
402     case 0 :
403     case 1 :
404     case 2 :
405       return ;
406     case 3 :
407     case 4 :
408     case 5 :
409       ptr = dimptr->pins ;
410       toprow = botrow = ptr->row ;
411       row_flagS[toprow] = 1 ;
412       for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
413         row = ptr->row ;
414         if( row < botrow ) {
415           botrow = row ;
416         }
417         if( row > toprow ) {
418           toprow = row ;
419         }
420         row_flagS[row] = 1 ;
421       }
422       for( row = botrow + 1 ; row < toprow ; row++ ) {
423         if( row_flagS[row] ) {
424           fd_estimateS[row]-- ;
425           row_flagS[row] = 0 ;
426         } else {
427           fd_estimateS[row] -= 1.5 ;
428         }
429       }
430       if( toprow > botrow ) {
431         fd_estimateS[botrow] -= 0.5 ;
432         fd_estimateS[toprow] -= 0.5 ;
433       }
434       row_flagS[botrow] = 0 ;
435       row_flagS[toprow] = 0 ;
436       break ;
437     default :
438       ptr = dimptr->pins ;
439       toprow = botrow = ptr->row ;
440       row_flagS[toprow] = 1 ;
441       for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
442         row = ptr->row ;
443         if( row < botrow ) {
444           botrow = row ;
445         }
446         if( row > toprow ) {
447           toprow = row ;
448         }
449         row_flagS[row] = 1 ;
450       }
451       for( row = botrow + 1 ; row < toprow ; row++ ) {
452         if( row_flagS[row] ) {
453           fd_estimateS[row]-- ;
454           row_flagS[row] = 0 ;
455         } else {
456           fd_estimateS[row] -= 1.5 ;
457         }
458       }
459       if( toprow > botrow ) {
460         fd_estimateS[botrow]-- ;
461         fd_estimateS[toprow]-- ;
462       }
463       row_flagS[botrow] = 0 ;
464       row_flagS[toprow] = 0 ;
465       break ;
466   }
467   for( seg = netsegHeadG[net]->next ; seg ; seg = seg->next ) {
468     row1 = seg->pin1ptr->row ;
469     row2 = seg->pin2ptr->row ;
470     if( row1 == row2 ) {
471       if( ABS( seg->pin1ptr->pinloc - seg->pin2ptr->pinloc ) <= 1 ) {
472         continue ;
473       } else {
474         fd_estimateS[row1]++ ;
475       }
476     } else {
477       for( row = row1 + 1 ; row < row2 ; row++ ) {
478         fd_estimateS[row]++ ;
479       }
480       if( seg->pin1ptr->pinloc < NEITHER ) {
481         fd_estimateS[row1]++ ;
482       }
483       if( seg->pin2ptr->pinloc > NEITHER ) {
484         fd_estimateS[row2]++ ;
485       }
486       if( add_Lcorner_feedG && seg->switchvalue != nswLINE ) {
487         fd_estimateS[row1] += 0.5 ;
488         fd_estimateS[row2] += 0.5 ;
489       }
490     }
491   }
492   for( ptr = steinerHeadG[net]->next; ptr ; ptr = ptr->next ) {
493     fd_estimateS[ ptr->row ]++ ;
494   }
495 
496   estimate_pass_thru_penalty( botrow , toprow ) ;
497 
498 }
499 
500 
free_up_feedest_malloc()501 void free_up_feedest_malloc()
502 {
503 
504   Ysafe_free( fd_estimateS ) ;
505   Ysafe_free( min_feedS ) ;
506   Ysafe_free( row_flagS ) ;
507   Ysafe_free( rowfeed_penaltyG ) ;
508   Ysafe_free( est_min_ratioS ) ;
509 }
510 
511 
update_segment_data(segptr)512 void update_segment_data( segptr )
513   SEGBOXPTR segptr ;
514 {
515   PINBOXPTR ptr1 , ptr2 ;
516 
517   ptr1 = segptr->pin1ptr ;
518   ptr2 = segptr->pin2ptr ;
519   segptr->flag = NEW ;
520   if( ptr1->row < ptr2->row ) {
521     segptr->pin1ptr = ptr1 ;
522     segptr->pin2ptr = ptr2 ;
523     if( ABS( ptr1->xpos - ptr2->xpos ) >= average_feed_sepG ) {
524       segptr->switchvalue = swL_up ;
525     } else {
526       segptr->switchvalue = nswLINE ;
527     }
528   } else if( ptr1->row > ptr2->row ) {
529     segptr->pin2ptr = ptr1 ;
530     segptr->pin1ptr = ptr2 ;
531     if( ABS( ptr1->xpos - ptr2->xpos ) >= average_feed_sepG ) {
532       segptr->switchvalue = swL_up ;
533     } else {
534       segptr->switchvalue = nswLINE ;
535     }
536   } else if( (INT) ptr1->pinloc == BOTCELL && (INT) ptr2->pinloc == TOPCELL ) {
537     segptr->pin1ptr = ptr1 ;
538     segptr->pin2ptr = ptr2 ;
539     segptr->switchvalue = nswLINE ;
540   } else if( (INT) ptr1->pinloc == TOPCELL && (INT) ptr2->pinloc == BOTCELL ) {
541     segptr->pin1ptr = ptr2 ;
542     segptr->pin2ptr = ptr1 ;
543     segptr->switchvalue = nswLINE ;
544   } else if( ptr1->xpos <= ptr2->xpos ) {
545     segptr->pin1ptr = ptr1 ;
546     segptr->pin2ptr = ptr2 ;
547     segptr->switchvalue = nswLINE ;
548   } else {
549     segptr->pin1ptr = ptr2 ;
550     segptr->pin2ptr = ptr1 ;
551     segptr->switchvalue = nswLINE ;
552   }
553 }
554 
555 
makeSTpt(net,ptr1,ptr2)556 PINBOXPTR makeSTpt( net , ptr1 , ptr2 )
557   INT net ;
558   PINBOXPTR ptr1 , ptr2 ;
559 {
560 
561   PINBOXPTR ptr ;
562 
563   ptr = (PINBOXPTR)Ysafe_malloc( sizeof(PINBOX) ) ;
564   ptr->xpos = ptr1->xpos ;
565   ptr->ypos = ptr2->ypos ;
566   ptr->terminal = 0 ;
567   if( ptr1->terminal == 0 ) {
568     ptr->newx = ptr1->newx ;
569   } else {
570     ptr->newx = ptr1->terminal ;
571   }
572   /* the 'newx' field is temporary used for storing the
573      y-direction terminal that steiner points refered to */
574   ptr->row = ptr2->row ;
575   ptr->pinloc = NEITHER ;
576   ptr->newy = 3 * ptr->row ;
577   ptr->net = net ;
578   ptr->adjptr = (ADJASEGPTR)Ysafe_calloc( 1, sizeof(ADJASEG) ) ;
579   ptr->next = steinerHeadG[net]->next ;
580   steinerHeadG[net]->next = ptr ;
581   return( ptr ) ;
582 }
583 
584 
makeseg(lowptr,highptr)585 SEGBOXPTR makeseg( lowptr , highptr )
586   PINBOXPTR lowptr , highptr ;
587 {
588   ADJASEG *adj1, *adj2 ;
589   SEGBOXPTR segptr ;
590 
591   segptr = ( SEGBOXPTR )Ysafe_malloc( sizeof(SEGBOX) ) ;
592   if( lowptr->row < highptr->row ) {
593     segptr->pin1ptr = lowptr ;
594     segptr->pin2ptr = highptr ;
595     segptr->switchvalue = swL_up ;
596   } else if( lowptr->row > highptr->row ) {
597     segptr->pin2ptr = lowptr ;
598     segptr->pin1ptr = highptr ;
599     segptr->switchvalue = swL_up ;
600   } else if( (INT) lowptr->pinloc == BOTCELL && (INT) highptr->pinloc == TOPCELL ) {
601     segptr->pin1ptr = lowptr ;
602     segptr->pin2ptr = highptr ;
603     segptr->switchvalue = swL_up ;
604   } else if( (INT) lowptr->pinloc == TOPCELL && (INT) highptr->pinloc == BOTCELL ) {
605     segptr->pin1ptr = highptr ;
606     segptr->pin2ptr = lowptr ;
607     segptr->switchvalue = swL_up ;
608   } else if( lowptr->xpos < highptr->xpos ) {
609     segptr->pin1ptr = lowptr ;
610     segptr->pin2ptr = highptr ;
611     segptr->switchvalue = nswLINE ;
612   } else {
613     segptr->pin2ptr = lowptr ;
614     segptr->pin1ptr = highptr ;
615     segptr->switchvalue = nswLINE ;
616   }
617   adj1 = (ADJASEGPTR)Ysafe_calloc( 1, sizeof(ADJASEG) ) ;
618   adj2 = (ADJASEGPTR)Ysafe_calloc( 1, sizeof(ADJASEG) ) ;
619   adj1->segptr = segptr ;
620   adj2->segptr = segptr ;
621   adj1->next =  lowptr->adjptr->next ;
622   adj2->next = highptr->adjptr->next ;
623   lowptr->adjptr->next = adj1 ;
624   highptr->adjptr->next = adj2 ;
625   segptr->next = netsegHeadG[lowptr->net]->next ;
626   netsegHeadG[lowptr->net]->next = segptr ;
627   return( segptr ) ;
628 }
629 
630 
dbg_cost()631 void dbg_cost()
632 {
633   FILE *fp ;
634   INT row ;
635   DOUBLE cost, ratio ;
636 
637   fp = TWOPEN("vcost.dat", "w", ABORT ) ;
638   fprintf(fp, " rowHeightG = %d\n", rowHeightG ) ;
639   fprintf(fp, " row  cost actual estimate    ratio\n" ) ;
640   for( row = 1 ; row <= numRowsG ; row++ ) {
641     cost = (DOUBLE)(rowfeed_penaltyG[row]) / (DOUBLE)(rowHeightG) ;
642     ratio = (DOUBLE)(FeedInRowG[row]) / fd_estimateS[row] ;
643     fprintf(fp, " %3d %5.2f %6d %8.2f %8.2f\n", row, cost,
644         FeedInRowG[row], fd_estimateS[row], ratio ) ;
645   }
646   TWCLOSE(fp) ;
647 }
648 
649 
dbx_fdpen()650 void dbx_fdpen()
651 {
652 
653   FILE *fp ;
654   FEED_DATA *feedptr ;
655   INT row , i , s ;
656 
657   fp = TWOPEN("pen.dat" , "w", ABORT ) ;
658   fprintf(fp," row min_feedSS fd_estimateS act_feed needed\n" ) ;
659   for( row = 1 ; row <= numRowsG ; row++ ) {
660     feedptr = feedpptrG[row] ;
661     s = 0 ;
662     for( i = 1 ; i <= chan_node_noG ; i++ ) {
663       s += feedptr[i]->needed ;
664     }
665     fprintf(fp," %3d %8d %8d %8d %6d\n", row, min_feedS[row],
666         (INT)fd_estimateS[row] , FeedInRowG[row] , s ) ;
667   }
668   TWCLOSE(fp) ;
669 }
670