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] Versal optimizations #1093

Merged
merged 70 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
f89c96e
Add optimization of signal routing
WenhaoLin-AMD Nov 4, 2024
57f39df
Merge new method into RoutingGraph.isAccessible()
eddieh-xlnx Nov 4, 2024
74df324
Fix typo
eddieh-xlnx Nov 4, 2024
3bf9cb9
Add TestNode.testNodeReachabilityVersal() to check assumptions
eddieh-xlnx Nov 4, 2024
bf4d076
Add NODE_CLE_OUTPUT too
eddieh-xlnx Nov 4, 2024
1f8a9d3
Expand TestNode.testNodeReachabilityUltraScale()
eddieh-xlnx Nov 4, 2024
bba91e1
More
eddieh-xlnx Nov 5, 2024
4356b03
Add and use RouteNodeType.LOCAL
eddieh-xlnx Nov 5, 2024
7e7015a
Merge RouteNodeType.PINBOUNCE into LOCAL; rename WIRE, PINFEED_{I,O}
eddieh-xlnx Nov 5, 2024
b9ff45f
LUT routethru fixes
eddieh-xlnx Nov 5, 2024
aabab3c
Add testNodeReachabilityVersal()
eddieh-xlnx Nov 5, 2024
9929603
Support UltraScale
eddieh-xlnx Nov 5, 2024
e47cd18
Merge branch 'us_node_reach' into signal_router_optimize_eh
eddieh-xlnx Nov 5, 2024
9aba0ac
Extend RouteNodeType.LOCAL to Versal
eddieh-xlnx Nov 5, 2024
c197f08
Exclude Versal's NODE_IMUX/NODE_{CLE,INTF}_CTRL if not in RRG
eddieh-xlnx Nov 5, 2024
9717cd4
Merge branch 'master' into signal_router_optimize
eddieh-xlnx Nov 6, 2024
7274b33
More explanatory approach; no difference
eddieh-xlnx Nov 7, 2024
14955fe
Improvement?
eddieh-xlnx Nov 7, 2024
56afd4b
Cleanup
eddieh-xlnx Nov 7, 2024
cac787e
Update comments
eddieh-xlnx Nov 7, 2024
ef4227c
Add NODE_INTF_{CNODE,BNODE}
eddieh-xlnx Nov 7, 2024
cd631ac
[TestNode] Expand testNodeReachabilityUltraScale
eddieh-xlnx Nov 7, 2024
038aa80
Expand testNodeReachabilityVersal too
eddieh-xlnx Nov 7, 2024
77fa308
UltraScale+: Sub-divide LOCALs into _EAST/_WEST and stick to sink's side
eddieh-xlnx Nov 8, 2024
6229dbe
Re-add EXCLUSIVE_SINK (non-sided) for CTRL sinks
eddieh-xlnx Nov 8, 2024
74fdf59
Support UltraScale
eddieh-xlnx Nov 8, 2024
a1dca37
Print
eddieh-xlnx Nov 8, 2024
977b068
Expand testNodeReachabilityVersal
eddieh-xlnx Nov 8, 2024
967890d
Do not error out for Versal
eddieh-xlnx Nov 8, 2024
9a48765
Fix failing assertions
eddieh-xlnx Nov 8, 2024
95bba95
Remove unused import
eddieh-xlnx Nov 8, 2024
3a25ead
Fix another typo
eddieh-xlnx Nov 8, 2024
0d60f48
Fix SLR crossings
eddieh-xlnx Nov 8, 2024
d4e0ea5
More Versal fixes
eddieh-xlnx Nov 8, 2024
07935a4
Update testSLRCrossingNonTimingDriven golden values
eddieh-xlnx Nov 8, 2024
bb9db76
Tidy up and comments
eddieh-xlnx Nov 8, 2024
9e7d383
Add a few more testcases
eddieh-xlnx Nov 8, 2024
4f43cf5
[RWRoute] Non-verbose mode to print out nodes popped
eddieh-xlnx Nov 8, 2024
7890b5a
Update comments/asserts
eddieh-xlnx Nov 8, 2024
15b7453
Clean up RouteNodeGraph.isAccessible()
eddieh-xlnx Nov 8, 2024
b61a199
Fixes for UltraScale
eddieh-xlnx Nov 8, 2024
a937982
Skip another assert for Versal
eddieh-xlnx Nov 8, 2024
da6c175
Merge branch 'master' into signal_router_optimize
eddieh-xlnx Nov 12, 2024
6f0b9ae
Merge branch 'rwroute_east_west' into signal_router_optimize
eddieh-xlnx Nov 12, 2024
b07f2db
Fix Versal assertion
eddieh-xlnx Nov 12, 2024
90e8d80
Fix assertion
eddieh-xlnx Nov 12, 2024
bdf791f
Expand test
eddieh-xlnx Nov 12, 2024
c1e8274
Apply #1098 to Versal too
eddieh-xlnx Nov 12, 2024
50287fe
Assign CNODEs to be LOCAL_{EAST,WEST} (opposite to name)
eddieh-xlnx Nov 13, 2024
b048ef3
Merge branch 'master' into signal_router_optimize
eddieh-xlnx Nov 13, 2024
f4df052
Fix merge
eddieh-xlnx Nov 13, 2024
003a051
Resolve FIXMEs
eddieh-xlnx Nov 13, 2024
c057226
Restore comment
eddieh-xlnx Nov 13, 2024
353775c
Fix continue
eddieh-xlnx Nov 13, 2024
a9f5161
On Versal, make all NODE_PINFEEDs RouteNodeType.LOCAL
eddieh-xlnx Nov 13, 2024
76bc5cc
Handle NODE_INTF_CNODE too
eddieh-xlnx Nov 13, 2024
7b190bf
Add comment
eddieh-xlnx Nov 13, 2024
e877503
Simplify if
eddieh-xlnx Nov 13, 2024
ce90eb7
Introduce LOCAL_RESERVED
eddieh-xlnx Nov 13, 2024
1c2b471
Allow INODE and PINBOUNCE either side of CTRL sink to be used
eddieh-xlnx Nov 13, 2024
5414206
Update comment
eddieh-xlnx Nov 13, 2024
57ed051
Clearer names
eddieh-xlnx Nov 13, 2024
8c0acba
Fix
eddieh-xlnx Nov 13, 2024
d1e843a
Tidy up
eddieh-xlnx Nov 13, 2024
fb08d82
Merge branch 'master' into signal_router_optimize
eddieh-xlnx Nov 14, 2024
fc4499a
Use RouteNodeInfo.getType() with ignoreLaguna param
eddieh-xlnx Nov 14, 2024
9768314
Rename param to forceSink
eddieh-xlnx Nov 14, 2024
7e5ff64
Address review comments
eddieh-xlnx Nov 14, 2024
ddbc814
Fix polarity of assert
eddieh-xlnx Nov 14, 2024
025004b
Tidy
eddieh-xlnx Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/com/xilinx/rapidwright/rwroute/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public void addAltSinkRnode(RouteNode sinkRnode) {
} else {
assert(!altSinkRnodes.contains(sinkRnode));
}
assert(sinkRnode.getType().isExclusiveSink() ||
assert(sinkRnode.getType().isAnyExclusiveSink() ||
// Can be a WIRE if node is not exclusive a sink
sinkRnode.getType() == RouteNodeType.NON_LOCAL);
altSinkRnodes.add(sinkRnode);
Expand Down Expand Up @@ -487,7 +487,7 @@ public void setAllTargets(RWRoute.ConnectionState state) {
// where the same physical pin services more than one logical pin
if (rnode.countConnectionsOfUser(netWrapper) == 0 ||
// Except if it is not an EXCLUSIVE_SINK
rnode.getType().isExclusiveSink()) {
rnode.getType().isAnyExclusiveSink()) {
assert(rnode.getIntentCode() != IntentCode.NODE_PINBOUNCE);
rnode.markTarget(state);
}
Expand Down
4 changes: 2 additions & 2 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().isExclusiveSink());
assert(sinkRnode.getType().isAnyExclusiveSink());
}
}

Expand Down Expand Up @@ -599,7 +599,7 @@ protected void unpreserveNet(Net net) {
RouteNode sourceRnode = connection.getSourceRnode();
RouteNode sinkRnode = connection.getSinkRnode();
assert(sourceRnode.getType() == RouteNodeType.EXCLUSIVE_SOURCE);
assert(sinkRnode.getType().isExclusiveSink());
assert(sinkRnode.getType().isAnyExclusiveSink());

// 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
84 changes: 57 additions & 27 deletions src/com/xilinx/rapidwright/rwroute/RWRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,32 @@ protected void determineRoutingTargets() {

// Wait for all outstanding RouteNodeGraph.preserveAsync() calls to complete
routingGraph.awaitPreserve();

// On Versal only, reserve all uphills of NODE_(CLE|INTF)_CTRL sinks since
// their [BC]NODEs can also be used to reach NODE_INODEs --- not applying this
// heuristic can lead to avoidable congestion
if (routingGraph.isVersal) {
for (Connection connection : indirectConnections) {
RouteNode sinkRnode = connection.getSinkRnode();
if (sinkRnode.getType() == RouteNodeType.EXCLUSIVE_SINK_BOTH) {
for (Node uphill : sinkRnode.getAllUphillNodes()) {
if (uphill.isTiedToVcc()) {
continue;
}
Net preservedNet = routingGraph.getPreservedNet(uphill);
if (preservedNet != null && preservedNet != connection.getNetWrapper().getNet()) {
continue;
}
assert((sinkRnode.getIntentCode() == IntentCode.NODE_CLE_CTRL &&
(uphill.getIntentCode() == IntentCode.NODE_CLE_CNODE || uphill.getIntentCode() == IntentCode.NODE_CLE_BNODE)) ||
(sinkRnode.getIntentCode() == IntentCode.NODE_INTF_CTRL &&
(uphill.getIntentCode() == IntentCode.NODE_INTF_CNODE || uphill.getIntentCode() == IntentCode.NODE_INTF_BNODE)));
RouteNode rnode = routingGraph.getOrCreate(uphill, RouteNodeType.LOCAL_RESERVED);
rnode.setType(RouteNodeType.LOCAL_RESERVED);
}
}
}
}
}

private void categorizeNets() {
Expand Down Expand Up @@ -601,19 +627,19 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
}

indirectConnections.add(connection);
BitSet[] eastWestWires = (routingGraph.eastWestWires == null) ? null :
routingGraph.eastWestWires.get(sinkINTNode.getTile().getTileTypeEnum());
RouteNode sinkRnode;
if (eastWestWires != null && eastWestWires[0].get(sinkINTNode.getWireIndex())) {
sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.EXCLUSIVE_SINK_EAST);
sinkRnode.setType(RouteNodeType.EXCLUSIVE_SINK_EAST);
} else if (eastWestWires != null && eastWestWires[1].get(sinkINTNode.getWireIndex())) {
sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.EXCLUSIVE_SINK_WEST);
sinkRnode.setType(RouteNodeType.EXCLUSIVE_SINK_WEST);
} else {
sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.EXCLUSIVE_SINK);
sinkRnode.setType(RouteNodeType.EXCLUSIVE_SINK);
}

// Inform RouteNodeInfo.getType() that this a sink to prevent it from returning
// RouteNodeType.LAGUNA_PINFEED and instead return LOCAL_{EAST,WEST}
boolean forceSink = true;
RouteNodeType sinkType = RouteNodeInfo.getType(sinkINTNode, null, routingGraph, forceSink);
assert(sinkType.isAnyLocal());
sinkType = sinkType == RouteNodeType.LOCAL_EAST ? RouteNodeType.EXCLUSIVE_SINK_EAST :
sinkType == RouteNodeType.LOCAL_WEST ? RouteNodeType.EXCLUSIVE_SINK_WEST :
sinkType == RouteNodeType.LOCAL_BOTH ? RouteNodeType.EXCLUSIVE_SINK_BOTH :
null;
assert(sinkType != null);
RouteNode sinkRnode = routingGraph.getOrCreate(sinkINTNode, sinkType);
sinkRnode.setType(sinkType);
connection.setSinkRnode(sinkRnode);

// Where appropriate, allow all 6 LUT pins to be swapped to begin with
Expand Down Expand Up @@ -665,7 +691,7 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
continue;
}
RouteNode altSinkRnode = routingGraph.getOrCreate(node, sinkRnode.getType());
assert(altSinkRnode.getType().isExclusiveSink());
assert(altSinkRnode.getType().isAnyExclusiveSink());
connection.addAltSinkRnode(altSinkRnode);
}

Expand Down Expand Up @@ -1811,22 +1837,24 @@ private void exploreAndExpand(ConnectionState state, RouteNode rnode) {
continue;
}
switch (childRNode.getType()) {
case LOCAL:
case LOCAL_BOTH:
case LOCAL_EAST:
case LOCAL_WEST:
case LOCAL_RESERVED:
if (!routingGraph.isAccessible(childRNode, connection)) {
continue;
}
// Verify invariant that east/west wires stay east/west
assert(rnode.getType() != RouteNodeType.LOCAL_EAST || childRNode.getType() == RouteNodeType.LOCAL_EAST);
assert(rnode.getType() != RouteNodeType.LOCAL_WEST || childRNode.getType() == RouteNodeType.LOCAL_WEST);
// Verify invariant that east/west wires stay east/west ...
assert(rnode.getType() != RouteNodeType.LOCAL_EAST || childRNode.getType() == RouteNodeType.LOCAL_EAST ||
// ... unless it's an exclusive sink using a LOCAL_RESERVED node
(childRNode.getType() == RouteNodeType.LOCAL_RESERVED && connection.getSinkRnode().getType() == RouteNodeType.EXCLUSIVE_SINK_BOTH));
assert(rnode.getType() != RouteNodeType.LOCAL_WEST || childRNode.getType() == RouteNodeType.LOCAL_WEST ||
(childRNode.getType() == RouteNodeType.LOCAL_RESERVED && connection.getSinkRnode().getType() == RouteNodeType.EXCLUSIVE_SINK_BOTH));
break;
case NON_LOCAL:
// LOCALs cannot connect to NON_LOCALs except via a LUT routethru
assert(!rnode.getType().isLocal() ||
routingGraph.lutRoutethru && rnode.getIntentCode() == IntentCode.NODE_PINFEED ||
// FIXME:
design.getSeries() == Series.Versal);
assert(!rnode.getType().isAnyLocal() ||
routingGraph.lutRoutethru && rnode.getIntentCode() == IntentCode.NODE_PINFEED);

if (!routingGraph.isAccessible(childRNode, connection)) {
continue;
Expand All @@ -1837,14 +1865,16 @@ private void exploreAndExpand(ConnectionState state, RouteNode rnode) {
continue;
}
break;
case EXCLUSIVE_SINK:
case EXCLUSIVE_SINK_BOTH:
case EXCLUSIVE_SINK_EAST:
case EXCLUSIVE_SINK_WEST:
assert(childRNode.getType() != RouteNodeType.EXCLUSIVE_SINK_EAST || rnode.getType() == RouteNodeType.LOCAL_EAST);
assert(childRNode.getType() != RouteNodeType.EXCLUSIVE_SINK_WEST || rnode.getType() == RouteNodeType.LOCAL_WEST);
assert(childRNode.getType() != RouteNodeType.EXCLUSIVE_SINK || rnode.getType() == RouteNodeType.LOCAL ||
// FIXME:
design.getSeries() == Series.Versal);
assert(childRNode.getType() != RouteNodeType.EXCLUSIVE_SINK_BOTH || rnode.getType() == RouteNodeType.LOCAL_BOTH ||
// [BC]NODEs are LOCAL_{EAST,WEST} since they connect to INODEs, but also service CTRL sinks
(routingGraph.isVersal && EnumSet.of(IntentCode.NODE_CLE_BNODE, IntentCode.NODE_CLE_CNODE,
IntentCode.NODE_INTF_BNODE, IntentCode.NODE_INTF_CNODE)
.contains(rnode.getIntentCode())));
if (!isAccessibleSink(childRNode, connection)) {
continue;
}
Expand Down Expand Up @@ -1889,7 +1919,7 @@ protected boolean isAccessibleSink(RouteNode child, Connection connection) {
}

protected boolean isAccessibleSink(RouteNode child, Connection connection, boolean assertOnOveruse) {
assert(child.getType().isExclusiveSink());
assert(child.getType().isAnyExclusiveSink());
assert(!assertOnOveruse || !child.isOverUsed());

if (child.isTarget()) {
Expand Down
30 changes: 11 additions & 19 deletions src/com/xilinx/rapidwright/rwroute/RouteNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.xilinx.rapidwright.util.RuntimeTracker;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -123,22 +124,24 @@ private void setBaseCost(Series series) {
assert(length == 0 ||
(length <= 3 && series == Series.Versal));
break;
case EXCLUSIVE_SINK:
case EXCLUSIVE_SINK_BOTH:
case EXCLUSIVE_SINK_EAST:
case EXCLUSIVE_SINK_WEST:
assert(length == 0 ||
(length == 1 && (series == Series.UltraScalePlus || series == Series.UltraScale) && getIntentCode() == IntentCode.NODE_PINBOUNCE));
break;
case LOCAL:
case LOCAL_BOTH:
assert(length == 0);
break;
case LOCAL_EAST:
case LOCAL_WEST:
case LOCAL_RESERVED:
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]"))
(series == Series.UltraScale && getWireName().matches("INODE_[12]_[EW]_\\d+_FT[NS]")) ||
(series == Series.Versal && EnumSet.of(IntentCode.NODE_CLE_BNODE, IntentCode.NODE_CLE_CNODE).contains(getIntentCode()))
))
);
break;
Expand Down Expand Up @@ -221,20 +224,6 @@ private void setBaseCost(Series series) {
// Feedthrough nodes to reach tiles immediately above/below
(length == 1 && getWireName().matches("OUT_[NESW]NODE_[EW]_\\d+")));
break;
case NODE_INODE: // INT.INT_NODE_IMUX_ATOM_*_INT_OUT[01]
case NODE_IMUX: // INT.IMUX_B_[EW]*
case NODE_CLE_CTRL: // CLE_BC_CORE*.CTRL_[LR]_B*
case NODE_INTF_CTRL: // INTF_[LR]OCF_[TB][LR]_TILE.INTF_IRI*
assert(length == 0);
break;
case NODE_CLE_BNODE: // CLE_BC_CORE*.BNODE_OUTS_[EW]*
case NODE_CLE_CNODE: // CLE_BC_CORE*.CNODE_OUTS_[EW]*
case NODE_INTF_BNODE: // INTF_[LR]OCF_[TB][LR]_TILE.IF_INT_BNODE_OUTS*
case NODE_INTF_CNODE: // INTF_[LR]OCF_[TB][LR]_TILE.IF_INT_CNODE_OUTS*
// length == 1 because one side of BCNODE-s are shared between CLE_W_CORE_XaYb and CLE_E_CORE_X(a+1)Yb
// or CLE_W_CORE_X(a-1)Yb and CLE_E_CORE_XaYb
assert(length <= 1);
break;
default:
throw new RuntimeException(ic.toString());
}
Expand Down Expand Up @@ -367,10 +356,13 @@ public RouteNodeType getType() {
public void setType(RouteNodeType type) {
assert(this.type == type ||
// Support demotion from EXCLUSIVE_SINK to LOCAL since they have the same base cost
(this.type.isExclusiveSink() && type.isLocal()) ||
(this.type.isAnyExclusiveSink() && type.isAnyLocal()) ||
// Or promotion from LOCAL to EXCLUSIVE_SINK (by PartialRouter when NODE_PINBOUNCE on
// a newly unpreserved net becomes a sink)
(this.type.isLocal() && type.isExclusiveSink()));
(this.type.isAnyLocal() && type.isAnyExclusiveSink())) ||
// Or promotion for any LOCAL to a LOCAL_RESERVED (by determineRoutingTargets()
// for uphills of CTRL sinks)
(this.type.isAnyLocal() && type == RouteNodeType.LOCAL_RESERVED);
this.type = type;
}

Expand Down
Loading
Loading