diff --git a/src/com/xilinx/rapidwright/rwroute/PartialRouter.java b/src/com/xilinx/rapidwright/rwroute/PartialRouter.java index b8c66578a..edd035a08 100644 --- a/src/com/xilinx/rapidwright/rwroute/PartialRouter.java +++ b/src/com/xilinx/rapidwright/rwroute/PartialRouter.java @@ -40,12 +40,9 @@ import com.xilinx.rapidwright.design.Design; import com.xilinx.rapidwright.design.DesignTools; import com.xilinx.rapidwright.design.Net; -import com.xilinx.rapidwright.design.SiteInst; import com.xilinx.rapidwright.design.SitePinInst; -import com.xilinx.rapidwright.device.IntentCode; import com.xilinx.rapidwright.device.Node; import com.xilinx.rapidwright.device.PIP; -import com.xilinx.rapidwright.device.SitePin; import com.xilinx.rapidwright.device.Tile; import com.xilinx.rapidwright.router.UltraScaleClockRouting; import com.xilinx.rapidwright.tests.CodePerfTracker; @@ -217,51 +214,6 @@ protected int getNumConnectionsCrossingSLRs() { return numCrossingSLRs; } - @Override - protected NodeStatus getGlobalRoutingNodeStatus(Net net, Node node) { - Net preservedNet = routingGraph.getPreservedNet(node); - if (preservedNet == net) { - return NodeStatus.INUSE; - } - if (preservedNet != null) { - if (!softPreserve) { - return NodeStatus.UNAVAILABLE; - } - - // Do not steal from other global nets, since we can't tell if they - // can be re-routed - if (preservedNet.isClockNet() || preservedNet.isStaticNet()) { - return NodeStatus.UNAVAILABLE; - } - - // Do not steal PINBOUNCEs from preserved nets that serve as - // a used site pin - if (node.getIntentCode() == IntentCode.NODE_PINBOUNCE) { - SitePin sitePin = node.getSitePin(); - SiteInst si = (sitePin != null) ? design.getSiteInstFromSite(sitePin.getSite()) : null; - Net netOnSiteWire = (si != null) ? si.getNetFromSiteWire(sitePin.getPinName()) : null; - if (netOnSiteWire != null) { - assert(netOnSiteWire == preservedNet); - return NodeStatus.UNAVAILABLE; - } - } - } - - RouteNode rnode = routingGraph.getNode(node); - if (rnode != null) { - if (!softPreserve) { - return NodeStatus.UNAVAILABLE; - } - - if (rnode.getType() == RouteNodeType.PINFEED_I) { - // Node must be a sink pin for a non-global net - return NodeStatus.UNAVAILABLE; - } - } - - return NodeStatus.AVAILABLE; - } - @Override protected void routeGlobalClkNets() { if (clkNets.isEmpty()) @@ -277,102 +229,11 @@ protected void routeGlobalClkNets() { super.routeGlobalClkNet(clk); } else { System.out.println("INFO: Routing " + clkPins.size() + " pins of clock " + clk + " (non timing-driven)"); - Function gns = (node) -> this.getGlobalRoutingNodeStatus(clk, node); + Function gns = (node) -> getGlobalRoutingNodeStatus(clk, node); UltraScaleClockRouting.incrementalClockRouter(clk, clkPins, gns); preserveNet(clk, false); } } - - List unpreserveNets = unpreserveCongestedNets(clkNets); - if (!unpreserveNets.isEmpty()) { - System.out.println("INFO: Unpreserving " + unpreserveNets.size() + " nets due to clock congestion"); - for (Net net : unpreserveNets) { - System.out.println("\t" + net); - } - } - } - - @Override - protected void routeStaticNets() { - if (staticNetAndRoutingTargets.isEmpty()) - return; - - super.routeStaticNets(); - - List unpreserveNets = unpreserveCongestedNets(staticNetAndRoutingTargets.keySet()); - if (!unpreserveNets.isEmpty()) { - System.out.println("INFO: Unpreserving " + unpreserveNets.size() + " nets due to static net congestion"); - for (Net net : unpreserveNets) { - System.out.println("\t" + net); - } - } - } - - private List unpreserveCongestedNets(Collection globalNets) { - if (!softPreserve) { - return Collections.emptyList(); - } - - // Even though route{GlobalClk,Static}Nets() has called preserveNet() for all its nets, - // it will not overwrite those nodes which have already been preserved by other nets. - // Discover such occurrences so that the entire 'victim' net can be correctly - // unpreserved (thus re-routed) and re-preserve the global. - List unpreserveNets = new ArrayList<>(); - for (Net net : globalNets) { - for (PIP pip : net.getPIPs()) { - for (Node node : Arrays.asList(pip.getStartNode(), pip.getEndNode())) { - RouteNode rnode; - Net preservedNet = routingGraph.getPreservedNet(node); - if (preservedNet == net) { - rnode = routingGraph.getNode(node); - if (rnode == null) { - continue; - } - - // This could be a leftover node from a previously unpreserved net - // (with its prev pointer set to allow its routing to be recovered) - // Fall through so that this can be cleared and blocked - } else { - if (preservedNet == null) { - // Assume this node has already been unpreserved - } else if (RouterHelper.isRoutableNetWithSourceSinks(preservedNet)) { - unpreserveNet(preservedNet); - unpreserveNets.add(preservedNet); - } - - // Preserve node for global net - Net oldNet = routingGraph.preserve(node, net); - if (oldNet != null) { - // oldNet/preservedNet is not a routable net (e.g. driven by hier port) - assert(oldNet == preservedNet); - assert(!RouterHelper.isRoutableNetWithSourceSinks(preservedNet)); - } - - rnode = routingGraph.getNode(node); - if (rnode == null) { - assert(oldNet != null); - continue; - } - - assert(rnode.getPrev() != null); - } - - // RouteNode must only exist if its net has been unpreserved - // Clear its prev pointer so that it doesn't get misinterpreted - // by RouteNodeGraphPartial.isPartOfExistingRoute as being part of an existing route - rnode.clearPrev(); - - // Ideally, we would want to blow this RouteNode from existence as if it was preserved - // from the beginning. However, since other objects (e.g. Connection-s) may hold a reference - // to this, that would not be wise. - // Instead, increment the use of this RouteNode with a null net (since global nets have - // no corresponding NetWrapper) in order to indicate to Connection.isCongested() that it needs - // to be rerouted. - rnode.incrementUser(null); - } - } - } - return unpreserveNets; } @Override diff --git a/src/com/xilinx/rapidwright/rwroute/RWRoute.java b/src/com/xilinx/rapidwright/rwroute/RWRoute.java index a82f1c6bc..357c9a9b8 100644 --- a/src/com/xilinx/rapidwright/rwroute/RWRoute.java +++ b/src/com/xilinx/rapidwright/rwroute/RWRoute.java @@ -516,28 +516,6 @@ protected void routeStaticNets() { GlobalSignalRouting.routeStaticNet(staticNet, gns, design, routethruHelper); preserveNet(staticNet, false); - - // When a [A-H]MUX pin is used as a static source, also preserve the [A-H]_O pin - // so that it can't be used by other static nets, nor as a LUT routethru - for (SitePinInst spi : staticNet.getPins()) { - if (!spi.isOutPin()) { - continue; - } - - SiteInst si = spi.getSiteInst(); - if (!Utils.isSLICE(si)) { - continue; - } - - String pinName = spi.getName(); - if (pinName.endsWith("MUX")) { - char lutLetter = pinName.charAt(0); - Node oNode = si.getSite().getConnectedNode(lutLetter + "_O"); - routingGraph.preserve(oNode, staticNet); - } else { - assert(pinName.endsWith("_O")); - } - } } } diff --git a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java index f35fe16ff..89e01ad87 100644 --- a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java +++ b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java @@ -41,6 +41,7 @@ import com.xilinx.rapidwright.design.Design; import com.xilinx.rapidwright.design.Net; +import com.xilinx.rapidwright.design.SiteInst; import com.xilinx.rapidwright.design.SitePinInst; import com.xilinx.rapidwright.device.Device; import com.xilinx.rapidwright.device.IntentCode; @@ -308,8 +309,32 @@ private Net preserve(Tile tile, int wireIndex, Net net) { } public void preserve(Net net, List pins) { + boolean isStaticNet = net.isStaticNet(); for (SitePinInst pin : pins) { preserve(pin.getConnectedNode(), net); + + if (isStaticNet && pin.isOutPin()) { + // When a LUT output is used as a static source, also preserve the other pin + // ([A-H]_O <-> [A-H]MUX) so that it can't be used by any other nets + SiteInst si = pin.getSiteInst(); + if (!Utils.isSLICE(si)) { + continue; + } + + String pinName = pin.getName(); + char lutLetter = pinName.charAt(0); + String otherPinName; + if (pinName.endsWith("MUX")) { + otherPinName = lutLetter + "_O"; + } else if (pinName.endsWith("_O")) { + otherPinName = lutLetter + "MUX"; + } else { + throw new RuntimeException("ERROR: Unsupported site pin " + pin); + } + + Node otherNode = si.getSite().getConnectedNode(otherPinName); + preserve(otherNode, net); + } } for (PIP pip : net.getPIPs()) {