-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathgcrFlags.c
144 lines (135 loc) · 4.7 KB
/
gcrFlags.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* 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;
}
}
}
}