summaryrefslogtreecommitdiff
path: root/maze.c
diff options
context:
space:
mode:
Diffstat (limited to 'maze.c')
-rw-r--r--maze.c110
1 files changed, 69 insertions, 41 deletions
diff --git a/maze.c b/maze.c
index 37420f4..be909ca 100644
--- a/maze.c
+++ b/maze.c
@@ -236,6 +236,7 @@ void clear_non_source_targets(NET net, POINT *pushlist)
void clear_target_node(NODE node)
{
int x, y, lay;
+ NODEINFO lnode;
DPOINT ntap;
PROUTE *Pr;
@@ -245,7 +246,8 @@ void clear_target_node(NODE node)
lay = ntap->layer;
x = ntap->gridx;
y = ntap->gridy;
- if ((lay < Pinlayers) && (NODELOC(x, y, lay) == (NODE)NULL))
+ if ((lay < Pinlayers) && (((lnode = NODEIPTR(x, y, lay)) == NULL)
+ || (lnode->nodeloc == NULL)))
continue;
Pr = &OBS2VAL(x, y, lay);
Pr->flags = 0;
@@ -257,10 +259,11 @@ void clear_target_node(NODE node)
x = ntap->gridx;
y = ntap->gridy;
- if (( (lay < Pinlayers)
- && NODESAV(x, y, lay) == (NODE)NULL)
- || NODESAV(x, y, lay) != node)
- continue;
+ if (lay < Pinlayers) {
+ lnode = NODEIPTR(x, y, lay);
+ if (lnode == NULL) continue;
+ if (lnode->nodesav != node) continue;
+ }
Pr = &OBS2VAL(x, y, lay);
Pr->flags = 0;
@@ -352,6 +355,7 @@ int set_node_to_net(NODE node, int newflags, POINT *pushlist, SEG bbox, u_char s
int x, y, lay, obsnet = 0;
int result = 0;
u_char found_one = (u_char)0;
+ NODEINFO lnode;
POINT gpoint;
DPOINT ntap;
PROUTE *Pr;
@@ -433,9 +437,11 @@ int set_node_to_net(NODE node, int newflags, POINT *pushlist, SEG bbox, u_char s
// Don't process extended areas if they coincide with other nodes.
- if ((lay < Pinlayers) && (NODESAV(x, y, lay) == (NODE)NULL
- || NODESAV(x, y, lay) != node))
- continue;
+ if (lay < Pinlayers) {
+ lnode = NODEIPTR(x, y, lay);
+ if (lnode == NULL) continue;
+ if (lnode->nodesav != node) continue;
+ }
Pr = &OBS2VAL(x, y, lay);
if (Pr->flags & PR_SOURCE) {
@@ -552,6 +558,7 @@ int set_route_to_net(NET net, ROUTE rt, int newflags, POINT *pushlist,
{
int x, y, lay;
int result = 0;
+ NODEINFO lnode;
POINT gpoint;
SEG seg;
NODE n2;
@@ -591,7 +598,8 @@ int set_route_to_net(NET net, ROUTE rt, int newflags, POINT *pushlist,
// If we found another node connected to the route,
// then process it, too.
- n2 = (lay >= Pinlayers) ? NULL : NODELOC(x, y, lay);
+ lnode = (lay >= Pinlayers) ? NULL : NODEIPTR(x, y, lay);
+ n2 = (lnode) ? lnode->nodeloc : NULL;
if ((n2 != (NODE)NULL) && (n2 != net->netnodes)) {
if (newflags == PR_SOURCE) clear_target_node(n2);
result = set_node_to_net(n2, newflags, pushlist, bbox, stage);
@@ -772,12 +780,13 @@ NETLIST find_colliding(NET net, int *ripnum)
/* */
/* If argument "restore" is TRUE, then at each node, restore */
/* the crossover cost by attaching the node back to the */
-/* NODELOC array. */
+/* Nodeinfo array. */
/*--------------------------------------------------------------*/
u_char ripup_net(NET net, u_char restore)
{
int thisnet, oldnet, x, y, lay, dir;
+ NODEINFO lnode;
NODE node;
ROUTE rt;
SEG seg;
@@ -805,10 +814,11 @@ u_char ripup_net(NET net, u_char restore)
// were routed over obstructions to reach off-grid
// taps are returned to obstructions.
- if ((lay >= Pinlayers) || NODESAV(x, y, lay) == (NODE)NULL) {
+ if ((lay >= Pinlayers) || ((lnode = NODEIPTR(x, y, lay)) == NULL)
+ || (lnode->nodesav == NULL)) {
dir = OBSVAL(x, y, lay) & PINOBSTRUCTMASK;
if (dir == 0)
- OBSVAL(x, y, lay) = 0;
+ OBSVAL(x, y, lay) = OBSVAL(x, y, lay) & BLOCKED_MASK;
else
OBSVAL(x, y, lay) = NO_NET | dir;
}
@@ -855,7 +865,7 @@ u_char ripup_net(NET net, u_char restore)
}
}
- // For each net node tap, restore the node pointer on NODELOC
+ // For each net node tap, restore the node pointer on Nodeinfo->nodeloc
// so that crossover costs are again applied to routes over this node
// tap.
@@ -865,8 +875,10 @@ u_char ripup_net(NET net, u_char restore)
lay = ntap->layer;
x = ntap->gridx;
y = ntap->gridy;
- if (lay < Pinlayers)
- NODELOC(x, y, lay) = NODESAV(x, y, lay);
+ if (lay < Pinlayers) {
+ lnode = NODEIPTR(x, y, lay);
+ if (lnode) lnode->nodeloc = lnode->nodesav;
+ }
}
}
}
@@ -916,7 +928,7 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
int thiscost = 0;
int netnum;
NODE node;
- NODEINFO nodeptr;
+ NODEINFO nodeptr, lnode;
NETLIST nl;
PROUTE *Pr, *Pt;
GRIDP newpt;
@@ -961,7 +973,7 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
// 2nd stage allows routes to cross existing routes
netnum = Pr->prdata.net;
if (stage && (netnum < MAXNETNUM)) {
- if ((newpt.lay < Pinlayers) && (nodeptr->nodesav != NULL))
+ if ((newpt.lay < Pinlayers) && nodeptr && (nodeptr->nodesav != NULL))
return 0; // But cannot route over terminals!
// Is net k in the "noripup" list? If so, don't route it */
@@ -981,7 +993,7 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
thiscost += ConflictCost;
}
else if (stage && (netnum == DRC_BLOCKAGE)) {
- if ((newpt.lay < Pinlayers) && (nodeptr->nodesav != NULL))
+ if ((newpt.lay < Pinlayers) && nodeptr && (nodeptr->nodesav != NULL))
return 0; // But cannot route over terminals!
// Position does not contain the net number, so we have to
@@ -1059,7 +1071,8 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
// so that routing over it could block it entirely.
if ((newpt.lay > 0) && (newpt.lay < Pinlayers)) {
- if ((node = NODELOC(newpt.x, newpt.y, newpt.lay - 1)) != (NODE)NULL) {
+ if (((lnode = NODEIPTR(newpt.x, newpt.y, newpt.lay - 1)) != (NODEINFO)NULL)
+ && ((node = lnode->nodeloc) != NULL)) {
Pt = &OBS2VAL(newpt.x, newpt.y, newpt.lay - 1);
if (!(Pt->flags & PR_TARGET) && !(Pt->flags & PR_SOURCE)) {
if (node->taps && (node->taps->next == NULL))
@@ -1083,7 +1096,8 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
}
}
if (((newpt.lay + 1) < Pinlayers) && (newpt.lay < Num_layers - 1)) {
- if ((node = NODELOC(newpt.x, newpt.y, newpt.lay + 1)) != (NODE)NULL) {
+ if (((lnode = NODEIPTR(newpt.x, newpt.y, newpt.lay + 1)) != (NODEINFO)NULL)
+ && ((node = lnode->nodeloc) != NULL)) {
Pt = &OBS2VAL(newpt.x, newpt.y, newpt.lay + 1);
if (!(Pt->flags & PR_TARGET) && !(Pt->flags & PR_SOURCE)) {
if (node->taps && (node->taps->next == NULL))
@@ -1160,11 +1174,14 @@ int eval_pt(GRIDP *ept, u_char flags, u_char stage)
void writeback_segment(SEG seg, int netnum)
{
double dist;
- int i, layer;
+ int i, layer, dir;
u_int sobs;
+ NODEINFO lnode;
if (seg->segtype == ST_VIA) {
- OBSVAL(seg->x1, seg->y1, seg->layer + 1) = netnum;
+ /* Preserve blocking information */
+ dir = OBSVAL(seg->x1, seg->y1, seg->layer + 1) & BLOCKED_MASK;
+ OBSVAL(seg->x1, seg->y1, seg->layer + 1) = netnum | dir;
if (needblock[seg->layer + 1] & VIABLOCKX) {
if ((seg->x1 < (NumChannelsX[seg->layer + 1] - 1)) &&
(OBSVAL(seg->x1 + 1, seg->y1, seg->layer + 1) & NETNUM_MASK) == 0)
@@ -1190,8 +1207,9 @@ void writeback_segment(SEG seg, int netnum)
layer = (seg->layer == 0) ? 0 : seg->layer - 1;
sobs = OBSVAL(seg->x1, seg->y1, seg->layer);
if (sobs & OFFSET_TAP) {
- dist = STUBVAL(seg->x1, seg->y1, seg->layer);
- if (sobs & STUBROUTE_EW) {
+ lnode = NODEIPTR(seg->x1, seg->y1, seg->layer);
+ dist = lnode->offset;
+ if (lnode->flags && NI_OFFSET_EW) {
if ((dist > 0) && (seg->x1 < (NumChannelsX[seg->layer] - 1))) {
OBSVAL(seg->x1 + 1, seg->y1, seg->layer) |= DRC_BLOCKAGE;
OBSVAL(seg->x1 + 1, seg->y1, seg->layer + 1) |= DRC_BLOCKAGE;
@@ -1201,7 +1219,7 @@ void writeback_segment(SEG seg, int netnum)
OBSVAL(seg->x1 - 1, seg->y1, seg->layer + 1) |= DRC_BLOCKAGE;
}
}
- else if (sobs & STUBROUTE_NS) {
+ else if (lnode->flags && NI_OFFSET_NS) {
if ((dist > 0) && (seg->y1 < (NumChannelsY[seg->layer] - 1))) {
OBSVAL(seg->x1, seg->y1 + 1, seg->layer) |= DRC_BLOCKAGE;
OBSVAL(seg->x1, seg->y1 + 1, seg->layer + 1) |= DRC_BLOCKAGE;
@@ -1215,7 +1233,8 @@ void writeback_segment(SEG seg, int netnum)
}
for (i = seg->x1; ; i += (seg->x2 > seg->x1) ? 1 : -1) {
- OBSVAL(i, seg->y1, seg->layer) = netnum;
+ dir = OBSVAL(i, seg->y1, seg->layer) & BLOCKED_MASK;
+ OBSVAL(i, seg->y1, seg->layer) = netnum | dir;
if (needblock[seg->layer] & ROUTEBLOCKY) {
if ((seg->y1 < (NumChannelsY[seg->layer] - 1)) &&
(OBSVAL(i, seg->y1 + 1, seg->layer) & NETNUM_MASK) == 0)
@@ -1236,8 +1255,9 @@ void writeback_segment(SEG seg, int netnum)
if (seg->y1 < (NumChannelsY[layer] - 1)) {
sobs = OBSVAL(i, seg->y1 + 1, layer);
if ((sobs & OFFSET_TAP) && !(sobs & ROUTED_NET)) {
- if (sobs & STUBROUTE_NS) {
- dist = STUBVAL(i, seg->y1 + 1, layer);
+ lnode = NODEIPTR(i, seg->y1 + 1, layer);
+ if (lnode->flags & NI_OFFSET_NS) {
+ dist = lnode->offset;
if (dist < 0) {
OBSVAL(i, seg->y1 + 1, layer) |= DRC_BLOCKAGE;
}
@@ -1247,8 +1267,9 @@ void writeback_segment(SEG seg, int netnum)
if (seg->y1 > 0) {
sobs = OBSVAL(i, seg->y1 - 1, layer);
if ((sobs & OFFSET_TAP) && !(sobs & ROUTED_NET)) {
- if (sobs & STUBROUTE_NS) {
- dist = STUBVAL(i, seg->y1 - 1, layer);
+ lnode = NODEIPTR(i, seg->y1 - 1, layer);
+ if (lnode->flags & NI_OFFSET_NS) {
+ dist = lnode->offset;
if (dist > 0) {
OBSVAL(i, seg->y1 - 1, layer) |= DRC_BLOCKAGE;
}
@@ -1258,7 +1279,8 @@ void writeback_segment(SEG seg, int netnum)
if (i == seg->x2) break;
}
for (i = seg->y1; ; i += (seg->y2 > seg->y1) ? 1 : -1) {
- OBSVAL(seg->x1, i, seg->layer) = netnum;
+ dir = OBSVAL(seg->x1, i, seg->layer) & BLOCKED_MASK;
+ OBSVAL(seg->x1, i, seg->layer) = netnum | dir;
if (needblock[seg->layer] & ROUTEBLOCKX) {
if ((seg->x1 < (NumChannelsX[seg->layer] - 1)) &&
(OBSVAL(seg->x1 + 1, i, seg->layer) & NETNUM_MASK) == 0)
@@ -1275,8 +1297,9 @@ void writeback_segment(SEG seg, int netnum)
if (seg->x1 < (NumChannelsX[layer] - 1)) {
sobs = OBSVAL(seg->x1 + 1, i, layer);
if ((sobs & OFFSET_TAP) && !(sobs & ROUTED_NET)) {
- if (sobs & STUBROUTE_EW) {
- dist = STUBVAL(seg->x1 + 1, i, layer);
+ lnode = NODEIPTR(seg->x1 + 1, i, layer);
+ if (lnode->flags & NI_OFFSET_EW) {
+ dist = lnode->offset;
if (dist < 0) {
OBSVAL(seg->x1 + 1, i, layer) |= DRC_BLOCKAGE;
}
@@ -1286,8 +1309,9 @@ void writeback_segment(SEG seg, int netnum)
if (seg->x1 > 0) {
sobs = OBSVAL(seg->x1 - 1, i, layer);
if ((sobs & OFFSET_TAP) && !(sobs & ROUTED_NET)) {
- if (sobs & STUBROUTE_EW) {
- dist = STUBVAL(seg->x1 - 1, i, layer);
+ lnode = NODEIPTR(seg->x1 - 1, i, layer);
+ if (lnode->flags & NI_OFFSET_EW) {
+ dist = lnode->offset;
if (dist > 0) {
OBSVAL(seg->x1 - 1, i, layer) |= DRC_BLOCKAGE;
}
@@ -1316,6 +1340,7 @@ void writeback_segment(SEG seg, int netnum)
int commit_proute(ROUTE rt, GRIDP *ept, u_char stage)
{
SEG seg, lseg;
+ NODEINFO lnode1, lnode2;
int lay2, rval;
int dx = -1, dy = -1, dl;
u_int netnum, netobs1, netobs2, dir1, dir2;
@@ -1853,6 +1878,9 @@ int commit_proute(ROUTE rt, GRIDP *ept, u_char stage)
netobs1 = OBSVAL(seg->x1, seg->y1, seg->layer);
netobs2 = OBSVAL(seg->x2, seg->y2, lay2);
+ lnode1 = (seg->layer < Pinlayers) ? NODEIPTR(seg->x1, seg->y1, seg->layer) : NULL;
+ lnode2 = (lay2 < Pinlayers) ? NODEIPTR(seg->x2, seg->y2, lay2) : NULL;
+
dir1 = netobs1 & PINOBSTRUCTMASK;
dir2 = netobs2 & PINOBSTRUCTMASK;
@@ -1898,8 +1926,8 @@ int commit_proute(ROUTE rt, GRIDP *ept, u_char stage)
if (lseg && ((lseg->segtype & (ST_VIA | ST_OFFSET_END)) ==
(ST_VIA | ST_OFFSET_END)))
if (seg->segtype != ST_VIA)
- if (((seg->x1 == seg->x2) && (dir1 & STUBROUTE_NS)) ||
- ((seg->y1 == seg->y2) && (dir1 & STUBROUTE_EW)))
+ if (((seg->x1 == seg->x2) && (lnode1->flags & NI_OFFSET_NS)) ||
+ ((seg->y1 == seg->y2) && (lnode1->flags & NI_OFFSET_EW)))
seg->segtype |= ST_OFFSET_START;
// Check if the route ends are offset. If so, add flags. The segment
@@ -1909,8 +1937,8 @@ int commit_proute(ROUTE rt, GRIDP *ept, u_char stage)
// the offset via, and does not extend past it.
if (dir1 & OFFSET_TAP) {
- if (((seg->x1 == seg->x2) && (dir1 & STUBROUTE_NS)) ||
- ((seg->y1 == seg->y2) && (dir1 & STUBROUTE_EW)))
+ if (((seg->x1 == seg->x2) && (lnode1->flags & NI_OFFSET_NS)) ||
+ ((seg->y1 == seg->y2) && (lnode1->flags & NI_OFFSET_EW)))
seg->segtype |= ST_OFFSET_START;
// An offset on a via needs to be applied to the previous route
@@ -1918,8 +1946,8 @@ int commit_proute(ROUTE rt, GRIDP *ept, u_char stage)
// in the same direction as the wire.
if (lseg && (seg->segtype & ST_VIA) && !(lseg->segtype & ST_VIA))
- if (((lseg->x1 == lseg->x2) && (dir2 & STUBROUTE_NS)) ||
- ((lseg->y1 == lseg->y2) && (dir2 & STUBROUTE_EW)))
+ if (((lseg->x1 == lseg->x2) && lnode2 && (lnode2->flags & NI_OFFSET_NS)) ||
+ ((lseg->y1 == lseg->y2) && lnode2 && (lnode2->flags & NI_OFFSET_EW)))
lseg->segtype |= ST_OFFSET_END;
}