From 088b3353bae962cdbc84c22db2cd578e9ca1d8da Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 28 Feb 2023 17:31:26 -0800 Subject: [PATCH] Refactor into RouteNodeInfo class Signed-off-by: Eddie Hung --- .../xilinx/rapidwright/rwroute/RouteNode.java | 171 +---------------- .../rapidwright/rwroute/RouteNodeInfo.java | 175 ++++++++++++++++++ 2 files changed, 185 insertions(+), 161 deletions(-) create mode 100644 src/com/xilinx/rapidwright/rwroute/RouteNodeInfo.java diff --git a/src/com/xilinx/rapidwright/rwroute/RouteNode.java b/src/com/xilinx/rapidwright/rwroute/RouteNode.java index 9c6eee731..7a2024079 100644 --- a/src/com/xilinx/rapidwright/rwroute/RouteNode.java +++ b/src/com/xilinx/rapidwright/rwroute/RouteNode.java @@ -29,9 +29,7 @@ import com.xilinx.rapidwright.device.Node; import com.xilinx.rapidwright.device.Tile; import com.xilinx.rapidwright.device.TileTypeEnum; -import com.xilinx.rapidwright.device.Wire; import com.xilinx.rapidwright.util.RuntimeTracker; -import com.xilinx.rapidwright.util.Utils; import java.util.ArrayList; import java.util.HashMap; @@ -54,12 +52,12 @@ abstract public class RouteNode implements Comparable { /** The associated {@link Node} instance */ protected Node node; /** The type of a rnode*/ - private RouteNodeType type; + private final RouteNodeType type; /** The tileXCoordinate and tileYCoordinate of the INT tile that the associated node stops at */ - private short endTileXCoordinate; - private short endTileYCoordinate; + private final short endTileXCoordinate; + private final short endTileYCoordinate; /** The wirelength of a rnode */ - private short length; + private final short length; /** The base cost of a rnode */ private float baseCost; /** A flag to indicate if this rnode is the target */ @@ -98,11 +96,12 @@ abstract public class RouteNode implements Comparable { protected RouteNode(Node node, RouteNodeType type) { this.node = node; - NodeInfo nodeInfo = getNodeInfo(node); - setType(type, nodeInfo); + RouteNodeInfo nodeInfo = RouteNodeInfo.get(node); + this.type = (type == RouteNodeType.WIRE) ? nodeInfo.type : type; + endTileXCoordinate = nodeInfo.endTileXCoordinate; + endTileYCoordinate = nodeInfo.endTileYCoordinate; + length = nodeInfo.length; children = null; - setLength(nodeInfo); - setEndTileXYCoordinates(nodeInfo); setBaseCost(); presentCongestionCost = initialPresentCongestionCost; historicalCongestionCost = initialHistoricalCongestionCost; @@ -246,111 +245,8 @@ public boolean hasMultiDrivers() { return RouteNode.capacity < uniqueDriverCount(); } - public static class NodeInfo { - public final short endTileXCoordinate; - public final short endTileYCoordinate; - public final short length; - public final boolean pinfeedIntoLaguna; - - public NodeInfo(short endTileXCoordinate, - short endTileYCoordinate, - short length, - boolean laguna_i) { - this.endTileXCoordinate = endTileXCoordinate; - this.endTileYCoordinate = endTileYCoordinate; - this.length = length; - this.pinfeedIntoLaguna = laguna_i; - } - } - - private static NodeInfo getNodeInfo(Node node) { - Wire[] wires = node.getAllWiresInNode(); - Tile baseTile = node.getTile(); - TileTypeEnum baseType = baseTile.getTileTypeEnum(); - Tile endTile = null; - boolean laguna_i = false; - for (Wire w : wires) { - Tile tile = w.getTile(); - TileTypeEnum tileType = tile.getTileTypeEnum(); - boolean lagunaTile = false; - if (tileType == TileTypeEnum.INT || - (lagunaTile = Utils.isLaguna(tileType))) { - if (!lagunaTile || - // Only consider a Laguna tile as an end tile if base tile is Laguna too - // (otherwise it's a PINFEED into a Laguna) - Utils.isLaguna(baseType)) { - boolean endTileWasNotNull = (endTile != null); - endTile = tile; - // Break if this is the second INT tile - if (endTileWasNotNull) break; - } else { - assert(!Utils.isLaguna(baseType)); - laguna_i = (node.getIntentCode() == IntentCode.NODE_PINFEED); - } - } - } - if (endTile == null) { - endTile = node.getTile(); - } - - short endTileXCoordinate = (short) endTile.getTileXCoordinate(); - short endTileYCoordinate = (short) endTile.getTileYCoordinate(); - short length = (short) (Math.abs(endTileXCoordinate - baseTile.getTileXCoordinate()) - + Math.abs(endTileYCoordinate - baseTile.getTileYCoordinate())); - - return new NodeInfo(endTileXCoordinate, endTileYCoordinate, length, laguna_i); - } - public static short getLength(Node node) { - return getNodeInfo(node).length; - } - - private void setLength(NodeInfo nodeInfo) { - length = nodeInfo.length; - - TileTypeEnum tileType = node.getTile().getTileTypeEnum(); - switch (tileType) { - case LAG_LAG: - case LAGUNA_TILE: - if (type == RouteNodeType.SUPER_LONG_LINE) { - assert(length == RouteNodeGraph.SUPER_LONG_LINE_LENGTH_IN_TILES); - } else { - if (length != 0) { - assert(type == RouteNodeType.WIRE); - assert(length == 1); - length = 0; - } - } - break; - case INT: - if (type == RouteNodeType.LAGUNA_I) { - assert(length == 0); - } - } - } - - private void setEndTileXYCoordinates(NodeInfo nodeInfo) { - endTileXCoordinate = nodeInfo.endTileXCoordinate; - endTileYCoordinate = nodeInfo.endTileYCoordinate; - - Tile tile = node.getTile(); - TileTypeEnum tileType = tile.getTileTypeEnum(); - if (tileType == TileTypeEnum.LAG_LAG) { // UltraScale+ only - // Correct the X coordinate of all Laguna nodes since they are accessed by the INT - // tile to its right, yet the LAG tile has a tile X coordinate one less than this. - // Do not apply this correction for NODE_LAGUNA_OUTPUT nodes (which the fanin and - // fanout nodes of the SLL are marked as) unless it is a fanin (LAGUNA_I) - // (i.e. do not apply it to the fanout nodes). - // Nor apply it to VCC_WIREs since their end tiles are INT tiles. - if ((node.getIntentCode() != IntentCode.NODE_LAGUNA_OUTPUT || type == RouteNodeType.LAGUNA_I) && - !node.isTiedToVcc()) { - assert(tile.getTileXCoordinate() == endTileXCoordinate); - endTileXCoordinate++; - } - } else if (tileType == TileTypeEnum.LAGUNA_TILE) { // UltraScale only - // In UltraScale, Laguna tiles have the same X as the base INT tile - assert(tile.getTileXCoordinate() == endTileXCoordinate); - } + return RouteNodeInfo.get(node).length; } /** @@ -508,53 +404,6 @@ public void resetChildren() { children = null; } - private void setType(RouteNodeType type, NodeInfo nodeInfo) { - this.type = type; - if (type == RouteNodeType.WIRE) { - // NOTE: IntentCode is device-dependent - IntentCode ic = node.getIntentCode(); - switch (ic) { - case NODE_PINBOUNCE: - this.type = RouteNodeType.PINBOUNCE; - break; - - case NODE_PINFEED: - this.type = nodeInfo.pinfeedIntoLaguna ? RouteNodeType.LAGUNA_I : RouteNodeType.PINFEED_I; - break; - - case NODE_LAGUNA_OUTPUT: // UltraScale+ only - assert(node.getTile().getTileTypeEnum() == TileTypeEnum.LAG_LAG); - if (node.getWireName().endsWith("_TXOUT")) { - this.type = RouteNodeType.LAGUNA_I; - } - break; - - case NODE_LAGUNA_DATA: // UltraScale+ only - assert(node.getTile().getTileTypeEnum() == TileTypeEnum.LAG_LAG); - if (nodeInfo.length == RouteNodeGraph.SUPER_LONG_LINE_LENGTH_IN_TILES) { - this.type = RouteNodeType.SUPER_LONG_LINE; - } else { - // U-turn node at the boundary of the device - assert(nodeInfo.length == 0); - assert(this.type == RouteNodeType.WIRE); - } - break; - - case INTENT_DEFAULT: - if (node.getTile().getTileTypeEnum() == TileTypeEnum.LAGUNA_TILE) { // UltraScale only - String wireName = node.getWireName(); - if (wireName.startsWith("UBUMP")) { - this.type = RouteNodeType.SUPER_LONG_LINE; - } else if (wireName.endsWith("_TXOUT")) { - // This is the inner LAGUNA_I, mark it so it gets a base cost discount - this.type = RouteNodeType.LAGUNA_I; - } - } - break; - } - } - } - /** * Gets the wirelength. * @return The wirelength, i.e. the number of INT tiles that the associated {@link Node} instance spans. diff --git a/src/com/xilinx/rapidwright/rwroute/RouteNodeInfo.java b/src/com/xilinx/rapidwright/rwroute/RouteNodeInfo.java new file mode 100644 index 000000000..2884931f2 --- /dev/null +++ b/src/com/xilinx/rapidwright/rwroute/RouteNodeInfo.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Eddie Hung, Advanced Micro Devices, Inc. + * + * This file is part of RapidWright. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.xilinx.rapidwright.rwroute; + +import com.xilinx.rapidwright.device.IntentCode; +import com.xilinx.rapidwright.device.Node; +import com.xilinx.rapidwright.device.Tile; +import com.xilinx.rapidwright.device.TileTypeEnum; +import com.xilinx.rapidwright.device.Wire; +import com.xilinx.rapidwright.util.Utils; + +public class RouteNodeInfo { + public final RouteNodeType type; + public final short endTileXCoordinate; + public final short endTileYCoordinate; + public final short length; + + private RouteNodeInfo(RouteNodeType type, + short endTileXCoordinate, + short endTileYCoordinate, + short length) { + this.type = type; + this.endTileXCoordinate = endTileXCoordinate; + this.endTileYCoordinate = endTileYCoordinate; + this.length = length; + } + + public static RouteNodeInfo get(Node node) { + Wire[] wires = node.getAllWiresInNode(); + Tile baseTile = node.getTile(); + TileTypeEnum baseType = baseTile.getTileTypeEnum(); + Tile endTile = null; + boolean pinfeedIntoLaguna = false; + for (Wire w : wires) { + Tile tile = w.getTile(); + TileTypeEnum tileType = tile.getTileTypeEnum(); + boolean lagunaTile = false; + if (tileType == TileTypeEnum.INT || + (lagunaTile = Utils.isLaguna(tileType))) { + if (!lagunaTile || + // Only consider a Laguna tile as an end tile if base tile is Laguna too + // (otherwise it's a PINFEED into a Laguna) + Utils.isLaguna(baseType)) { + boolean endTileWasNotNull = (endTile != null); + endTile = tile; + // Break if this is the second INT tile + if (endTileWasNotNull) break; + } else { + assert(!Utils.isLaguna(baseType)); + pinfeedIntoLaguna = (node.getIntentCode() == IntentCode.NODE_PINFEED); + } + } + } + if (endTile == null) { + endTile = node.getTile(); + } + + RouteNodeType type = getType(node, endTile, pinfeedIntoLaguna); + short endTileXCoordinate = getEndTileXCoordinate(node, type, (short) endTile.getTileXCoordinate()); + short endTileYCoordinate = (short) endTile.getTileYCoordinate(); + short length = getLength(baseTile, type, endTileXCoordinate, endTileYCoordinate); + + return new RouteNodeInfo(type, endTileXCoordinate, endTileYCoordinate, length); + } + + private static short getLength(Tile baseTile, RouteNodeType type, short endTileXCoordinate, short endTileYCoordinate) { + short length = (short) (Math.abs(endTileXCoordinate - baseTile.getTileXCoordinate()) + + Math.abs(endTileYCoordinate - baseTile.getTileYCoordinate())); + switch (baseTile.getTileTypeEnum()) { + case LAG_LAG: + length--; + // Fall through + case LAGUNA_TILE: + if (type == RouteNodeType.SUPER_LONG_LINE) { + assert(length == RouteNodeGraph.SUPER_LONG_LINE_LENGTH_IN_TILES); + } else { + assert(length == 0); + } + break; + case INT: + if (type == RouteNodeType.LAGUNA_I) { + assert(length == 0); + } + } + return length; + } + + private static short getEndTileXCoordinate(Node node, RouteNodeType type, short endTileXCoordinate) { + Tile baseTile = node.getTile(); + TileTypeEnum baseType = baseTile.getTileTypeEnum(); + switch (baseType) { + case LAG_LAG: // UltraScale+ only + // Correct the X coordinate of all Laguna nodes since they are accessed by the INT + // tile to its right, yet the LAG tile has a tile X coordinate one less than this. + // Do not apply this correction for NODE_LAGUNA_OUTPUT nodes (which the fanin and + // fanout nodes of the SLL are marked as) unless it is a fanin (LAGUNA_I) + // (i.e. do not apply it to the fanout nodes). + // Nor apply it to VCC_WIREs since their end tiles are INT tiles. + if ((node.getIntentCode() != IntentCode.NODE_LAGUNA_OUTPUT || type == RouteNodeType.LAGUNA_I) && + !node.isTiedToVcc()) { + assert(baseTile.getTileXCoordinate() == endTileXCoordinate); + endTileXCoordinate++; + } + break; + case LAGUNA_TILE: // UltraScale only + // In UltraScale, Laguna tiles have the same X as the base INT tile + assert(baseTile.getTileXCoordinate() == endTileXCoordinate); + break; + } + return endTileXCoordinate; + } + + private static RouteNodeType getType(Node node, Tile endTile, boolean pinfeedIntoLaguna) { + // NOTE: IntentCode is device-dependent + IntentCode ic = node.getIntentCode(); + switch (ic) { + case NODE_PINBOUNCE: + return RouteNodeType.PINBOUNCE; + + case NODE_PINFEED: + return pinfeedIntoLaguna ? RouteNodeType.LAGUNA_I : RouteNodeType.PINFEED_I; + + case NODE_LAGUNA_OUTPUT: // UltraScale+ only + assert(node.getTile().getTileTypeEnum() == TileTypeEnum.LAG_LAG); + if (node.getWireName().endsWith("_TXOUT")) { + return RouteNodeType.LAGUNA_I; + } + break; + + case NODE_LAGUNA_DATA: // UltraScale+ only + assert(node.getTile().getTileTypeEnum() == TileTypeEnum.LAG_LAG); + if (node.getTile() != endTile) { + return RouteNodeType.SUPER_LONG_LINE; + } + + // U-turn node at the boundary of the device + break; + + case INTENT_DEFAULT: + if (node.getTile().getTileTypeEnum() == TileTypeEnum.LAGUNA_TILE) { // UltraScale only + String wireName = node.getWireName(); + if (wireName.startsWith("UBUMP")) { + assert(node.getTile() != endTile); + return RouteNodeType.SUPER_LONG_LINE; + } else if (wireName.endsWith("_TXOUT")) { + // This is the inner LAGUNA_I, mark it so it gets a base cost discount + return RouteNodeType.LAGUNA_I; + } + } + break; + } + + return RouteNodeType.WIRE; + } +}