summaryrefslogtreecommitdiff
path: root/qrouter.c
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-07-12 22:31:02 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-07-12 22:31:02 +0200
commit178038ed02d94aaeb341792cce5e3d8f6767e0a5 (patch)
tree12a24a9583adaf2c581866018998d2f43c861e49 /qrouter.c
parent1fdeebded00f8f9c13229dcf48aca690513c7b00 (diff)
Imported 1.3.103
Diffstat (limited to 'qrouter.c')
-rw-r--r--qrouter.c182
1 files changed, 131 insertions, 51 deletions
diff --git a/qrouter.c b/qrouter.c
index b0b2164..7b5ae67 100644
--- a/qrouter.c
+++ b/qrouter.c
@@ -215,6 +215,7 @@ runqrouter(int argc, char *argv[])
char *dotptr;
char *Filename = NULL;
u_char readconfig = FALSE;
+ u_char doscript = FALSE;
Scales.iscale = 1;
Scales.mscale = 100;
@@ -240,6 +241,7 @@ runqrouter(int argc, char *argv[])
case 'p':
case 'g':
case 'r':
+ case 's':
argsep = *(argv[i] + 2);
if (argsep == '\0') {
i++;
@@ -283,6 +285,11 @@ runqrouter(int argc, char *argv[])
case 'g':
gndnet = strdup(optarg);
break;
+ case 's':
+ // The "-s" argument is not handled here but is used
+ // to avoid generating a warning message.
+ doscript = TRUE;
+ break;
case 'r':
if (sscanf(optarg, "%d", &Scales.iscale) != 1) {
Fprintf(stderr, "Bad resolution scalefactor \"%s\", "
@@ -305,6 +312,9 @@ runqrouter(int argc, char *argv[])
case 'e':
minEffort = atoi(optarg);
break;
+ case 'n':
+ /* Ignore '-noc' or '-nog', handled elsewhere */
+ break;
case '\0':
/* Ignore '-' */
break;
@@ -332,19 +342,21 @@ runqrouter(int argc, char *argv[])
#endif
}
- configFILEptr = fopen(configfile, "r");
+ if (!doscript) {
+ configFILEptr = fopen(configfile, "r");
- if (configFILEptr) {
- read_config(configFILEptr, (infoFILEptr == NULL) ? FALSE : TRUE);
- readconfig = TRUE;
- }
- else {
- if (configfile != configdefault)
- Fprintf(stderr, "Could not open %s\n", configfile );
- else
- Fprintf(stdout, "No .cfg file specified, continuing without.\n");
+ if (configFILEptr) {
+ read_config(configFILEptr, (infoFILEptr == NULL) ? FALSE : TRUE);
+ readconfig = TRUE;
+ }
+ else {
+ if (configfile != configdefault)
+ Fprintf(stderr, "Could not open %s\n", configfile );
+ else
+ Fprintf(stdout, "No .cfg file specified, continuing without.\n");
+ }
+ if (configfile != configdefault) free(configfile);
}
- if (configfile != configdefault) free(configfile);
if (infoFILEptr != NULL) {
@@ -441,6 +453,49 @@ runqrouter(int argc, char *argv[])
}
/*--------------------------------------------------------------*/
+/* remove_from_failed --- */
+/* */
+/* Remove one net from the list of failing nets. If "net" was */
+/* in the list FailedNets, then return TRUE, otherwise return */
+/* FALSE. */
+/*--------------------------------------------------------------*/
+
+u_char remove_from_failed(NET net)
+{
+ NETLIST nl, lastnl;
+
+ lastnl = (NETLIST)NULL;
+ for (nl = FailedNets; nl; nl = nl->next) {
+ if (nl->net == net) {
+ if (lastnl == NULL)
+ FailedNets = nl->next;
+ else
+ lastnl->next = nl->next;
+ free(nl);
+ return TRUE;
+ }
+ lastnl = nl;
+ }
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+/* remove_failed --- */
+/* */
+/* Free up memory in the list of route failures. */
+/*--------------------------------------------------------------*/
+
+void remove_failed()
+{
+ NETLIST nl;
+ while (FailedNets) {
+ nl = FailedNets;
+ FailedNets = FailedNets->next;
+ free(nl);
+ }
+}
+
+/*--------------------------------------------------------------*/
/* reinitialize --- */
/* */
/* Free up memory in preparation for reading another DEF file */
@@ -481,11 +536,7 @@ static void reinitialize()
// Free the netlist of failed nets (if there is one)
- while (FailedNets) {
- nl = FailedNets;
- FailedNets = FailedNets->next;
- free(nl);
- }
+ remove_failed();
// Free all net and route information
@@ -759,13 +810,7 @@ int dofirststage(u_char graphdebug, int debug_netnum)
// Clear the lists of failed routes, in case first
// stage is being called more than once.
- if (debug_netnum <= 0) {
- while (FailedNets) {
- nl = FailedNets->next;
- free(FailedNets);
- FailedNets = nl;
- }
- }
+ if (debug_netnum <= 0) remove_failed();
// Now find and route all the nets
@@ -891,7 +936,7 @@ static int ripup_colliding(NET net, u_char onlybreak)
nl2 = nl->next;
if (Verbose > 0)
Fprintf(stdout, "Ripping up blocking net %s\n", nl->net->netname);
- if (ripup_net(nl->net, TRUE, onlybreak) == TRUE) {
+ if (ripup_net(nl->net, TRUE, onlybreak, FALSE) == TRUE) {
for (fn = FailedNets; fn && fn->next != NULL; fn = fn->next);
if (fn)
fn->next = nl;
@@ -1109,7 +1154,7 @@ dosecondstage(u_char graphdebug, u_char singlestep, u_char onlybreak, u_int effo
// Remove both routing information and remove the route from
// Obs[] for all parts of the net that were previously routed
- ripup_net(net, TRUE, FALSE); // Remove routing information from net
+ ripup_net(net, TRUE, FALSE, FALSE); // Remove routing information from net
continue;
}
@@ -1125,7 +1170,7 @@ dosecondstage(u_char graphdebug, u_char singlestep, u_char onlybreak, u_int effo
progress[1] += failcount;
progress[0]++;
if (progress[0] > loceffort) {
- if ((progress[2] > 0) && (progress[2] < progress[1])) {
+ if ((progress[2] > 0) && (progress[2] <= progress[1])) {
Fprintf(stderr, "\nNo progress at level of effort %d;"
" ending 2nd stage.\n", loceffort);
break;
@@ -1183,20 +1228,12 @@ dosecondstage(u_char graphdebug, u_char singlestep, u_char onlybreak, u_int effo
int dothirdstage(u_char graphdebug, int debug_netnum, u_int effort)
{
int i, failcount, remaining, result, maskSave;
+ u_char failed;
NET net;
+ ROUTE rt;
NETLIST nl;
u_int loceffort = (effort > minEffort) ? effort : minEffort;
- // Clear the lists of failed routes
-
- if (debug_netnum <= 0) {
- while (FailedNets) {
- nl = FailedNets->next;
- free(FailedNets);
- FailedNets = nl;
- }
- }
-
// Now find and route all the nets
for (i = 0; i < 3; i++) progress[i] = 0;
@@ -1205,23 +1242,67 @@ int dothirdstage(u_char graphdebug, int debug_netnum, u_int effort)
for (i = (debug_netnum >= 0) ? debug_netnum : 0; i < Numnets; i++) {
net = getnettoroute(i);
+ failed = remove_from_failed(net);
if ((net != NULL) && (net->netnodes != NULL)) {
+
+ // Simple optimization: If every route has four or fewer
+ // segments, then rerouting is almost certainly a waste of
+ // time.
+
+ if (!failed) {
+ for (rt = net->routes; rt; rt = rt->next) {
+ int j;
+ SEG seg = rt->segments;
+ for (j = 0; j < 3; j++) {
+ if (seg->next == NULL) break;
+ seg = seg->next;
+ }
+ if (j == 3) break;
+ }
+ if (rt == NULL) {
+ if (Verbose > 0)
+ Fprintf(stdout, "Keeping route for net %s\n", net->netname);
+ remaining--;
+ continue;
+ }
+ }
+
setBboxCurrent(net);
- ripup_net(net, FALSE, FALSE);
+ ripup_net(net, FALSE, FALSE, TRUE); /* retain = TRUE */
+ // Set aside routes in case of failure.
+ rt = net->routes;
+ net->routes = NULL;
+
// set mask mode to BBOX, if auto
maskSave = maskMode;
if (maskMode == MASK_AUTO) maskMode = MASK_BBOX;
result = doroute(net, FALSE, graphdebug);
maskMode = maskSave;
if (result == 0) {
- remaining--;
if (Verbose > 0)
Fprintf(stdout, "Finished routing net %s\n", net->netname);
+ remaining--;
Fprintf(stdout, "Nets remaining: %d\n", remaining);
+ remove_routes(rt, FALSE); /* original is no longer needed */
+ }
+ else if (!failed) {
+ if (Verbose > 0)
+ Fprintf(stdout, "Failed to route net %s; restoring original\n",
+ net->netname);
+ remove_routes(net->routes, FALSE); /* should be NULL already */
+ net->routes = rt;
+ writeback_all_routes(net); /* restore the original */
+ remaining--;
+ /* Pull net from FailedNets, since we restored it. */
+ if (FailedNets && (FailedNets->net == net)) {
+ nl = FailedNets->next;
+ free(FailedNets);
+ FailedNets = nl;
+ }
}
else {
if (Verbose > 0)
- Fprintf(stdout, "Failed to route net %s\n", net->netname);
+ Fprintf(stdout, "Failed to route net %s.\n", net->netname);
}
}
else {
@@ -1406,7 +1487,7 @@ int doroute(NET net, u_char stage, u_char graphdebug)
FailedNets = nlist;
}
}
- return result;
+ return (unroutable > 0) ? -1 : result;
} /* doroute() */
@@ -1457,8 +1538,8 @@ static int next_route_setup(struct routeinfo_ *iroute, u_char stage)
else {
result = set_powerbus_to_net(iroute->nsrc->netnum);
clear_target_node(iroute->nsrc);
- rval = set_node_to_net(iroute->nsrc, PR_SOURCE, &iroute->glist[0],
- &iroute->bbox, stage);
+ rval = set_node_to_net(iroute->nsrc, PR_SOURCE,
+ &iroute->glist[0], &iroute->bbox, stage);
if (rval == -2) {
if (forceRoutable) {
make_routable(iroute->nsrc);
@@ -1479,8 +1560,8 @@ static int next_route_setup(struct routeinfo_ *iroute, u_char stage)
// Set positions on last route to PR_SOURCE
if (rt) {
- result = set_route_to_net(iroute->net, rt, PR_SOURCE, &iroute->glist[0],
- &iroute->bbox, stage);
+ result = set_route_to_net(iroute->net, rt, PR_SOURCE,
+ &iroute->glist[0], &iroute->bbox, stage);
if (result == -2) {
unable_to_route(iroute->net->netname, NULL, 0);
@@ -1519,7 +1600,7 @@ static int next_route_setup(struct routeinfo_ *iroute, u_char stage)
// If any target is found during the search, but is not the
// target that is chosen for the minimum-cost path, then it
// will be left marked "processed" and never visited again.
- // Make sure this doesn't happen my clearing the "processed"
+ // Make sure this doesn't happen by clearing the "processed"
// flag from all such target nodes, and placing the positions
// on the stack for processing again.
@@ -1607,8 +1688,8 @@ static int route_setup(struct routeinfo_ *iroute, u_char stage)
if (iroute->do_pwrbus == FALSE) {
// Set node to PR_SOURCE
- rval = set_node_to_net(iroute->nsrc, PR_SOURCE, &iroute->glist[0],
- &iroute->bbox, stage);
+ rval = set_node_to_net(iroute->nsrc, PR_SOURCE,
+ &iroute->glist[0], &iroute->bbox, stage);
if (rval == -2) {
unable_to_route(iroute->net->netname, NULL, 0);
@@ -1625,8 +1706,7 @@ static int route_setup(struct routeinfo_ *iroute, u_char stage)
result = 0;
for (node = iroute->net->netnodes; node; node = node->next) {
if (node == iroute->nsrc) continue;
- rval = set_node_to_net(node, PR_TARGET, NULL,
- &iroute->bbox, stage);
+ rval = set_node_to_net(node, PR_TARGET, NULL, &iroute->bbox, stage);
if (rval == 0) {
result = 1;
}
@@ -1651,8 +1731,8 @@ static int route_setup(struct routeinfo_ *iroute, u_char stage)
else { /* Do this for power bus connections */
while(1) {
- rval = set_node_to_net(iroute->nsrc, PR_SOURCE, &iroute->glist[0],
- &iroute->bbox, stage);
+ rval = set_node_to_net(iroute->nsrc, PR_SOURCE,
+ &iroute->glist[0], &iroute->bbox, stage);
if (rval == -2) {
iroute->nsrc = iroute->nsrc->next;
if (iroute->nsrc == NULL) break;