Skip to content

Commit

Permalink
[RWRoute] Cleanup static router and RouterHelper (#1059)
Browse files Browse the repository at this point in the history
* [RWRoute] Replace LightweightRouteNode with RouterHelper inner classes

Signed-off-by: Eddie Hung <[email protected]>

* Fix typo

Signed-off-by: Eddie Hung <[email protected]>

* More renaming

Signed-off-by: Eddie Hung <[email protected]>

* Insert sink node into visited set

Signed-off-by: Eddie Hung <[email protected]>

* Revert RapidWrightDCP

Signed-off-by: Eddie Hung <[email protected]>

* Fix broken tests

Signed-off-by: Eddie Hung <[email protected]>

* Try removing RouteNode.equals(Node) too

Signed-off-by: Eddie Hung <[email protected]>

* Remove unused RouteNode.flags

Signed-off-by: Eddie Hung <[email protected]>

* Remove unused RouterHelper.isInvertibleDSPBELPin()

Signed-off-by: Eddie Hung <[email protected]>

* Fix broken assumption with INUSE nodes

Signed-off-by: Eddie Hung <[email protected]>

* Cleanup, use ArrayDeque not LinkedList

Signed-off-by: Eddie Hung <[email protected]>

* Fix testRouteStaticNet() to avoid site pins, and fix golden values

Signed-off-by: Eddie Hung <[email protected]>

* Static router to check INUSE/GND/CC before push, and ...

... check for unused LUT outputs on pop

Signed-off-by: Eddie Hung <[email protected]>

* Much fewer static GND sources, fewer PIPs

Signed-off-by: Eddie Hung <[email protected]>

* Fix testRouteStaticNet() to avoid site pins, and fix golden values

Signed-off-by: Eddie Hung <[email protected]>

* Fix value

Signed-off-by: Eddie Hung <[email protected]>

* Remove equals() overrides

Signed-off-by: Eddie Hung <[email protected]>

* GlobalSignalRouting to not use NodeWithPrev

Signed-off-by: Eddie Hung <[email protected]>

* Remove use of RouterHelper.NodeWithDelay

Signed-off-by: Eddie Hung <[email protected]>

* Revert "Remove equals() overrides"

This reverts commit 3809009.

Signed-off-by: Eddie Hung <[email protected]>

* Remove commented code

Signed-off-by: Eddie Hung <[email protected]>

* Handle case where sink node is already used

Signed-off-by: Eddie Hung <[email protected]>

* Revert "Remove commented code"

This reverts commit 4af0d8e.

Signed-off-by: Eddie Hung <[email protected]>

* Uncomment code

Signed-off-by: Eddie Hung <[email protected]>

* More refactoring/opt

Signed-off-by: Eddie Hung <[email protected]>

* Further reduction in static sources/PIPs

Signed-off-by: Eddie Hung <[email protected]>

* Check for routing errors too

Signed-off-by: Eddie Hung <[email protected]>

* Allow terminating on routed BOUNCE/BYPASS nodes

Signed-off-by: Eddie Hung <[email protected]>

* Sort sinks to be routed by tile

Signed-off-by: Eddie Hung <[email protected]>

* Improve re-use further

Signed-off-by: Eddie Hung <[email protected]>

* Do not place any static sources in the queue

Signed-off-by: Eddie Hung <[email protected]>

* Clarity

Signed-off-by: Eddie Hung <[email protected]>

* Add a NodeStatus.PRESERVED, static router to ignore those for now

FIXME: Use those nodes as a last resort, if we can see the need
Signed-off-by: Eddie Hung <[email protected]>

* [PartialRouter] Disable ripup in global/static routing

Signed-off-by: Eddie Hung <[email protected]>

* Use net.getPins()

Signed-off-by: Eddie Hung <[email protected]>

* Move static net preserving into RouteNodeGraph

Signed-off-by: Eddie Hung <[email protected]>

* Add an extra assert

Signed-off-by: Eddie Hung <[email protected]>

* Revert "Add a NodeStatus.PRESERVED, static router to ignore those for now"

This reverts commit 9b49488.

Signed-off-by: Eddie Hung <[email protected]>

* [EDIF] Fixes rare bus renaming collision (#1065)

* [EDIF] Fixes rare bus renaming collision

Signed-off-by: Chris Lavin <[email protected]>

* Work-around for both issues, adds test for rare case

Signed-off-by: Chris Lavin <[email protected]>

* Minimizes bus suffix usage and resolves incorrect connectivity in MultGenerator

Signed-off-by: Chris Lavin <[email protected]>

* Fix comment

Signed-off-by: Chris Lavin <[email protected]>

* Update test/src/com/xilinx/rapidwright/edif/TestEDIFNetlist.java

Co-authored-by: eddieh-xlnx <[email protected]>
Signed-off-by: Chris Lavin <[email protected]>

* Fix typo

Signed-off-by: Chris Lavin <[email protected]>

---------

Signed-off-by: Chris Lavin <[email protected]>
Co-authored-by: eddieh-xlnx <[email protected]>

* [PartialRouter] Disable ripup in global/static routing

Signed-off-by: Eddie Hung <[email protected]>

* Move static net preserving into RouteNodeGraph

Signed-off-by: Eddie Hung <[email protected]>

* Update src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java

Signed-off-by: eddieh-xlnx <[email protected]>

---------

Signed-off-by: Eddie Hung <[email protected]>
Signed-off-by: Chris Lavin <[email protected]>
Signed-off-by: eddieh-xlnx <[email protected]>
Co-authored-by: Chris Lavin <[email protected]>
  • Loading branch information
eddieh-xlnx and clavin-xlnx authored Sep 21, 2024
1 parent 04e7c3c commit 9538212
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 401 deletions.
336 changes: 174 additions & 162 deletions src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java

Large diffs are not rendered by default.

90 changes: 0 additions & 90 deletions src/com/xilinx/rapidwright/rwroute/LightweightRouteNode.java

This file was deleted.

24 changes: 12 additions & 12 deletions src/com/xilinx/rapidwright/rwroute/RWRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -409,17 +409,21 @@ protected void addGlobalClkRoutingTargets(Net clk) {
* @return NodeStatus result.
*/
protected NodeStatus getGlobalRoutingNodeStatus(Net net, Node node) {
if (routingGraph.isPreserved(node)) {
// Node is preserved by any net -- for base RWRoute, we don't need
// to check which net it is nor whether it is already in use
// because global/static nets are routed from scratch
Net preservedNet = routingGraph.getPreservedNet(node);
if (preservedNet == net) {
return NodeStatus.INUSE;
}
if (preservedNet != null) {
return NodeStatus.UNAVAILABLE;
}

// A RouteNode will only be created if the net is necessary for
// a to-be-routed connection
return routingGraph.getNode(node) == null ? NodeStatus.AVAILABLE
: NodeStatus.UNAVAILABLE;
RouteNode rnode = routingGraph.getNode(node);
if (rnode != null) {
// A RouteNode will only be created if the net is necessary for
// a to-be-routed connection
return NodeStatus.UNAVAILABLE;
}
return NodeStatus.AVAILABLE;
}

/**
Expand Down Expand Up @@ -505,10 +509,6 @@ protected void routeStaticNets() {
for (Map.Entry<Net,List<SitePinInst>> e : staticNetAndRoutingTargets.entrySet()) {
Net staticNet = e.getKey();
List<SitePinInst> pins = e.getValue();
// Since we preserved all pins in addStaticNetRoutingTargets(), unpreserve them here
for (SitePinInst spi : pins) {
routingGraph.unpreserve(spi.getConnectedNode());
}

System.out.println("INFO: Routing " + pins.size() + " pins of " + staticNet);

Expand Down
31 changes: 0 additions & 31 deletions src/com/xilinx/rapidwright/rwroute/RouteNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ public class RouteNode extends Node implements Comparable<RouteNode> {
private float baseCost;
/** A flag to indicate if this rnode is the target */
private boolean isTarget;
/** Byte for the use as general purpose flags */
private byte flags;
/** The children (downhill rnodes) of this rnode */
protected RouteNode[] children;

Expand Down Expand Up @@ -108,7 +106,6 @@ protected RouteNode(RouteNodeGraph routingGraph, Node node, RouteNodeType type)
visited = 0;
assert(prev == null);
assert(!isTarget);
flags = 0;
}

@Override
Expand Down Expand Up @@ -264,14 +261,6 @@ public int hashCode() {
return super.hashCode();
}

public boolean equals(Node obj) {
if (this == obj)
return true;
if (obj == null)
return false;
return super.equals(obj);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
Expand Down Expand Up @@ -696,24 +685,4 @@ public boolean isExcluded(RouteNodeGraph routingGraph, Node child) {
public int getSLRIndex(RouteNodeGraph routingGraph) {
return routingGraph.intYToSLRIndex[getEndTileYCoordinate()];
}

/**
* @param index Bit index.
* @return True if index is set.
*/
public boolean getFlag(int index) {
return (flags & (1 << index)) != 0;
}

/**
* @param index Bit index to change.
* @param value True to set. False to clear.
*/
public void setFlag(int index, boolean value) {
if (value) {
flags |= (1 << index);
} else {
flags &= ~(1 << index);
}
}
}
119 changes: 57 additions & 62 deletions src/com/xilinx/rapidwright/rwroute/RouterHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@
* A collection of supportive methods for the router.
*/
public class RouterHelper {
static class NodeWithPrev extends Node {
protected NodeWithPrev prev;
NodeWithPrev(Node node) {
super(node);
}

void setPrev(NodeWithPrev prev) {
this.prev = prev;
}

NodeWithPrev getPrev() {
return prev;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
// This method requires that object is Node or a subclass of one, otherwise exception will be thrown.
// If so, explicitly call the Node.equals(Node) overload, rather than the general-purpose Node.equals(Object).
return super.equals((Node) obj);
}
}

/**
* Checks if a {@link Net} instance has source and sink {@link SitePinInst} instances to be routable.
* @param net The net to be checked.
Expand Down Expand Up @@ -165,23 +191,25 @@ public static Node projectOutputPinToINTNode(SitePinInst output) {
*/
public static List<Node> projectInputPinToINTNode(SitePinInst input) {
List<Node> sinkToSwitchBoxPath = new ArrayList<>();
LightweightRouteNode sink = new LightweightRouteNode(input.getConnectedNode());
NodeWithPrev sink = new NodeWithPrev(input.getConnectedNode());
sink.setPrev(null);
Queue<LightweightRouteNode> q = new LinkedList<>();
Queue<NodeWithPrev> q = new LinkedList<>();
q.add(sink);
int watchdog = 1000;
while (!q.isEmpty()) {
LightweightRouteNode n = q.poll();
if (n.getNode().getTile().getTileTypeEnum() == TileTypeEnum.INT) {
NodeWithPrev n = q.poll();
if (n.getTile().getTileTypeEnum() == TileTypeEnum.INT) {
while (n != null) {
sinkToSwitchBoxPath.add(n.getNode());
sinkToSwitchBoxPath.add(n);
n = n.getPrev();
}
return sinkToSwitchBoxPath;
}
for (Node uphill : n.getNode().getAllUphillNodes()) {
if (uphill.getAllUphillNodes().size() == 0) continue;
LightweightRouteNode prev = new LightweightRouteNode(uphill);
for (Node uphill : n.getAllUphillNodes()) {
if (uphill.getAllUphillNodes().size() == 0) {
continue;
}
NodeWithPrev prev = new NodeWithPrev(uphill);
prev.setPrev(n);
q.add(prev);
}
Expand Down Expand Up @@ -355,19 +383,6 @@ public static Collection<Node> getNodesOfNet(Net net) {
return nodes;
}

/**
* Checks if a DSP {@link BELPin} instance is invertible.
* @param belPin The bel pin in question.
* @return true, if the bel pin is invertible.
*/
private static boolean isInvertibleDSPBELPin(BELPin belPin) {
if (belPin.getBELName().equals("CLKINV")) {
//NEED TO BE INVERTED when BEL.canInvert returns false
return true;
}
return belPin.getBEL().canInvert();
}

/**
* Inverts all possible GND sink pins to VCC pins.
* @param design The target design.
Expand Down Expand Up @@ -520,60 +535,41 @@ public static void addNodeTypeLengthToMap(Node node, long wlNode, Map<IntentCode
* @param estimator An instantiation of DelayEstimatorBase.
* @return The map containing net delay for each sink pin paired with an INT tile node of a routed net.
*/
public static Map<Pair<SitePinInst, Node>, Short> getSourceToSinkINTNodeDelays(Net net, DelayEstimatorBase estimator) {
public static Map<SitePinInst, Pair<Node,Short>> getSourceToSinkINTNodeDelays(Net net, DelayEstimatorBase estimator) {
List<PIP> pips = net.getPIPs();
Map<Node, LightweightRouteNode> nodeRoutingNodeMap = new HashMap<>();
boolean firstPIP = true;
Map<Node, Integer> delayMap = new HashMap<>();
for (PIP pip : pips) {
Node startNode = pip.getStartNode();
LightweightRouteNode startrn = createRoutingNode(pip.getStartNode(), nodeRoutingNodeMap);

if (firstPIP) {
startrn.setDelayFromSource(0);
}
firstPIP = false;
int upstreamDelay = delayMap.getOrDefault(startNode, 0);

Node endNode = pip.getEndNode();
LightweightRouteNode endrn = createRoutingNode(endNode, nodeRoutingNodeMap);
endrn.setPrev(startrn);
int delay = 0;
if (endNode.getTile().getTileTypeEnum() == TileTypeEnum.INT) {//device independent?
delay = computeNodeDelay(estimator, endNode)
+ DelayEstimatorBase.getExtraDelay(endNode, DelayEstimatorBase.isLong(startNode));
}

endrn.setDelayFromSource(startrn.getDelayFromSource() + delay);
delayMap.put(endNode, upstreamDelay + delay);
}

Map<Pair<SitePinInst, Node>, Short> sinkNodeDelays = new HashMap<>();
Map<SitePinInst, Pair<Node,Short>> sinkNodeDelays = new HashMap<>();
for (SitePinInst sink : net.getSinkPins()) {
Node sinkNode = sink.getConnectedNode();
if (!(sinkNode.getTile().getTileTypeEnum() == TileTypeEnum.INT)) {
sinkNode = projectInputPinToINTNode(sink).get(0);
if (sinkNode.getTile().getTileTypeEnum() != TileTypeEnum.INT) {
List<Node> nodes = projectInputPinToINTNode(sink);
if (!nodes.isEmpty()) {
sinkNode = nodes.get(0);
} else {
// Must be a direct connection (e.g. COUT -> CIN)
}
}

short routeDelay = (short) nodeRoutingNodeMap.get(sinkNode).getDelayFromSource();
sinkNodeDelays.put(new Pair<>(sink, sinkNode), routeDelay);
short routeDelay = (short) delayMap.get(sinkNode).intValue();
sinkNodeDelays.put(sink, new Pair<>(sinkNode,routeDelay));
}

return sinkNodeDelays;
}

/**
* Creates a {@link LightweightRouteNode} Object based on a {@link Node} Object, avoiding duplicates.
* @param node The {@link Node} instance that is used to create a RoutingNode object.
* @param createdRoutingNodes A map storing created {@link LightweightRouteNode} instances and corresponding {@link Node} instances.
* @return A created RoutingNode instance based on a node
*/
public static LightweightRouteNode createRoutingNode(Node node, Map<Node, LightweightRouteNode> createdRoutingNodes) {
LightweightRouteNode resourceNode = createdRoutingNodes.get(node);
if (resourceNode == null) {
resourceNode = new LightweightRouteNode(node);
createdRoutingNodes.put(node, resourceNode);
}
return resourceNode;
}

/**
* Computes the delay of a node.
* @param estimator An instantiation of the DelayEstimatorBase.
Expand Down Expand Up @@ -613,25 +609,25 @@ public static List<Node> findPathBetweenNodes(Node source, Node sink) {
path.add(source);
return path;
}
LightweightRouteNode sourcer = new LightweightRouteNode(source);
NodeWithPrev sourcer = new NodeWithPrev(source);
sourcer.setPrev(null);
Queue<LightweightRouteNode> queue = new LinkedList<>();
Queue<NodeWithPrev> queue = new LinkedList<>();
queue.add(sourcer);

int watchdog = 10000;
boolean success = false;
while (!queue.isEmpty()) {
LightweightRouteNode curr = queue.poll();
if (curr.getNode().equals(sink)) {
NodeWithPrev curr = queue.poll();
if (curr.equals(sink)) {
while (curr != null) {
path.add(curr.getNode());
path.add(curr);
curr = curr.getPrev();
}
success = true;
break;
}
for (Node n : curr.getNode().getAllDownhillNodes()) {
LightweightRouteNode child = new LightweightRouteNode(n);
for (Node n : curr.getAllDownhillNodes()) {
NodeWithPrev child = new NodeWithPrev(n);
child.setPrev(curr);
queue.add(child);
}
Expand Down Expand Up @@ -699,5 +695,4 @@ public static List<String> parseVivadoPathToStringList(File file) throws IOExcep
reader.close();
return path;
}

}
Loading

0 comments on commit 9538212

Please sign in to comment.