From a355e7d95da928982a3ed0411fcead135a0d6b3b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 26 Oct 2023 13:58:28 -0700 Subject: [PATCH 1/3] RelocationTools to not revert routing, unroute less nets but unroute static nets when unsafe Signed-off-by: Eddie Hung --- .../design/tools/RelocationTools.java | 74 +++++++++---------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/src/com/xilinx/rapidwright/design/tools/RelocationTools.java b/src/com/xilinx/rapidwright/design/tools/RelocationTools.java index 0b8d6909a..1578d0682 100644 --- a/src/com/xilinx/rapidwright/design/tools/RelocationTools.java +++ b/src/com/xilinx/rapidwright/design/tools/RelocationTools.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2022, Xilinx, Inc. - * Copyright (c) 2022, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Eddie Hung, Xilinx Research Labs. @@ -23,15 +23,6 @@ package com.xilinx.rapidwright.design.tools; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - import com.xilinx.rapidwright.design.Cell; import com.xilinx.rapidwright.design.Design; import com.xilinx.rapidwright.design.DesignTools; @@ -39,16 +30,22 @@ import com.xilinx.rapidwright.design.SiteInst; import com.xilinx.rapidwright.design.SitePinInst; import com.xilinx.rapidwright.design.blocks.PBlock; -import com.xilinx.rapidwright.device.PIP; import com.xilinx.rapidwright.device.Site; import com.xilinx.rapidwright.device.SiteTypeEnum; import com.xilinx.rapidwright.device.Tile; import com.xilinx.rapidwright.edif.EDIFHierCellInst; import com.xilinx.rapidwright.edif.EDIFNetlist; import com.xilinx.rapidwright.interchange.PhysNetlistWriter; -import com.xilinx.rapidwright.util.Pair; import com.xilinx.rapidwright.util.Utils; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + /** * A collection of tools to help relocate designs. * @@ -238,9 +235,6 @@ public static boolean relocate(Design design, return false; } - List>> oldRoute = new ArrayList<>(); - boolean revertRouting = false; - DesignTools.createMissingSitePinInsts(design); for (Net n : design.getNets()) { @@ -248,15 +242,20 @@ public static boolean relocate(Design design, continue; } + Collection pins = n.getPins(); SitePinInst src = n.getSource(); if (src != null && !oldSite.containsKey(src.getSiteInst())) { - System.out.println("INFO: Unrouting Net '" + n.getName() + "' since output SiteInstPin '" + - src + "' does not belong to SiteInsts to be relocated"); - n.unroute(); + for (SitePinInst spi : pins) { + if (oldSite.containsKey(spi.getSiteInst())) { + // Source is not reloacted, but at least one pin inside site insts to be relocated + System.out.println("INFO: Unrouting Net '" + n.getName() + "' since output SiteInstPin '" + + src + "' does not belong to SiteInsts to be relocated"); + n.unroute(); + } + } continue; } - Collection pins = n.getPins(); Collection nonMatchingPins = pins.stream() .filter((spi) -> !oldSite.containsKey(spi.getSiteInst())) // Filter out SPIs on a "STATIC_SOURCE" SiteInst that would have been unplaced above @@ -266,19 +265,23 @@ public static boolean relocate(Design design, continue; } - oldRoute.add(new Pair<>(n, n.getPIPs())); - if (!nonMatchingPins.isEmpty()) { - for (SitePinInst spi : nonMatchingPins) { - System.out.println("INFO: Unrouting SitePinInst '" + spi + "' branch of Net '" + n.getName() + - "' since it does not belong to SiteInsts to be relocated"); + if (n.isStaticNet()) { + // Since static nets are global if there are any pins on SiteInsts that are not to be relocated, + // unroute the whole net as it's not obvious how to relocate the relevant subset of its PIPs + // instead of all of them + n.unroute(); + } else { + for (SitePinInst spi : nonMatchingPins) { + System.out.println("INFO: Unrouting SitePinInst '" + spi + "' branch of Net '" + n.getName() + + "' since it does not belong to SiteInsts to be relocated"); + } + DesignTools.unroutePins(n, nonMatchingPins); } - - DesignTools.unroutePins(n, nonMatchingPins); } boolean isClockNet = n.isClockNet() || n.hasGapRouting(); - for (PIP sp : n.getPIPs()) { + n.getPIPs().removeIf((sp) -> { Tile st = sp.getTile(); Tile dt = st.getTileXYNeighbor(tileColOffset, tileRowOffset); if (dt == null) { @@ -288,8 +291,9 @@ public static boolean relocate(Design design, String destTileName = st.getRootName() + "_X" + (st.getTileXCoordinate() + tileColOffset) + "Y" + (st.getTileYCoordinate() + tileRowOffset); if (sp.isStub()) { - System.out.println("INFO: Skipping stub PIP '" + sp + "' that failed to move to Tile '" + destTileName + + System.out.println("INFO: Removing stub PIP '" + sp + "' that failed to move to Tile '" + destTileName + "' (Net '" + n.getName() + "')"); + return true; } else { throw new RuntimeException("ERROR: Failed to move PIP '" + sp + "' to Tile '" + destTileName + "' (Net '" + n.getName() + "')"); @@ -299,23 +303,13 @@ public static boolean relocate(Design design, assert (st.getTileTypeEnum() == dt.getTileTypeEnum()); sp.setTile(dt); } - } - } - - if (revertRouting) { - revertPlacement(oldSite); - revertRouting(oldRoute); - return false; + return false; + }); } return true; } - private static void revertRouting(List>> oldRoute) { - for (Pair> e : oldRoute) { - e.getFirst().setPIPs(e.getSecond()); - } - } private static void revertPlacement(Map oldSite) { for (Map.Entry e : oldSite.entrySet()) { From b7710051336fa31a4f52ba126cdf2f1dfc0809db Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 26 Oct 2023 13:59:12 -0700 Subject: [PATCH 2/3] Update TestRelocationTools Signed-off-by: Eddie Hung --- .../design/TestRelocationTools.java | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/test/src/com/xilinx/rapidwright/design/TestRelocationTools.java b/test/src/com/xilinx/rapidwright/design/TestRelocationTools.java index 63a26332d..40bbb4011 100644 --- a/test/src/com/xilinx/rapidwright/design/TestRelocationTools.java +++ b/test/src/com/xilinx/rapidwright/design/TestRelocationTools.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2022, Xilinx, Inc. - * Copyright (c) 2022, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Eddie Hung, Xilinx Research Labs. @@ -41,7 +41,10 @@ import com.xilinx.rapidwright.edif.EDIFTools; import com.xilinx.rapidwright.support.RapidWrightDCP; import com.xilinx.rapidwright.tests.CodePerfTracker; +import com.xilinx.rapidwright.util.FileTools; import com.xilinx.rapidwright.util.Pair; +import com.xilinx.rapidwright.util.ReportRouteStatusResult; +import com.xilinx.rapidwright.util.VivadoTools; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -49,7 +52,7 @@ public class TestRelocationTools { - private void relocateModuleInstsAndCompare(int colOffset, int rowOffset, boolean expectSuccess, Design design1, Design design2, Collection moduleInsts) { + private void relocateModuleInstsAndCompare(int colOffset, int rowOffset, boolean expectSuccess, Design design1, Collection moduleInsts) { List> newSite = new ArrayList<>(); for (ModuleInst mi : moduleInsts) { Assertions.assertTrue(mi.isPlaced()); @@ -84,31 +87,31 @@ private void relocateModuleInstsAndCompare(int colOffset, int rowOffset, boolean Assertions.assertEquals(c1.getSite(), c2.getSite()); } } + } - for (Net n2 : mi.getNets()) { - Net n1 = design1.getNet(n2.getName()); - if (n1 == null && n2.getName().startsWith(mi.getName() + EDIFTools.EDIF_HIER_SEP)) { - // Retry without ModuleInst hierarchy in case it was flattened - n1 = design1.getNet(n2.getName().substring(mi.getName().length() + 1)); - } - Assertions.assertNotNull(n1); + for (Net n2 : mi.getNets()) { + Net n1 = design1.getNet(n2.getName()); + if (n1 == null && n2.getName().startsWith(mi.getName() + EDIFTools.EDIF_HIER_SEP)) { + // Retry without ModuleInst hierarchy in case it was flattened + n1 = design1.getNet(n2.getName().substring(mi.getName().length() + 1)); + } + Assertions.assertNotNull(n1); - if (n1.isClockNet() || n1.hasGapRouting()) { - // Module relocation unroutes all clock nets? - Assertions.assertFalse(n2.hasPIPs()); - continue; - } + if (n1.isClockNet() || n1.hasGapRouting()) { + // Module relocation unroutes all clock nets? + Assertions.assertFalse(n2.hasPIPs()); + continue; + } - Set p1 = new HashSet<>(n1.getPIPs()); - Set p2 = new HashSet<>(n2.getPIPs()); - if (!n1.isStaticNet()) { - Assertions.assertEquals(p1, p2); - } else { - // For static nets, ModuleInst.place() will merge its - // static PIPs into the parent Design's static net, so - // check that it is contained within - Assertions.assertTrue(p1.containsAll(p2)); - } + Set p1 = new HashSet<>(n1.getPIPs()); + Set p2 = new HashSet<>(n2.getPIPs()); + if (!n1.isStaticNet()) { + Assertions.assertEquals(p1, p2); + } else { + // For static nets, ModuleInst.place() will merge its + // static PIPs into the parent Design's static net, so + // check that it is contained within + Assertions.assertTrue(p1.containsAll(p2)); } } } @@ -131,7 +134,7 @@ public void testPicoblazeOOC(String instanceName, int colOffset, int rowOffset, mi.placeOnOriginalAnchor(); Collection moduleInsts = Arrays.asList(mi); - relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, design2, moduleInsts); + relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, moduleInsts); } } @@ -169,13 +172,12 @@ public void testPicoblaze4OOC(String instanceName, int colOffset, int rowOffset, if (instanceName.isEmpty()) { moduleInsts = design2.getModuleInsts(); } else { - moduleInsts = new ArrayList<>(); ModuleInst mi = design2.getModuleInst(instanceName); Assertions.assertNotNull(mi); moduleInsts = Arrays.asList(mi); } - relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, design2, moduleInsts); + relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, moduleInsts); } public static Stream testPicoblaze4OOC() { @@ -210,7 +212,7 @@ public void testPicoblaze4OOC_PBlock(PBlock pblock, int colOffset, int rowOffset Collection moduleInsts2 = moduleInsts1.stream().map((mi) -> design2.getModuleInst(mi.getName())) .collect(Collectors.toList()); - relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, design2, moduleInsts2); + relocateModuleInstsAndCompare(colOffset, rowOffset, expectSuccess, design1, moduleInsts2); } public static Stream testPicoblaze4OOC_PBlock() { @@ -225,23 +227,28 @@ public static Stream testPicoblaze4OOC_PBlock() { @ParameterizedTest(name = "Relocate MicroBlazeAndILA ''{0}'' ({1},{2})") @MethodSource() - public void testMicroBlazeAndILA(String instanceName, int colOffset, int rowOffset, boolean expectSuccess) { + public void testMicroBlazeAndILA(String instanceName, int colOffset, int rowOffset, boolean expectSuccess, int expectedNetsWithRoutingErrors) { String dcpPath = RapidWrightDCP.getString("microblazeAndILA_3pblocks.dcp"); Design design1 = Design.readCheckpoint(dcpPath, CodePerfTracker.SILENT); Assertions.assertEquals(RelocationTools.relocate(design1, instanceName, colOffset, rowOffset), expectSuccess); + + if (expectSuccess && FileTools.isVivadoOnPath()) { + ReportRouteStatusResult rrs = VivadoTools.reportRouteStatus(design1); + Assertions.assertEquals(expectedNetsWithRoutingErrors, rrs.netsWithRoutingErrors); + } } public static Stream testMicroBlazeAndILA() { return Stream.of( - Arguments.of("", 0, 5, true) - , Arguments.of("", 0, 60, true) - , Arguments.of("base_mb_i", 0, 10, true) - , Arguments.of("dbg_hub", 0, 20, true) - , Arguments.of("u_ila_0", 0, 30, true) - , Arguments.of("dbg_hub", 16, 0, false) // placement conflict + Arguments.of("", 0, 5, true, 0) + , Arguments.of("", 0, 60, true, 0) + , Arguments.of("base_mb_i", 0, 10, true, 26 /* unrouted pins and resource conflicts */ ) + , Arguments.of("dbg_hub", 0, 20, true, 19 /* unrouted pins */) + , Arguments.of("u_ila_0", 0, 30, true, 0) + , Arguments.of("dbg_hub", 16, 0, false, -1) // placement conflict ); } From 64eb043464f8f5a13373b96eef67d719bf624385 Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Fri, 27 Oct 2023 10:24:45 -0700 Subject: [PATCH 3/3] Update src/com/xilinx/rapidwright/design/tools/RelocationTools.java Co-authored-by: Chris Lavin Signed-off-by: eddieh-xlnx --- src/com/xilinx/rapidwright/design/tools/RelocationTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/xilinx/rapidwright/design/tools/RelocationTools.java b/src/com/xilinx/rapidwright/design/tools/RelocationTools.java index 1578d0682..ff90091d6 100644 --- a/src/com/xilinx/rapidwright/design/tools/RelocationTools.java +++ b/src/com/xilinx/rapidwright/design/tools/RelocationTools.java @@ -247,7 +247,7 @@ public static boolean relocate(Design design, if (src != null && !oldSite.containsKey(src.getSiteInst())) { for (SitePinInst spi : pins) { if (oldSite.containsKey(spi.getSiteInst())) { - // Source is not reloacted, but at least one pin inside site insts to be relocated + // Source is not relocated, but at least one pin inside site insts to be relocated System.out.println("INFO: Unrouting Net '" + n.getName() + "' since output SiteInstPin '" + src + "' does not belong to SiteInsts to be relocated"); n.unroute();