Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RWRoute] Divide nodes into LOCAL and NON_LOCAL #1095

Merged
merged 13 commits into from
Nov 6, 2024
8 changes: 4 additions & 4 deletions src/com/xilinx/rapidwright/rwroute/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ public void addAltSinkRnode(RouteNode sinkRnode) {
} else {
assert(!altSinkRnodes.contains(sinkRnode));
}
assert(sinkRnode.getType() == RouteNodeType.PINFEED_I ||
assert(sinkRnode.getType() == RouteNodeType.EXCLUSIVE_SINK ||
// Can be a WIRE if node is not exclusive a sink
sinkRnode.getType() == RouteNodeType.WIRE);
sinkRnode.getType() == RouteNodeType.NON_LOCAL);
altSinkRnodes.add(sinkRnode);
}

Expand Down Expand Up @@ -486,8 +486,8 @@ public void setAllTargets(RWRoute.ConnectionState state) {
// if it's not already in use by the current net to prevent the case
// where the same physical pin services more than one logical pin
if (rnode.countConnectionsOfUser(netWrapper) == 0 ||
// Except if it is not a PINFEED_I
rnode.getType() != RouteNodeType.PINFEED_I) {
// Except if it is not an EXCLUSIVE_SINK
rnode.getType() != RouteNodeType.EXCLUSIVE_SINK) {
assert(rnode.getIntentCode() != IntentCode.NODE_PINBOUNCE);
rnode.markTarget(state);
}
Expand Down
2 changes: 1 addition & 1 deletion src/com/xilinx/rapidwright/rwroute/NetWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public SitePinInst getOrCreateAlternateSource(RouteNodeGraph routingGraph) {
return null;
}

altSourceRnode = routingGraph.getOrCreate(altSourceNode, RouteNodeType.PINFEED_O);
altSourceRnode = routingGraph.getOrCreate(altSourceNode, RouteNodeType.EXCLUSIVE_SOURCE);
}
assert(altSourceRnode != null);
return altSource;
Expand Down
6 changes: 3 additions & 3 deletions src/com/xilinx/rapidwright/rwroute/PartialRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ protected void determineRoutingTargets() {
preservedNet = routingGraph.getPreservedNet(sinkRnode);
if (preservedNet != null && preservedNet != net) {
unpreserveNets.add(preservedNet);
assert(sinkRnode.getType() == RouteNodeType.PINFEED_I);
assert(sinkRnode.getType() == RouteNodeType.EXCLUSIVE_SINK);
}
}

Expand Down Expand Up @@ -598,8 +598,8 @@ protected void unpreserveNet(Net net) {
assert(!connection.isDirect());
RouteNode sourceRnode = connection.getSourceRnode();
RouteNode sinkRnode = connection.getSinkRnode();
assert(sourceRnode.getType() == RouteNodeType.PINFEED_O);
assert(sinkRnode.getType() == RouteNodeType.PINFEED_I);
assert(sourceRnode.getType() == RouteNodeType.EXCLUSIVE_SOURCE);
assert(sinkRnode.getType() == RouteNodeType.EXCLUSIVE_SINK);

// Even though this connection is not expected to have any routing yet,
// perform a rip up anyway in order to release any exclusive sinks
Expand Down
59 changes: 25 additions & 34 deletions src/com/xilinx/rapidwright/rwroute/RWRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
import com.xilinx.rapidwright.util.Pair;
import com.xilinx.rapidwright.util.RuntimeTracker;
import com.xilinx.rapidwright.util.RuntimeTrackerTree;
import com.xilinx.rapidwright.util.Utils;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -589,7 +588,7 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
if (connection.getSourceRnode() == null) {
assert(sourceINTNode != null);
if (sourceINTRnode == null) {
sourceINTRnode = routingGraph.getOrCreate(sourceINTNode, RouteNodeType.PINFEED_O);
sourceINTRnode = routingGraph.getOrCreate(sourceINTNode, RouteNodeType.EXCLUSIVE_SOURCE);
// Where only a single primary source exists, always preserve
// its projected-to-INT source node, since it could
// be a projection from LAGUNA/RXQ* -> RXD* (node for INT/LOGIC_OUTS_*)
Expand All @@ -601,8 +600,8 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
}

indirectConnections.add(connection);
RouteNode sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.PINFEED_I);
sinkRnode.setType(RouteNodeType.PINFEED_I);
RouteNode sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.EXCLUSIVE_SINK);
sinkRnode.setType(RouteNodeType.EXCLUSIVE_SINK);
connection.setSinkRnode(sinkRnode);

// Where appropriate, allow all 6 LUT pins to be swapped to begin with
Expand Down Expand Up @@ -651,8 +650,8 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
if (routingGraph.isPreserved(node)) {
continue;
}
RouteNode altSinkRnode = routingGraph.getOrCreate(node, RouteNodeType.PINFEED_I);
assert(altSinkRnode.getType() == RouteNodeType.PINFEED_I);
RouteNode altSinkRnode = routingGraph.getOrCreate(node, RouteNodeType.EXCLUSIVE_SINK);
assert(altSinkRnode.getType() == RouteNodeType.EXCLUSIVE_SINK);
connection.addAltSinkRnode(altSinkRnode);
}

Expand Down Expand Up @@ -1798,7 +1797,18 @@ private void exploreAndExpand(ConnectionState state, RouteNode rnode) {
continue;
}
switch (childRNode.getType()) {
case WIRE:
case LOCAL:
if (!routingGraph.isAccessible(childRNode, connection)) {
continue;
}
break;
case NON_LOCAL:
// LOCALs cannot connect to NON_LOCALs except via a LUT routethru
assert(rnode.getType() != RouteNodeType.LOCAL ||
routingGraph.lutRoutethru && rnode.getIntentCode() == IntentCode.NODE_PINFEED ||
// FIXME:
design.getSeries() == Series.Versal);
eddieh-xlnx marked this conversation as resolved.
Show resolved Hide resolved

if (!routingGraph.isAccessible(childRNode, connection)) {
continue;
}
Expand All @@ -1808,19 +1818,12 @@ private void exploreAndExpand(ConnectionState state, RouteNode rnode) {
continue;
}
break;
case PINBOUNCE:
// A PINBOUNCE can only be a target if this connection has an alternate sink
assert(!childRNode.isTarget() || connection.getAltSinkRnodes().isEmpty());
if (!isAccessiblePinbounce(childRNode, connection)) {
continue;
}
break;
case PINFEED_I:
if (!isAccessiblePinfeedI(childRNode, connection)) {
case EXCLUSIVE_SINK:
if (!isAccessibleSink(childRNode, connection)) {
continue;
}
break;
case LAGUNA_I:
case LAGUNA_PINFEED:
if (!connection.isCrossSLR() ||
connection.getSinkRnode().getSLRIndex(routingGraph) == childRNode.getSLRIndex(routingGraph)) {
// Do not consider approaching a SLL if not needing to cross
Expand Down Expand Up @@ -1854,25 +1857,13 @@ protected boolean isAccessible(RouteNode child, Connection connection) {
return !config.isUseBoundingBox() || child.isInConnectionBoundingBox(connection);
}

/**
* Checks if a NODE_PINBOUNCE is suitable to be used for routing to a target.
* @param child The PINBOUNCE rnode in question.
* @param connection The connection to route.
* @return true, if the PINBOUNCE rnode is in the same column as the target and within one INT tile of the target.
*/
protected boolean isAccessiblePinbounce(RouteNode child, Connection connection) {
assert(child.getType() == RouteNodeType.PINBOUNCE);

return routingGraph.isAccessible(child, connection);
}

protected boolean isAccessiblePinfeedI(RouteNode child, Connection connection) {
// When LUT pin swapping is enabled, PINFEED_I are not exclusive anymore
return isAccessiblePinfeedI(child, connection, !lutPinSwapping);
protected boolean isAccessibleSink(RouteNode child, Connection connection) {
// When LUT pin swapping is enabled, EXCLUSIVE_SINK-s are not exclusive anymore
return isAccessibleSink(child, connection, !lutPinSwapping);
}

protected boolean isAccessiblePinfeedI(RouteNode child, Connection connection, boolean assertOnOveruse) {
assert(child.getType() == RouteNodeType.PINFEED_I);
protected boolean isAccessibleSink(RouteNode child, Connection connection, boolean assertOnOveruse) {
assert(child.getType() == RouteNodeType.EXCLUSIVE_SINK);
assert(!assertOnOveruse || !child.isOverUsed());

if (child.isTarget()) {
Expand Down
48 changes: 30 additions & 18 deletions src/com/xilinx/rapidwright/rwroute/RouteNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.xilinx.rapidwright.design.Net;
import com.xilinx.rapidwright.device.IntentCode;
import com.xilinx.rapidwright.device.Node;
import com.xilinx.rapidwright.device.Series;
import com.xilinx.rapidwright.device.Tile;
import com.xilinx.rapidwright.device.TileTypeEnum;
import com.xilinx.rapidwright.util.RuntimeTracker;
Expand Down Expand Up @@ -92,13 +93,13 @@ public class RouteNode extends Node implements Comparable<RouteNode> {

protected RouteNode(RouteNodeGraph routingGraph, Node node, RouteNodeType type) {
super(node);
RouteNodeInfo nodeInfo = RouteNodeInfo.get(this, routingGraph.lagunaI);
RouteNodeInfo nodeInfo = RouteNodeInfo.get(this, routingGraph);
this.type = (type == null) ? nodeInfo.type : type;
endTileXCoordinate = nodeInfo.endTileXCoordinate;
endTileYCoordinate = nodeInfo.endTileYCoordinate;
length = nodeInfo.length;
children = null;
setBaseCost();
setBaseCost(routingGraph.design.getSeries());
presentCongestionCost = initialPresentCongestionCost;
historicalCongestionCost = initialHistoricalCongestionCost;
usersConnectionCounts = null;
Expand All @@ -115,10 +116,27 @@ public int compareTo(RouteNode that) {
return (int) Math.signum(this.lowerBoundTotalPathCost - that.lowerBoundTotalPathCost);
}

private void setBaseCost() {
private void setBaseCost(Series series) {
baseCost = 0.4f;
switch (type) {
case LAGUNA_I:
case EXCLUSIVE_SOURCE:
assert(length == 0 ||
(length <= 3 && series == Series.Versal));
break;
case EXCLUSIVE_SINK:
assert(length == 0 ||
(length == 1 && (series == Series.UltraScalePlus || series == Series.UltraScale) && getIntentCode() == IntentCode.NODE_PINBOUNCE));
break;
case LOCAL:
assert(length == 0 ||
(length == 1 && (
((series == Series.UltraScalePlus || series == Series.UltraScale) && getIntentCode() == IntentCode.NODE_PINBOUNCE) ||
(series == Series.UltraScalePlus && getWireName().matches("INODE_[EW]_\\d+_FT[01]")) ||
(series == Series.UltraScale && getWireName().matches("INODE_[12]_[EW]_\\d+_FT[NS]"))
))
);
break;
case LAGUNA_PINFEED:
// Make all approaches to SLLs zero-cost to encourage exploration
// Assigning a base cost of zero would normally break congestion resolution
// (since RWroute.getNodeCost() would return zero) but doing it here should be
Expand All @@ -129,7 +147,7 @@ private void setBaseCost() {
assert(length == RouteNodeGraph.SUPER_LONG_LINE_LENGTH_IN_TILES);
baseCost = 0.3f * length;
break;
case WIRE:
case NON_LOCAL:
// NOTE: IntentCode is device-dependent
IntentCode ic = getIntentCode();
switch(ic) {
Expand All @@ -139,10 +157,10 @@ private void setBaseCost() {
case NODE_LAGUNA_OUTPUT: // LAG_LAG.{LAG_MUX_ATOM_*_TXOUT,RXD*} (US+)
case NODE_LAGUNA_DATA: // LAG_LAG.UBUMP* super long lines for u-turns at the boundary of the device (US+)
case NODE_PINFEED:
case INTENT_DEFAULT: // INT.VCC_WIRE
assert(length == 0);
break;
case NODE_LOCAL: // US and US+
case INTENT_DEFAULT:
case NODE_LOCAL: // US and US+
assert(length <= 1);
break;
case NODE_VSINGLE: // Versal-only
Expand Down Expand Up @@ -215,12 +233,6 @@ private void setBaseCost() {
throw new RuntimeException(ic.toString());
}
break;
case PINFEED_I:
case PINBOUNCE:
break;
case PINFEED_O:
baseCost = 1f;
break;
default:
throw new RuntimeException(type.toString());
}
Expand Down Expand Up @@ -348,11 +360,11 @@ public RouteNodeType getType() {
*/
public void setType(RouteNodeType type) {
assert(this.type == type ||
// Support demotion from PINFEED_I to PINBOUNCE since they have the same base cost
(this.type == RouteNodeType.PINFEED_I && type == RouteNodeType.PINBOUNCE) ||
// Or promotion from PINBOUNCE to PINFEED_I (by PartialRouter when PINBOUNCE on
// preserved net needs to become a PINFEED_I)
(this.type == RouteNodeType.PINBOUNCE && type == RouteNodeType.PINFEED_I));
// Support demotion from EXCLUSIVE_SINK to LOCAL since they have the same base cost
(this.type == RouteNodeType.EXCLUSIVE_SINK && type == RouteNodeType.LOCAL) ||
// Or promotion from LOCAL to EXCLUSIVE_SINK (by PartialRouter when NODE_PINBOUNCE on
// a newly unpreserved net becomes a sink)
(this.type == RouteNodeType.LOCAL && type == RouteNodeType.EXCLUSIVE_SINK));
this.type = type;
}

Expand Down
Loading
Loading