diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-07-12 22:31:02 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-07-12 22:31:02 +0200 |
commit | 178038ed02d94aaeb341792cce5e3d8f6767e0a5 (patch) | |
tree | 12a24a9583adaf2c581866018998d2f43c861e49 /qrouter.c | |
parent | 1fdeebded00f8f9c13229dcf48aca690513c7b00 (diff) |
Imported 1.3.103
Diffstat (limited to 'qrouter.c')
-rw-r--r-- | qrouter.c | 182 |
1 files changed, 131 insertions, 51 deletions
@@ -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; |