Skip to content

Commit

Permalink
Merge branch 'master' into rwroute_cleanup2
Browse files Browse the repository at this point in the history
Conflicts:
	src/com/xilinx/rapidwright/design/DesignTools.java
	src/com/xilinx/rapidwright/rwroute/PartialRouter.java
	src/com/xilinx/rapidwright/rwroute/RouteNode.java
  • Loading branch information
eddieh-xlnx committed Oct 23, 2024
2 parents 07d8f12 + 080a905 commit ab908c2
Show file tree
Hide file tree
Showing 14 changed files with 539 additions and 162 deletions.
23 changes: 12 additions & 11 deletions src/com/xilinx/rapidwright/design/DesignTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -3421,7 +3421,7 @@ public static void createCeSrRstPinsToVCC(Design design) {
throw new RuntimeException(series.toString());
}
for (Cell cell : design.getCells()) {
if (isUnisimFlipFlopType(cell.getType())) {
if (isFlipFlopOrLatchNeedingCeSrToVcc(cell.getType())) {
SiteInst si = cell.getSiteInst();
if (!Utils.isSLICE(si)) {
continue;
Expand Down Expand Up @@ -3483,19 +3483,20 @@ private static void maybeCreateVccPin(SiteInst si, String sitePinName, Net vcc)
vcc.addPin(sitePin, updateSiteRouting);
}

static HashSet<String> unisimFlipFlopTypes;
// Used by createCeSrRstPinsToVCC()
static Set<String> flipFlopAndLatchTypesNeedingCeSrToVcc;
static {
unisimFlipFlopTypes = new HashSet<>();
unisimFlipFlopTypes.add("FDSE");//S CE, logical cell
unisimFlipFlopTypes.add("FDPE");//PRE CE
unisimFlipFlopTypes.add("FDRE");//R and CE
unisimFlipFlopTypes.add("FDCE");//CLR CE
unisimFlipFlopTypes.add("LDCE");
unisimFlipFlopTypes.add("LPCE");
flipFlopAndLatchTypesNeedingCeSrToVcc = new HashSet<>();
flipFlopAndLatchTypesNeedingCeSrToVcc.add("FDSE");//S CE, logical cell
flipFlopAndLatchTypesNeedingCeSrToVcc.add("FDPE");//PRE CE
flipFlopAndLatchTypesNeedingCeSrToVcc.add("FDRE");//R and CE
flipFlopAndLatchTypesNeedingCeSrToVcc.add("FDCE");//CLR CE
flipFlopAndLatchTypesNeedingCeSrToVcc.add("LDCE");
flipFlopAndLatchTypesNeedingCeSrToVcc.add("LDPE");
}

private static boolean isUnisimFlipFlopType(String cellType) {
return unisimFlipFlopTypes.contains(cellType);
private static boolean isFlipFlopOrLatchNeedingCeSrToVcc(String cellType) {
return flipFlopAndLatchTypesNeedingCeSrToVcc.contains(cellType);
}

/** Mapping from device Series to another mapping from FF BEL name to CKEN/SRST site pin name **/
Expand Down
6 changes: 5 additions & 1 deletion src/com/xilinx/rapidwright/rwroute/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.xilinx.rapidwright.design.Net;
import com.xilinx.rapidwright.design.SitePinInst;
import com.xilinx.rapidwright.device.Node;
import com.xilinx.rapidwright.device.Series;
import com.xilinx.rapidwright.timing.TimingEdge;
import com.xilinx.rapidwright.timing.delayestimator.DelayEstimatorBase;
import com.xilinx.rapidwright.util.Pair;
Expand Down Expand Up @@ -83,7 +84,7 @@ public class Connection implements Comparable<Connection>{
/** To indicate if the route delay of a connection has been patched up, when there are consecutive long nodes */
private boolean dlyPatched;
/** true to indicate that a connection cross SLRs */
private boolean crossSLR;
private final boolean crossSLR;
/** List of nodes assigned to a connection to form the path for generating PIPs */
private List<Node> nodes;

Expand All @@ -96,6 +97,9 @@ public Connection(int id, SitePinInst source, SitePinInst sink, NetWrapper netWr
this.netWrapper = netWrapper;
netWrapper.addConnection(this);
crossSLR = !source.getTile().getSLR().equals(sink.getTile().getSLR());
if (crossSLR && source.getSiteInst().getDesign().getSeries() == Series.Versal) {
throw new RuntimeException("ERROR: Cross-SLR connections not yet supported on Versal.");
}
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,10 @@ public static Map<RouteNode, List<SitePinInst>> getLCBPinMappings(List<SitePinIn
for (SitePinInst p : clkPins) {
if (p.isOutPin()) continue;
assert(lcbCandidates.isEmpty());
List<Node> intNodes = RouterHelper.projectInputPinToINTNode(p);
if (intNodes == null || intNodes.isEmpty()) {
Node intNode = RouterHelper.projectInputPinToINTNode(p);
if (intNode == null) {
throw new RuntimeException("Unable to get INT tile for pin " + p);
}
Node intNode = intNodes.get(0);

outer: for (Node prev : intNode.getAllUphillNodes()) {
NodeStatus prevNodeStatus = getNodeStatus.apply(prev);
Expand Down
36 changes: 31 additions & 5 deletions src/com/xilinx/rapidwright/rwroute/PartialRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
import com.xilinx.rapidwright.design.DesignTools;
import com.xilinx.rapidwright.design.Net;
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.Series;
import com.xilinx.rapidwright.router.UltraScaleClockRouting;
import com.xilinx.rapidwright.tests.CodePerfTracker;
import com.xilinx.rapidwright.timing.ClkRouteTiming;
Expand Down Expand Up @@ -234,11 +236,13 @@ protected void determineRoutingTargets() {
// if so, unpreserve that blocking net
Set<Net> unpreserveNets = new HashSet<>();
for (Connection connection : indirectConnections) {
Net net = connection.getNet();
Net net = connection.getNetWrapper().getNet();
Net preservedNet;
assert((preservedNet = routingGraph.getPreservedNet(connection.getSourceRnode())) == null || preservedNet == net);
RouteNode sinkRnode = connection.getSinkRnode();
Net unpreserveNet = routingGraph.getPreservedNet(sinkRnode);
if (unpreserveNet != null && unpreserveNet != net) {
unpreserveNets.add(unpreserveNet);
preservedNet = routingGraph.getPreservedNet(sinkRnode);
if (preservedNet != null && preservedNet != net) {
unpreserveNets.add(preservedNet);
assert(sinkRnode.getType() == RouteNodeType.PINFEED_I);
}
}
Expand Down Expand Up @@ -351,6 +355,8 @@ protected void addNetConnectionToRoutingTargets(Net net) {
}

if (net.hasPIPs()) {
final boolean isVersal = design.getSeries() == Series.Versal;

// Create all nodes used by this net and set its previous pointer so that:
// (a) the routing for each connection can be recovered by
// finishRouteConnection()
Expand All @@ -362,8 +368,28 @@ protected void addNetConnectionToRoutingTargets(Net net) {

// Do not include arcs that the router wouldn't explore
// e.g. those that leave the INT tile, since we project pins to their INT tile
if (routingGraph.isExcludedTile(end))
if (routingGraph.isExcludedTile(end)) {
continue;
}

if (isVersal) {
// Skip all PIPs downstream from a NODE_INTF_CTRL (since that is the intent that
// RouterHelper.projectInputPinToINTNode() will terminate at)
// NODE_INTF_CTRL -> NODE_PINFEED -> NODE_IRI -> NODE_IRI -> NODE_PINFEED (site pin)

IntentCode startIntent = start.getIntentCode();
if (startIntent == IntentCode.NODE_INTF_CTRL || startIntent == IntentCode.NODE_IRI) {
continue;
}

IntentCode endIntent = end.getIntentCode();
if (endIntent == IntentCode.NODE_IRI ||
// Skip NODE_OUTPUT -> NODE_INTF[24] since RouterHelper.projectOutputPinToINTNode()
// terminates at the latter
endIntent == IntentCode.NODE_INTF2 || endIntent == IntentCode.NODE_INTF4) {
continue;
}
}

RouteNode rstart = routingGraph.getOrCreate(start);
RouteNode rend = routingGraph.getOrCreate(end);
Expand Down
100 changes: 74 additions & 26 deletions src/com/xilinx/rapidwright/rwroute/RWRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.xilinx.rapidwright.design.Design;
import com.xilinx.rapidwright.design.DesignTools;
import com.xilinx.rapidwright.design.Net;
import com.xilinx.rapidwright.design.NetTools;
import com.xilinx.rapidwright.design.NetType;
import com.xilinx.rapidwright.design.SiteInst;
import com.xilinx.rapidwright.design.SitePinInst;
Expand Down Expand Up @@ -180,7 +181,10 @@ public class RWRoute {
public static final EnumSet<Series> SUPPORTED_SERIES;

static {
SUPPORTED_SERIES = EnumSet.of(Series.UltraScale, Series.UltraScalePlus);
SUPPORTED_SERIES = EnumSet.of(
Series.UltraScale,
Series.UltraScalePlus,
Series.Versal);
}

public RWRoute(Design design, RWRouteConfig config) {
Expand All @@ -190,6 +194,15 @@ public RWRoute(Design design, RWRouteConfig config) {
connectionsRoutedThisIteration = new AtomicInteger();
nodesPushed = new AtomicLong();
nodesPopped = new AtomicLong();

if (design.getSeries() == Series.Versal) {
if (config.isLutPinSwapping()) {
throw new RuntimeException("ERROR: '--lutPinSwapping' not yet supported on Versal.");
}
if (config.isLutRoutethru()) {
throw new RuntimeException("ERROR: '--lutRoutethru' not yet supported on Versal.");
}
}
}

protected static String getUnsupportedSeriesMessage(Part part) {
Expand Down Expand Up @@ -328,7 +341,7 @@ private void categorizeNets() {
staticNetAndRoutingTargets = new HashMap<>();

for (Net net : design.getNets()) {
if (net.isClockNet()) {
if (NetTools.isGlobalClock(net)) {
addGlobalClkRoutingTargets(net);

} else if (net.isStaticNet()) {
Expand Down Expand Up @@ -479,6 +492,9 @@ protected void addStaticNetRoutingTargets(Net staticNet) {
List<SitePinInst> sinks = staticNet.getSinkPins();
if (sinks.size() > 0) {
staticNet.unroute();
// Remove all output pins from unrouted net as those used will be repopulated
staticNet.getPins().removeIf(SitePinInst::isOutPin);

// Preserve all pins (e.g. in case of BOUNCE nodes that may serve as a site pin)
preserveNet(staticNet, true);
staticNetAndRoutingTargets.put(staticNet, sinks);
Expand Down Expand Up @@ -552,8 +568,8 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
int indirect = 0;
for (SitePinInst sink : sinkPins) {
Connection connection = new Connection(numConnectionsToRoute++, source, sink, netWrapper);
List<Node> nodes = RouterHelper.projectInputPinToINTNode(sink);
if (sourceINTNode == null && !nodes.isEmpty()) {
Node sinkINTNode = RouterHelper.projectInputPinToINTNode(sink);
if (sourceINTNode == null && sinkINTNode != null) {
// Sink can be projected to an INT tile, but primary source (e.g. COUT)
// cannot be; try alternate source
Pair<SitePinInst,RouteNode> altSourceAndRnode = connection.getOrCreateAlternateSource(routingGraph);
Expand All @@ -565,7 +581,7 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
}
}

if ((sourceINTNode == null && connection.getSourceRnode() == null) || nodes.isEmpty()) {
if ((sourceINTNode == null && connection.getSourceRnode() == null) || sinkINTNode == null) {
// Direct connection if either source or sink pin cannot be projected to INT tile
directConnections.add(connection);
connection.setDirect(true);
Expand All @@ -584,7 +600,6 @@ protected NetWrapper createNetWrapperAndConnections(Net net) {
connection.setSourceRnode(sourceINTRnode);
}

Node sinkINTNode = nodes.get(0);
indirectConnections.add(connection);
RouteNode sinkRnode = routingGraph.getOrCreate(sinkINTNode, RouteNodeType.PINFEED_I);
sinkRnode.setType(RouteNodeType.PINFEED_I);
Expand Down Expand Up @@ -1284,16 +1299,15 @@ private void computesNodeUsageAndTotalWirelength() {
Set<Node> netNodes = new HashSet<>();
for (Entry<Net,NetWrapper> e : nets.entrySet()) {
NetWrapper netWrapper = e.getValue();
for (Connection connection:netWrapper.getConnections()) {
for (Connection connection : netWrapper.getConnections()) {
if (connection.getNodes() == null) {
continue;
}

netNodes.addAll(connection.getNodes());
}
for (Node node:netNodes) {
TileTypeEnum tileType = node.getTile().getTileTypeEnum();
if (tileType != TileTypeEnum.INT && !Utils.isLaguna(tileType)) {
for (Node node : netNodes) {
if (RouteNodeGraph.isExcludedTile(node)) {
continue;
}
totalINTNodes++;
Expand All @@ -1306,18 +1320,45 @@ private void computesNodeUsageAndTotalWirelength() {
}
}

static List<IntentCode> nodeTypes = new ArrayList<>();
static List<IntentCode> nodeUsageForUltraScale = new ArrayList<>();
static {
nodeUsageForUltraScale.add(IntentCode.NODE_SINGLE);
nodeUsageForUltraScale.add(IntentCode.NODE_DOUBLE);
nodeUsageForUltraScale.add(IntentCode.NODE_VQUAD);
nodeUsageForUltraScale.add(IntentCode.NODE_HQUAD);
nodeUsageForUltraScale.add(IntentCode.NODE_VLONG);
nodeUsageForUltraScale.add(IntentCode.NODE_HLONG);
nodeUsageForUltraScale.add(IntentCode.NODE_LOCAL);
nodeUsageForUltraScale.add(IntentCode.NODE_PINBOUNCE);
nodeUsageForUltraScale.add(IntentCode.NODE_PINFEED);
nodeUsageForUltraScale.add(IntentCode.NODE_LAGUNA_DATA); // UltraScale+ only intent code,
// but super long lines from UltraScale (which have
// IntentCode.INTENT_DEFAULT are mapped to this)
}

static List<IntentCode> nodeUsageForVersal = new ArrayList<>();
static {
nodeTypes.add(IntentCode.NODE_SINGLE);
nodeTypes.add(IntentCode.NODE_DOUBLE);
nodeTypes.add(IntentCode.NODE_VQUAD);
nodeTypes.add(IntentCode.NODE_HQUAD);
nodeTypes.add(IntentCode.NODE_VLONG);
nodeTypes.add(IntentCode.NODE_HLONG);
nodeTypes.add(IntentCode.NODE_LOCAL);
nodeTypes.add(IntentCode.NODE_PINBOUNCE);
nodeTypes.add(IntentCode.NODE_PINFEED);
nodeTypes.add(IntentCode.NODE_LAGUNA_DATA); // UltraScale+ only
nodeUsageForVersal.add(IntentCode.NODE_VSINGLE);
nodeUsageForVersal.add(IntentCode.NODE_HSINGLE);
nodeUsageForVersal.add(IntentCode.NODE_VDOUBLE);
nodeUsageForVersal.add(IntentCode.NODE_HDOUBLE);
nodeUsageForVersal.add(IntentCode.NODE_VQUAD);
nodeUsageForVersal.add(IntentCode.NODE_HQUAD);
nodeUsageForVersal.add(IntentCode.NODE_VLONG7);
nodeUsageForVersal.add(IntentCode.NODE_VLONG12);
nodeUsageForVersal.add(IntentCode.NODE_HLONG6);
nodeUsageForVersal.add(IntentCode.NODE_HLONG10);
nodeUsageForVersal.add(IntentCode.NODE_CLE_BNODE);
nodeUsageForVersal.add(IntentCode.NODE_INTF_BNODE);
nodeUsageForVersal.add(IntentCode.NODE_CLE_CNODE);
nodeUsageForVersal.add(IntentCode.NODE_INTF_CNODE);
nodeUsageForVersal.add(IntentCode.NODE_PINBOUNCE);
nodeUsageForVersal.add(IntentCode.NODE_IMUX);
// NODE_PINFEED exists on Versal but is behind a NODE_IMUX
// and gets projectInputPinToINTNode() -ed away

// TODO: Enable when SLR crossings are supported
// nodeUsageForVersal.add(IntentCode.NODE_SLL_DATA);
}

/**
Expand Down Expand Up @@ -1433,7 +1474,7 @@ protected void setPIPsOfNets() {
for (Entry<Net,NetWrapper> e : nets.entrySet()) {
NetWrapper netWrapper = e.getValue();
Net net = netWrapper.getNet();
assert(net.getType() == NetType.WIRE && !net.isClockNet());
assert(net.getType() == NetType.WIRE && !NetTools.isGlobalClock(net));

Set<PIP> newPIPs = new HashSet<>();
for (Connection connection:netWrapper.getConnections()) {
Expand All @@ -1456,7 +1497,13 @@ protected void setPIPsOfNets() {
if (pip.isRouteThru()) {
continue;
}
SitePin sp = pip.getStartNode().getSitePin();
Node startNode = pip.getStartNode();
IntentCode startIntent = startNode.getIntentCode();
if (startIntent != IntentCode.NODE_CLE_OUTPUT && // US+ and Versal
startIntent != IntentCode.NODE_OUTPUT) { // US
continue;
}
SitePin sp = startNode.getSitePin();
if (sp.getPinName().equals(source.getName())) {
pip.setIsLogicalDriver(true);
break;
Expand Down Expand Up @@ -2020,11 +2067,12 @@ private void printTimingInfo() {
}
}

public static void printNodeTypeUsageAndWirelength(boolean verbose, Map<IntentCode, Long> nodeTypeUsage, Map<IntentCode, Long> nodeTypeLength) {
public static void printNodeTypeUsageAndWirelength(boolean verbose, Map<IntentCode, Long> nodeTypeUsage, Map<IntentCode, Long> nodeTypeLength, Series series) {
if (verbose) {
System.out.println("Node Usage Per Type");
System.out.printf(" %-16s %13s %12s\n", "Node Type", "Usage", "Length");
for (IntentCode ic : nodeTypes) {
List<IntentCode> nodeTypeList = (series == Series.Versal) ? nodeUsageForVersal : nodeUsageForUltraScale;
for (IntentCode ic : nodeTypeList) {
long usage = nodeTypeUsage.getOrDefault(ic, 0L);
long length = nodeTypeLength.getOrDefault(ic, 0L);
System.out.printf(" %-16s %13d %12d\n", ic, usage, length);
Expand Down Expand Up @@ -2074,7 +2122,7 @@ private static void printFormattedString(String s, long value) {
protected void printRoutingStatistics() {
MessageGenerator.printHeader("Statistics");
computesNodeUsageAndTotalWirelength();
printNodeTypeUsageAndWirelength(config.isVerbose(), nodeTypeUsage, nodeTypeLength);
printNodeTypeUsageAndWirelength(config.isVerbose(), nodeTypeUsage, nodeTypeLength, design.getSeries());
printFormattedString("Total wirelength:", totalWL);
if (config.isVerbose()) {
printFormattedString("Total INT tile nodes:", totalINTNodes);
Expand Down
Loading

0 comments on commit ab908c2

Please sign in to comment.