-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathgcrRiver.c
179 lines (159 loc) · 5.11 KB
/
gcrRiver.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
* gcrRiver.c -
*
* The greedy router: river-routing across the tops of channels.
*
* *********************************************************************
* * 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/gcrRiver.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 "gcr/gcr.h"
#include "textio/textio.h"
#include "utils/malloc.h"
/* Forward declarations */
bool gcrOverCellVert();
bool gcrOverCellHoriz();
/*
* ----------------------------------------------------------------------------
*
* gcrRiverRoute --
*
* Determine if a channel should be routed by a simple river-router;
* if so, then route it. Currently, river-routing channels are identified
* during channel decomposition.
*
* Results:
* Returns TRUE on success, FALSE on failure (in which case
* the caller should try to route the channel by other means.
*
* Side effects:
* If successful, sets flags in the channel structure to show
* where routing is to be placed.
*
* ----------------------------------------------------------------------------
*/
bool
gcrRiverRoute(ch)
GCRChannel *ch;
{
switch (ch->gcr_type)
{
case CHAN_HRIVER:
if (gcrOverCellHoriz(ch))
return (TRUE);
break;
case CHAN_VRIVER:
if (gcrOverCellVert(ch))
return (TRUE);
break;
}
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* gcrOverCellHoriz --
* gcrOverCellVert --
*
* Route an over-cell channel if possible. These channels should be
* river-routable. We perform a few quick checks to ensure that there
* are terminals only on opposite sides in pairs. Channels routed
* horizontally are processed by gcrOverCellHoriz(); those routed
* vertically are processed by gcrOverCellVert().
*
* Results:
* TRUE if the channel met our requirements and we routed it
* successfully; FALSE if we couldn't route it.
*
* Side effects:
* Sets flags in the channel structure to show where routing
* is to be placed.
*
* ----------------------------------------------------------------------------
*/
#define USED(pin) \
((pin)->gcr_pId != (GCRNet *) 0 && (pin)->gcr_pId != (GCRNet *) -1)
bool
gcrOverCellHoriz(ch)
GCRChannel *ch;
{
short **result = ch->gcr_result;
int col, row;
/* Ensure top and bottom pins aren't used */
for (col = 1; col <= ch->gcr_length; col++)
if (USED(&ch->gcr_tPins[col]) || USED(&ch->gcr_bPins[col]))
{
TxPrintf("Failing because top or bottom pins are used\n");
return (FALSE);
}
/* Ensure left and right pins match */
for (row = 1; row <= ch->gcr_width; row++)
if (USED(&ch->gcr_lPins[row]) && USED(&ch->gcr_rPins[row]))
{
if (ch->gcr_lPins[row].gcr_pId != ch->gcr_rPins[row].gcr_pId
|| ch->gcr_lPins[row].gcr_pSeg != ch->gcr_rPins[row].gcr_pSeg)
{
TxPrintf("Failing because left and right pins don't match\n");
return (FALSE);
}
}
/*
* Channel is routable by a simple river-router:
* zoom across for each row that is to be connected
* across the channel.
*/
for (row = 1; row <= ch->gcr_width; row++)
if (USED(&ch->gcr_lPins[row]))
for (col = 0; col <= ch->gcr_length; col++)
result[col][row] |= GCRR;
return (TRUE);
}
bool
gcrOverCellVert(ch)
GCRChannel *ch;
{
short **result = ch->gcr_result;
int col, row;
/* Ensure left and right pins aren't used */
for (row = 1; row <= ch->gcr_width; row++)
if (USED(&ch->gcr_lPins[row]) || USED(&ch->gcr_rPins[row]))
{
TxPrintf("Failing because left or right pins are used\n");
return (FALSE);
}
/* Ensure top and bottom pins match */
for (col = 1; col <= ch->gcr_length; col++)
if (USED(&ch->gcr_tPins[col]) && USED(&ch->gcr_bPins[col]))
{
if (ch->gcr_tPins[col].gcr_pId != ch->gcr_bPins[col].gcr_pId
|| ch->gcr_tPins[col].gcr_pSeg != ch->gcr_bPins[col].gcr_pSeg)
{
TxPrintf("Failing because top and bottom pins don't match\n");
return (FALSE);
}
}
/*
* Channel is routable by a simple river-router:
* zoom across for each column that is to be connected
* across the channel.
*/
for (col = 1; col <= ch->gcr_length; col++)
if (USED(&ch->gcr_tPins[col]))
for (row = 0; row <= ch->gcr_width; row++)
result[col][row] |= GCRU;
return (TRUE);
}