/* 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 #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; } } } }