Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit 9538212
Author: eddieh-xlnx <[email protected]>
Date:   Fri Sep 20 17:01:46 2024 -0700

    [RWRoute] Cleanup static router and RouterHelper (#1059)

    * [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]>

commit 04e7c3c
Author: eddieh-xlnx <[email protected]>
Date:   Fri Sep 20 14:48:12 2024 -0700

    [PartialRouter] Disable ripup in global/static routing (#1067)

    * [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: eddieh-xlnx <[email protected]>

commit ef2a82d
Author: Chris Lavin <[email protected]>
Date:   Fri Sep 20 09:44:54 2024 -0600

    [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]>

commit e298a18
Author: eddieh-xlnx <[email protected]>
Date:   Thu Sep 19 19:20:58 2024 -0700

    [RWRoute] Always clear prev pointer of unpreserved RouteNode-s (#1056)

    * Use upload-artifact v4 for checks

    Signed-off-by: Wenhao Lin <[email protected]>

    * Make each uploaded artifact have a unique name

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

    * Try again

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

    * [RWRoute] Always clear prev pointer of unpreserved RouteNode-s

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

    * Tidy

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

    * Apply suggestions from code review

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

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

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

    ---------

    Signed-off-by: Wenhao Lin <[email protected]>
    Signed-off-by: Eddie Hung <[email protected]>
    Signed-off-by: eddieh-xlnx <[email protected]>
    Co-authored-by: Wenhao Lin <[email protected]>
  • Loading branch information
eddieh-xlnx committed Sep 21, 2024
1 parent 70b3ec8 commit f7abc50
Show file tree
Hide file tree
Showing 15 changed files with 380 additions and 553 deletions.
16 changes: 15 additions & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,23 @@ public void exportEDIF(OutputStream os, EDIFWriteLegalNameCache<?> cache, boolea
* @throws IOException
*/
public void exportEDIFBusName(OutputStream os, EDIFWriteLegalNameCache<?> cache) throws IOException {
exportSomeEDIFName(os, getName(), cache.getEDIFRename(busName));
exportSomeEDIFName(os, getName(), getBusEDIFRename(cache));
}

/**
* Handles bus name collisions with single bit ports (same root name) to avoid
* EDIF export name legalization collisions.
*
* @param cache The current EDIF name legalization cache
* @return The legalize EDIF bus name for this port
*/
protected byte[] getBusEDIFRename(EDIFWriteLegalNameCache<?> cache) {
String busName = getBusName(false);
boolean collision = parentCell.getPortMap().containsKey(busName);
byte[] rename = collision ? cache.getBusCollisionEDIFRename(busName) : cache.getEDIFRename(busName);
return rename == null ? busName.getBytes(StandardCharsets.UTF_8) : rename;
}

/**
* @return the parentCell
*/
Expand Down
2 changes: 1 addition & 1 deletion src/com/xilinx/rapidwright/edif/EDIFPortInst.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public void writeEDIFExport(OutputStream os, byte[] indent, EDIFWriteLegalNameCa
}
else {
os.write(EXPORT_CONST_MEMBER);
os.write(cache.getLegalEDIFName(getPort().getBusName(true)));
os.write(getPort().getBusEDIFRename(cache));
os.write(' ');
os.write(Integer.toString(index).getBytes(StandardCharsets.UTF_8));
os.write(')');
Expand Down
8 changes: 8 additions & 0 deletions src/com/xilinx/rapidwright/edif/EDIFWriteLegalNameCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,15 @@ public abstract class EDIFWriteLegalNameCache<T> {
*/
private final Map<String, byte[]>[] renames;

private final Map<String, byte[]> busCollisionRenames;

private EDIFWriteLegalNameCache(Map<String, T> usedRenames, Supplier<Map<String, byte[]>> renameSupplier) {
this.usedRenames = usedRenames;
this.renames = new Map[256];
for (int i = 0; i < renames.length; i++) {
renames[i] = renameSupplier.get();
}
this.busCollisionRenames = new HashMap<>();
}

protected abstract int getAndIncrement(String rename);
Expand Down Expand Up @@ -86,6 +89,11 @@ public byte[] getEDIFRename(String name) {
return rename;
}

public byte[] getBusCollisionEDIFRename(String name) {
return busCollisionRenames.computeIfAbsent(name,
n -> (EDIFTools.makeNameEDIFCompatible(n) + "_BUS_").getBytes(StandardCharsets.UTF_8));
}

public static EDIFWriteLegalNameCache<?> singleThreaded() {
return new EDIFWriteLegalNameCache<Integer>(new HashMap<>(), HashMap::new) {

Expand Down
7 changes: 6 additions & 1 deletion src/com/xilinx/rapidwright/examples/MultGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,12 @@ public static PBlock createMult(Design d, Site origin, int width, String designN
for (int i=0; i < port.getWidth(); i++) {
EDIFNet net = top.createNet(port.getBusName() + (port.getWidth() > 1 ? "[" + i + "]" : ""));
int ii = port.getWidth() - 1 - i;
net.createPortInst(port.getBusName(), ii, inst);
if (port.isBus()) {
net.createPortInst(port.getBusName(), ii, inst);
} else {
net.createPortInst(port, inst);
}

Net physNet = d.createNet(inst + "/" + net.getName());

// Correct differences in physical pin names
Expand Down
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.

129 changes: 2 additions & 127 deletions src/com/xilinx/rapidwright/rwroute/PartialRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -160,7 +157,7 @@ protected static boolean isPartOfExistingRoute(RouteNodeGraph routingGraph, Rout

// Presence of a prev pointer means that:
// (a) end node has been visited before
// (b) only this is arc allowed to enter this end node
// (b) only that arc is allowed to enter this end node
RouteNode prev = endRnode.getPrev();
if (prev != null) {
if (endRnode.isVisited(start.getVisited())) {
Expand Down Expand Up @@ -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())
Expand All @@ -277,88 +229,11 @@ protected void routeGlobalClkNets() {
super.routeGlobalClkNet(clk);
} else {
System.out.println("INFO: Routing " + clkPins.size() + " pins of clock " + clk + " (non timing-driven)");
Function<Node, NodeStatus> gns = (node) -> this.getGlobalRoutingNodeStatus(clk, node);
Function<Node, NodeStatus> gns = (node) -> getGlobalRoutingNodeStatus(clk, node);
UltraScaleClockRouting.incrementalClockRouter(clk, clkPins, gns);
preserveNet(clk, false);
}
}

List<Net> 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<Net> 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<Net> unpreserveCongestedNets(Collection<Net> 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<Net> unpreserveNets = new ArrayList<>();
for (Net net : globalNets) {
for (PIP pip : net.getPIPs()) {
for (Node node : Arrays.asList(pip.getStartNode(), pip.getEndNode())) {
Net preservedNet = routingGraph.getPreservedNet(node);
if (preservedNet == net) {
continue;
}
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));
}

// RouteNode must only exist if the net has been unpreserved
RouteNode rnode = routingGraph.getNode(node);
if (rnode != null) {
// Clear its prev pointer so that it doesn't get misinterpreted
// by RouteNodeGraph.mustInclude as being part of an existing route
assert (rnode.getPrev() != null);
rnode.clearPrev();

// Increment this RouteNode with a null net (since global nets have
// no corresponding NetWrapper) in order to flag it as being irreversibly
// used by a global net thus forcing the non-global to find another path
rnode.incrementUser(null);
} else {
assert(oldNet != null);
}
}
}
}
return unpreserveNets;
}

@Override
Expand Down
Loading

0 comments on commit f7abc50

Please sign in to comment.