예제 #1
0
/* initialization before parsing nets */
init_nets()
{
    YHASHPTR getNetTable() ;
    numpathsG = 0 ;
    netTableS = getNetTable() ;
    net_cap_matchG = (INT **) Ysafe_calloc( numnetsG+1,sizeof(INT *) ) ;
    net_res_matchG = (INT **) Ysafe_calloc( numnetsG+1,sizeof(INT *) ) ;
} /* end init_nets */
예제 #2
0
outpin()
{

    INT net ;               /* counter */
    char filename[LRECL] ;  /* open this filename for writing */
    NETBOXPTR netptr ;      /* current net info */
    PINBOXPTR pinptr ;      /* current pin info */

    sprintf( filename, "%s.mpin", cktNameG ) ;
    fpS = TWOPEN( filename , "w", ABORT ) ;

    output_alreadyS = (BOOL *) Ysafe_calloc( numpinsG+1, sizeof(BOOL) ) ;
    output_typeS = NONE ;
    for( net = 1 ; net <= numnetsG ; net++ ) {
	netptr =  netarrayG[net] ;
	if( netptr->numpins <= 1 ){
	    /* no need to global route 1 pin nets */
	    continue ;
	}
	if( netptr->analog_info ){
	    process_analog_net( netptr ) ;
	    output_typeS |= ANALOG ;
	    continue ;
	}
	fprintf(fpS,"net %s\n", netptr->nname ) ;
	for( pinptr = netptr->pins ;pinptr;pinptr = pinptr->next ) {
	    output_pin( pinptr ) ;
	    output_typeS |= DIGITAL ;
	}
	fprintf( fpS,"\n" ) ;
    }
    output_matches() ;
    TWCLOSE(fpS);
    return ;
} /* end outpins */
예제 #3
0
findrcost()
{

SEGBOXPTR segptr ;
CHANGRDPTR gdptr ;
DENSITYPTR *hdptr , headptr , dptr ;
INT chan ;
INT trackG , max_trk , k ;
INT net ;


for( net = 1 ; net <= numnetsG ; net++ ) {
    for( segptr = netsegHeadG[net]->next ;
	segptr ; segptr = segptr->next ){
	initial_tracks( segptr ) ;
    }
    for( segptr = netsegHeadG[net]->next ;
	segptr ; segptr = segptr->next ){
	process_cross( segptr , 0 ) ;
    }
}
DboxHeadG  = ( DENSITYPTR ** )Ysafe_calloc( numChansG + 1,
				sizeof( DENSITYPTR * ) ) ;
maxTrackG  = (INT *)Ysafe_malloc( ( numChansG + 1 ) * sizeof( INT ) ) ;
nmaxTrackG = (INT *)Ysafe_malloc( ( numChansG + 1 ) * sizeof( INT ) ) ;
max_tdensityG = 0 ;
tracksG   = 0 ;
if( uneven_cell_heightG ) {
    set_cedgebin( ) ;
    reset_track( ) ;
}
for( chan = 1 ; chan <= numChansG ; chan++ ) {
    max_trk = 0 ;
    for( gdptr = BeginG[ chan ] ; gdptr != GRDNULL ;
					gdptr = gdptr->nextgrd ) {
	if( gdptr->tracks > max_trk ) {
	    max_trk = gdptr->tracks ;
	}
    }
    maxTrackG[ chan ]   = max_trk ;
    if( max_trk > max_tdensityG ) {
	max_tdensityG = max_trk ;
    }
    tracksG += max_trk ;
}
printf(" the starting value of tracks = %4d\n" , tracksG ) ;
k = max_tdensityG + 100 ;
for( chan = 1 ; chan <= numChansG ; chan++ ) {
    DboxHeadG[ chan ]  = hdptr = ( DENSITYPTR *)Ysafe_calloc( k + 1,
			    sizeof( DENSITYPTR) ) ;
    for( trackG = 0 ; trackG <= k ; trackG++ ) {
	hdptr[trackG] = ( DENSITYPTR )Ysafe_calloc( 1, sizeof(DENSITYBOX));
    }
    for( gdptr = BeginG[ chan ] ; gdptr ; gdptr = gdptr->nextgrd ) {
	trackG = gdptr->tracks ;
	gdptr->dptr = dptr = 
	    ( DENSITYPTR )Ysafe_calloc( 1,sizeof(DENSITYBOX) ) ;
	headptr = hdptr[trackG] ;
	if( headptr->next ) {
	    dptr->next = headptr->next ;
	    dptr->next->back = dptr ;
	    headptr->next = dptr ;
	    dptr->back = headptr;
	} else {
	    headptr->next = dptr ;
	    dptr->back = headptr ;
	}
	dptr->grdptr = gdptr ;
    }
}
}
예제 #4
0
feedest()
{

DOUBLE ratio ;
INT net , row , toprow , botrow, maxdesire ;
DBOXPTR dimptr ;
PINBOXPTR ptr ;

fd_estimateS = (DOUBLE *)Ysafe_calloc( numChansG + 1, sizeof(DOUBLE) ) ;
min_feedS = (INT *)Ysafe_calloc( numChansG + 1, sizeof(INT) ) ;
row_flagS = (INT *)Ysafe_calloc( numChansG + 1, sizeof(INT) ) ;
rowfeed_penaltyG = (INT *)Ysafe_malloc( ( numChansG + 1 ) * sizeof(INT) ) ;
est_min_ratioS = (INT *)Ysafe_malloc( numChansG * sizeof(INT) ) ;

maxdesire = barrayG[1]->desire ;
for( row = 2 ; row <= numRowsG ; row++ ) {
    if( maxdesire < barrayG[row]->desire ) {
	maxdesire = barrayG[row]->desire ;
    }
}

ratio = (DOUBLE)(maxdesire) / (DOUBLE)( barrayG[numRowsG]->bycenter -
			  barrayG[1]->bycenter + rowHeightG ) ;
ratio = 1.0 / ratio ;  /* to fix Kai-Win's bug */

if( absolute_minimum_feedsG ) {
    if( ratio >= 1.0 ) {
	chip_width_penaltyS = barrayG[numRowsG]->bycenter -
			  barrayG[1]->bycenter + rowHeightG ;
    } else {
	chip_width_penaltyS = maxdesire ;
    }
} else {
    /* chip_width_penaltyS = 2.0 * (DOUBLE) rowHeightG ; */
    chip_width_penaltyS = 6.9 * (DOUBLE) rowHeightG ;
}



if( !absolute_minimum_feedsG ) {
    add_Lcorner_feedG = TRUE ;
    /* Carl */
    for( row = 1 ; row <= numRowsG ; row++ ) {
	if( FeedInRowG[row] == 0 ) {
	    add_Lcorner_feedG = FALSE ;
	    break ;
	}
    }
    /* Carl */
} else {
    add_Lcorner_feedG = FALSE ;
}
for( net = 1 ; net <= numnetsG ; net++ ) {
    dimptr = netarrayG[net] ;
    if( !(dimptr->pins) ) {
	continue ;
    }
    switch( dimptr->numpins ) {
    case 0 :
    case 1 :
	break ;
    case 2 :
	ptr = dimptr->pins ;
	toprow = ptr->row ;
	botrow = ptr->next->row ;
	if( toprow > botrow ) {
	    for( row = botrow + 1 ; row < toprow ; row++ ) {
		fd_estimateS[row]++ ;
		min_feedS[row]++ ;
	    }
	    if( ABS( ptr->xpos - ptr->next->xpos ) >=
				    average_feed_sepG ) {
		fd_estimateS[botrow] += 0.5 ;
		fd_estimateS[toprow] += 0.5 ;
	    }
	} else if( toprow < botrow ) {
	    for( row = toprow + 1 ; row < botrow ; row++ ) {
		fd_estimateS[row]++ ;
		min_feedS[row]++ ;
	    }
	    if( ABS( ptr->xpos - ptr->next->xpos ) >=
				    average_feed_sepG ) {
		fd_estimateS[botrow] += 0.5 ;
		fd_estimateS[toprow] += 0.5 ;
	    }
	}
	row_flagS[botrow] = 0 ;
	row_flagS[toprow] = 0 ;
	break ;
    case 3 :
    case 4 :
    case 5 :
	ptr = dimptr->pins ;
	toprow = botrow = ptr->row ;
	row_flagS[toprow] = 1 ;
	for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
	    row = ptr->row ;
	    if( row < botrow ) {
		botrow = row ;
	    }
	    if( row > toprow ) {
		toprow = row ;
	    }
	    row_flagS[row] = 1 ;
	}
	for( row = botrow + 1 ; row < toprow ; row++ ) {
	    if( row_flagS[row] ) {
		fd_estimateS[row]++ ;
		row_flagS[row] = 0 ;
	    } else {
		fd_estimateS[row] += 1.5 ;
		min_feedS[row]++ ;
	    }
	}
	if( toprow > botrow ) {
	    fd_estimateS[botrow] += 0.5 ;
	    fd_estimateS[toprow] += 0.5 ;
	}
	row_flagS[botrow] = 0 ;
	row_flagS[toprow] = 0 ;
	break ;
    default :
	ptr = dimptr->pins ;
	toprow = botrow = ptr->row ;
	row_flagS[toprow] = 1 ;
	for( ptr = ptr->next ; ptr ; ptr = ptr->next ) {
	    row = ptr->row ;
	    if( row < botrow ) {
		botrow = row ;
	    }
	    if( row > toprow ) {
		toprow = row ;
	    }
	    row_flagS[row] = 1 ;
	}
	for( row = botrow + 1 ; row < toprow ; row++ ) {
	    if( row_flagS[row] ) {
		fd_estimateS[row]++ ;
		row_flagS[row] = 0 ;
	    } else {
		fd_estimateS[row] += 1.5 ;
		min_feedS[row]++ ;
	    }
	}
	if( toprow > botrow ) {
	    fd_estimateS[botrow]++ ;
	    fd_estimateS[toprow]++ ;
	}
	row_flagS[botrow] = 0 ;
	row_flagS[toprow] = 0 ;
	break ;
    }
}

estimate_pass_thru_penalty( 1 , numRowsG ) ;

}
예제 #5
0
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 */
예제 #6
0
파일: netgraph.c 프로젝트: radc/qflow
postFeedAssgn()
{

INT net , i , row , botrow , toprow , last_i ;
SEGBOXPTR segptr , nextseg ;
PINBOXPTR netptr , nextptr , st_head , stptr ;

for( net = 1 ; net <= numnetsG ; net++ ) {
    for( segptr = netsegHeadG[net]->next ; segptr ; segptr = nextseg ) {
	nextseg = segptr->next ;
	Ysafe_free( segptr ) ;
    }
    netsegHeadG[net]->next = NULL ;
    netptr = netarrayG[net]->pins ;
    st_head = steinerHeadG[net] ;
    if( st_head->next ) { /* there are steiner point for this net */
	for( stptr = st_head ; stptr->next ; ) {
	    nextptr = stptr->next ;
	    if( nextptr->terminal == 0 || !nextptr->flag ) {
		/* steiner point in bottom pads or top pads
		   or they are pseudo steiner point.         */
		stptr->next = nextptr->next ;
		Ysafe_free( nextptr ) ;
	    } else {
		stptr = nextptr ;
	    }
	}
	stptr->next = netptr ;
	netarrayG[net]->pins = st_head->next ;
	/* put all the netbox of the steiner point into the
	   netarrayG linked lists.                           */
    }
    Ysafe_free( steinerHeadG[net] ) ;
}
Ysafe_free( steinerHeadG ) ;

maxpin_numberS = 0 ;
pins_at_rowS = (INT *)Ysafe_calloc( numChansG + 1, sizeof(INT) ) ;
for( net = 1 ; net <= numnetsG ; net++ ) {
    if( netarrayG[net]->numpins <= 2 ) {
	continue ;
    }
    botrow = numChansG ;
    toprow = 0 ;
    for( netptr = netarrayG[net]->pins ; netptr ; netptr = netptr->next ) {
	row = netptr->row ;
	pins_at_rowS[ row ]++ ;
	if( row < botrow ) {
	    botrow = row ;
	}
	if( row > toprow ) {
	    toprow = row ;
	}
    }
    for( row = botrow ; row <= toprow ; row++ ) {
	if( pins_at_rowS[row] > maxpin_numberS ) {
	    maxpin_numberS = pins_at_rowS[row] ;
	}
	pins_at_rowS[row] = 0 ;
    }
}

maxpin_numberS += 3 ;
count_G    = (INT *)Ysafe_malloc( 2 * Max_numPinsG * sizeof( INT ) ) ;
father_G   = (INT *)Ysafe_malloc( 2 * Max_numPinsG * sizeof( INT ) ) ;
root_G     = (INT *)Ysafe_malloc( 2 * Max_numPinsG * sizeof( INT ) ) ;
stack_G    = (INT *)Ysafe_malloc( 2 * Max_numPinsG * sizeof( INT ) ) ;
first_indexS = (INT *)Ysafe_malloc( ( numChansG + 1 ) * sizeof( INT ) ) ;
vertex_G   = (PINBOXPTR *)Ysafe_malloc( 2 * Max_numPinsG * sizeof(PINBOXPTR) );
last_i = maxpin_numberS * maxpin_numberS * numRowsG - 1 ;
edge_dataS = (EDGE_COST *)Ysafe_malloc( ( last_i + 1 )
				       * sizeof(EDGE_COST) ) ;
for( i = 1 ; i <= last_i ; i++ ) {
    edge_dataS[i] = (EDGE_COST)Ysafe_malloc( sizeof(EDGE_COST_BOX) );
}
z_S = (PINBOXPTR **)Ysafe_malloc( ( numChansG + 1 ) * sizeof(PINBOXPTR *) ) ;
for( i = 0 ; i <= numChansG ; i++ ) {
    z_S[i] = (PINBOXPTR *)Ysafe_malloc( maxpin_numberS * sizeof(PINBOXPTR) ) ;
}

for( net = 1 ; net <= numnetsG ; net++ ) {
    if( netarrayG[net]->numpins <= 1 ) {
	continue ;
    }
    rebuild_netgraph( net ) ;
    /* find minimum cost tree connection from all the pins of a net */
}
}