summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2015-09-11 07:39:55 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2015-09-11 07:39:55 +0200
commit160fcb379168bdc472699865daa79d76441a2039 (patch)
tree3fc159177dfd554fc5c141e2678edf7cdf0665df
parent24f45f018e6f0b94e13e5cf71a2d1ef44ee635b8 (diff)
parentab5e89b0c2f41e1b36c8e6a4d899737a97f7e488 (diff)
Merge tag 'upstream/1.3.15'
-rw-r--r--VERSION2
-rw-r--r--node.c47
-rw-r--r--qrouter.c151
-rw-r--r--qrouter.h1
4 files changed, 140 insertions, 61 deletions
diff --git a/VERSION b/VERSION
index 90a7f60..5bdcf5c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.12
+1.3.15
diff --git a/node.c b/node.c
index c282786..1131d4f 100644
--- a/node.c
+++ b/node.c
@@ -836,16 +836,16 @@ void create_obstructions_from_gates()
/ PitchY[ds->layer]) - 1;
while (1) {
dy = (gridy * PitchY[ds->layer]) + Ylowerbound;
- if (dy > (ds->y2 + deltay)
+ if ((dy + EPS) > (ds->y2 + deltay)
|| gridy >= NumChannelsY[ds->layer]) break;
- if (dy >= (ds->y1 - deltay) && gridy >= 0) {
+ if ((dy - EPS) >= (ds->y1 - deltay) && gridy >= 0) {
// If it clears distance for a route layer but not
// vias, then block vias only.
deltaxy = get_route_clear(ds->layer, ds);
- if ((dx < (ds->x1 - deltaxy)) ||
- (dx > (ds->x2 + deltaxy)) ||
- (dy < (ds->y1 - deltaxy)) ||
- (dy > (ds->y2 + deltaxy))) {
+ if (((dx - EPS) < (ds->x1 - deltaxy)) ||
+ ((dx + EPS) > (ds->x2 + deltaxy)) ||
+ ((dy - EPS) < (ds->y1 - deltaxy)) ||
+ ((dy + EPS) > (ds->y2 + deltaxy))) {
block_route(gridx, gridy, ds->layer, UP);
block_route(gridx, gridy, ds->layer, DOWN);
}
@@ -1155,7 +1155,8 @@ void create_obstructions_from_nodes()
}
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = (u_int)node->netnum | dir;
+ = (Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ & BLOCKED_MASK) | (u_int)node->netnum | dir;
Nodeloc[ds->layer][OGRID(gridx, gridy, ds->layer)]
= node;
Nodesav[ds->layer][OGRID(gridx, gridy, ds->layer)]
@@ -1194,7 +1195,8 @@ void create_obstructions_from_nodes()
Nodesav[ds->layer][OGRID(gridx, gridy, ds->layer)]
= node;
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = (u_int)node->netnum;
+ = (Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ & BLOCKED_MASK) | (u_int)node->netnum;
if (orignet & OBSTRUCT_N) {
offd = -(sdisty - Obsinfo[ds->layer]
@@ -1266,7 +1268,8 @@ void create_obstructions_from_nodes()
((dy - ds->y1 + EPS) > deltay) &&
((ds->y2 - dy + EPS) > deltay)) {
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = (u_int)node->netnum;
+ = (Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ & BLOCKED_MASK) | (u_int)node->netnum;
Nodeloc[ds->layer][OGRID(gridx, gridy, ds->layer)]
= node;
Nodesav[ds->layer][OGRID(gridx, gridy, ds->layer)]
@@ -1538,18 +1541,24 @@ void create_obstructions_from_nodes()
if ((k < Numnets) && (dir != STUBROUTE_X)) {
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = (u_int)g->netnum[i] | dir;
+ = (Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ & BLOCKED_MASK) | (u_int)g->netnum[i] | dir;
Nodeloc[ds->layer][OGRID(gridx, gridy, ds->layer)]
= node;
Nodesav[ds->layer][OGRID(gridx, gridy, ds->layer)]
= node;
}
- else {
+ else if ((Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ & NO_NET) != 0) {
// Keep showing an obstruction, but add the
// direction info and log the stub distance.
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
|= dir;
}
+ else {
+ Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
+ |= (dir | (g->netnum[i] & ROUTED_NET_MASK));
+ }
Stub[ds->layer][OGRID(gridx, gridy, ds->layer)]
= dist;
}
@@ -1704,7 +1713,9 @@ void create_obstructions_from_nodes()
Stub[ds->layer][OGRID(gridx, gridy,
ds->layer)] = ds->y1 - dy;
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = node->netnum | STUBROUTE_NS;
+ = (Obs[ds->layer][OGRID(gridx, gridy,
+ ds->layer)] & BLOCKED_MASK) |
+ node->netnum | STUBROUTE_NS;
Nodeloc[ds->layer][OGRID(gridx, gridy,
ds->layer)] = node;
Nodesav[ds->layer][OGRID(gridx, gridy,
@@ -1720,7 +1731,9 @@ void create_obstructions_from_nodes()
Stub[ds->layer][OGRID(gridx, gridy,
ds->layer)] = ds->y2 - dy;
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = node->netnum | STUBROUTE_NS;
+ = (Obs[ds->layer][OGRID(gridx, gridy,
+ ds->layer)] & BLOCKED_MASK) |
+ node->netnum | STUBROUTE_NS;
Nodeloc[ds->layer][OGRID(gridx, gridy,
ds->layer)] = node;
Nodesav[ds->layer][OGRID(gridx, gridy,
@@ -1738,7 +1751,9 @@ void create_obstructions_from_nodes()
Stub[ds->layer][OGRID(gridx, gridy,
ds->layer)] = ds->x1 - dx;
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = node->netnum | STUBROUTE_EW;
+ = (Obs[ds->layer][OGRID(gridx, gridy,
+ ds->layer)] & BLOCKED_MASK) |
+ node->netnum | STUBROUTE_EW;
Nodeloc[ds->layer][OGRID(gridx, gridy,
ds->layer)] = node;
Nodesav[ds->layer][OGRID(gridx, gridy,
@@ -1754,7 +1769,9 @@ void create_obstructions_from_nodes()
Stub[ds->layer][OGRID(gridx, gridy,
ds->layer)] = ds->x2 - dx;
Obs[ds->layer][OGRID(gridx, gridy, ds->layer)]
- = node->netnum | STUBROUTE_EW;
+ = (Obs[ds->layer][OGRID(gridx, gridy,
+ ds->layer)] & BLOCKED_MASK) |
+ node->netnum | STUBROUTE_EW;
Nodeloc[ds->layer][OGRID(gridx, gridy,
ds->layer)] = node;
Nodesav[ds->layer][OGRID(gridx, gridy,
diff --git a/qrouter.c b/qrouter.c
index 6995081..59906ca 100644
--- a/qrouter.c
+++ b/qrouter.c
@@ -512,28 +512,35 @@ int post_def_setup()
needblock[i] = (u_char)0;
sreq1 = LefGetRouteSpacing(i);
- if (i == 0)
- sreq2 = LefGetViaWidth(i, i, 0) + sreq1;
- else
- sreq2 = LefGetViaWidth(i - 1, i, 0) + sreq1;
+ sreq2 = LefGetViaWidth(i, i, 0) + sreq1;
if ((sreq2 - EPS) > PitchX[i]) needblock[i] |= VIABLOCKX;
- if (i == 0)
- sreq2 = LefGetViaWidth(i, i, 1) + sreq1;
- else
- sreq2 = LefGetViaWidth(i - 1, i, 1) + sreq1;
+ if (i != 0) {
+ sreq2 = LefGetViaWidth(i - 1, i, 0) + sreq1;
+ if ((sreq2 - EPS) > PitchX[i]) needblock[i] |= VIABLOCKX;
+ }
+
+ sreq2 = LefGetViaWidth(i, i, 1) + sreq1;
if ((sreq2 - EPS) > PitchY[i]) needblock[i] |= VIABLOCKY;
+ if (i != 0) {
+ sreq2 = LefGetViaWidth(i - 1, i, 1) + sreq1;
+ if ((sreq2 - EPS) > PitchY[i]) needblock[i] |= VIABLOCKY;
+ }
sreq1 += 0.5 * LefGetRouteWidth(i);
- if (i == 0)
- sreq2 = sreq1 + 0.5 * LefGetViaWidth(i, i, 0);
- else
- sreq2 = sreq1 + 0.5 * LefGetViaWidth(i - 1, i, 0);
+
+ sreq2 = sreq1 + 0.5 * LefGetViaWidth(i, i, 0);
if ((sreq2 - EPS) > PitchX[i]) needblock[i] |= ROUTEBLOCKX;
- if (i == 0)
- sreq2 = sreq1 + 0.5 * LefGetViaWidth(i, i, 1);
- else
- sreq2 = sreq1 + 0.5 * LefGetViaWidth(i - 1, i, 1);
+ if (i != 0) {
+ sreq2 = sreq1 + 0.5 * LefGetViaWidth(i - 1, i, 0);
+ if ((sreq2 - EPS) > PitchX[i]) needblock[i] |= ROUTEBLOCKX;
+ }
+
+ sreq2 = sreq1 + 0.5 * LefGetViaWidth(i, i, 1);
if ((sreq2 - EPS) > PitchY[i]) needblock[i] |= ROUTEBLOCKY;
+ if (i != 0) {
+ sreq2 = sreq1 + 0.5 * LefGetViaWidth(i - 1, i, 1);
+ if ((sreq2 - EPS) > PitchY[i]) needblock[i] |= ROUTEBLOCKY;
+ }
}
// Now we have netlist data, and can use it to get a list of nets.
@@ -697,10 +704,12 @@ void pathstart(FILE *cmd, int layer, int x, int y, u_char special, double oscale
if (special) {
double wvia;
- if (layer == 0)
- wvia = LefGetViaWidth(layer, layer, horizontal);
- else
- wvia = LefGetViaWidth(layer - 1, layer, horizontal);
+ wvia = LefGetViaWidth(layer, layer, horizontal);
+ if (layer > 0) {
+ double wvia2;
+ wvia2 = LefGetViaWidth(layer - 1, layer, horizontal);
+ if (wvia2 > wvia) wvia = wvia2;
+ }
fprintf(cmd, "%s %g ( %g %g ) ", CIFLayer[layer],
invscale * (int)(oscale * wvia + 0.5),
@@ -2446,6 +2455,7 @@ void cleanup_net(NET net)
for (layer = 0; layer < Num_layers; layer++) {
xcheck = needblock[layer] & VIABLOCKX;
ycheck = needblock[layer] & VIABLOCKY;
+
if (xcheck || ycheck) {
for (rt = net->routes; rt; rt = rt->next) {
fixed = FALSE;
@@ -2494,13 +2504,23 @@ void cleanup_net(NET net)
ls = seg->layer;
if (ls != layer && ls != layer - 1) continue;
if (fcheck) {
- if (ls != lf) {
- // NOTE: This is still an error, and we should
- // deal with it by creating a special net.
- continue;
- }
if ((ABSDIFF(seg->x1, segf->x1) == 1) &&
(seg->y1 == segf->y1) && xcheck) {
+ if (ls != lf) {
+ // NOTE: This is still an error, and we should
+ // deal with it by creating a special net.
+ SEG newseg;
+ newseg = (SEG)malloc(sizeof(struct seg_));
+ rt->segments = newseg;
+ newseg->next = segf;
+ newseg->layer = ll;
+ newseg->segtype = ST_WIRE;
+ newseg->x1 = segf->x1;
+ newseg->y1 = segf->y1;
+ newseg->x2 = seg->x1;
+ newseg->y2 = seg->y1;
+ continue;
+ }
segf->segtype = ST_WIRE;
segf->x1 = seg->x1;
fixed = TRUE;
@@ -2508,6 +2528,21 @@ void cleanup_net(NET net)
}
else if ((ABSDIFF(seg->y1, segf->y1) == 1) &&
(seg->x1 == segf->x1) && ycheck) {
+ if (ls != lf) {
+ // NOTE: This is still an error, and we should
+ // deal with it by creating a special net.
+ SEG newseg;
+ newseg = (SEG)malloc(sizeof(struct seg_));
+ rt->segments = newseg;
+ newseg->next = segf;
+ newseg->layer = ll;
+ newseg->segtype = ST_WIRE;
+ newseg->x1 = segf->x1;
+ newseg->y1 = segf->y1;
+ newseg->x2 = seg->x1;
+ newseg->y2 = seg->y1;
+ continue;
+ }
segf->segtype = ST_WIRE;
segf->y1 = seg->y1;
fixed = TRUE;
@@ -2515,14 +2550,24 @@ void cleanup_net(NET net)
}
}
if (lcheck) {
- if (ls != ll) {
- // NOTE: This is still an error, and we should
- // deal with it by creating a special net.
- continue;
- }
if ((ABSDIFF(seg->x1, segl->x1) == 1) &&
(seg->y1 == segl->y1) && xcheck) {
- if (lastrlayer < lastlayer) {
+ if (ls != ll) {
+ // NOTE: This is still an error, and we should
+ // deal with it by creating a special net.
+ SEG newseg;
+ newseg = (SEG)malloc(sizeof(struct seg_));
+ segl->next = newseg;
+ newseg->next = NULL;
+ newseg->layer = ll;
+ newseg->segtype = ST_WIRE;
+ newseg->x1 = segl->x1;
+ newseg->y1 = segl->y1;
+ newseg->x2 = seg->x1;
+ newseg->y2 = seg->y1;
+ continue;
+ }
+ else if (lastrlayer < lastlayer) {
seg->segtype = ST_WIRE;
seg->x2 = segl->x2;
}
@@ -2535,7 +2580,22 @@ void cleanup_net(NET net)
}
else if ((ABSDIFF(seg->y1, segl->y1) == 1) &&
(seg->x1 == segl->x1) && ycheck) {
- if (lastrlayer < lastlayer) {
+ if (ls != ll) {
+ // NOTE: This is still an error, and we should
+ // deal with it by creating a special net.
+ SEG newseg;
+ newseg = (SEG)malloc(sizeof(struct seg_));
+ segl->next = newseg;
+ newseg->next = NULL;
+ newseg->layer = ll;
+ newseg->segtype = ST_WIRE;
+ newseg->x1 = segl->x1;
+ newseg->y1 = segl->y1;
+ newseg->x2 = seg->x1;
+ newseg->y2 = seg->y1;
+ continue;
+ }
+ else if (lastrlayer < lastlayer) {
seg->segtype = ST_WIRE;
seg->y2 = segl->y2;
}
@@ -2588,7 +2648,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
int horizontal;
DPOINT dp1, dp2;
float offset1, offset2;
- u_char cancel;
+ u_char cancel, segtype;
double invscale = (double)(1.0 / (double)iscale);
/* If the STUB flag is set, then we need to write out the net name */
@@ -2906,7 +2966,8 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
dc = Ylowerbound + (double)seg->y2 * PitchY[layer];
if (dir2 == (STUBROUTE_NS | OFFSET_TAP)) dc += offset2;
y2 = (int)((REPS(dc)) * oscale);
- switch (seg->segtype & ~(ST_OFFSET_START | ST_OFFSET_END)) {
+ segtype = seg->segtype & ~(ST_OFFSET_START | ST_OFFSET_END);
+ switch (segtype) {
case ST_WIRE:
if (Pathon != 1) { // 1st point of route seg
if (x == x2) {
@@ -2926,7 +2987,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
" at (%d %d) to (%d %d)\n", x, y, x2, y2);
}
if (special == (u_char)0) {
- pathstart(Cmd, seg->layer, x, y, (u_char)0, oscale, invscale,
+ pathstart(Cmd, seg->layer, x, y, special, oscale, invscale,
horizontal);
lastx = x;
lasty = y;
@@ -3002,7 +3063,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
if (seg->x1 > 0 && ((tdir = (Obs[layer][OGRID(seg->x1 - 1,
seg->y1, layer)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x + viaOffsetX[layer][0],
y, lastx, lasty, seg->x1, seg->y1, invscale);
}
@@ -3010,7 +3071,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
&& ((tdir = (Obs[layer][OGRID(seg->x1 + 1, seg->y1,
layer)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x - viaOffsetX[layer][0],
y, lastx, lasty, seg->x1, seg->y1, invscale);
}
@@ -3022,15 +3083,15 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
if (seg->y1 > 0 && ((tdir = (Obs[layer][OGRID(seg->x1,
seg->y1 - 1, layer)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
- pathvia(Cmd, layer, x, y - viaOffsetY[layer][0],
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
+ pathvia(Cmd, layer, x, y + viaOffsetY[layer][0],
lastx, lasty, seg->x1, seg->y1, invscale);
}
else if ((seg->y1 < NumChannelsY[layer] - 1)
&& ((tdir = (Obs[layer][OGRID(seg->x1, seg->y1 + 1,
layer)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x, y - viaOffsetY[layer][0],
lastx, lasty, seg->x1, seg->y1, invscale);
}
@@ -3042,7 +3103,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
if (seg->x1 > 0 && ((tdir = (Obs[layer + 1][OGRID(seg->x1 - 1,
seg->y1, layer + 1)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x + viaOffsetX[layer][1],
y, lastx, lasty, seg->x1, seg->y1, invscale);
}
@@ -3050,7 +3111,7 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
&& ((tdir = (Obs[layer + 1][OGRID(seg->x1 + 1, seg->y1,
layer + 1)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x - viaOffsetX[layer][1],
y, lastx, lasty, seg->x1, seg->y1, invscale);
}
@@ -3062,15 +3123,15 @@ emit_routed_net(FILE *Cmd, NET net, u_char special, double oscale, int iscale)
if (seg->y1 > 0 && ((tdir = (Obs[layer + 1][OGRID(seg->x1,
seg->y1 - 1, layer + 1)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
- pathvia(Cmd, layer, x, y - viaOffsetY[layer][1],
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
+ pathvia(Cmd, layer, x, y + viaOffsetY[layer][1],
lastx, lasty, seg->x1, seg->y1, invscale);
}
else if ((seg->y1 < NumChannelsY[layer + 1] - 1)
&& ((tdir = (Obs[layer][OGRID(seg->x1, seg->y1 + 1,
layer + 1)] & ROUTED_NET_MASK)) !=
(net->netnum | ROUTED_NET)) &&
- ((tdir & (ROUTED_NET | NO_NET) == ROUTED_NET))) {
+ (((tdir & (ROUTED_NET | NO_NET)) == ROUTED_NET))) {
pathvia(Cmd, layer, x, y - viaOffsetY[layer][1],
lastx, lasty, seg->x1, seg->y1, invscale);
}
diff --git a/qrouter.h b/qrouter.h
index 1d83844..74c365f 100644
--- a/qrouter.h
+++ b/qrouter.h
@@ -135,6 +135,7 @@ struct string_ {
#define ST_VIA 0x02
#define ST_OFFSET_START 0x04 /* (x1, y1) is offset from grid */
#define ST_OFFSET_END 0x08 /* (x2, y2) is offset from grid */
+#define ST_SPECIAL 0x10 /* wide metal (special net) */
typedef struct seg_ *SEG;