diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2015-09-11 07:39:55 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2015-09-11 07:39:55 +0200 |
commit | 160fcb379168bdc472699865daa79d76441a2039 (patch) | |
tree | 3fc159177dfd554fc5c141e2678edf7cdf0665df | |
parent | 24f45f018e6f0b94e13e5cf71a2d1ef44ee635b8 (diff) | |
parent | ab5e89b0c2f41e1b36c8e6a4d899737a97f7e488 (diff) |
Merge tag 'upstream/1.3.15'
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | node.c | 47 | ||||
-rw-r--r-- | qrouter.c | 151 | ||||
-rw-r--r-- | qrouter.h | 1 |
4 files changed, 140 insertions, 61 deletions
@@ -1 +1 @@ -1.3.12 +1.3.15 @@ -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, @@ -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); } @@ -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; |