145 lines
4.7 KiB
C
145 lines
4.7 KiB
C
/* gcrFlags.c -
|
|
*
|
|
* Code to set contact and end flags at each grid point in a channel.
|
|
* This code assumes the channel has already been transformed into left
|
|
* to right routing form. These flags are used during channel routing.
|
|
*
|
|
* Hazard flags are set in the router module, as they are needed by the
|
|
* global router. The contact and end flags can not be set at that
|
|
* time, since we don't yet know in which direction the channel will be
|
|
* routed.
|
|
*
|
|
* CONTACT FLAGS mark clear locations bordering single layer obstacles.
|
|
* Extending a track horizontally across an obstacle requires a track
|
|
* contact and a layer switch. Extending a column vertically across an
|
|
* obstacle requires a column contact and a layer switch.
|
|
*
|
|
* END FLAGS mark locations beyond which tracks or columns cannot be
|
|
* extended due to two-layer obstacles.
|
|
*
|
|
* *********************************************************************
|
|
* * 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/gcr/gcrFlags.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "tiles/tile.h"
|
|
#include "gcr/gcr.h"
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* gcrSetFlags --
|
|
*
|
|
* Scan the channel obstacle map. Set flags for track and column
|
|
* contacts, and track and column termination.
|
|
*
|
|
* Use a top to bottom, left to right point by point scan. Wherever
|
|
* a vertical boundary between space and a track material obstacle
|
|
* occurs, make a track contact flag. Wherever a horizontal boundary
|
|
* between space and a column material obstacle occurs, make a column
|
|
* contact flag.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
gcrSetFlags(ch)
|
|
GCRChannel *ch; /* The channel to be flagged */
|
|
{
|
|
short *curPtr, *nextPtr;
|
|
short **map, *curCol, *curEnd, *nextCol;
|
|
int col;
|
|
|
|
/*
|
|
* Scan the channel bottom to top, left to right.
|
|
* For each location scanned, look up and right to
|
|
* figure out what flags to set.
|
|
*/
|
|
map = ch->gcr_result;
|
|
nextCol = map[1];
|
|
for (col = 1; col <= ch->gcr_length; col++)
|
|
{
|
|
curCol = nextCol;
|
|
curEnd = &curCol[ch->gcr_width];
|
|
nextCol = map[col+1];
|
|
for (curPtr = &curCol[1], nextPtr = &nextCol[1];
|
|
curPtr <= curEnd;
|
|
curPtr++, nextPtr++)
|
|
{
|
|
/*
|
|
* Set column contact bits at the border between space and poly.
|
|
* Set column end bits at the border of blocked areas.
|
|
*/
|
|
if (CLEAR(*curPtr))
|
|
{
|
|
if (HAS_M(*nextPtr)) /* Look right for track obstacle */
|
|
*curPtr |= GCRTC;
|
|
else if (BLOCK(*nextPtr)) /* Look right for blocked area */
|
|
*curPtr |= GCRTE;
|
|
|
|
if (HAS_P(*(curPtr+1))) /* Look up for column obstacle */
|
|
*curPtr |= GCRCC;
|
|
else if (BLOCK(*(curPtr+1)))/* Look up for blocked area */
|
|
*curPtr |= GCRCE;
|
|
}
|
|
else if (HAS_P(*curPtr))
|
|
{
|
|
if (HAS_M(*nextPtr))
|
|
*curPtr |= GCRTE;
|
|
else if (BLOCK(*nextPtr))
|
|
*curPtr |= GCRTE;
|
|
|
|
if (CLEAR(*(curPtr+1))) /* Look up for column obstacle end */
|
|
*(curPtr+1) |= GCRCC;
|
|
else if (HAS_M(*(curPtr+1)) || BLOCK(*(curPtr+1)))
|
|
*curPtr |= GCRCE; /* Look up for column blocked */
|
|
}
|
|
else if (HAS_M(*curPtr))
|
|
{
|
|
if (CLEAR(*nextPtr)) /* Look right for track obstacle end */
|
|
*nextPtr |= GCRTC;
|
|
else if (HAS_P(*nextPtr) || BLOCK(*nextPtr))
|
|
*curPtr |= GCRTE; /* Look right for blocked area */
|
|
|
|
if (HAS_P(*(curPtr+1)) || BLOCK(*(curPtr+1)))
|
|
{
|
|
*curPtr |= GCRCE; /* Look up for column blocked */
|
|
*(curPtr+1) |= GCRCE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* When a contact is encountered, mark self and up.
|
|
* Don't need to mark GCRTE to the right, since this
|
|
* flag simply means that the track is blocked to the right.
|
|
*/
|
|
ASSERT(BLOCK(*curPtr), "Bizarre case");
|
|
*curPtr |= (GCRTE | GCRCE);
|
|
*(curPtr+1) |= GCRCE;
|
|
}
|
|
}
|
|
}
|
|
}
|