magic/gcr/gcrFlags.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;
}
}
}
}