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;
|
||
}
|
||
}
|
||
}
|
||
}
|