328 lines
8.4 KiB
C
328 lines
8.4 KiB
C
/*
|
|
* grouteDens.c
|
|
*
|
|
* Procedures for manipulating DensMap structures.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/grouter/grouteDens.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* lint */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/hash.h"
|
|
#include "utils/heap.h"
|
|
#include "tiles/tile.h"
|
|
#include "database/database.h"
|
|
#include "utils/netlist.h"
|
|
#include "gcr/gcr.h"
|
|
#include "router/router.h"
|
|
#include "grouter/grouter.h"
|
|
#include "utils/signals.h"
|
|
#include "textio/textio.h"
|
|
#include "utils/malloc.h"
|
|
#include "utils/styles.h"
|
|
#include "debug/debug.h"
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDensAdjust --
|
|
*
|
|
* Increment the density in the channel as a result of routing the segment
|
|
* from p1 to p2 through the channel common to both. The segment is
|
|
* identified by the NetId 'netid'. The density map 'dens' is incremented
|
|
* for each column/row of the channel through which the segment must run,
|
|
* where the segment doesn't already exist.
|
|
*
|
|
* Results:
|
|
* Returns TRUE if any more of srcPin->gcr_ch became filled
|
|
* up to maximum density.
|
|
*
|
|
* Side effects:
|
|
* Modifies the local and possibly the maximum densities in *dens.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
bool
|
|
glDensAdjust(dens, srcPin, dstPin, netid)
|
|
DensMap dens[2];
|
|
GCRPin *srcPin, *dstPin;
|
|
NetId netid;
|
|
{
|
|
int minprow, maxprow, minpcol, maxpcol, mincol, maxcol, minrow, maxrow;
|
|
int maxvd, maxhd, col, row, nrow, ncol;
|
|
GCRChannel *ch = srcPin->gcr_ch;
|
|
GCRPin *p1, *p2;
|
|
short *dvec;
|
|
bool densChanged;
|
|
|
|
/* Sanity checking */
|
|
ASSERT(srcPin && dstPin, "glDensAdjust");
|
|
ASSERT(srcPin->gcr_ch == dstPin->gcr_ch, "glDensAdjust");
|
|
|
|
if (DebugIsSet(glDebugID, glDebGreedy))
|
|
return FALSE;
|
|
|
|
/*
|
|
* Find the first and last column where this net (netId)
|
|
* is previously present in the channel, and also the first
|
|
* and last row.
|
|
*/
|
|
nrow = dens[CZ_ROW].dm_size - 1;
|
|
ncol = dens[CZ_COL].dm_size - 1;
|
|
maxprow = 0, minprow = dens[CZ_ROW].dm_size;
|
|
maxpcol = 0, minpcol = dens[CZ_COL].dm_size;
|
|
|
|
/* Rows */
|
|
p1 = &ch->gcr_lPins[1], p2 = &ch->gcr_rPins[1];
|
|
for (row = 1; row < dens[CZ_ROW].dm_size; row++, p1++, p2++)
|
|
{
|
|
if (SAMENET(p1, netid.netid_net, netid.netid_seg))
|
|
{
|
|
minpcol = 1;
|
|
minprow = MIN(row, minprow);
|
|
maxprow = MAX(row, maxprow);
|
|
}
|
|
if (SAMENET(p2, netid.netid_net, netid.netid_seg))
|
|
{
|
|
maxpcol = ncol;
|
|
minprow = MIN(row, minprow);
|
|
maxprow = MAX(row, maxprow);
|
|
}
|
|
}
|
|
|
|
/* Columns */
|
|
p1 = &ch->gcr_bPins[1], p2 = &ch->gcr_tPins[1];
|
|
for (col = 1; col < dens[CZ_COL].dm_size; col++, p1++, p2++)
|
|
{
|
|
if (SAMENET(p1, netid.netid_net, netid.netid_seg))
|
|
{
|
|
minprow = 1;
|
|
minpcol = MIN(col, minpcol);
|
|
maxpcol = MAX(col, maxpcol);
|
|
}
|
|
if (SAMENET(p2, netid.netid_net, netid.netid_seg))
|
|
{
|
|
maxprow = nrow;
|
|
minpcol = MIN(col, minpcol);
|
|
maxpcol = MAX(col, maxpcol);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Increment the density over any range where
|
|
* this net was not already present but is now.
|
|
*/
|
|
p1 = srcPin;
|
|
p2 = dstPin;
|
|
|
|
#define CLIPTORANGE(x, min, max) \
|
|
((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
|
|
|
densChanged = FALSE;
|
|
minrow = MIN(p1->gcr_y, p2->gcr_y);
|
|
minrow = CLIPTORANGE(minrow, 1, nrow);
|
|
maxrow = MAX(p1->gcr_y, p2->gcr_y);
|
|
maxrow = CLIPTORANGE(maxrow, 1, nrow);
|
|
maxvd = dens[CZ_ROW].dm_max;
|
|
dvec = dens[CZ_ROW].dm_value;
|
|
for (row = minrow; row <= maxrow; row++)
|
|
if (row < minprow || row > maxprow)
|
|
if (++dvec[row] >= maxvd)
|
|
{
|
|
densChanged = TRUE;
|
|
maxvd = dvec[row];
|
|
}
|
|
dens[CZ_ROW].dm_max = maxvd;
|
|
|
|
mincol = MIN(p1->gcr_x, p2->gcr_x);
|
|
mincol = CLIPTORANGE(mincol, 1, ncol);
|
|
maxcol = MAX(p1->gcr_x, p2->gcr_x);
|
|
maxcol = CLIPTORANGE(maxcol, 1, ncol);
|
|
maxhd = dens[CZ_COL].dm_max;
|
|
dvec = dens[CZ_COL].dm_value;
|
|
for (col = mincol; col <= maxcol; col++)
|
|
if (col < minpcol || col > maxpcol)
|
|
if (++dvec[col] >= maxhd)
|
|
{
|
|
maxhd = dvec[col];
|
|
densChanged = TRUE;
|
|
}
|
|
dens[CZ_COL].dm_max = maxhd;
|
|
return densChanged;
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDMAlloc --
|
|
*
|
|
* Allocate and zero the dm_value array for the DensMap structure 'dm'.
|
|
* This array will have size 'top+1'. The maximum capacity is 'cap'.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
glDMAlloc(dm, top, cap)
|
|
DensMap *dm;
|
|
int top, cap;
|
|
{
|
|
dm->dm_max = 0;
|
|
dm->dm_size = top + 1;
|
|
dm->dm_cap = cap;
|
|
dm->dm_value = (short *) callocMagic((unsigned) (sizeof (short) * dm->dm_size));
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDMCopy --
|
|
*
|
|
* Copy the DensMap structure *dm1 to *dm2, copying the dm_value array
|
|
* as well. (The two DensMap structures better have the same size;
|
|
* also, dm2->dm_value must already be allocated).
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
glDMCopy(dm1, dm2)
|
|
DensMap *dm1, *dm2;
|
|
{
|
|
dm2->dm_max = dm1->dm_max;
|
|
ASSERT(dm2->dm_size == dm1->dm_size, "glDMCopy");
|
|
ASSERT(dm2->dm_cap == dm1->dm_cap, "glDMCopy");
|
|
bcopy((char *) dm1->dm_value, (char *) dm2->dm_value,
|
|
sizeof (short) * dm1->dm_size);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDMFree --
|
|
*
|
|
* Free the memory allocated to dm->dm_value.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* Frees memory.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
glDMFree(dm)
|
|
DensMap *dm;
|
|
{
|
|
freeMagic((char *) dm->dm_value);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDMMaxInRange --
|
|
*
|
|
* Return the maximum value of the DensMap in the inclusive range lo .. hi.
|
|
*
|
|
* Results:
|
|
* See above.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
glDMMaxInRange(dm, lo, hi)
|
|
DensMap *dm;
|
|
int lo, hi;
|
|
{
|
|
short *dval = dm->dm_value;
|
|
int n, max;
|
|
|
|
/* Sanity checks */
|
|
ASSERT(lo > 0, "glDMMaxInRange");
|
|
ASSERT(hi < dm->dm_size, "glDMMaxInRange");
|
|
|
|
max = 0;
|
|
for (n = lo; n <= hi; n++)
|
|
if (dval[n] > max)
|
|
max = dval[n];
|
|
|
|
return (max);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* glDensInit --
|
|
*
|
|
* Initialize the DensMap pair dmap[] from the already-initialized
|
|
* density map in the GCRChannel *ch. (The use of two separate kinds
|
|
* of density maps is a temporary measure that will go away when the
|
|
* integration of the new routing code is complete).
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
glDensInit(dmap, ch)
|
|
DensMap dmap[2];
|
|
GCRChannel *ch;
|
|
{
|
|
short *dSrc, *dDst, *dEnd;
|
|
|
|
dmap[CZ_COL].dm_max = ch->gcr_dMaxByCol;
|
|
dmap[CZ_ROW].dm_max = ch->gcr_dMaxByRow;
|
|
dSrc = ch->gcr_dRowsByCol;
|
|
dDst = dmap[CZ_COL].dm_value;
|
|
dEnd = &dmap[CZ_COL].dm_value[dmap[CZ_COL].dm_size];
|
|
while (dDst < dEnd)
|
|
*dDst++ = *dSrc++;
|
|
|
|
dSrc = ch->gcr_dColsByRow;
|
|
dDst = dmap[CZ_ROW].dm_value;
|
|
dEnd = &dmap[CZ_ROW].dm_value[dmap[CZ_ROW].dm_size];
|
|
while (dDst < dEnd)
|
|
*dDst++ = *dSrc++;
|
|
}
|