void sortpins() { INT j , n , cell ; CELLBOXPTR ptr ; PINBOXPTR pin, *xpptr ; /* static INT comparePin() ;*/ INT maxpins ; /* find maximum number of pins on a cell for allocation */ maxpins = INT_MIN ; for( cell = 1 ; cell <= totalcellsG ; cell++ ) { ptr = cellarrayG[ cell ] ; maxpins = MAX( ptr->numpins, maxpins ) ; } /* allocate array for sort */ xpptr = (PINBOXPTR *) Ysafe_malloc((maxpins+1) * sizeof(PINBOXPTR) ) ; /* now go thru all cells sorting pins */ for( cell = 1 ; cell <= totalcellsG ; cell++ ) { ptr = cellarrayG[ cell ] ; n = 0 ; for( pin = ptr->pinptr ; pin ; pin = pin->nextpin ) { xpptr[ n++ ] = pin ; } /* net number then by pin name */ Yquicksort( (char *)xpptr, n, sizeof(PINBOXPTR),comparePin ) ; /* terminate list */ xpptr[ n ] = NIL(PINBOXPTR) ; ptr->pinptr = xpptr[ 0 ] ; for( j = 0 ; j < n ; j++ ) { xpptr[j]->nextpin = xpptr[j+1] ; } } Ysafe_free( xpptr ) ; } /* end sortpins */
DOUBLE analyze() { INT **number , i , net , net1 , net2 , num , cell ; INT *count , different , cnum , c2num , *arraynet ; INT num_nets , tot_cels ; DOUBLE C , C1 , C2 , C3 , wireRatio ; PINBOXPTR pinptr ; INT comparex() ; DOUBLE weight_past_runs( /* wireRatio */ ) ; count = (INT *) Ysafe_malloc( (1 + numcellsG) * sizeof( INT ) ) ; number = (INT **) Ysafe_malloc( (1 + numnetsG) * sizeof( INT *) ) ; howmanyS = (INT *) Ysafe_malloc( (1 + numnetsG) * sizeof( INT ) ) ; arraynet = (INT *) Ysafe_malloc( (1 + numnetsG) * sizeof( INT ) ) ; for( net = 0 ; net <= numnetsG ; net++ ) { number[net] = (INT *) Ysafe_malloc( (1 + numcellsG) * sizeof(INT) ) ; } for( net = 1 ; net <= numnetsG ; net++ ) { for( cell = 0 ; cell <= numcellsG ; cell++ ) { count[cell] = 0 ; number[net][cell] = 0 ; } for( pinptr=netarrayG[net]->pins;pinptr; pinptr = pinptr->next ){ if( pinptr->cell <= numcellsG ) { count[pinptr->cell] = 1 ; } } /* * I would like to find the number of distinct nets */ for( cell = 1 ; cell <= numcellsG ; cell++ ) { if( count[cell] == 1 ) { number[net][ ++number[net][0] ] = cell ; } } } /* ********************************************************** */ num_nets = 0 ; tot_cels = 0 ; for( net1 = 1 ; net1 <= numnetsG ; net1++ ) { if( number[net1][0] <= 1 ) { continue ; } num_nets++ ; tot_cels += number[net1][0] ; } OUT1("\n\n*************************************\n"); OUT2("AVERAGE NUMBER OF CELLS PER NET: %f\n", ( (DOUBLE) tot_cels / (DOUBLE) num_nets ) ) ; OUT1("*************************************\n\n\n"); /* ********************************************************** */ for( net1 = 1 ; net1 <= numnetsG ; net1++ ) { if( number[net1][0] == 0 ) { howmanyS[net1] = 0 ; continue ; } if( number[net1][0] == 1 ) { number[net1][0] = 0 ; howmanyS[net1] = 0 ; continue ; } howmanyS[net1] = 1 ; for( net2 = net1 + 1 ; net2 <= numnetsG ; net2++ ) { if( number[net2][0] != number[net1][0] ) { continue ; } different = 0 ; for( i = 1 ; i <= numcellsG ; i++ ) { if( number[net2][i] != number[net1][i] ) { different = 1 ; break ; } } if( ! different ) { number[net2][0] = 0 ; howmanyS[net1]++ ; } } } arraynet[0] = 0 ; for( net = 1 ; net <= numnetsG ; net++ ) { if( howmanyS[net] <= 0 ) { continue ; } arraynet[ ++arraynet[0] ] = net ; } num = arraynet[0] ; arraynet[0] = arraynet[ arraynet[0] ] ; Yquicksort( (char *) arraynet , num , sizeof( INT ), comparex ) ; /* sorted: most occurrences first */ num = 0 ; cnum = 0 ; c2num = 0 ; for( net = 1 ; net <= numnetsG ; net++ ) { if( number[net][0] > 0 ) { cnum += number[net][0] - 1 ; c2num += number[net][0] ; num++ ; } } C = (DOUBLE) num / (DOUBLE) numcellsG ; C1 = (DOUBLE) cnum / (DOUBLE) num ; C2 = (DOUBLE) c2num / (DOUBLE) num ; C3 = (DOUBLE) cnum / (DOUBLE)(numcellsG - 1) ; OUT1("\n\n\n**********************************************\n\n"); OUT1("The average number of distinct nets per cell is\n"); OUT2("given by: %6.2f\n\n", C ); OUT1("The average number of cells per net is\n"); OUT2("given by: %6.2f\n\n", C2 ); OUT1("The average number of other cells per net is\n"); OUT2("given by: %6.2f\n\n", C1 ); OUT1("The ratio of total cells specified per net to\n"); OUT2("numcells is given by: %6.2f\n\n", C3 ); OUT1("The average number of cells connected to a cell is\n"); OUT2("given by: %6.2f\n\n", C * C1 ); OUT1("**********************************************\n\n\n"); wireRatio = EXPECTEDWIRERATIO ; OUT2("Expected Wire Reduction Relative to Random:%6.2f\n\n",wireRatio); FLUSHOUT(); wireRatio = weight_past_runs( wireRatio ) ; sprintf( YmsgG,"\n\nWire ratio updated to:%4.2f\n\n", wireRatio ) ; M( MSG, "analyze", YmsgG ) ; return( wireRatio ); }
ERRORPTR buildYGraph() { int i ; /* counter */ int overlapx ; /* overlap conditions in x direction */ int overlapy ; /* overlap conditions in y direction */ int sortbyYX() ; /* sort the tiles Y then X */ int left, right ; /* coordinates of tiles */ int bottom, top ; /* coordinates of tiles */ BOOL firstPick ; /* TRUE if first picket which matches */ BOOL possibleEdgetoSource; /* TRUE if this could be edge to source */ BOOL *yancestorB ; /* TRUE for a cell if cell has B ancestors */ BOOL *yancestorF ; /* TRUE for a cell if cell has F ancestors */ COMPACTPTR candidate ; /* this is the tile in question */ COMPACTPTR t ; /* this is the current picket */ PICKETPTR freepick ; /* used to free the pickets at the end */ PICKETPTR curPick ; /* traverse the pickets */ PICKETPTR lowerLimit ; /* first picket tile overlaps/touches */ PICKETPTR upperLimit ; /* last picket tile overlaps or touches */ ERRORPTR errorPtr ; /* form a list of errors to be processed*/ ERRORPTR lasterror ; /* last error in list */ ERRORPTR violations ; /* head of the error list */ /* initialize error list */ lasterror = NULL ; violations = NULL ; yancestorB = (BOOL *) Ysafe_calloc( last_cellG+1,sizeof(BOOL) ) ; yancestorF = (BOOL *) Ysafe_calloc( last_cellG+1,sizeof(BOOL) ) ; inityPicket() ; /* yGraphG is now initialized */ /* sort by ymin xmin of the bounding box */ /* we give it two chances - second time we expand core if necessary */ for( i=0; i <= 1 ; i++ ){ Yquicksort((char *)yGraphG,numtilesG+2,sizeof(COMPACTPTR),sortbyYX); if( yGraphG[SOURCE]->cell == YSOURCEC && yGraphG[SINK]->cell == YSINKC ){ break ; } else { find_core( &left, &right, &bottom, &top ) ; /* expand core region */ t = tileNodeG[YSOURCE] ; t->b = bottom ; t->t = t->b ; t = tileNodeG[YSINK] ; t->b = top ; t->t = t->b ; } } if( yGraphG[SOURCE]->cell != YSOURCEC || yGraphG[SINK]->cell != YSINKC ){ M( ERRMSG, "ycompact", "Fatal error in configuration\n" ) ; if( graphicsG ){ G( TWcloseGraphics() ) ; } YexitPgm( PGMFAIL ) ; } for( i=1 ; i<= numtilesG ; i++ ){ firstPick = TRUE ; lowerLimit = NULL ; upperLimit = NULL ; possibleEdgetoSource = FALSE ; candidate = yGraphG[i] ; /* search thru picket list for adjacencies */ for( curPick=leftPickS;curPick;curPick=curPick->next){ overlapx = projectX( curPick->pt2.lft, curPick->pt1.rght, candidate->l, candidate->r) ; if( overlapx > 0 ){ /* allow touching */ /* save span of overlap */ if( firstPick ){ lowerLimit = curPick ; firstPick = FALSE ; } upperLimit = curPick ; t = tileNodeG[curPick->node] ; /* multiple tile case - no error possible */ if( candidate->cell == t->cell ){ continue ; } /* check for errors */ overlapy = projectY( t->b, t->t, candidate->b, candidate->t ) ; if( overlapx > 0 && overlapy > 0 ){ /* save violations - add to violation list */ if( lasterror ){ errorPtr = (ERRORPTR) Ysafe_malloc( sizeof(ERRORBOX) ) ; lasterror->next = errorPtr ; lasterror = errorPtr ; } else { violations = errorPtr = lasterror = (ERRORPTR) Ysafe_malloc( sizeof(ERRORBOX) ) ; } errorPtr->next = NULL ; errorPtr->nodeI = candidate->node ; errorPtr->nodeJ = t->node ; /* for debug only : sprintf( YmsgG, Overlap detected: cell %d and cell %d\n", candidate->cell, t->cell ) ; M( MSG, NULL, YmsgG ) ; */ } ASSERT( t->node == curPick->node, "buildCGraph", "tileNodeG != curPick. Problem \n" ) ; /* form edge on only first occurance of cell */ if( t->node == numtilesG+2 ){ /* source node */ /* delay adding this edge */ possibleEdgetoSource = TRUE ; } else { formyEdge( t->node, candidate->node ) ; } } else if( upperLimit ){ /* we are past the upper limit so break & save time */ break ; } } ASSERT( lowerLimit, "compact", "lowerLimit is NULL" ) ; ASSERT( upperLimit, "compact", "lowerLimit is NULL" ) ; if( possibleEdgetoSource && yancestorF[candidate->cell] == FALSE ){ /* no need to make an edge to source if we already */ /* have an ancestor. Always make sure it is one of the lowest */ /* nodes of the multi-tiled cell */ formyEdge( numtilesG+2, cellarrayG[candidate->cell]->ylo ) ; yancestorF[candidate->cell] = TRUE ; } update_ypicket( i, lowerLimit, upperLimit ) ; } /* end for loop */ /* process sink last */ /* search thru picket list for adjacencies */ for( curPick=leftPickS;curPick;curPick=curPick->next){ /* remaining pickets must necessarily overlap sink */ t = tileNodeG[curPick->node] ; ASSERT( t->node == curPick->node, "buildCGraph", "tileNodeG != curPick. Problem \n" ) ; if( curPick->node != numtilesG+2 && /* avoid the source */ yancestorB[t->cell] == FALSE ){ /* no parents */ formyEdge( cellarrayG[t->cell]->yhi, yGraphG[last_tileG]->node ) ; yancestorB[t->cell] = TRUE ; } } /* now add multiple tile edges to graph. Precomputed in multi.c */ add_mtiles_to_ygraph() ; cleanupGraph( YFORWARD ) ; cleanupGraph( YBACKWARD ) ; Ysafe_free( yancestorB ) ; Ysafe_free( yancestorF ) ; /* delete all pickets */ for( curPick = leftPickS; curPick ; ) { freepick = curPick ; curPick = curPick->next ; Ysafe_free( freepick ) ; } return( violations ) ; } /* end buildYGraph */