Exemplo n.º 1
0
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 */
Exemplo n.º 2
0
sortpin()
{

    INT cell ;                      /* current cell */
    INT maxpins ;                   /* maximum numpins over all pins */
    CBOXPTR ptr ;                   /* current cell */
    BOOL pin_groups ;               /* true if swappable gates occur */

    /* find the maximum number of pins on a cell for allocation */
    /* also see if pin groups exist on any of the cells */
    maxpins = INT_MIN ;
    pin_groups = FALSE ;
    for( cell = 1; cell <= numcellsG; cell++ ){
	ptr = carrayG[cell] ;
	maxpins = MAX( ptr->numterms, maxpins ) ;
	if( ptr->num_pin_group > 0 ){
	    pin_groups = TRUE ;
	}
    }

    sortArrayS = (PINBOXPTR *) 
	Ysafe_malloc( (maxpins+2)*sizeof(PINBOXPTR) );

    for( cell = 1 ; cell <= numcellsG ; cell++ ) {
	sortpin1( cell ) ;
    }
    if( pin_groups ){
	/* we we have swappable gates we need to create second array */
	/* and leave first one allocated */
	sortArraySwapS = (PINBOXPTR *) 
	    Ysafe_malloc( (maxpins+2)*sizeof(PINBOXPTR) );
    } else {
	/* in the normal case we are done with sorting free array */
	Ysafe_free( sortArrayS ) ;
    }
} /* end sortpin */
Exemplo n.º 3
0
void output()
{

FILE *fpp1 , *fpp2 ;
INT locx , locy , height , width ;
INT xloc , i , cell , block , orient ;
INT num ;
INT xloc2 , yloc2 , yloc ;
INT *array , desire , k , limit ;
INT left , right , bottom , top , end ;
INT *deleted_feeds ;
INT eliminated_feeds ;
char filename[LRECL] , ctmp[32] ;
CBOXPTR cellptr ;
TIBOXPTR tptr ;
PADBOXPTR pptr ;
/* added on 06/01/90 Sury */
INT length;
INT row ;
char instance_name[LRECL], tmp_name[LRECL], *tmp_string;


deleted_feeds = (INT *) Ysafe_malloc( numcellsG * sizeof(INT) ) ;
eliminated_feeds = 0 ;

sprintf( filename , "%s.pl1" , cktNameG ) ;
fpp1 = TWOPEN( filename , "w", ABORT ) ;

sprintf( filename , "%s.pl2" , cktNameG ) ;
fpp2 = TWOPEN( filename , "w", ABORT ) ;

for( block = 1 ; block <= numRowsG ; block++ ) {

    left   = barrayG[block]->bxcenter + barrayG[block]->bleft   ;
    right  = barrayG[block]->bxcenter + barrayG[block]->bright  ;
    bottom = barrayG[block]->bycenter + barrayG[block]->bbottom ;
    top    = barrayG[block]->bycenter + barrayG[block]->btop    ;

    if( restartG == 0 && costonlyG == 1 ) {
	desire = barrayG[block]->desire ;
    } else {
	if( pairArrayG[block][0] > 0 ) {
	    cell = pairArrayG[block][ pairArrayG[block][0] ] ;
	    end  = carrayG[cell]->cxcenter + carrayG[cell]->tileptr
			    ->right ;
	    desire = end - left ;
	} else {
	    desire = 0 ;
	}
    }

    if( barrayG[block]->borient > 0 ) {
	fprintf(fpp2,"%d %d %d  %d %d  0 0\n", block ,
			    left, bottom, left + desire, top ) ;
    } else {
	fprintf(fpp2,"%d %d %d  %d %d  0 0\n", block ,
			    left, bottom, right, bottom + desire ) ;
    }

    num = pairArrayG[block][0] ;
    if( num == 0 ) {
	continue ;
    }
    array = pairArrayG[block] + 1 ;

    for( i = 0 ; i < num ; i++ ) {
	cell = array[ i ] ;
	cellptr = carrayG[ cell ] ;
	if( cellptr->clength == 0 ){
	    continue ;
	}
	if( strcmp( cellptr->cname , "TW_EXCEPT" ) == 0 ) {
	    continue ;
	}
	if( stand_cell_as_gate_arrayG ) {
	    if( strcmp( cellptr->cname , "GATE_ARRAY_SPACER" ) == 0 ) {
		continue ;
	    }
	}
	if( unused_feed_name_twspacerG ) {
	    if( strncmp(cellptr->cname,"twfeed",6) == STRINGEQ ) {
		if( tearrayG[cellptr->imptr->terminal] == NULL ) {
		    strcpy( ctmp , cellptr->cname ) ;
		    cellptr->cname = (char *) Ysafe_realloc(
			    cellptr->cname, (strlen(cellptr->cname)+3) *
			    sizeof(char) ) ;
		    sprintf( cellptr->cname , "%s%s" , "twspacer",
				strpbrk(ctmp, "0123456789") ) ;
		}
	    }
	}
	orient = cellptr->corient ;

	xloc = cellptr->cxcenter + cellptr->tileptr->left ;
	yloc = cellptr->cycenter + cellptr->tileptr->bottom ;

	xloc2 = cellptr->tileptr->right - 
		cellptr->tileptr->left ; 
	yloc2 = cellptr->tileptr->top - 
		cellptr->tileptr->bottom ; 

/* The following code was added on 06/01/90 Sury */
#ifdef NSC
	strcpy( tmp_name , cellptr->cname ) ;
	length = strcspn( tmp_name , ":" ) ;
	if( length < strlen( tmp_name ) ) {
	    tmp_string = strtok( tmp_name , ":" ) ;
	    tmp_string = strtok( NULL , ":" ) ;
	    sprintf( instance_name, "%s" , tmp_string ) ;
	} else {
	    sprintf( instance_name , "%s" , tmp_name ) ;
	}
	fprintf(fpp1,"%s %d %d  %d %d  %d %d\n",
			instance_name,
			xloc, yloc, xloc + xloc2,
			yloc + yloc2, orient, block ) ;
#else
	fprintf(fpp1,"%s %d %d  %d %d  %d %d\n",
			cellptr->cname ,
			xloc, yloc, xloc + xloc2,
			yloc + yloc2, orient, block ) ;
#endif
    }
}

if( deleted_feeds[0] > 0 ) {
    fprintf(fpoG,"Confirming number of eliminated feeds:%d\n",
					    eliminated_feeds ) ;
}

/* now output the pads and macros */
for( i = numcellsG + 1 ; i <= lastpadG ; i++ ) {
    cellptr = carrayG[ i ]  ;
    orient = cellptr->corient ;
    tptr = cellptr->tileptr ;
    left = tptr->left ;
    right = tptr->right ;
    bottom = tptr->bottom ;
    top = tptr->top ;
    YtranslateT( &left, &bottom, &right, &top, orient ) ;
    locx = cellptr->cxcenter + left ;
    locy = cellptr->cycenter + bottom ;
    height = top - bottom ;
    width =  right - left ;
    /* determine row */
    pptr = cellptr->padptr ;
    if( pptr->macroNotPad ){
	row = 0 ;
    } else {
	switch( pptr->padside ){
	    case L:
		row = - 1 ;
		break ;
	    case T:
		row = -4 ;
		break ;
	    case R:
		row = - 2 ;
		break ;
	    case B:
		row = - 3 ;
		break ;
	    default:
		M(ERRMSG,"output", "Unknown padside\n" ) ;
	}
    }


#ifndef DEC
/* The following code was added on 06/01/90 Sury */
#ifdef NSC
	strcpy( tmp_name , cellptr->cname ) ;
	length = strcspn( tmp_name , ":" ) ;
	if( length < strlen( tmp_name ) ) {
	    tmp_string = strtok( tmp_name , ":" ) ;
	    tmp_string = strtok( NULL , ":" ) ;
	    sprintf( instance_name, "%s" , tmp_string ) ;
	} else {
	sprintf( instance_name , "%s" , tmp_name ) ;
	}
    fprintf(fpp1,"%s %d %d  %d %d  %d %d\n", instance_name,
				locx, locy, locx + width,
				locy + height, orient, row ) ;
    fprintf(fpp2,"%s %d %d  %d %d  %d %d\n", instance_name,
				locx, locy, locx + width,
				locy + height, orient, row ) ;
#else
    /* normal case */
    fprintf(fpp1,"%s %d %d  %d %d  %d %d\n", cellptr->cname ,
				locx, locy, locx + width,
				locy + height, orient, row ) ;
    fprintf(fpp2,"%s %d %d  %d %d  %d %d\n", cellptr->cname ,
				locx, locy, locx + width,
				locy + height, orient, row ) ;
#endif
#else
    /* DEC case */
    fprintf(fpp1,"%s %d %d  %d %d  %d %d\n", cellptr->cname ,
		    locx, locy, locx + width,
		    locy + height, orient, -cellptr->padside ) ;
    fprintf(fpp2,"%s %d %d  %d %d  %d %d\n", cellptr->cname ,
		    locx, locy, locx + width,
		    locy + height, orient, -cellptr->padside ) ;
#endif

}
TWCLOSE( fpp1 ) ;
TWCLOSE( fpp2 ) ;

if( create_new_cel_fileG ) {
    create_cel_file() ;
}

Ysafe_free( deleted_feeds ) ;

return ;
}
Exemplo n.º 4
0
void final_free_up()
{
INT i, j, k, row, pin, net, cell, chan, track ;
CBOXPTR cellptr ;
DBOXPTR dimptr ;
PINBOXPTR ptr, nextptr ;
ADJASEGPTR adj, nextadj ;
SEGBOXPTR segptr, nextseg ;
CHANGRDPTR gdptr, nextgrd ;
DENSITYPTR *hdptr ;
IPBOXPTR imptr ;
FEED_DATA *feedptr ;

Ysafe_free( FeedInRowG ) ;
for( row = 1 ; row <= numRowsG ; row++ ) {
    Ysafe_free( impFeedsG[row] ) ;
}
Ysafe_free( impFeedsG ) ;

for( i = 1 ; i <= numRowsG ; i++ ) {
    feedptr = feedpptrG[i] ;
    for( j = 1 ; j <= chan_node_noG ; j++ ) {
	Ysafe_free( feedptr[j] ) ;
    }
    Ysafe_free( feedpptrG[i] ) ;
}
Ysafe_free( feedpptrG ) ;

k = max_tdensityG + 100 ;
for( chan = 1 ; chan <= numChansG ; chan++ ) {
    Ysafe_free( BeginG[chan]->netptr ) ;
    Ysafe_free( EndG[chan]->netptr ) ;
    for( gdptr = BeginG[chan] ; gdptr ; gdptr = nextgrd ) {
	nextgrd = gdptr->nextgrd ;
	Ysafe_free( gdptr->dptr ) ;
	Ysafe_free( gdptr ) ;
    }

    hdptr = DboxHeadG[chan] ;
    for( track = 0 ; track <= k ; track++ ) {
	Ysafe_free( hdptr[track] ) ;
    }
    Ysafe_free( DboxHeadG[chan] ) ;
}
Ysafe_free( BeginG ) ;
Ysafe_free( EndG ) ;
Ysafe_free( DboxHeadG ) ;
Ysafe_free( maxTrackG ) ;
Ysafe_free( nmaxTrackG ) ;

k = maxtermG + 2 * numChansG ;
for( pin = 1 ; pin <= k ; pin++ ) {
    Ysafe_free( TgridG[pin] ) ;
}
Ysafe_free( TgridG ) ;

/*
Not needed as this is done in findunlap.c
for( i = 1 ; i <= numRowsG ; i++ ) {
    Ysafe_free( pairArrayG[i] ) ;
}
Ysafe_free( pairArrayG ) ;
pairArrayG = NULL ;
*/

for( cell = 1 ; cell <= numcellsG ; cell++ ) {
    cellptr = carrayG[cell] ;
    imptr = cellptr->imptr ;
    if( imptr ) {
	for( ; imptr->next; imptr = imptr->next ) {
	    if( imptr->next->cell != cell ) break ;
	}
	imptr->next = NULL ;
    }
}
fprintf( fpoG,"Actual # of Feed Cells Added:\t%d\n\n\n",
    actual_feed_thru_cells_addedG ) ;
k = numcellsG + numtermsG + actual_feed_thru_cells_addedG ;
for( cell = numcellsG + numtermsG + 1 ; cell <= k ; cell++ ) {
    cellptr = carrayG[cell] ;
    cellptr->imptr->next = NULL ;
    Ysafe_free( cellptr->cname ) ;
    Ysafe_free( cellptr->tileptr ) ;
    Ysafe_free( cellptr->imptr->pinname ) ;
    Ysafe_free( cellptr->imptr->eqpinname ) ;
    Ysafe_free( cellptr->imptr ) ;
    Ysafe_free( carrayG[cell] ) ;
    carrayG[cell] = NULL ;
}
actual_feed_thru_cells_addedG = 0 ;

for( net = 1 ; net <= numnetsG ; net++ ) {
    for( segptr = netsegHeadG[net] ; segptr ; segptr = nextseg ) {
	nextseg = segptr->next ;
	Ysafe_free( segptr ) ;
    }
    dimptr = netarrayG[net] ;
    if( !dimptr->pins ) {
	continue ;
    }
    if( dimptr->pins->terminal > TotRegPinsG ) {
	for( ptr = dimptr->pins ; ptr ; ptr = nextptr ) {
	    nextptr = ptr->next ;
	    for( adj = ptr->adjptr ; adj ; adj = nextadj ) {
		nextadj = adj->next ;
		Ysafe_free( adj ) ;
	    }
	    Ysafe_free( ptr->eqptr ) ;
	    if( nextptr->terminal <= TotRegPinsG ) break ;
	}
	dimptr->pins = nextptr ;
    }
    for( ptr = dimptr->pins ; ptr ; ptr = ptr->next ) {
	for( adj = ptr->adjptr->next ; adj ; adj = nextadj ) {
	    nextadj = adj->next ;
	    Ysafe_free( adj ) ;
	}
	ptr->adjptr->next = NULL ;
    }
}
Ysafe_free( netsegHeadG ) ;

}
Exemplo n.º 5
0
void
construct_segment()
{

register int i	;
register int j	;
register int v	;
register int v1	;
register int v2	;
int	count	;
int	degree	;
int	Degree	;
int	order	;

LISTPTR  Pnode	  ;
MDATAPTR Pcurrent ;	/* vertex of its adjdacent list is searched	*/
MDATAPTR Plast	  ;	/* last vertex in the segment tree list		*/
MDATAPTR Pparent  ;	/* start of the path to current vertex		*/
MDATAPTR Pnew	  ;	/* temporary pointer for new vertex		*/
PINPTR	 Pfirst	  ;
PINPTR	 Ppin	  ;
STACKPTR Pstack	  ;
STACKPTR Psteiner ;

/***********************************************************
* Label all the vertices in the minimum Steiner tree with
* one and label the others with zero.
***********************************************************/
numnode = numpins ;
numtree_e = 0 ;
for (i=1; i<=numnodes; i++)
{
    garray[i]->status = FALSE ;
    iarray[i] = 0 ;
}
for (i=numnodes+1; i<=totnodes; i++)
{
    garray[i]->status = TRUE ;
    iarray[i] = 0 ;
}

for (i=1; i<=totedges; i++)
{
    earray[i]->numpins = FALSE ;

    if (earray[i]->intree&MIN_MASK)
    {
	earray[i]->numpins = TRUE ;
	jarray[++numtree_e] = i ;

	v1 = earray[i]->node[0] ;
	v2 = earray[i]->node[1] ;

	if (!garray[v1]->status)
	{
	    numnode++ ;
	    garray[v1]->status = TRUE ;
	}
	if (!garray[v2]->status)
	{
	    numnode++ ;
	    garray[v2]->status = TRUE ;
	}
    }
}

/***********************************************************
* Initialize field key of parray to be zero.
***********************************************************/
for (i=1; i<=numpins; i++)
{
    parray[i]->key = FALSE ;
}

i = numnodes + 1 ;

/***********************************************************
* Find a pin which is a leaf of the minimum Steiner tree.
***********************************************************/
while (1)
{
    degree = 0 ;
    Pnode = garray[i]->first ;

    while (Pnode)
    {
	if (earray[Pnode->edge]->numpins)
	{
	    degree++ ;
	}
	Pnode = Pnode->next ;
    }

    if (degree==1)
    {
	break ;
    }
    i++ ;
}

Pstack = NIL(STACK) ;

count = 0 ;
order = 1 ;

Pcurrent = Plast = Pparent = Proot = make_node() ;

Proot->dist = 0 ;
Proot->leaf = FALSE ;
Proot->order = 1 ;
Proot->parent = 0 ;
Proot->vertex = i ;
Proot->prev = NIL(MDATA) ;
Proot->next = NIL(MDATA) ;
Proot->f_node = NIL(MDATA) ;

if (parray[i-numnodes]->equiv)
{
    Proot->equiv = TRUE ;
    parray[i-numnodes]->key = TRUE ;
}
else
{
    Proot->equiv = FALSE ;
}

if (EQUIVAL==FALSE)
{
    do {
	degree = 0 ;
	Pnode = garray[i]->first ;

	if (!count)
	{
	    /***********************************************************
	    * Search the adjacent list of the current vertex to test if
	    * a vertex in the list is a pin or has a degree greater than
	    * two.
	    * count = 0 --- the current vertex is not a Steiner vertex.
	    ***********************************************************/
	    while (Pnode)
	    {
		v1 = Pnode->t_vertex ;

		if (garray[v1]->status && v1!=Pcurrent->parent)
		{
		    if (earray[Pnode->edge]->intree&MIN_MASK)
		    {
			j = v1 ;
			degree++ ;
		    }
		}
		Pnode = Pnode->next ;
	    }
	}
	else
	{
	    /***********************************************************
	    * The search just returns to a Steiner vertex. We need to
	    * go through the number of count times for adjacent vertices
	    * which are in the minimum Steiner tree and add the vertex
	    * into the segment tree.
	    * count!=0 --- the current vertex is a Steiner vertex.
	    ***********************************************************/
	    while (Pnode)
	    {
		v1 = Pnode->t_vertex ;

		if (garray[v1]->status && v1!=Pcurrent->parent)
		{
		    if (earray[Pnode->edge]->intree&MIN_MASK)
		    {
			j = v1 ;
			degree++ ;
		    }

		    if (degree==count)
		    {
			count = 0 ;
			break ;
		    }
		}
		Pnode = Pnode->next ;
	    }
	}

	if (degree)
	{
	    /***********************************************************
	    * The current vertex is not a leaf. Generate a new node and
	    * expand the tree.
	    ***********************************************************/
	    Pnew = make_node() ;

	    Pnew->equiv = FALSE ;
	    Pnew->leaf = FALSE ;
	    Pnew->order = ++order ;
	    Pnew->parent = i ;
	    Pnew->status = 0 ;
	    Pnew->vertex = j ;

	    Plast->next = Pnew ;
	    Pnew->prev = Plast ;
	    Plast = Pnew ;

	    Pnew->next = NIL(MDATA) ;
	    Pnew->f_node = Pparent ;
	    Pcurrent = Pnew ;

	    v = i ;
	    i = j ;
	}
	else
	{
	    Pcurrent->leaf = TRUE ;
	}

	if (degree==1 && j>numnodes)
	{
	    /***********************************************************
	    * A pin is reached which, with the start vertex i, forms a
	    * segment. Set Pparent to be Pnew and continue the search.
	    ***********************************************************/
	    Pparent = Pnew ;

	}
	else if (degree>1)
	{
	    /***********************************************************
	    * A Steiner vertex is reached which, with the start vertex
	    * i, forms a segment. Set Pparent to be Pnew, update the
	    * stack, and continue the search.
	    ***********************************************************/
	    if (Pstack && Pstack->Pparent->vertex==v)
	    {
		Pnew->f_node = Pstack->Pparent ;
		/*********************************************************
		* The Steiner point is in the stack already. Use goto to
		* jump over the part of pushing it to the stack.
		*********************************************************/
		goto contin ;
	    }

	    Psteiner = (STACKPTR) Ysafe_malloc(sizeof(STACK)) ;
	    Psteiner->degree = --degree ;
	    Psteiner->Pparent = Pnew->prev ;
	    Psteiner->next = Pstack ;
	    Pstack = Psteiner ;
	    Pnew->f_node = Pnew->prev ;

	    contin:

	    if (j>numnodes)
	    {
		Pparent = Pnew ;
	    }
	    else
	    {
		Pparent = Pnew->f_node ;
	    }
	}
	else if (!degree)
	{
	    /***********************************************************
	    * A leaf is reached. Pop a vertex from the stack and continue
	    * the search from that vertex.
	    ***********************************************************/
	    Psteiner = Pstack ;
	    Pcurrent = Pparent = Psteiner->Pparent ;
	    count = Psteiner->degree ;
	    i = Pcurrent->vertex ;
	    Psteiner->degree-- ;

	    if (!Psteiner->degree)
	    {
		Pstack = Pstack->next ;
		Ysafe_free(Psteiner) ;
	    }
	}
    } while (order<numnode) ;
}
else
{
    do {
	degree = 0 ;
	Pnode = garray[i]->first ;

	if (!count)
	{
	    /***********************************************************
	    * Search the adjacent list of the current vertex to test if
	    * a vertex in the list is a pin or has a degree greater than
	    * two.
	    * count = 0 --- the current vertex is not a Steiner vertex.
	    ***********************************************************/
	    while (Pnode)
	    {
		v1 = Pnode->t_vertex ;

		if (garray[v1]->status && v1!=Pcurrent->parent)
		{
		    if (earray[Pnode->edge]->intree&MIN_MASK)
		    {
			j = v1 ;
			degree++ ;
		    }
		}
		Pnode = Pnode->next ;
	    }
	}
	else
	{
	    /***********************************************************
	    * The search just returns to a Steiner vertex. We need to
	    * go through the number of count times for adjacent vertices
	    * which are in the minimum Steiner tree and add the vertex
	    * into the segment tree.
	    * count!=0 --- the current vertex is a Steiner vertex.
	    ***********************************************************/
	    while (Pnode)
	    {
		v1 = Pnode->t_vertex ;

		if (garray[v1]->status && v1!=Pcurrent->parent)
		{
		    if (earray[Pnode->edge]->intree&MIN_MASK)
		    {
			j = v1 ;
			degree++ ;
		    }

		    if (degree==count)
		    {
			count = 0 ;
			break ;
		    }
		}
		Pnode = Pnode->next ;
	    }
	}

	if (i>numnodes && parray[i-numnodes]->equiv)
	{
	    /***********************************************************
	    * The vertex is an equivalent pin. Scan through all its
	    * equivalent pins. If one is an isolated equivalent pin,
	    * then created a node in the segment tree for it and skip
	    * it; otherwise, create a node in the segment tree for it
	    * and push it into the stack.
	    ***********************************************************/
	    Pcurrent->equiv = TRUE ;
	    Pfirst = parray[i-numnodes] ;
	    Pfirst->key = TRUE ;
	    Ppin = Pfirst->next ;

	    while (Ppin!=Pfirst)
	    {
		if (Ppin->key==TRUE)
		{
		    Ppin = Ppin->next ;
		    continue ;
		}
		else
		{
		    Ppin->key = TRUE ;
		}
		Pnew = make_node() ;
		Pnew->equiv = TRUE ;
		Pnew->leaf = TRUE ;
		Pnew->order = ++order ;
		Pnew->parent = i ;
		Pnew->status = 0 ;
		Pnew->vertex = Ppin->vertex + numnodes ;
		Pnew->f_node = Pcurrent ;

		Plast->next = Pnew ;
		Pnew->prev = Plast ;
		Pnew->next = NIL(MDATA) ;
		Plast = Pnew ;

		Degree = 0 ;
		Pnode = garray[Ppin->vertex+numnodes]->first ; 
		while (Pnode)
		{
		    if (earray[Pnode->edge]->numpins)
		    {
			Degree++ ;
		    }
		    Pnode = Pnode->next ;
		}
		if (Degree)
		{
		    /*****************************************************
		    * The pin is not isolated. Push it into the stack.
		    *****************************************************/
		    Pnew->leaf = FALSE ;
		    Psteiner = (STACKPTR) Ysafe_malloc(sizeof(STACK)) ;
		    Psteiner->degree = Degree ;
		    Psteiner->Pparent = Pnew ;
		    Psteiner->next = Pstack ;
		    Pstack = Psteiner ;
		}
		/*
		Psteiner = (STACKPTR) Ysafe_malloc(sizeof(STACK)) ;
		Psteiner->degree = Degree ;
		Psteiner->Pparent = Pnew ;
		Psteiner->next = Pstack ;
		Pstack = Psteiner ;
		*/
		Ppin = Ppin->next ;
	    }
	}

	if (degree)
	{
	    /***********************************************************
	    * The current vertex is not a leaf. Generate a new node and
	    * expand the tree.
	    ***********************************************************/
	    Pnew = make_node() ;

	    Pnew->equiv = FALSE ;
	    Pnew->leaf = FALSE ;
	    Pnew->order = ++order ;
	    Pnew->parent = i ;
	    Pnew->status = 0 ;
	    Pnew->vertex = j ;

	    Plast->next = Pnew ;
	    Pnew->prev = Plast ;
	    Plast = Pnew ;

	    Pnew->next = NIL(MDATA) ;
	    Pnew->f_node = Pparent ;
	    Pcurrent = Pnew ;

	    v = i ;
	    i = j ;
	}
	else
	{
	    /***********************************************************
	    * If the current vertex is an equivalent pin, then check
	    * whether it has a son.
	    ***********************************************************/
	    if (Pcurrent->equiv && Pcurrent->next)
	    {
		v1 = Pcurrent->vertex - numnodes ;
		v2 = Pcurrent->next->vertex - numnodes ;
		if (parray[v1]->equiv==parray[v2]->equiv)
		{
		    Pcurrent->leaf = FALSE ;
		}
	    }
	    else
	    {
		Pcurrent->leaf = TRUE ;
	    }
	}

	if (degree==1 && j>numnodes)
	{
	    /***********************************************************
	    * A pin is reached which, with the start vertex i, forms a
	    * segment. Set Pparent to be Pnew and continue the search.
	    ***********************************************************/
	    Pparent = Pnew ;

	}
	else if (degree>1)
	{
	    /***********************************************************
	    * A Steiner vertex is reached which, with the start vertex
	    * i, forms a segment. Set Pparent to be Pnew, update the
	    * stack, and continue the search.
	    ***********************************************************/
	    if (Pstack && Pstack->Pparent->vertex==v)
	    {
		Pnew->f_node = Pstack->Pparent ;
		/*********************************************************
		* The Steiner point is in the stack already. Use goto to
		* jump over the part of pushing it to the stack.
		*********************************************************/
		goto contin_equiv ;
	    }

	    Psteiner = (STACKPTR) Ysafe_malloc(sizeof(STACK)) ;
	    Psteiner->degree = --degree ;
	    Psteiner->Pparent = Pnew->prev ;
	    Psteiner->next = Pstack ;
	    Pstack = Psteiner ;
	    Pnew->f_node = Pnew->prev ;

	    contin_equiv:

	    if (j>numnodes)
	    {
		Pparent = Pnew ;
	    }
	    else
	    {
		Pparent = Pnew->f_node ;
	    }
	}
	else if (!degree && Pstack)
	{
	    /***********************************************************
	    * A leaf is reached. Pop a vertex from the stack and continue
	    * the search from that vertex.
	    ***********************************************************/
	    Psteiner = Pstack ;
	    Pparent = Pcurrent = Psteiner->Pparent ;
	    count = Psteiner->degree ;
	    i = Pcurrent->vertex ;
	    Psteiner->degree-- ;

	    if (!Psteiner->degree)
	    {
		Pstack = Pstack->next ;
		Ysafe_free(Psteiner) ;
	    }
	}
    } while (order<numnode) ;
}

/***********************************************************
* Assign the segment tree to an array and set up the index
* array for quick access.
***********************************************************/
marray = (MDATAPTR *) Ysafe_malloc((numnode+1) * sizeof(MDATAPTR)) ;
marray[0] = NIL(MDATA) ;

Pcurrent = Proot ;
while (Pcurrent)
{
    i = Pcurrent->order ;
    marray[i] = Pcurrent ;
    j = Pcurrent->vertex ;
    iarray[j] = i ;

    Pcurrent = Pcurrent->next ;
}

/***********************************************************
* Assign the distance to the field in each entry of marray.
***********************************************************/
if (EQUIVAL==FALSE)
{
    for (i=2; i<=numnode; i++)
    {
	v1 = marray[i-1]->vertex ;
	v2 = marray[i]->vertex ;
	Pnode = garray[v1]->first ;

	while (Pnode && Pnode->t_vertex!=v2)
	{
	    Pnode = Pnode->next ;
	}

	if (Pnode && earray[Pnode->edge]->intree)
	{
	    marray[i]->dist = marray[i-1]->dist + Pnode->length ;
	}
	else
	{
	    j = marray[i]->f_node->order ;
	    v1 = marray[j]->vertex ;
	    Pnode = garray[v1]->first ;

	    while(Pnode && Pnode->t_vertex!=v2)
	    {
		Pnode = Pnode->next ;
	    }
	    marray[i]->dist = marray[j]->dist + Pnode->length ;
	}
    }
}
else
{
    for (i=2; i<=numnode; i++)
    {
	if (marray[i]->equiv && marray[i]->f_node->equiv)
	{
	    /***********************************************************
	    * Both pins are equivalent pins.
	    ***********************************************************/
	    v1 = marray[i]->vertex - numnodes ;
	    v2 = marray[i]->f_node->vertex - numnodes ;
	    if (parray[v1]->equiv==parray[v2]->equiv)
	    {
		/*********************************************************
		* Both pins are in the same group of equivalent pins.
		*********************************************************/
		marray[i]->dist = marray[i]->f_node->dist ;
	    }
	    else
	    {
		/*********************************************************
		* Both pins are not in the same group of equivalent pins.
		*********************************************************/
		goto USUAL_CASE ;
	    }
	}
	else
	{
	    USUAL_CASE:
	    v1 = marray[i-1]->vertex ;
	    v2 = marray[i]->vertex ;
	    Pnode = garray[v1]->first ;

	    while (Pnode && Pnode->t_vertex!=v2)
	    {
		Pnode = Pnode->next ;
	    }

	    if (Pnode && earray[Pnode->edge]->intree)
	    {
		marray[i]->dist = marray[i-1]->dist + Pnode->length ;
	    }
	    else
	    {
		j = marray[i]->f_node->order ;
		v1 = marray[j]->vertex ;
		Pnode = garray[v1]->first ;

		while(Pnode && Pnode->t_vertex!=v2)
		{
		    Pnode = Pnode->next ;
		}
		marray[i]->dist = marray[j]->dist + Pnode->length ;
	    }
	}
    }
}

marray[numnode]->leaf = TRUE ;

} /* end of construct_segment */
Exemplo n.º 6
0
globroute()
{

INT flips , attempts , net ;
INT pick , number , attlimit ;
INT found , trys , maxtrys ;
INT x , x1 , x2 , channel ;
SEGBOXPTR segptr , *segment ;
DENSITYPTR denptr ;
PINBOXPTR netptr1 , netptr2 ;


changrid( ) ;

pre_findrcost( ) ;

findrcost() ;

fprintf(fpoG,"\n\nTHIS IS THE ORIGINAL NUMBER OF TRACKS: %d\n\n\n" , 
							tracksG ) ;
fflush(fpoG);

flips    =  0 ;
attempts =  0 ;
attlimit = 25 * numnetsG ;
segment  = ( SEGBOXPTR *)Ysafe_malloc(
	( Max_numPinsG + 1 ) * sizeof( SEGBOXPTR ) ) ;

while( ++attempts < attlimit ) {
    if( attempts % 1000 == 0 ) {
	printf(" tracks = %3d at attempts = %5d\n" ,tracksG ,attempts ) ;
    }
    do {
	net = (INT) ( (DOUBLE) numnetsG * ( (DOUBLE) RAND / 
				      (DOUBLE) 0x7fffffff ) ) + 1 ;
    } while( net == numnetsG + 1 ) ;
    number = 0 ;
    for( segptr = netsegHeadG[net]->next ; segptr ;
			    segptr = segptr->next ){
	process_cross( segptr , 1 ) ;
	if( segptr->switchvalue != nswLINE ) {
	    segment[ ++number ] = segptr ;
	}
    }
    maxtrys = 4 * number ;
    trys = 0 ;
    while( ++trys <= maxtrys ) {
	do {
	    pick = (INT) ( (DOUBLE) number * ( (DOUBLE) RAND / 
					  (DOUBLE) 0x7fffffff ) ) + 1 ;
	} while( pick == number + 1 ) ;
	segptr = segment[ pick ] ;
	netptr1 = segptr->pin1ptr ;
	netptr2 = segptr->pin2ptr ;
	if( segptr->switchvalue == swUP ) {
	    channel = netptr1->row + 1 ;
	} else {
	    channel = netptr2->row ;
	}
	x1 = netptr1->xpos ;
	x2 = netptr2->xpos ;

	found = NO ;
	for( denptr = DboxHeadG[ channel ][ maxTrackG[channel] ]->next
		    ; denptr != DENSENULL ; denptr = denptr->next ) {
	    x = denptr->grdptr->netptr->xpos ;
	    if( x1 <= x && x2 >= x ) {
		found = YES ;
		break ;
	    }
	}
	if( !found ) {
	    continue ;
	}

	if( urcost( segptr ) ) {
	    flips++    ;
	}
    }
    for( segptr = netsegHeadG[net]->next ; segptr ;
			    segptr = segptr->next ){
	process_cross( segptr , 0 ) ;
    }
}

Ysafe_free( segment );
fprintf(fpoG,"no. of accepted flips: %d\n", flips ) ;
fprintf(fpoG,"no. of attempted flips: %d\n", attempts ) ;
fprintf(fpoG,"THIS IS THE NUMBER OF TRACKS: %d\n\n\n" , tracksG ) ;
fflush(fpoG);

return ;
}
Exemplo n.º 7
0
findcostf()
{
TIBOXPTR tileptr1 ;
CBOXPTR cellptr1 ;
BINPTR bptr ;
INT left , right ;
INT bin , LoBin , HiBin ;
INT block , cell , blk ;
INT startx , endx ;
INT cost ;
INT k , cbin , row ;

blkleftG = INT_MAX ;
blkriteG = INT_MIN ;
for( block = 1 ; block <= numRowsG ; block++ ) {
    if( barrayG[ block ]->bxcenter + barrayG[ block ]->bleft <
						blkleftG ) {
	blkleftG = barrayG[ block ]->bxcenter +
					barrayG[ block ]->bleft ;
    } 
    if( barrayG[ block ]->bxcenter + 
			barrayG[ block ]->bright > blkriteG ) {
	blkriteG = barrayG[ block ]->bxcenter +
				    barrayG[ block ]->bright ;
    }
}
binOffstG = blkleftG ;
max_blklengthG = blkriteG - blkleftG ;

old_numBinS = numBinsG ;

numBinsG = (INT)( ( blkriteG - binOffstG ) / binWidthG ) ;
if( ( blkriteG - binOffstG ) > ( numBinsG * binWidthG ) ) {
    numBinsG++ ;
}

if( numBinsG > old_numBinS ) {
    for( row = 1 ; row <= numRowsG ; row++ ) {
	bin_configG[row] = (INT *) Ysafe_realloc( bin_configG[row] ,
				(1 + numBinsG) * sizeof(INT) ) ;
	for( bin = old_numBinS + 1 ; bin <= numBinsG ; bin++ ) {
	    bin_configG[row][bin] = 0 ;
	}
    }
}

cost = recompute_wirecost() ;

binpenalG = 0 ;
rowpenalG = 0 ;
penaltyG = 0 ;

for( block = 1 ; block <= numRowsG ; block++ ) {
    for( bin = 0 ; bin <= old_numBinS ; bin++ ) {
	Ysafe_free( binptrG[block][bin]->cell ) ;
	Ysafe_free( binptrG[block][bin] ) ;
    }
    Ysafe_free( binptrG[block] ) ;
}

for( block = 1 ; block <= numRowsG ; block++ ) {

    binptrG[block] = (BINPTR * ) Ysafe_malloc( (numBinsG + 1) *
				      sizeof( BINPTR ) ) ;
    left  = barrayG[ block ]->bleft + barrayG[ block ]->bxcenter ;
    right = barrayG[ block ]->bleft + barrayG[ block ]->bxcenter 
				   + barrayG[ block ]->desire   ;
    /* set barray->oldsize to zero for upcoming calculation */
    barrayG[ block ]->oldsize = 0 ;
    LoBin = SetBin( left ) ;
    HiBin = SetBin( right ) ;
    
    for( bin = 0 ; bin <= numBinsG ; bin++ ) {
	binptrG[block][bin] = (BINBOX *) Ysafe_malloc( 
					    sizeof(BINBOX) ) ; 
	binptrG[block][bin]->cell = (INT *)Ysafe_malloc( 
					    10 * sizeof(INT) );
	bptr = binptrG[block][bin] ;
	bptr->cell[0] = 0 ;
	bptr->right = binOffstG + bin * binWidthG ;
	bptr->left  = bptr->right - binWidthG ;
	if( bin == LoBin ) {
	    bptr->penalty = left - bptr->right ;
	} else if( bin == HiBin ) {
	    bptr->penalty = bptr->left - right ;
	} else if( bin > HiBin || bin < LoBin ) {
	    bptr->penalty = 0 ;
	} else {
	    bptr->penalty = - binWidthG ;
	}
    }
}

installf() ;

for( cell = 1 ; cell <= numcellsG - extra_cellsG ; cell++ ) {

    cellptr1 = carrayG[ cell ] ;
    tileptr1 = cellptr1->tileptr ;
    block = cellptr1->cblock ;

    startx = cellptr1->cxcenter + tileptr1->left  ;
    endx   = cellptr1->cxcenter + tileptr1->right ;

    barrayG[block]->oldsize += endx - startx ;

    cbin  = SetBin( cellptr1->cxcenter ) ;
    LoBin = SetBin( startx ) ;
    HiBin = SetBin( endx ) ;

    k = ++(binptrG[block][cbin]->cell[0]) ;
    if( k % 10 == 0 ) {
	binptrG[block][cbin]->cell = (INT *) Ysafe_realloc(
	      binptrG[block][cbin]->cell, (k + 10) * sizeof( INT ) ) ;
    }
    binptrG[block][cbin]->cell[k] = cell ;
    if( LoBin == HiBin ) {
	binptrG[block][LoBin]->penalty +=  ( endx - startx ) ;
    } else {
	bptr = binptrG[block][LoBin] ;
	bptr->penalty += ( bptr->right - startx ) ;

	bptr = binptrG[block][HiBin] ;
	bptr->penalty +=  ( endx - bptr->left ) ;

	if( LoBin + 1 < HiBin ) {
	    for( bin = LoBin + 1 ; bin <= HiBin - 1 ; bin++ ) {
		binptrG[block][bin]->penalty += binWidthG ;
	    }
	}
    }
}

for( block = 1 ; block <= numRowsG ; block++ ) {
    for( bin = 0 ; bin <= numBinsG ; bin++ ) {
	binpenalG += ABS( binptrG[block][bin]->penalty ) ;
    }
}

for( blk = 1 ; blk <= numRowsG ; blk++ ) {
    rowpenalG += ABS(barrayG[blk]->oldsize - barrayG[blk]->desire) ;
}

penaltyG = (INT)( binpenConG * (DOUBLE) binpenalG + 
				roLenConG * (DOUBLE) rowpenalG ) ;

timingcostG = recompute_timecost() ;

return( cost ) ;
}
Exemplo n.º 8
0
install_clusters()
{

INT row , n , i , bin , i_error , delta_bin , length_in_row , cell ;
INT total ;
INT total_actual_clusters ;
DOUBLE error , n_DOUBLE , cluster_norm ;

fprintf(fpoG,"total number of clusters which should be added in: %d\n",
			num_clustersG ) ;
total_actual_clusters = 0 ;

cluster_configS = (INT **) Ysafe_malloc((1 + numRowsG) * sizeof(INT *)) ;
for( row = 1 ; row <= numRowsG ; row++ ) {
    cluster_configS[row] = (INT *) Ysafe_malloc((1+numBinsG)*sizeof(INT));
    for( bin = 0 ; bin <= numBinsG ; bin++ ) {
	cluster_configS[row][bin] = 0 ;
    }
}

cluster_norm = (DOUBLE) num_clustersG / (DOUBLE) numRowsG + cluster_norm_offsetS ;

if( num_clustersG == 0 ) {
    return ;
}

error = 0.0 ;
total = 0 ;

for( row = 1 ; total < num_clustersG && row <= numRowsG ; row++ ) {
    length_in_row = 0 ;
    for( cell = 1 ; cell <= numcellsG - extra_cellsG ; cell++ ) {
	if( carrayG[cell]->cblock == row ) {
	    if( carrayG[cell]->cclass < 0 ) {
		length_in_row += carrayG[cell]->clength ;
	    }
	}
    }
    n_DOUBLE = cluster_norm + error ;

    n = (INT) n_DOUBLE ;
    if( n_DOUBLE - (DOUBLE) n >= 0.5 ) {
	n++ ;
    }
    error = n_DOUBLE - (DOUBLE) n ;

    while( total + n > num_clustersG ) {
	n-- ;
    }

    if( length_in_row + n * cluster_widthG > barrayG[row]->desire ) {
	if( row == numRowsG ) {
	    /*  can't fit all the required clusters; increase cluster_norm */
	    ++cluster_norm_offsetS ;
	    for( row = 1 ; row <= numRowsG ; row++ ) {
		Ysafe_free( cluster_configS[row] ) ;
	    }
	    Ysafe_free( cluster_configS ) ;
	    install_clusters() ;
	    return ;
	}
	n = (barrayG[row]->desire - length_in_row) / cluster_widthG ;
	if( n < 0 ) {
	    n = 0 ;
	}
	error += (DOUBLE)( (INT) n_DOUBLE - n ) ; 
    }

    if( n == 0 ) {
	continue ;
    }
    total += n ;

    i_error = 0 ;
    bin = 0 ;
    for( i = 0 ; i < n ; i++ ) {
	delta_bin = (numBinsG + i_error) / n ;
	bin += delta_bin ;
	i_error += numBinsG - delta_bin * n ;
	if( bin < 1 ) bin = 1 ;
	if( bin > numBinsG ) bin = numBinsG ;
	cluster_configS[row][bin]++ ;
    }

    fprintf(fpoG,"Number of clusters added to row:%d was:%d\n", row,i);
    total_actual_clusters += i ;
    for( bin = 1 ; bin <= numBinsG ; bin++ ) {
	if( cluster_configS[row][bin] >= 1 ) {
	    barrayG[row]->oldsize += cluster_configS[row][bin] *
						    cluster_widthG ;
	}
    }
}
fprintf(fpoG,"actual total number of clusters which were added in: %d\n",
			total_actual_clusters ) ;
return;
} /* end install_clusters */
Exemplo n.º 9
0
void
free_mem()
{

    int i;
    int j;
    LISTPTR Pnode;
    TREEPTR *tarray;

    totnodes = numnodes + maxpins;
    totedges = numedges + maxpins;

    for (i = 1; i <= totnodes; i++)
    {
	tarray = garray[i]->tree;
	for (j = 0; j <= totnodes; j++)
	{
	    Ysafe_free((char *) tarray[j]);
	}
	Ysafe_free((char *) tarray);

	Pnode = garray[i]->first;
	while (Pnode)
	{
	    garray[i]->first = garray[i]->first->next;
	    Ysafe_free((char *) Pnode);
	    Pnode = garray[i]->first;
	}

	Ysafe_free((char *) garray[i]);
    }
    Ysafe_free((char *) garray);

    for (i = 1; i <= numnodes; i++)
    {
	tarray = sarray[i]->tree;
	for (j = 0; j <= numnodes; j++)
	{
	    Ysafe_free((char *) tarray[j]);
	}
	Ysafe_free((char *) tarray);
	sarray[i]->tree = NIL(TREEPTR);
    }
    garray = sarray;

    for (i = 1; i <= totedges; i++)
    {
	Ysafe_free((char *) earray[i]);
    }
    Ysafe_free((char *) earray);

    for (i = 1; i <= numedges; i++)
    {
	Ysafe_free((char *) carray[i]);
    }
    Ysafe_free((char *) carray);

} /* end of free_mem */
Exemplo n.º 10
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 */
Exemplo n.º 11
0
/*=====================================================================
*  In order to have this file work properly, there must be a blank line
* between the records of two consecutive nets and the very first line
* can not be a blank line. Also the name of nets can not be over 256
* characters.
=====================================================================*/
BOOLEAN
read_one_net()
{
    char input[LRECL];
    char **tokens;
    int i;
    int v1; /* Vertex index */
    int v2; /* Vertex index */
    int pin;
    int equiv;
    INT numtokens;

    C_LISTPTR Pnew;
    LISTPTR Pnode;
    PINPTR Pfirst; /* Header of the pin list */
    PINPTR Ppin;

    EQUIVAL = FALSE;
    SHIFTED = FALSE;
    CAP_MATCH = FALSE;
    MIX_MATCH = FALSE;
    RES_MATCH = FALSE;
    COMMON_POINT = FALSE;

    equiv = 0;
    numpins = 0;
    net_type = 0;
    numcomms = 0;
    max_volt_drop = 0;
    Pfirst = NIL(PIN);
    Plist = NIL(C_LIST);

    while (fgets(input, LRECL, fin))
    {
	tokens = Ystrparser(input, " \t\n", &numtokens);

	if (numtokens == 0)
	{
	    /***********************************************************
	    * An empty line is reached. A complete record is read in
	    * so quit reading the net.
	    ***********************************************************/
	    break;
	}

	if (strncmp(tokens[0], "net", 3) == STRINGEQ)
	{
	    /***********************************************************
	    * The beginning of a digital net is read in. Get the net
	    * name and set the net type to be noisy.
	    ***********************************************************/
	    (void) strcpy(netName, tokens[1]);
	    DIGITAL = TRUE;
	    net_type = NOISY;
	}
	else if (strncmp(tokens[0], "analog_net", 10) == STRINGEQ)
	{
	    /***********************************************************
	    * The beginning of an analog net is read in. Get the net
	    * name and read in the capacitance upper bound, resistance
	    * upper bound, maximum value of the voltage drop, plus the
	    * net type specification. Note that not all the  parameters
	    * have to be present.
	    ***********************************************************/
	    (void) strcpy(netName, tokens[1]);

	    if (numtokens < 3)
	    {
		ERROR1("\n\nThe entry line for an analog net must have ");
		ERROR1("at least 3 fields!\n");
		ERROR2("Net name: %s\n", netName);
		exit(GP_FAIL);
	    }

	    for (i = 2; i < numtokens; i += 2)
	    {
		if (strncmp(tokens[i], "cap", 3) == STRINGEQ)
		{
		    cap_upper_bound = atof(tokens[i+1]);
		}
		else if (strncmp(tokens[i], "res", 3) == STRINGEQ)
		{
		    res_upper_bound = atof(tokens[i+1]);
		}
		else if (strncmp(tokens[i], "max_drop", 8) == STRINGEQ)
		{
		    max_volt_drop = atof(tokens[i+1]);
		}
		else if (strncmp(tokens[i], "noisy", 5) == STRINGEQ)
		{
		    if (net_type == SENSITIVE)
		    {
			net_type = MIXED;
		    }
		    else if(net_type == SHIELD)
		    {
			ERROR1("\n\n");
			ERROR1("A net can not be NOISY and SHIELDING ");
			ERROR1("at the same time\n");
			ERROR2("Net name: %s\n", netName);
			exit(GP_FAIL);
		    }
		    else
		    {
			net_type = NOISY;
		    }
		    i--;
		}
		else if(strncmp(tokens[i], "sensitive", 9) == STRINGEQ)
		{
		    if (net_type == NOISY)
		    {
			net_type = MIXED;
		    }
		    else if(net_type == SHIELD)
		    {
			ERROR1("\n\nA net can not be SENSITIVE and ");
			ERROR1("SHIELDING at the same time\n");
			ERROR2("Net name: %s\n", netName);
			exit(GP_FAIL);
		    }
		    else
		    {
			net_type = SENSITIVE;
		    }
		    i--;
		}
		else if (strncmp(tokens[i], "shielding", 9) == STRINGEQ)
		{
		    if (net_type == NOISY || net_type == SENSITIVE)
		    {
			ERROR1("\n\nA net can not be SENSITIVE and ");
			ERROR1("SHIELDING or NOISY and\n");
			ERROR1("SHIELDING at the same time\n");
			ERROR2("Net name: %s\n", netName);
			exit(GP_FAIL);
		    }
		    else
		    {
			net_type = SHIELD;
		    }
		    i--;
		}
		else
		{
		    ERROR1("\n\n");
		    ERROR2("Unknown keyword \"%s\" for the ", tokens[i]);
		    ERROR2("net %s.\nNotice that the keywords", netName);
		    ERROR1(" are case-sensitive. DO NOT USE capital");
		    ERROR1(" letters in the keywords.\n");
		    exit(GP_FAIL);
		}
	    }
	    if (!net_type)
	    {
		ERROR1("\n\nNet type must be specified for analog nets");
		ERROR2(".\nNo net type is specified for net %s\n",
		    netName);
		exit(GP_FAIL);
	    }
	    DIGITAL = FALSE;
	}
	else if (strncmp(tokens[0], "common_point", 12) == STRINGEQ)
	{
	    numcomms++;
	    Pnew = (C_LISTPTR) Ysafe_malloc(sizeof(C_LIST));
	    Pnew->numpin = atoi(tokens[1]);
	    Pnew->cap_match = FALSE;
	    Pnew->res_match = FALSE;
	    Pnew->next = Plist;
	    Plist = Pnew;
	    COMMON_POINT = TRUE;
	}
	else if (strncmp(tokens[0], "pin", 3) == STRINGEQ
	      || strncmp(tokens[0], "equiv", 5) == STRINGEQ)
	{
	    Ppin = (PINPTR) Ysafe_malloc(sizeof(PIN));
	    if (tokens[0][0] == 'e')
	    {
		/*********************************************************
		* This pin is an equivalent pin of the previous pin(s).
		*********************************************************/
		EQUIVAL = TRUE;
		if (Pfirst->equiv)
		{
		    Ppin->equiv = Pfirst->equiv;
		}
		else
		{
		    Ppin->equiv = ++equiv;
		    Pfirst->equiv = equiv;
		}
	    }
	    else
	    {
		Ppin->equiv = FALSE;
	    }
	    Ppin->node[0] = v1 = atoi(tokens[5]);
	    Ppin->node[1] = v2 = atoi(tokens[6]);
	    Ppin->shifted = FALSE;
	    Ppin->vertex = ++numpins;
	    Ppin->pin[0] = Ppin->pin[1] = 0;
	    Ppin->dist[0] = atoi(tokens[8]);

	    if (numtokens == ANALOG_PIN)
	    {
		Ppin->density = atoi(tokens[11]);
	    }
	    else
	    {
		Ppin->density = 0;
	    }

	    /***********************************************************
	    * Find the edge index of the channel on which the pin is
	    * located. This is for removing the rectilinear restriction.
	    ***********************************************************/
	    Pnode = garray[v1]->first;
	    while (Pnode->t_vertex != v2)
	    {
		Pnode = Pnode->next;
	    }

	    Ppin->dist[1] = Pnode->length - Ppin->dist[0];

	    /*********************************************************
	    * Check if the pin overlaps with a vertex of the channel
	    * graph. If so, we have to shift the pin along the channel
	    * a bit due to the data structure. 
	    *********************************************************/
	    if (!(Ppin->dist[0]))
	    {
		/*****************************************************
		* The pin overlaps with vertex v1 of the channel
		* graph.
		*****************************************************/
		Ppin->dist[0]++;
		Ppin->dist[1]--;
		Ppin->shifted = 1;
		SHIFTED = TRUE;
	    }

	    if (!(Ppin->dist[1]))
	    {
		/*****************************************************
		* The pin overlaps with vertex v2 of the channel
		* graph.
		*****************************************************/
		Ppin->dist[0]--;
		Ppin->dist[1]++;
		Ppin->shifted = -1;
		SHIFTED = TRUE;
	    }

	    Ppin->next = Pfirst;
	    Pfirst = Ppin;
	}
	else if (strncmp(tokens[0], "cap_match", 9) == STRINGEQ)
	{
	    Pnew->cap_match = TRUE;
	}
	else if (strncmp(tokens[0], "res_match", 9) == STRINGEQ)
	{
	    Pnew->res_match = TRUE;
	}
	else
	{
	    ERROR1("\n\n");
	    ERROR2("Unknown keyword \"%s\" in the record ", tokens[0]);
	    ERROR2("for the net %s\n", netName);
	    exit(GP_FAIL);
	}
    }

    if (numpins)
    {
	/***********************************************************
	* Make an array for the list of pins.
	***********************************************************/
	pin = numpins;
	parray = (PINPTR *) Ysafe_malloc((numpins+1) * sizeof(PINPTR));
	while (Pfirst)
	{
	    parray[pin--] = Pfirst;
	    Pfirst = Pfirst->next;
	}
    }

    if (EQUIVAL == TRUE)
    {
	/***********************************************************
	* Make each group of equivalent pins a circular linked list
	* which will be used to construct the segment tree.
	***********************************************************/
	for (i = 1; i <= numpins ;)
	{
	    if (parray[i]->equiv)
	    {
		v1 = i;
		v2 = i + 1;
		pin = parray[i]->equiv;

		while (v2 <= numpins && parray[v2]->equiv == pin)
		{
		    parray[v1]->next = parray[v2];
		    v1++;
		    v2++;
		}

		parray[v1]->next = parray[i];
		i = v2;
	    }
	    else
	    {
		parray[i]->next = NIL(PIN);
		i++;
	    }
	}

	/***********************************************************
	* Check each set of equivalent pins on their geometric
	* positions and make sure that they are NOT on top each
	* other.
	***********************************************************/
	for (i = 1; i <= numpins; i++)
	{
	    if (parray[i]->next)
	    {
		/*********************************************************
		* A set of equivalent pins is found. Check each pair of
		* the equivalent pins in the set and make sure that none
		* of them are on top each other.
		*********************************************************/
		Pfirst = parray[i];
		while (Pfirst->next != parray[i])
		{
		    for (Ppin = Pfirst->next;
			 Ppin != Pfirst;
			 Ppin = Ppin->next)
		    {
			if (Pfirst->dist[0] == Ppin->dist[0]
			 && Pfirst->node[0] == Ppin->node[0]
			 && Pfirst->node[1] == Ppin->node[1])
			{
			    ERROR1("\n\n");
			    ERROR1("FATAL ERROR: Equivalent pins are ");
			    ERROR1("on top each other in the net ");
			    ERROR2("%s.\nMust exit. Sorry!\n\n", netName);
			    exit(GP_FAIL);
			}
		    }
		    Pfirst = Pfirst->next;
		}
	    }
	}
    }
    else
    {
	/***********************************************************
	* There are equivalent pins in this net. Clean the field
	* next in parray.
	***********************************************************/
	for (i = 1; i <= numpins; i++)
	{
	    parray[i]->next = NIL(PIN);
	}
    }

    if (COMMON_POINT != FALSE)
    {
	/***********************************************************
	* There exit common pins in this net. Make sure the common
	* pins have no equivalent pins to them. Mickey can not
	* handle common pins with equivalent pins.
	***********************************************************/
	v1 = 0;
	Pnew = Plist;
	while (Pnew)
	{
	    v2 = Pnew->numpin;
	    for (i = ++v1; i < v2; i++)
	    {
		if (parray[i]->next)
		{
		    ERROR1("\n\nMickey can not handle pins which are");
		    ERROR1(" equivalent pins\n and");
		    ERROR1(" are to be connected to a common point\n");
		    exit(GP_FAIL);
		}
		parray[i]->next = parray[i+1];
	    }
	    parray[i]->next = parray[v1];
	    v1 = i + 1;
	    Pnew = Pnew->next;
	}

	while (Plist)
	{
	    Pnew = Plist;
	    Plist = Plist->next;
	    Ysafe_free((char *) Pnew);
	}
    }

    return(numpins);
} /* end of read_one_net */
Exemplo n.º 12
0
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 */
}
}