From d9b027da0b094a4f270a894c7a2aa3e0b395f035 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 12 Jun 2024 12:24:00 -0600 Subject: [PATCH 01/22] rc1 jar Signed-off-by: Chris Lavin --- .classpath | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.classpath b/.classpath index 47e56a9d8..dcd346ea5 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eeb9dd76f..d54c94612 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2024.1.0-beta + RAPIDWRIGHT_VERSION: v2024.1.1-rc1-beta jobs: build: From 9fe8131bac7a8e5e4aad7d31b363fb038c61fba6 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Thu, 20 Jun 2024 20:13:35 -0600 Subject: [PATCH 02/22] rc2 Signed-off-by: Chris Lavin --- .classpath | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.classpath b/.classpath index dcd346ea5..b7e70b83c 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d54c94612..60c7c127d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2024.1.1-rc1-beta + RAPIDWRIGHT_VERSION: v2024.1.1-rc2-beta jobs: build: From 532b001050d4801e54d14c898ab5cc6da25e259a Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 3 Jul 2024 14:53:52 -0600 Subject: [PATCH 03/22] Remove flawed loop intended to for encrypted cell removal (#1023) Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/design/DesignTools.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index dfa7c109e..181e9c57a 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -1751,15 +1751,6 @@ public static void makeBlackBox(Design d, EDIFHierCellInst hierarchicalCell) { } cells.add(c); } - // Find encrypted cells that need to be removed - if (d.getNetlist().getEncryptedCells().size() > 0) { - String name = hierarchicalCell.getFullHierarchicalInstName(); - for (Cell c : d.getCells()) { - if (c.getName().startsWith(name)) { - cells.add(c); - } - } - } // Remove all placement and routing information related to the cell to be // blackboxed From 0aea28f54d6a16cdff14759f02d6085ea5dc025a Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 3 Jul 2024 14:54:33 -0600 Subject: [PATCH 04/22] Adding legacy support for u280 (#1021) Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/util/DataVersions.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/com/xilinx/rapidwright/util/DataVersions.java b/src/com/xilinx/rapidwright/util/DataVersions.java index acb16a962..c7e0645c7 100644 --- a/src/com/xilinx/rapidwright/util/DataVersions.java +++ b/src/com/xilinx/rapidwright/util/DataVersions.java @@ -29,7 +29,7 @@ import java.util.Map; /** - * Generated on: Wed May 15 09:21:24 MDT 2024 + * Generated on: Mon Jul 01 15:12:48 MDT 2024 * by: com.xilinx.rapidwright.release.UploadFilesToAzure * * Versioned list of data files to use in current RapidWright environment @@ -257,6 +257,7 @@ public class DataVersions { dataVersionMap.put("data/devices/virtexuplus58g/xcvu27p_db.dat", new Pair<>("xcvu27p-db-dat", "ae2fe858e3aa6c868dbb521180134ec7")); dataVersionMap.put("data/devices/virtexuplus58g/xcvu29p_CIV_db.dat", new Pair<>("xcvu29p-civ-db-dat", "21a39c93719cec9782e01118e69c1ddb")); dataVersionMap.put("data/devices/virtexuplus58g/xcvu29p_db.dat", new Pair<>("xcvu29p-db-dat", "c9adeb4229782a48d628d1e9b79d5f85")); + dataVersionMap.put("data/devices/virtexuplushbm/xcu280_db.dat", new Pair<>("xcu280-db-dat", "ee607e7acc31dd410bb52847db491779")); dataVersionMap.put("data/devices/virtexuplushbm/xcu50_db.dat", new Pair<>("xcu50-db-dat", "94adbe337bda80262a92fcc91134e526")); dataVersionMap.put("data/devices/virtexuplushbm/xcu55c_db.dat", new Pair<>("xcu55c-db-dat", "fc3f7906b84a56d87fdb535330631a7f")); dataVersionMap.put("data/devices/virtexuplushbm/xcu55n_db.dat", new Pair<>("xcu55n-db-dat", "c35073c30c01fa7735d775487fdce538")); @@ -367,8 +368,8 @@ public class DataVersions { dataVersionMap.put("data/devices/zynquplusrfsoc/xqzu49dr_db.dat", new Pair<>("xqzu49dr-db-dat", "7679cff74241eac6a9daee28c5a9966a")); dataVersionMap.put("data/devices/zynquplusrfsoc/xqzu65dr_db.dat", new Pair<>("xqzu65dr-db-dat", "f15adefc7ab374462079410477aec96b")); dataVersionMap.put("data/devices/zynquplusrfsoc/xqzu67dr_db.dat", new Pair<>("xqzu67dr-db-dat", "143425fe53e695b473ca16676db07680")); - dataVersionMap.put("data/partdump.csv", new Pair<>("partdump-csv", "340fe27fdc56f500436ad94573a242ed")); - dataVersionMap.put("data/parts.db", new Pair<>("parts-db", "20b420efdffa5a11ceef871741f3ed2e")); + dataVersionMap.put("data/partdump.csv", new Pair<>("partdump-csv", "7c9bd6bf647f18f869c91944e8cd6b15")); + dataVersionMap.put("data/parts.db", new Pair<>("parts-db", "5600d0879f1c7cd2d8dac6dada2f52aa")); dataVersionMap.put("data/unisim_data.dat", new Pair<>("unisim-data-dat", "4c693316fa695c9147b6f987f0686446")); } } From 2a87520b97021adbb5857b00c5102efab477824b Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 10 Jul 2024 15:48:49 -0600 Subject: [PATCH 05/22] Adds UNKWN state for LSFJobs (#1027) Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/util/JobState.java | 3 ++- src/com/xilinx/rapidwright/util/LSFJob.java | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/com/xilinx/rapidwright/util/JobState.java b/src/com/xilinx/rapidwright/util/JobState.java index 032da4387..d771f2139 100644 --- a/src/com/xilinx/rapidwright/util/JobState.java +++ b/src/com/xilinx/rapidwright/util/JobState.java @@ -27,7 +27,8 @@ public enum JobState { RUNNING("running"), EXITED("exited"), SUSPENDED("suspended"), - PENDING("pending"); + PENDING("pending"), + UNKNOWN("unknown"); private final String name; diff --git a/src/com/xilinx/rapidwright/util/LSFJob.java b/src/com/xilinx/rapidwright/util/LSFJob.java index 8e51ba880..96804f9d3 100644 --- a/src/com/xilinx/rapidwright/util/LSFJob.java +++ b/src/com/xilinx/rapidwright/util/LSFJob.java @@ -173,6 +173,8 @@ private Pair getStatus() { return new Pair<>(JobState.RUNNING, 0); case "PEND": return new Pair<>(JobState.PENDING, 0); + case "UNKWN": + return new Pair<>(JobState.UNKNOWN, 0); case "PSUSP": case "USUSP": case "SSUSP": From 7b3fd0a44f766c5fcfb7b48499252fdf09887d07 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 10 Jul 2024 16:13:53 -0600 Subject: [PATCH 06/22] rc3 Signed-off-by: Chris Lavin --- .classpath | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.classpath b/.classpath index b7e70b83c..4358c9002 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60c7c127d..ad5027be4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2024.1.1-rc2-beta + RAPIDWRIGHT_VERSION: v2024.1.1-rc3-beta jobs: build: From 475f3f5153210d6b543d75d123a2418e375e98fb Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Wed, 10 Jul 2024 15:50:21 -0700 Subject: [PATCH 07/22] [RWRoute] Do not assume Y = 0 has Laguna tiles, since it could be HBM device (#1026) * Do not assume Y = 0 has Laguna tiles, since it could be HBM device Signed-off-by: Eddie Hung * Add test for xcu50 Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung --- .../xilinx/rapidwright/rwroute/RouteNodeGraph.java | 3 ++- .../xilinx/rapidwright/rwroute/TestRWRoute.java | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java index dcd8d4e6a..f66cd5167 100644 --- a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java +++ b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java @@ -267,7 +267,8 @@ public RouteNodeGraph(RuntimeTracker setChildrenTimer, Design design, RWRouteCon for (int x = 0; x < lagunaTilesAtY.length; x++) { Tile tile = lagunaTilesAtY[x]; if (tile != null) { - if (y == 0) { + // For LAGUNA tiles on the first SLR boundary + if (nextLagunaColumn[x] == Integer.MAX_VALUE) { assert(x == tile.getTileXCoordinate()); // Looks like (on US+) LAGUNA tiles are always on the left side of an INT tile, // with tile X coordinate one smaller diff --git a/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java b/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java index 4bb8c52b1..5c8666565 100644 --- a/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java +++ b/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java @@ -383,16 +383,20 @@ public void testTimingAndWirelengthReport() { @ParameterizedTest @CsvSource({ // Dedicated connections, hence no nodes popped - "GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_SYNC_X0Y46,CLK_IN,0", - "GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_X0Y78,CLK_IN,0", // (dst pin can be projected to INT but not src pin) + "xcvu3p,GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_SYNC_X0Y46,CLK_IN,0", + "xcvu3p,GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_X0Y78,CLK_IN,0", // (dst pin can be projected to INT but not src pin) // Non-dedicated connections - "IOB_X0Y47,I,SLICE_X77Y122,FX,600", + "xcvu3p,IOB_X0Y47,I,SLICE_X77Y122,FX,600", + + // 240 CLB height SLR, no LAG tiles on Y0 (since HBM on bottom edge) + "xcu50,SLICE_X38Y239,AQ,SLICE_X38Y240,A1,500" }) - public void testSingleConnection(String srcSiteName, String srcPinName, + public void testSingleConnection(String partName, + String srcSiteName, String srcPinName, String dstSiteName, String dstPinName, int nodesPoppedLimit) { - testSingleConnectionHelper("xcvu3p", + testSingleConnectionHelper(partName, srcSiteName, srcPinName, dstSiteName, dstPinName, nodesPoppedLimit); From a7b940f087fac3f2788e162a144d178478949a00 Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Wed, 10 Jul 2024 15:50:46 -0700 Subject: [PATCH 08/22] [RWRoute] Do not NPE on encrypted netlists (#1025) * Do not NPE on encrypted netlists Signed-off-by: Eddie Hung * Apply suggestions from code review Co-authored-by: Chris Lavin Signed-off-by: eddieh-xlnx --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Chris Lavin --- src/com/xilinx/rapidwright/design/DesignTools.java | 6 +++++- .../xilinx/rapidwright/edif/EDIFHierPortInst.java | 11 +++++++---- src/com/xilinx/rapidwright/timing/TimingGraph.java | 12 +++++++++--- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index 181e9c57a..987ab92ab 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -2597,7 +2597,11 @@ private static EDIFHierPortInst getPortInstFromBELPin(SiteInst siteInst, BELPin } String logPinName = targetCell.getLogicalPinMapping(belPin.getName()); if (logPinName == null) return null; - EDIFPortInst portInst = targetCell.getEDIFCellInst().getPortInst(logPinName); + EDIFCellInst eci = targetCell.getEDIFCellInst(); + if (eci == null) { + return null; + } + EDIFPortInst portInst = eci.getPortInst(logPinName); final EDIFNetlist netlist = targetCell.getSiteInst().getDesign().getNetlist(); EDIFHierPortInst hierPortInst = new EDIFHierPortInst(netlist.getHierCellInstFromName(targetCell.getParentHierarchicalInstName()), portInst); diff --git a/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java b/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java index 54c482f99..71f304f32 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java +++ b/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java @@ -88,10 +88,13 @@ public String getFullHierarchicalInstName() { return hierarchicalInst.getFullHierarchicalInstName(); } - EDIFCellInst topCellInst = portInst.getCellInst().getCellType().getLibrary().getNetlist().getTopCellInst(); - if (portInst.getCellInst() == topCellInst) { - //Outward side of top - return ""; + EDIFLibrary library = portInst.getCellInst().getCellType().getLibrary(); + if (!library.isHDIPrimitivesLibrary()) { + EDIFCellInst topCellInst = library.getNetlist().getTopCellInst(); + if (portInst.getCellInst() == topCellInst) { + // Outward side of top + return ""; + } } StringBuilder sb = new StringBuilder(); diff --git a/src/com/xilinx/rapidwright/timing/TimingGraph.java b/src/com/xilinx/rapidwright/timing/TimingGraph.java index 151acfe52..d6f4ab6ad 100644 --- a/src/com/xilinx/rapidwright/timing/TimingGraph.java +++ b/src/com/xilinx/rapidwright/timing/TimingGraph.java @@ -223,15 +223,21 @@ private Map generateCellMapOfNets(Collection nets) { if (n.isClockNet() || n.isStaticNet() || n.hasPIPs()) continue; if (!RouterHelper.isRoutableNetWithSourceSinks(n)) continue; List ehportInsts = design.getNetlist().getPhysicalPins(n.getName()); - for (EDIFHierPortInst eportInst : ehportInsts) { - keys.add(eportInst.getFullHierarchicalInstName()); + if (ehportInsts == null) { + System.out.println("WARNING: Unable to find physical pins on Net '" + n.getName() + "'; possibly due to an encrypted netlist."); + + } else { + for (EDIFHierPortInst eportInst : ehportInsts) { + keys.add(eportInst.getFullHierarchicalInstName()); + } } } for (String fullHierInstName : keys) { EDIFCellInst edifCellInst = myCellMap.get(fullHierInstName); if (edifCellInst == null) { - System.out.println("WARNING: Null EDIFCellInst under name " + fullHierInstName); + System.out.println("WARNING: Unable to find EDIFCellInst '" + fullHierInstName + "'; possibly due to an encrypted netlist."); + continue; } partialCellMap.put(fullHierInstName, edifCellInst); From 1979e17d3c1eafeedca9aa78174fa81bcc4d97ca Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Thu, 11 Jul 2024 13:08:18 -0600 Subject: [PATCH 09/22] Test for site routing from raw placed design (#1000) * Test for site routing from raw placed design Signed-off-by: Chris Lavin * Update src/com/xilinx/rapidwright/util/VivadoTools.java Co-authored-by: eddieh-xlnx Signed-off-by: Chris Lavin * Refactoring Signed-off-by: Chris Lavin * Switching to HEAD Signed-off-by: Chris Lavin --------- Signed-off-by: Chris Lavin Co-authored-by: eddieh-xlnx --- .github/workflows/check-git-submodules.yml | 2 - .../xilinx/rapidwright/util/VivadoTools.java | 47 +++++++++++++++++-- test/RapidWrightDCP | 2 +- .../rapidwright/util/VivadoToolsHelper.java | 19 +++++++- .../rapidwright/design/TestSiteInst.java | 10 ++++ 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check-git-submodules.yml b/.github/workflows/check-git-submodules.yml index dbe52a759..161f57719 100644 --- a/.github/workflows/check-git-submodules.yml +++ b/.github/workflows/check-git-submodules.yml @@ -2,8 +2,6 @@ name: Submodule refs on origin on: pull_request: - branches: - - master jobs: check: diff --git a/src/com/xilinx/rapidwright/util/VivadoTools.java b/src/com/xilinx/rapidwright/util/VivadoTools.java index 67ca7b5de..183fd4fbd 100644 --- a/src/com/xilinx/rapidwright/util/VivadoTools.java +++ b/src/com/xilinx/rapidwright/util/VivadoTools.java @@ -39,6 +39,7 @@ public class VivadoTools { public static final String REPORT_ROUTE_STATUS = "report_route_status"; public static final String PLACE_DESIGN = "place_design"; + public static final String ROUTE_DESIGN = "route_design"; public static final String WRITE_CHECKPOINT = "write_checkpoint"; public static final String WRITE_EDIF = "write_edif"; @@ -337,11 +338,49 @@ public static Design placeDesign(Path dcp, Path workdir, boolean encrypted) { } /** - * Run Vivado's `get_timing_paths -setup` command on the provided DCP path - * (to find its worst setup timing path) and return its SLACK property as a float. - * - * @param dcp Path to DCP to report on. + * Run Vivado's `route_design` command on the design provided and get the + * `report_route_status` results. Note: this method does not preserve the routed + * output from Vivado. + * + * @param design The design to route and report on. * @param workdir Directory to work within. + * @return The results of `report_route_status`. + */ + public static ReportRouteStatusResult routeDesignAndGetStatus(Design design, Path workdir) { + boolean encrypted = !design.getNetlist().getEncryptedCells().isEmpty(); + Path dcp = workdir.resolve("routeDesignAndGetStatus.dcp"); + design.writeCheckpoint(dcp); + return routeDesignAndGetStatus(dcp, workdir, encrypted); + } + + /** + * Run Vivado's `route_design` command on the provided DCP path and return the + * `report_route_status` results. Note: this method does not preserve the routed + * output from Vivado. + * + * @param dcp Path to DCP to route and report on. + * @param workdir Directory to work within. + * @param encrypted Indicates whether DCP contains encrypted EDIF cells. + * @return The results of `report_route_status`. + */ + public static ReportRouteStatusResult routeDesignAndGetStatus(Path dcp, Path workdir, boolean encrypted) { + final Path outputLog = workdir.resolve("outputLog.log"); + + StringBuilder sb = new StringBuilder(); + sb.append(createTclDCPLoadCommand(dcp, encrypted)); + sb.append(ROUTE_DESIGN + "; "); + sb.append(REPORT_ROUTE_STATUS + "; "); + + List log = VivadoTools.runTcl(outputLog, sb.toString(), true); + return new ReportRouteStatusResult(log); + } + + /** + * Run Vivado's `get_timing_paths -setup` command on the provided DCP path (to + * find its worst setup timing path) and return its SLACK property as a float. + * + * @param dcp Path to DCP to report on. + * @param workdir Directory to work within. * @param encrypted Indicates whether DCP contains encrypted EDIF cells. * @return Worst slack of design as float. */ diff --git a/test/RapidWrightDCP b/test/RapidWrightDCP index 85c47fd5d..9c4416ef7 160000 --- a/test/RapidWrightDCP +++ b/test/RapidWrightDCP @@ -1 +1 @@ -Subproject commit 85c47fd5d6e01b012b827bb9288f65a402a17e0a +Subproject commit 9c4416ef76e590988dda9036e8101768f5574730 diff --git a/test/shared/com/xilinx/rapidwright/util/VivadoToolsHelper.java b/test/shared/com/xilinx/rapidwright/util/VivadoToolsHelper.java index 4037bced3..b106dafa4 100644 --- a/test/shared/com/xilinx/rapidwright/util/VivadoToolsHelper.java +++ b/test/shared/com/xilinx/rapidwright/util/VivadoToolsHelper.java @@ -22,10 +22,11 @@ package com.xilinx.rapidwright.util; -import com.xilinx.rapidwright.design.Design; +import java.nio.file.Path; + import org.junit.jupiter.api.Assertions; -import java.nio.file.Path; +import com.xilinx.rapidwright.design.Design; public class VivadoToolsHelper { public static void assertFullyRouted(Design design) { @@ -45,4 +46,18 @@ public static void assertFullyRouted(Path dcp) { ReportRouteStatusResult rrs = VivadoTools.reportRouteStatus(dcp); Assertions.assertTrue(rrs.isFullyRouted()); } + + /** + * Ensures that the provided design can be routed successfully in Vivado. + * + * @param design The design to route. + * @param dir The directory to work within. + */ + public static void assertRoutedSuccessfullyByVivado(Design design, Path dir) { + if (!FileTools.isVivadoOnPath()) { + return; + } + ReportRouteStatusResult rrs = VivadoTools.routeDesignAndGetStatus(design, dir); + Assertions.assertTrue(rrs.isFullyRouted()); + } } diff --git a/test/src/com/xilinx/rapidwright/design/TestSiteInst.java b/test/src/com/xilinx/rapidwright/design/TestSiteInst.java index 3a371d385..a694bdbc5 100644 --- a/test/src/com/xilinx/rapidwright/design/TestSiteInst.java +++ b/test/src/com/xilinx/rapidwright/design/TestSiteInst.java @@ -29,11 +29,14 @@ import com.xilinx.rapidwright.device.Device; import com.xilinx.rapidwright.device.Series; import com.xilinx.rapidwright.support.RapidWrightDCP; +import com.xilinx.rapidwright.util.VivadoToolsHelper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import java.nio.file.Path; import java.util.Arrays; public class TestSiteInst { @@ -365,4 +368,11 @@ public void testUnrouteSiteUpdatesNetSiteInsts() { Assertions.assertTrue(net.getSiteInsts().isEmpty()); } + + @Test + public void testSiteRouting(@TempDir Path dir) { + Design design = RapidWrightDCP.loadDCP("gnl_2_4_3_1.3_gnl_3000_07_3_80_80_placed.dcp"); + design.routeSites(); + VivadoToolsHelper.assertRoutedSuccessfullyByVivado(design, dir); + } } From d06c22cfdcae5793f49ee900d79c2288c154c469 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Fri, 12 Jul 2024 11:19:01 -0600 Subject: [PATCH 10/22] Adding HDIOB types Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/util/Utils.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/xilinx/rapidwright/util/Utils.java b/src/com/xilinx/rapidwright/util/Utils.java index 0597aa1e6..6d3b5fa4e 100644 --- a/src/com/xilinx/rapidwright/util/Utils.java +++ b/src/com/xilinx/rapidwright/util/Utils.java @@ -384,6 +384,9 @@ public static boolean isIOB(SiteTypeEnum s) { SiteTypeEnum.IOB, SiteTypeEnum.IOBM, SiteTypeEnum.IOBS, + SiteTypeEnum.HDIOB, + SiteTypeEnum.HDIOB_M, + SiteTypeEnum.HDIOB_S, SiteTypeEnum.HPIOB, SiteTypeEnum.HPIOB_M, SiteTypeEnum.HPIOB_S, From a55fac3184bd2de1789b8b625bb8538aa7778beb Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Fri, 12 Jul 2024 17:08:36 -0600 Subject: [PATCH 11/22] Adding HDIOB types (#1028) Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/util/Utils.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/xilinx/rapidwright/util/Utils.java b/src/com/xilinx/rapidwright/util/Utils.java index 0597aa1e6..6d3b5fa4e 100644 --- a/src/com/xilinx/rapidwright/util/Utils.java +++ b/src/com/xilinx/rapidwright/util/Utils.java @@ -384,6 +384,9 @@ public static boolean isIOB(SiteTypeEnum s) { SiteTypeEnum.IOB, SiteTypeEnum.IOBM, SiteTypeEnum.IOBS, + SiteTypeEnum.HDIOB, + SiteTypeEnum.HDIOB_M, + SiteTypeEnum.HDIOB_S, SiteTypeEnum.HPIOB, SiteTypeEnum.HPIOB_M, SiteTypeEnum.HPIOB_S, From 8131a2336ff8423638f75beefd04fd3ff693c256 Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Fri, 12 Jul 2024 16:20:01 -0700 Subject: [PATCH 12/22] [EDIFTools] writeTclLoadScriptForPartialEncryptedDesigns abspath (#1029) Write *_load.tcl into same dir as DCP rather than into current working dir Signed-off-by: Eddie Hung --- src/com/xilinx/rapidwright/edif/EDIFTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/xilinx/rapidwright/edif/EDIFTools.java b/src/com/xilinx/rapidwright/edif/EDIFTools.java index 1c997a8bc..bc3ced3db 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFTools.java +++ b/src/com/xilinx/rapidwright/edif/EDIFTools.java @@ -1019,7 +1019,7 @@ public static void writeTclLoadScriptForPartialEncryptedDesigns(EDIFNetlist edif lines.add("read_checkpoint {" + pathDCPFileName + "}"); lines.add("set_property top "+edif.getName()+" [current_fileset]"); lines.add("link_design -part " + partName); - Path tclFileName = FileTools.replaceExtension(pathDCPFileName.getFileName(), LOAD_TCL_SUFFIX); + Path tclFileName = FileTools.replaceExtension(pathDCPFileName, LOAD_TCL_SUFFIX); try { Files.write(tclFileName, lines); } catch (IOException e) { From f54155511f4f637732212588afdedd734f0bab54 Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Fri, 12 Jul 2024 16:21:00 -0700 Subject: [PATCH 13/22] Add TestSite.testGetIntTile() (#1022) * [RWRoute] Do not assume Y = 0 has Laguna tiles, since it could be HBM device (#1026) * Do not assume Y = 0 has Laguna tiles, since it could be HBM device Signed-off-by: Eddie Hung * Add test for xcu50 Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung * [RWRoute] Do not NPE on encrypted netlists (#1025) * Do not NPE on encrypted netlists Signed-off-by: Eddie Hung * Apply suggestions from code review Co-authored-by: Chris Lavin Signed-off-by: eddieh-xlnx --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Chris Lavin * Add TestSite.testGetIntTile() Signed-off-by: Eddie Hung * Update test/src/com/xilinx/rapidwright/device/TestSite.java Co-authored-by: Chris Lavin Signed-off-by: eddieh-xlnx --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Chris Lavin --- .../rapidwright/design/DesignTools.java | 6 ++- .../rapidwright/edif/EDIFHierPortInst.java | 11 ++++-- .../rapidwright/rwroute/RouteNodeGraph.java | 3 +- .../rapidwright/timing/TimingGraph.java | 12 ++++-- .../xilinx/rapidwright/device/TestSite.java | 39 +++++++++++++++++++ .../rapidwright/rwroute/TestRWRoute.java | 14 ++++--- 6 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 test/src/com/xilinx/rapidwright/device/TestSite.java diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index 181e9c57a..987ab92ab 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -2597,7 +2597,11 @@ private static EDIFHierPortInst getPortInstFromBELPin(SiteInst siteInst, BELPin } String logPinName = targetCell.getLogicalPinMapping(belPin.getName()); if (logPinName == null) return null; - EDIFPortInst portInst = targetCell.getEDIFCellInst().getPortInst(logPinName); + EDIFCellInst eci = targetCell.getEDIFCellInst(); + if (eci == null) { + return null; + } + EDIFPortInst portInst = eci.getPortInst(logPinName); final EDIFNetlist netlist = targetCell.getSiteInst().getDesign().getNetlist(); EDIFHierPortInst hierPortInst = new EDIFHierPortInst(netlist.getHierCellInstFromName(targetCell.getParentHierarchicalInstName()), portInst); diff --git a/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java b/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java index 54c482f99..71f304f32 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java +++ b/src/com/xilinx/rapidwright/edif/EDIFHierPortInst.java @@ -88,10 +88,13 @@ public String getFullHierarchicalInstName() { return hierarchicalInst.getFullHierarchicalInstName(); } - EDIFCellInst topCellInst = portInst.getCellInst().getCellType().getLibrary().getNetlist().getTopCellInst(); - if (portInst.getCellInst() == topCellInst) { - //Outward side of top - return ""; + EDIFLibrary library = portInst.getCellInst().getCellType().getLibrary(); + if (!library.isHDIPrimitivesLibrary()) { + EDIFCellInst topCellInst = library.getNetlist().getTopCellInst(); + if (portInst.getCellInst() == topCellInst) { + // Outward side of top + return ""; + } } StringBuilder sb = new StringBuilder(); diff --git a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java index dcd8d4e6a..f66cd5167 100644 --- a/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java +++ b/src/com/xilinx/rapidwright/rwroute/RouteNodeGraph.java @@ -267,7 +267,8 @@ public RouteNodeGraph(RuntimeTracker setChildrenTimer, Design design, RWRouteCon for (int x = 0; x < lagunaTilesAtY.length; x++) { Tile tile = lagunaTilesAtY[x]; if (tile != null) { - if (y == 0) { + // For LAGUNA tiles on the first SLR boundary + if (nextLagunaColumn[x] == Integer.MAX_VALUE) { assert(x == tile.getTileXCoordinate()); // Looks like (on US+) LAGUNA tiles are always on the left side of an INT tile, // with tile X coordinate one smaller diff --git a/src/com/xilinx/rapidwright/timing/TimingGraph.java b/src/com/xilinx/rapidwright/timing/TimingGraph.java index 151acfe52..d6f4ab6ad 100644 --- a/src/com/xilinx/rapidwright/timing/TimingGraph.java +++ b/src/com/xilinx/rapidwright/timing/TimingGraph.java @@ -223,15 +223,21 @@ private Map generateCellMapOfNets(Collection nets) { if (n.isClockNet() || n.isStaticNet() || n.hasPIPs()) continue; if (!RouterHelper.isRoutableNetWithSourceSinks(n)) continue; List ehportInsts = design.getNetlist().getPhysicalPins(n.getName()); - for (EDIFHierPortInst eportInst : ehportInsts) { - keys.add(eportInst.getFullHierarchicalInstName()); + if (ehportInsts == null) { + System.out.println("WARNING: Unable to find physical pins on Net '" + n.getName() + "'; possibly due to an encrypted netlist."); + + } else { + for (EDIFHierPortInst eportInst : ehportInsts) { + keys.add(eportInst.getFullHierarchicalInstName()); + } } } for (String fullHierInstName : keys) { EDIFCellInst edifCellInst = myCellMap.get(fullHierInstName); if (edifCellInst == null) { - System.out.println("WARNING: Null EDIFCellInst under name " + fullHierInstName); + System.out.println("WARNING: Unable to find EDIFCellInst '" + fullHierInstName + "'; possibly due to an encrypted netlist."); + continue; } partialCellMap.put(fullHierInstName, edifCellInst); diff --git a/test/src/com/xilinx/rapidwright/device/TestSite.java b/test/src/com/xilinx/rapidwright/device/TestSite.java new file mode 100644 index 000000000..aac61d908 --- /dev/null +++ b/test/src/com/xilinx/rapidwright/device/TestSite.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024, 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.device; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class TestSite { + @ParameterizedTest + @CsvSource({ + "xcvu3p,BUFG_GT_X0Y96,INT_X0Y256" + }) + public void testGetIntTile(String deviceName, String siteName, String intTileName) { + Device device = Device.getDevice(deviceName); + Site site = device.getSite(siteName); + Assertions.assertEquals(intTileName, site.getIntTile().getName()); + } +} diff --git a/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java b/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java index 4bb8c52b1..5c8666565 100644 --- a/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java +++ b/test/src/com/xilinx/rapidwright/rwroute/TestRWRoute.java @@ -383,16 +383,20 @@ public void testTimingAndWirelengthReport() { @ParameterizedTest @CsvSource({ // Dedicated connections, hence no nodes popped - "GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_SYNC_X0Y46,CLK_IN,0", - "GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_X0Y78,CLK_IN,0", // (dst pin can be projected to INT but not src pin) + "xcvu3p,GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_SYNC_X0Y46,CLK_IN,0", + "xcvu3p,GTYE4_CHANNEL_X0Y12,TXOUTCLK_INT,BUFG_GT_X0Y78,CLK_IN,0", // (dst pin can be projected to INT but not src pin) // Non-dedicated connections - "IOB_X0Y47,I,SLICE_X77Y122,FX,600", + "xcvu3p,IOB_X0Y47,I,SLICE_X77Y122,FX,600", + + // 240 CLB height SLR, no LAG tiles on Y0 (since HBM on bottom edge) + "xcu50,SLICE_X38Y239,AQ,SLICE_X38Y240,A1,500" }) - public void testSingleConnection(String srcSiteName, String srcPinName, + public void testSingleConnection(String partName, + String srcSiteName, String srcPinName, String dstSiteName, String dstPinName, int nodesPoppedLimit) { - testSingleConnectionHelper("xcvu3p", + testSingleConnectionHelper(partName, srcSiteName, srcPinName, dstSiteName, dstPinName, nodesPoppedLimit); From baa5e1ebf590ed67f06d3cfccaff16058c74131a Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Fri, 12 Jul 2024 18:01:37 -0600 Subject: [PATCH 14/22] Adds multi-message support for logical/physical netlists Signed-off-by: Chris Lavin --- .../interchange/DeviceResourcesVerifier.java | 2 +- .../rapidwright/interchange/Interchange.java | 28 +++++ .../interchange/LogNetlistReader.java | 110 +++++++++++++----- .../interchange/LogNetlistWriter.java | 59 +++++++++- .../interchange/PhysNetlistReader.java | 79 ++++++------- .../interchange/PhysNetlistWriter.java | 36 +++++- 6 files changed, 232 insertions(+), 82 deletions(-) diff --git a/src/com/xilinx/rapidwright/interchange/DeviceResourcesVerifier.java b/src/com/xilinx/rapidwright/interchange/DeviceResourcesVerifier.java index 506eb3678..684847436 100644 --- a/src/com/xilinx/rapidwright/interchange/DeviceResourcesVerifier.java +++ b/src/com/xilinx/rapidwright/interchange/DeviceResourcesVerifier.java @@ -495,7 +495,7 @@ public static boolean verifyDeviceResources(String devResFileName, String device put(LogNetlistWriter.DEVICE_PRIMITIVES_LIB, EDIFTools.EDIF_LIBRARY_HDI_PRIMITIVES_NAME); }} ); - EDIFNetlist primsAndMacros = netlistReader.readLogNetlist(primLibs, + EDIFNetlist primsAndMacros = netlistReader.readLogNetlistSingleMessage(primLibs, /* skipTopStuff= */true, /* expandMacros= */false, CodePerfTracker.SILENT); Set libsFound = new HashSet(); diff --git a/src/com/xilinx/rapidwright/interchange/Interchange.java b/src/com/xilinx/rapidwright/interchange/Interchange.java index 5dba373cb..7169c3ccf 100644 --- a/src/com/xilinx/rapidwright/interchange/Interchange.java +++ b/src/com/xilinx/rapidwright/interchange/Interchange.java @@ -372,6 +372,34 @@ private static double printFileSize(String title, String fileName) { return fileSize; } + /** + * Takes an array of file names and concatenates them into a single GZIP'ed file + * in the order presented in the array. This is used for assembling a list of + * separate Interchange messages into a single compressed file of those + * messages. This also deletes the input files after they have been + * concatenated. + * + * @param msgFileNames Ordered list of input files to be concatenated and then + * deleted + * @param gzipFileName The desired output GZIP file. + */ + public static void concatMessagesToSingleGZIPFile(String[] msgFileNames, String gzipFileName) { + try (GZIPOutputStream gos = new GZIPOutputStream(new FileOutputStream(gzipFileName))) { + byte[] buffer = new byte[1024]; + int len = 0; + for (String messageFile : msgFileNames) { + try (FileInputStream fis = new FileInputStream(messageFile)) { + while ((len = fis.read(buffer)) > 0) { + gos.write(buffer, 0, len); + } + } + FileTools.deleteFile(messageFile); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public static void main(String[] args) throws IOException { if (args.length < 1 || args.length > 2) { System.out.println("USAGE: [input EDIF]"); diff --git a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java index 506731860..6fd50769b 100644 --- a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java @@ -54,6 +54,8 @@ import org.capnproto.TextList; import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.channels.ReadableByteChannel; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -328,15 +330,8 @@ public static EDIFNetlist readLogNetlist(String fileName) throws IOException { */ public static EDIFNetlist readLogNetlist(String fileName, boolean expandMacros) throws IOException { CodePerfTracker t = new CodePerfTracker("Read LogNetlist"); - - t.start("Read File"); - ReaderOptions readerOptions = new ReaderOptions(32L * 1024L * 1024L * 1024L, 64); - MessageReader readMsg = Interchange.readInterchangeFile(fileName, readerOptions); - Netlist.Reader netlist = readMsg.getRoot(Netlist.factory); - t.stop(); - LogNetlistReader reader = new LogNetlistReader(); - return reader.readLogNetlist(netlist, false, expandMacros, t); + return reader.readLogNetlistMultiMessage(fileName, false, expandMacros, t); } private EDIFPort readEDIFPort(Port.Reader portReader) { @@ -404,28 +399,6 @@ private EDIFLibrary getLibrary(Integer libraryIdx) { }); } - /** - * Reads an Interchange netlist from Cap'n Proto reader. Will expand macros by default. - * @param netlist The Cap'n Proto netlist reader - * @param skipTopStuff If true, skips netlist design object - * @return The logical netlist. - */ - public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff) { - return readLogNetlist(netlist, skipTopStuff, true); - } - - /** - * Reads an Interchange netlist from Cap'n Proto reader. - * @param netlist The Cap'n Proto netlist reader - * @param skipTopStuff If true, skips netlist design object - * @param expandMacros If true, expands the macros in the netlist before returning it to the caller. - * @return The logical netlist. - */ - public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff, boolean expandMacros) { - CodePerfTracker t = new CodePerfTracker("readLogNetlist"); - return readLogNetlist(netlist, skipTopStuff, expandMacros, t); - } - /** * Reads an Interchange netlist from Cap'n Proto reader. * @param netlist The Cap'n Proto netlist reader @@ -434,7 +407,7 @@ public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff, * @param t CodePerfTracker object. * @return The logical netlist. */ - public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff, boolean expandMacros, CodePerfTracker t) { + public EDIFNetlist readLogNetlistSingleMessage(Netlist.Reader netlist, boolean skipTopStuff, boolean expandMacros, CodePerfTracker t) { n = new EDIFNetlist(netlist.getName().toString()); t.start("Read Strings"); @@ -487,4 +460,79 @@ public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff, return n; } + + /** + * Reads an Interchange netlist from Cap'n Proto reader. + * @param netlist The Cap'n Proto netlist reader + * @param skipTopStuff If true, skips netlist design object + * @param expandMacros If true, expands the macros in the netlist before returning it to the caller. + * @param t CodePerfTracker object. + * @return The logical netlist. + */ + public EDIFNetlist readLogNetlistMultiMessage(String fileName, boolean skipTopStuff, boolean expandMacros, CodePerfTracker t) { + try (ReadableByteChannel channel = Interchange.getReadableByteChannel(fileName)) { + ReaderOptions options = new ReaderOptions(32L * 1024L * 1024L * 1024L, 64); + Netlist.Reader netlist = null; + + t.start("Read Strings"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + readAllStrings(netlist.getStrList()); + n = new EDIFNetlist(netlist.getName().toString()); + + t.stop().start("Read Ports"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + readAllPorts(netlist.getPortList()); + + t.stop().start("Read CellDecls"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + readAllCellDecls(netlist.getCellDecls()); + + t.stop().start("Read Insts"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + readAllInsts(netlist.getInstList()); + + t.stop().start("Read Cells"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + readAllCells(netlist.getCellList()); + + t.stop().start("Read Top"); + netlist = Interchange.readMessageFromChannel(channel, options).getRoot(Netlist.factory); + if (!skipTopStuff) { + EDIFDesign design = new EDIFDesign(allCells[netlist.getTopInst().getCell()].getName()); + design.setTopCell(allCells[netlist.getTopInst().getCell()]); + n.setDesign(design); + if (netlist.hasPropMap()) { + extractPropertyMap(netlist.getPropMap(), design); + } + } + + t.stop().start("Order Libraries"); + + // Put libraries in proper export order + List libs = n.getLibrariesInExportOrder(); + n.getLibrariesMap().clear(); + for (EDIFLibrary lib : libs) { + n.addLibrary(lib); + } + + if (expandMacros) { + t.stop().start("Expand Macros"); + String partName = EDIFTools.getPartName(n); + if (partName != null) { + n.expandMacroUnisims(PartNameTools.getPart(partName).getSeries()); + } else { + System.err.println("WARNING: Could not determine target device from netlist. Macro " + + "unisims are not expanded. Please add a top netlist property to indicate the " + + "target part such as [part=xcvu095-ffva2104-2-e]. Macro expansion can also be" + + " run manually with EDIFNetlist.expandMacroUnisims(Series)"); + } + } + t.stop().printSummary(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + return n; + } + } diff --git a/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java index 3e21867ad..5ce80488d 100644 --- a/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java @@ -64,6 +64,8 @@ public class LogNetlistWriter { public static final String DEVICE_PRIMITIVES_LIB = "primitives"; public static final String DEVICE_MACROS_LIB = "macros"; + public static final int NUM_LOG_NETLIST_MULTI_MESSAGES = 6; + LogNetlistWriter() { this(null, null); } @@ -346,18 +348,65 @@ public static void writeLogNetlist(EDIFNetlist n, String fileName, boolean colla } } t.stop().start("Initialize"); + Interchange.IS_GZIPPED = false; MessageBuilder message = new MessageBuilder(); Netlist.Builder netlist = message.initRoot(Netlist.factory); LogNetlistWriter writer = new LogNetlistWriter(); - t.stop(); - writer.populateNetlistBuilder(n, netlist, t); - t.start("Write Top"); + String[] fileNames = new String[NUM_LOG_NETLIST_MULTI_MESSAGES]; + + t.stop().start("Populate Enums"); + writer.populateEnumerations(n); + + t.stop().start("Write Ports"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); + writer.writeAllPortsToNetlistBuilder(netlist); + fileNames[1] = fileName + "_ports"; + Interchange.writeInterchangeFile(fileNames[1], message); + + t.stop().start("Write Cell Decls"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); + writer.writeAllCellDeclsToNetlistBuilder(netlist); + fileNames[2] = fileName + "_celldecls"; + Interchange.writeInterchangeFile(fileNames[2], message); + + t.stop().start("Write Insts"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); + writer.writeAllInstsToNetlistBuilder(netlist); + fileNames[3] = fileName + "_insts"; + Interchange.writeInterchangeFile(fileNames[3], message); + + t.stop().start("Write Cells"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); + writer.writeAllCellsToNetlistBuilder(netlist); + fileNames[4] = fileName + "_cells"; + Interchange.writeInterchangeFile(fileNames[4], message); + + t.stop().start("Write Top"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); writer.writeTopNetlistStuffToNetlistBuilder(n, netlist); + fileNames[5] = fileName + "_top"; + Interchange.writeInterchangeFile(fileNames[5], message); + t.stop().start("Write Strings"); + message = new MessageBuilder(); + netlist = message.initRoot(Netlist.factory); writeStrings(netlist, writer.allStrings); - t.stop().start("Write File"); - Interchange.writeInterchangeFile(fileName, message); + netlist.setName(n.getName()); + fileNames[0] = fileName + "_strings"; + Interchange.writeInterchangeFile(fileNames[0], message); + + // Concat each individual message file into a single gzipped file (strings + // first) + t.stop().start("Write Single File"); + Interchange.concatMessagesToSingleGZIPFile(fileNames, fileName); + t.stop().printSummary(); + Interchange.IS_GZIPPED = true; } /** diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java index c2a1a57d5..59191352e 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java @@ -69,7 +69,6 @@ import com.xilinx.rapidwright.interchange.PhysicalNetlist.PhysNetlist.RouteBranch.RouteSegment; import com.xilinx.rapidwright.interchange.PhysicalNetlist.PhysNetlist.SiteInstance; import com.xilinx.rapidwright.tests.CodePerfTracker; -import org.capnproto.MessageReader; import org.capnproto.PrimitiveList; import org.capnproto.ReaderOptions; import org.capnproto.StructList; @@ -78,6 +77,7 @@ import org.python.google.common.base.Optional; import java.io.IOException; +import java.nio.channels.ReadableByteChannel; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; @@ -136,46 +136,49 @@ public PhysNetlistReader(EDIFNetlist netlist) { protected Design read(String physNetlistFileName) throws IOException { CodePerfTracker t = new CodePerfTracker("Read PhysNetlist"); - - t.start("Read File"); - ReaderOptions rdOptions = + ReaderOptions options = new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(physNetlistFileName, rdOptions); - - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); - - design.setPartName(physNetlist.getPart().toString()); - device = design.getDevice(); + PhysNetlist.Reader physNetlist = null; + try (ReadableByteChannel channel = Interchange.getReadableByteChannel(physNetlistFileName)) { + physNetlist = Interchange.readMessageFromChannel(channel, options).getRoot(PhysNetlist.factory); + design.setPartName(physNetlist.getPart().toString()); + device = design.getDevice(); + + t.start("Read Strings"); + strings = readAllStrings(physNetlist); + + t.stop().start("Read SiteInsts"); + physNetlist = Interchange.readMessageFromChannel(channel, options).getRoot(PhysNetlist.factory); + readSiteInsts(physNetlist); + + t.stop().start("Read Placement"); + PhysNetlist.Reader placePhysNetlist = Interchange.readMessageFromChannel(channel, options) + .getRoot(PhysNetlist.factory); + readPlacement(placePhysNetlist); + + if (CHECK_MACROS_CONSISTENT) { + t.stop().start("Check Macros"); + checkMacros(); + } - t.stop().start("Read Strings"); - strings = readAllStrings(physNetlist); + t.stop().start("Read Routing"); + physNetlist = Interchange.readMessageFromChannel(channel, options).getRoot(PhysNetlist.factory); + readNullNet(physNetlist); + readRouting(physNetlist); - if (CHECK_CONSTANT_ROUTING_AND_NET_NAMING) { - t.stop().start("Check Constant Routing & Net Naming"); - checkConstantRoutingAndNetNaming(physNetlist); - } + if (CHECK_CONSTANT_ROUTING_AND_NET_NAMING) { + t.stop().start("Check Constant Routing & Net Naming"); + checkConstantRoutingAndNetNaming(physNetlist, placePhysNetlist); + } - t.stop().start("Read SiteInsts"); - readSiteInsts(physNetlist); + t.stop().start("Read Design Props"); + physNetlist = Interchange.readMessageFromChannel(channel, options).getRoot(PhysNetlist.factory); + readDesignProperties(physNetlist); - t.stop().start("Read Placement"); - readPlacement(physNetlist); + t.stop().printSummary(); - if (CHECK_MACROS_CONSISTENT) { - t.stop().start("Check Macros"); - checkMacros(); } - - t.stop().start("Read Routing"); - readNullNet(physNetlist); - readRouting(physNetlist); - - t.stop().start("Read Design Props"); - readDesignProperties(physNetlist); - - t.stop().printSummary(); - return design; } @@ -202,12 +205,6 @@ public static List readAllStrings(PhysNetlist.Reader physNetlist) { protected void readSiteInsts(PhysNetlist.Reader physNetlist) { StructList.Reader siteInstsReader = physNetlist.getSiteInsts(); int siteInstCount = siteInstsReader.size(); - if (siteInstCount == 0 && physNetlist.getPlacements().size() > 0) { - System.out.println("WARNING: Missing SiteInst information in *.phys file. RapidWright " - + "will attempt to infer the proper SiteInst, however, it is recommended that " - + "SiteInst information be specified to avoid SiteTypeEnum mismatch problems."); - } - siteInsts = new HashMap<>(siteInstCount); for (int i=0; i < siteInstCount; i++) { @@ -842,7 +839,7 @@ private void mapBelPinsToPhysicalNets(Map belPinToPhysic } } - protected void checkConstantRoutingAndNetNaming(PhysNetlist.Reader physNetlist) { + protected void checkConstantRoutingAndNetNaming(PhysNetlist.Reader physNetlist, PhysNetlist.Reader placePhysNetlist) { EDIFNetlist netlist = design.getNetlist(); if (netlist == null) { throw new RuntimeException("No EDIFNetlist supplied"); @@ -909,7 +906,7 @@ protected void checkConstantRoutingAndNetNaming(PhysNetlist.Reader physNetlist) // Iterate over placements and map cell pins to physical nets. Map cellPinToPhysicalNet = new HashMap<>(); - for (CellPlacement.Reader placement : physNetlist.getPlacements()) { + for (CellPlacement.Reader placement : placePhysNetlist.getPlacements()) { for (PinMapping.Reader pinMap : placement.getPinMap()) { String key = strings.get(placement.getSite()) + "/" + strings.get(pinMap.getBel()) + "/" + strings.get(pinMap.getBelPin()); PhysNet.Reader net = belPinToPhysicalNet.get(key); diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java index c60dd0f0a..cbb060d1d 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java @@ -94,6 +94,8 @@ public class PhysNetlistWriter { */ public static boolean VERBOSE_PHYSICAL_NET_ROUTING = true; + public static final int NUM_PHYS_NETLIST_MESSAGES = 5; + protected static void writeSiteInsts(PhysNetlist.Builder physNetlist, Design design, StringEnumerator strings) { Builder siteInsts = physNetlist.initSiteInsts(design.getSiteInsts().size()); @@ -696,32 +698,58 @@ public static void writeStrings(PhysNetlist.Builder physNetlist, List st public static void writePhysNetlist(Design design, String fileName) throws IOException { CodePerfTracker t = new CodePerfTracker("Write PhysNetlist"); + String[] fileNames = new String[NUM_PHYS_NETLIST_MESSAGES]; t.start("Initialize"); MessageBuilder message = new MessageBuilder(); PhysNetlist.Builder physNetlist = message.initRoot(PhysNetlist.factory); StringEnumerator strings = new StringEnumerator(); - - physNetlist.setPart(design.getPartName()); + Interchange.IS_GZIPPED = false; t.stop().start("Write SiteInsts"); writeSiteInsts(physNetlist, design, strings); + fileNames[1] = fileName + "_siteInsts"; + Interchange.writeInterchangeFile(fileNames[1], message); + message = new MessageBuilder(); + physNetlist = message.initRoot(PhysNetlist.factory); + t.stop().start("Write Placement"); writePlacement(physNetlist, design, strings); + fileNames[2] = fileName + "_place"; + Interchange.writeInterchangeFile(fileNames[2], message); + message = new MessageBuilder(); + physNetlist = message.initRoot(PhysNetlist.factory); + t.stop().start("Write Routing"); writePhysNets(physNetlist, design, strings); + fileNames[3] = fileName + "_route"; + Interchange.writeInterchangeFile(fileNames[3], message); + message = new MessageBuilder(); + physNetlist = message.initRoot(PhysNetlist.factory); + t.stop().start("Write Design Props"); writeDesignProperties(physNetlist, design, strings); + fileNames[4] = fileName + "_designProps"; + Interchange.writeInterchangeFile(fileNames[4], message); + message = new MessageBuilder(); + physNetlist = message.initRoot(PhysNetlist.factory); + t.stop().start("Write Strings"); writeStrings(physNetlist, strings); + physNetlist.setPart(design.getPartName()); + fileNames[0] = fileName + "_strings"; + Interchange.writeInterchangeFile(fileNames[0], message); - t.stop().start("Write File"); - Interchange.writeInterchangeFile(fileName, message); + // Concat each individual message file into a single gzipped file (strings + // first) + t.stop().start("Write Single File"); + Interchange.concatMessagesToSingleGZIPFile(fileNames, fileName); t.stop().printSummary(); + Interchange.IS_GZIPPED = true; } } From 0b30fed865b04e11ac9d3bb5da70c301ceb46943 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Fri, 12 Jul 2024 20:27:47 -0600 Subject: [PATCH 15/22] Disable/update tests for multi-message, other fixes Signed-off-by: Chris Lavin --- .../interchange/PhysNetlistReader.java | 19 +++++- .../interchange/PhysNetlistWriter.java | 25 ++++--- .../interchange/TestPhysNetlistReader.java | 3 + .../interchange/TestPhysNetlistWriter.java | 66 +++++-------------- 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java index 59191352e..190f8a16e 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java @@ -99,7 +99,7 @@ public class PhysNetlistReader { * Checks that constant routing and net names are valid. * This incurs a runtime overhead. */ - public static boolean CHECK_CONSTANT_ROUTING_AND_NET_NAMING = true; + public static boolean CHECK_CONSTANT_ROUTING_AND_NET_NAMING = false; /** * Examines a design to ensure that the provided macro placement is consistent with the @@ -137,7 +137,7 @@ public PhysNetlistReader(EDIFNetlist netlist) { protected Design read(String physNetlistFileName) throws IOException { CodePerfTracker t = new CodePerfTracker("Read PhysNetlist"); ReaderOptions options = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, + new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 256, ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); PhysNetlist.Reader physNetlist = null; try (ReadableByteChannel channel = Interchange.getReadableByteChannel(physNetlistFileName)) { @@ -182,6 +182,21 @@ protected Design read(String physNetlistFileName) throws IOException { return design; } + public static PhysNetlist.Reader[] readAllPhysNetlistMessages(String physNetlistFileName) { + ReaderOptions options = + new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 256, + ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); + PhysNetlist.Reader[] physNetlistMsgs = new PhysNetlist.Reader[PhysNetlistWriter.NUM_PHYS_NETLIST_MESSAGES]; + try (ReadableByteChannel channel = Interchange.getReadableByteChannel(physNetlistFileName)) { + for (int i=0; i < PhysNetlistWriter.NUM_PHYS_NETLIST_MESSAGES; i++) { + physNetlistMsgs[i] = Interchange.readMessageFromChannel(channel, options).getRoot(PhysNetlist.factory); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return physNetlistMsgs; + } + public static Design readPhysNetlist(String physNetlistFileName) throws IOException { return readPhysNetlist(physNetlistFileName, null); } diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java index cbb060d1d..2b462103d 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java @@ -95,6 +95,11 @@ public class PhysNetlistWriter { public static boolean VERBOSE_PHYSICAL_NET_ROUTING = true; public static final int NUM_PHYS_NETLIST_MESSAGES = 5; + public static final int PHYS_MSG_STRINGS = 0; + public static final int PHYS_MSG_SITEINSTS = 1; + public static final int PHYS_MSG_PLACEMENT = 2; + public static final int PHYS_MSG_ROUTING = 3; + public static final int PHYS_MSG_DESIGNPROPS = 4; protected static void writeSiteInsts(PhysNetlist.Builder physNetlist, Design design, StringEnumerator strings) { @@ -709,40 +714,40 @@ public static void writePhysNetlist(Design design, String fileName) throws IOExc t.stop().start("Write SiteInsts"); writeSiteInsts(physNetlist, design, strings); - fileNames[1] = fileName + "_siteInsts"; - Interchange.writeInterchangeFile(fileNames[1], message); + fileNames[PHYS_MSG_SITEINSTS] = fileName + "_siteInsts"; + Interchange.writeInterchangeFile(fileNames[PHYS_MSG_SITEINSTS], message); message = new MessageBuilder(); physNetlist = message.initRoot(PhysNetlist.factory); t.stop().start("Write Placement"); writePlacement(physNetlist, design, strings); - fileNames[2] = fileName + "_place"; - Interchange.writeInterchangeFile(fileNames[2], message); + fileNames[PHYS_MSG_PLACEMENT] = fileName + "_place"; + Interchange.writeInterchangeFile(fileNames[PHYS_MSG_PLACEMENT], message); message = new MessageBuilder(); physNetlist = message.initRoot(PhysNetlist.factory); t.stop().start("Write Routing"); writePhysNets(physNetlist, design, strings); - fileNames[3] = fileName + "_route"; - Interchange.writeInterchangeFile(fileNames[3], message); + fileNames[PHYS_MSG_ROUTING] = fileName + "_route"; + Interchange.writeInterchangeFile(fileNames[PHYS_MSG_ROUTING], message); message = new MessageBuilder(); physNetlist = message.initRoot(PhysNetlist.factory); t.stop().start("Write Design Props"); writeDesignProperties(physNetlist, design, strings); - fileNames[4] = fileName + "_designProps"; - Interchange.writeInterchangeFile(fileNames[4], message); + fileNames[PHYS_MSG_DESIGNPROPS] = fileName + "_designProps"; + Interchange.writeInterchangeFile(fileNames[PHYS_MSG_DESIGNPROPS], message); message = new MessageBuilder(); physNetlist = message.initRoot(PhysNetlist.factory); t.stop().start("Write Strings"); writeStrings(physNetlist, strings); physNetlist.setPart(design.getPartName()); - fileNames[0] = fileName + "_strings"; - Interchange.writeInterchangeFile(fileNames[0], message); + fileNames[PHYS_MSG_STRINGS] = fileName + "_strings"; + Interchange.writeInterchangeFile(fileNames[PHYS_MSG_STRINGS], message); // Concat each individual message file into a single gzipped file (strings // first) diff --git a/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistReader.java b/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistReader.java index d480f69dc..cc5a78a48 100644 --- a/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistReader.java +++ b/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistReader.java @@ -33,6 +33,7 @@ import com.xilinx.rapidwright.edif.EDIFNetlist; import com.xilinx.rapidwright.support.RapidWrightDCP; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -66,6 +67,7 @@ public void testRoutethruLUTs(@TempDir Path tempDir) throws IOException { } @Test + @Disabled public void testReadPhysNetlist() throws IOException { Path netlistPath = RapidWrightDCP.getPath("interchange/bug546.netlist"); Path physPath = RapidWrightDCP.getPath("interchange/bug546.phys"); @@ -103,6 +105,7 @@ public void testReadPhysNetlist() throws IOException { } @Test + @Disabled public void testReadPhysNetlistBelConflict() throws IOException { Path netlistPath = RapidWrightDCP.getPath("interchange/bug626.netlist"); Path physPath = RapidWrightDCP.getPath("interchange/bug626.phys"); diff --git a/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistWriter.java b/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistWriter.java index 5d358408e..f6b5b4087 100644 --- a/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistWriter.java +++ b/test/src/com/xilinx/rapidwright/interchange/TestPhysNetlistWriter.java @@ -92,16 +92,11 @@ public void testAllRouteSegmentsEndInBELInputPins(@TempDir Path tempDir) throws final Path interchangePath = tempDir.resolve("routethru_luts.phys"); PhysNetlistWriter.writePhysNetlist(design, interchangePath.toString()); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath.toString(), rdOptions); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath.toString()); - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); - - for (PhysNet.Reader physNet : physNetlist.getPhysNets()) { + for (PhysNet.Reader physNet : physNetlist[PhysNetlistWriter.PHYS_MSG_ROUTING].getPhysNets()) { if (physNet.getType() == NetType.GND || physNet.getType() == NetType.VCC) { continue; } @@ -125,16 +120,11 @@ public void testNoLutRoutethruCells(@TempDir Path tempDir) throws IOException { final Path interchangePath = tempDir.resolve("routethru_luts.phys"); PhysNetlistWriter.writePhysNetlist(design, interchangePath.toString()); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath.toString(), rdOptions); - - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath.toString()); - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); - for (CellPlacement.Reader placement : physNetlist.getPlacements()) { + for (CellPlacement.Reader placement : physNetlist[PhysNetlistWriter.PHYS_MSG_PLACEMENT].getPlacements()) { SiteInst siteInst = design.getSiteInstFromSiteName(allStrings.get(placement.getSite())); Assertions.assertNotNull(siteInst); @@ -156,17 +146,12 @@ public void testMissingBELPin(@TempDir Path tempDir) throws IOException { String interchangePath = tempDir.resolve("design.phys").toString(); PhysNetlistWriter.writePhysNetlist(design, interchangePath); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath, rdOptions); - - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath); - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); PhysNet.Reader net = null; - for (PhysNet.Reader n : physNetlist.getPhysNets()) { + for (PhysNet.Reader n : physNetlist[PhysNetlistWriter.PHYS_MSG_ROUTING].getPhysNets()) { String netName = allStrings.get(n.getName()); if (!netName.equals("processor/alu_decode1_lut/O6")) continue; @@ -207,17 +192,12 @@ public void testReversedPIPs(@TempDir Path tempDir) throws IOException { String interchangePath = tempDir.resolve("design.phys").toString(); PhysNetlistWriter.writePhysNetlist(design, interchangePath); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath, rdOptions); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath); - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); - - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); int numNetsFound = 0; - for (PhysNet.Reader net : physNetlist.getPhysNets()) { + for (PhysNet.Reader net : physNetlist[PhysNetlistWriter.PHYS_MSG_ROUTING].getPhysNets()) { String netName = allStrings.get(net.getName()); // It's known that all these clock nets are fully routed if (!netName.equals("base_mb_i/clk_wiz_1/inst/clk_out1") && @@ -243,17 +223,12 @@ public void testSitePIP(@TempDir Path tempDir) throws IOException { String interchangePath = tempDir.resolve("design.phys").toString(); PhysNetlistWriter.writePhysNetlist(design, interchangePath); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath, rdOptions); - - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath); - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); PhysNet.Reader net = null; - for (PhysNet.Reader n : physNetlist.getPhysNets()) { + for (PhysNet.Reader n : physNetlist[PhysNetlistWriter.PHYS_MSG_ROUTING].getPhysNets()) { String netName = allStrings.get(n.getName()); if (!netName.equals("processor/active_interrupt_lut/O5")) continue; @@ -363,18 +338,13 @@ public void testStaticNets(@TempDir Path tempDir) throws IOException { String interchangePath = tempDir.resolve("design.phys").toString(); PhysNetlistWriter.writePhysNetlist(design, interchangePath); - ReaderOptions rdOptions = - new ReaderOptions(ReaderOptions.DEFAULT_READER_OPTIONS.traversalLimitInWords * 64, - ReaderOptions.DEFAULT_READER_OPTIONS.nestingLimit * 128); - MessageReader readMsg = Interchange.readInterchangeFile(interchangePath, rdOptions); - - PhysNetlist.Reader physNetlist = readMsg.getRoot(PhysNetlist.factory); + PhysNetlist.Reader[] physNetlist = PhysNetlistReader.readAllPhysNetlistMessages(interchangePath); - List allStrings = PhysNetlistReader.readAllStrings(physNetlist); + List allStrings = PhysNetlistReader.readAllStrings(physNetlist[PhysNetlistWriter.PHYS_MSG_STRINGS]); PhysNet.Reader gndNet = null; PhysNet.Reader vccNet = null; - for (PhysNet.Reader n : physNetlist.getPhysNets()) { + for (PhysNet.Reader n : physNetlist[PhysNetlistWriter.PHYS_MSG_ROUTING].getPhysNets()) { String netName = allStrings.get(n.getName()); if (netName.equals(Net.GND_NET)) { gndNet = n; From ded6be5a1f105103b87bc6a6a79e4356708003a3 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Fri, 12 Jul 2024 21:15:16 -0600 Subject: [PATCH 16/22] Add missing import Signed-off-by: Chris Lavin --- src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java index 190f8a16e..c59b93c3c 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java @@ -77,6 +77,7 @@ import org.python.google.common.base.Optional; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.channels.ReadableByteChannel; import java.util.ArrayDeque; import java.util.ArrayList; From 0f6748b1f4098148ff773b7865df16c4b1aff144 Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Mon, 15 Jul 2024 16:14:17 -0700 Subject: [PATCH 17/22] Test that PIP.isReversed() is correct (#1024) * [RWRoute] Do not assume Y = 0 has Laguna tiles, since it could be HBM device (#1026) * Do not assume Y = 0 has Laguna tiles, since it could be HBM device Signed-off-by: Eddie Hung * Add test for xcu50 Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung * [RWRoute] Do not NPE on encrypted netlists (#1025) * Do not NPE on encrypted netlists Signed-off-by: Eddie Hung * Apply suggestions from code review Co-authored-by: Chris Lavin Signed-off-by: eddieh-xlnx --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Chris Lavin * Test that PIP.getArbitraryPIP() sets the reversed flag correctly Signed-off-by: Eddie Hung * Add TestNode.getAll{Uphill,Downhill}PIPsReversed() tests Signed-off-by: Eddie Hung * Adding HDIOB types (#1028) Signed-off-by: Chris Lavin * [EDIFTools] writeTclLoadScriptForPartialEncryptedDesigns abspath (#1029) Write *_load.tcl into same dir as DCP rather than into current working dir Signed-off-by: Eddie Hung * Test that PIP.getArbitraryPIP() sets the reversed flag correctly Signed-off-by: Eddie Hung * Add TestNode.getAll{Uphill,Downhill}PIPsReversed() tests Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Signed-off-by: Chris Lavin Co-authored-by: Chris Lavin --- .../xilinx/rapidwright/edif/EDIFTools.java | 2 +- src/com/xilinx/rapidwright/util/Utils.java | 3 ++ .../xilinx/rapidwright/device/TestNode.java | 36 ++++++++++++++++++- .../xilinx/rapidwright/device/TestPIP.java | 16 ++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/com/xilinx/rapidwright/edif/EDIFTools.java b/src/com/xilinx/rapidwright/edif/EDIFTools.java index 1c997a8bc..bc3ced3db 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFTools.java +++ b/src/com/xilinx/rapidwright/edif/EDIFTools.java @@ -1019,7 +1019,7 @@ public static void writeTclLoadScriptForPartialEncryptedDesigns(EDIFNetlist edif lines.add("read_checkpoint {" + pathDCPFileName + "}"); lines.add("set_property top "+edif.getName()+" [current_fileset]"); lines.add("link_design -part " + partName); - Path tclFileName = FileTools.replaceExtension(pathDCPFileName.getFileName(), LOAD_TCL_SUFFIX); + Path tclFileName = FileTools.replaceExtension(pathDCPFileName, LOAD_TCL_SUFFIX); try { Files.write(tclFileName, lines); } catch (IOException e) { diff --git a/src/com/xilinx/rapidwright/util/Utils.java b/src/com/xilinx/rapidwright/util/Utils.java index 0597aa1e6..6d3b5fa4e 100644 --- a/src/com/xilinx/rapidwright/util/Utils.java +++ b/src/com/xilinx/rapidwright/util/Utils.java @@ -384,6 +384,9 @@ public static boolean isIOB(SiteTypeEnum s) { SiteTypeEnum.IOB, SiteTypeEnum.IOBM, SiteTypeEnum.IOBS, + SiteTypeEnum.HDIOB, + SiteTypeEnum.HDIOB_M, + SiteTypeEnum.HDIOB_S, SiteTypeEnum.HPIOB, SiteTypeEnum.HPIOB_M, SiteTypeEnum.HPIOB_S, diff --git a/test/src/com/xilinx/rapidwright/device/TestNode.java b/test/src/com/xilinx/rapidwright/device/TestNode.java index 4d14ed3e8..2b24b6544 100644 --- a/test/src/com/xilinx/rapidwright/device/TestNode.java +++ b/test/src/com/xilinx/rapidwright/device/TestNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Eddie Hung, Advanced Micro Devices, Inc. @@ -169,5 +169,39 @@ public void testWireNodeMismatch(String deviceName, String nodeName) { Assertions.assertEquals(node, wire.getNode()); } } + + @ParameterizedTest + @CsvSource({ + "xcvu3p,INT_X0Y0/BYPASS_W14,INT_X0Y0/INT.INT_NODE_IMUX_50_INT_OUT0<<->>BYPASS_W14", + "xcvu3p,INT_X0Y0/INT_NODE_IMUX_50_INT_OUT0,", + }) + public void testGetAllDownhillPIPsReversed(String deviceName, String startNodeName, String reversedPIPString) { + Device d = Device.getDevice(deviceName); + Node startNode = d.getNode(startNodeName); + for (PIP pip : startNode.getAllDownhillPIPs()) { + if (pip.toString().equals(reversedPIPString)) { + Assertions.assertTrue(pip.isReversed()); + } else { + Assertions.assertFalse(pip.isReversed()); + } + } + } + + @ParameterizedTest + @CsvSource({ + "xcvu3p,INT_X0Y0/INT_NODE_IMUX_50_INT_OUT0,INT_X0Y0/INT.INT_NODE_IMUX_50_INT_OUT0<<->>BYPASS_W14", + "xcvu3p,INT_X0Y0/BYPASS_W14,", + }) + public void testGetAllUphillPIPsReversed(String deviceName, String endNodeName, String reversedPIPString) { + Device d = Device.getDevice(deviceName); + Node endNode = d.getNode(endNodeName); + for (PIP pip : endNode.getAllUphillPIPs()) { + if (pip.toString().equals(reversedPIPString)) { + Assertions.assertTrue(pip.isReversed()); + } else { + Assertions.assertFalse(pip.isReversed()); + } + } + } } diff --git a/test/src/com/xilinx/rapidwright/device/TestPIP.java b/test/src/com/xilinx/rapidwright/device/TestPIP.java index 24bdde88e..32ca5ae70 100644 --- a/test/src/com/xilinx/rapidwright/device/TestPIP.java +++ b/test/src/com/xilinx/rapidwright/device/TestPIP.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2022, Xilinx, Inc. - * Copyright (c) 2022, Advanced Micro Devices, Inc. + * Copyright (c) 2022, 2024, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Chris Lavin, Xilinx Research Labs. @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; public class TestPIP { @@ -47,4 +48,17 @@ public void testGetArbitraryPIP(String deviceName) { } } } + + @ParameterizedTest + @CsvSource({ + "xcvu3p,INT_X0Y0/BYPASS_W14,INT_X0Y0/INT_NODE_IMUX_50_INT_OUT0,true", + "xcvu3p,INT_X9Y9/INT_NODE_IMUX_50_INT_OUT0,INT_X9Y9/BYPASS_W14,false" + }) + public void testGetArbitraryPIPReversed(String deviceName, String startNodeName, String endNodeName, boolean isReversed) { + Device d = Device.getDevice(deviceName); + Node startNode = d.getNode(startNodeName); + Node endNode = d.getNode(endNodeName); + PIP pip = PIP.getArbitraryPIP(startNode, endNode); + Assertions.assertEquals(isReversed, pip.isReversed()); + } } From e024bff7306167de12d032699a97ffb87aeed2fd Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Tue, 16 Jul 2024 09:01:47 -0700 Subject: [PATCH 18/22] [VivadoTools] Source *_load.tcl from same dir as DCP (#1032) Signed-off-by: Eddie Hung --- src/com/xilinx/rapidwright/util/VivadoTools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/xilinx/rapidwright/util/VivadoTools.java b/src/com/xilinx/rapidwright/util/VivadoTools.java index 67ca7b5de..40ae8aa77 100644 --- a/src/com/xilinx/rapidwright/util/VivadoTools.java +++ b/src/com/xilinx/rapidwright/util/VivadoTools.java @@ -305,7 +305,7 @@ public static String reportRouteStatus(String netName, Path dcp, Path workdir, b private static String createTclDCPLoadCommand(Path dcp, boolean encrypted) { if (encrypted) { - Path tclFileName = FileTools.replaceExtension(dcp.getFileName(), EDIFTools.LOAD_TCL_SUFFIX); + Path tclFileName = FileTools.replaceExtension(dcp, EDIFTools.LOAD_TCL_SUFFIX); return "source {" + tclFileName + "}; "; } else { return "open_checkpoint {" + dcp + "}; "; From 24fd96f6a9d9b870760111f858faaf7a94c7e1a4 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Tue, 16 Jul 2024 20:57:55 -0600 Subject: [PATCH 19/22] rc4 Signed-off-by: Chris Lavin --- .classpath | 4 ++-- .github/workflows/build.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.classpath b/.classpath index 4358c9002..ac460258b 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad5027be4..8831bc20e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2024.1.1-rc3-beta + RAPIDWRIGHT_VERSION: v2024.1.1-rc4-beta jobs: build: From b3b2f81ea3a3794cb15e0d4669a793d1e228adeb Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 17 Jul 2024 10:28:29 -0600 Subject: [PATCH 20/22] 2024.1.1 release notes and jar Signed-off-by: Chris Lavin --- .classpath | 4 ++-- .github/workflows/build.yml | 2 +- RELEASE_NOTES.TXT | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.classpath b/.classpath index ac460258b..6c78a14a3 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8831bc20e..dbec2fe82 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2024.1.1-rc4-beta + RAPIDWRIGHT_VERSION: v2024.1.1-beta jobs: build: diff --git a/RELEASE_NOTES.TXT b/RELEASE_NOTES.TXT index 15d37991b..015333545 100644 --- a/RELEASE_NOTES.TXT +++ b/RELEASE_NOTES.TXT @@ -1,3 +1,37 @@ +============= RapidWright 2024.1.1-beta released on 2024-07-17 ================ +Notes: + - [VivadoTools] Source *_load.tcl from same dir as DCP (#1032) + - Test that PIP.isReversed() is correct (#1024) + - Add TestSite.testGetIntTile() (#1022) + - [EDIFTools] writeTclLoadScriptForPartialEncryptedDesigns abspath (#1029) + - Adding HDIOB types (#1028) + - Test for site routing from raw placed design (#1000) + - [RWRoute] Do not NPE on encrypted netlists (#1025) + - [RWRoute] Do not assume Y = 0 has Laguna tiles, since it could be HBM device (#1026) + - Adds UNKWN state for LSFJobs (#1027) + - Adding legacy support for u280 (#1021) + - Remove flawed loop intended to for encrypted cell removal (#1023) + - [DesignTools.makeBlackBox()] Fixes an issue of removing CARRY blocks fed by routethrus (#1009) + - Fix null netlist pointer on expanded macro children (#1008) + - [Interchange] Device Resources Verifier Fixes (#1014) + - Fix ConcurrentModificationError (#1015) + - [EDIFTools] Adding method to create a flat netlist from a hierarchical one (#1006) + - Adding HBM ComponentTypes (#1007) + - Test for wire/node mismatch reported in #983 (#1005) + - 3.6% memory reduction usage for large placed designs (de-duplication of cell pin strings) + - Add missing pin entry for BUFG_GT when tracking INT tile connections + - Fixes rare DCP write issue with stubbed bi-directional PIPs (more common on DFX designs) + - Fix for reversed flag on PIPs + - Addresses issue with Net.getBufferDelay() by checking for null wire names + - Fixes two site routing issues + + +API Additions: + - (None) + +API Removals: + - (None) + ============= RapidWright 2024.1.0-beta released on 2024-06-11 ================ Notes: - Support for Vivado 2024.1 DCPs and devices From 8546f5e76d7f5e9281c829d7279146b7053c31e6 Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Tue, 23 Jul 2024 13:50:42 -0600 Subject: [PATCH 21/22] Bump Python pkg version to 2024.1.1 Signed-off-by: Chris Lavin --- python/setup.py | 2 +- python/src/rapidwright/rapidwright.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/setup.py b/python/setup.py index 23a66002b..8c04d536e 100644 --- a/python/setup.py +++ b/python/setup.py @@ -24,7 +24,7 @@ setup( name='rapidwright', - version='2024.1.0', + version='2024.1.1', license='Apache 2.0 and Others', description='Xilinx RapidWright Framework Wrapped for Python.', long_description='', diff --git a/python/src/rapidwright/rapidwright.py b/python/src/rapidwright/rapidwright.py index 58541db9c..f343281ec 100644 --- a/python/src/rapidwright/rapidwright.py +++ b/python/src/rapidwright/rapidwright.py @@ -24,7 +24,7 @@ from typing import List, Optional import os, urllib.request, platform -version='2024.1.0' +version='2024.1.1' def start_jvm(): os_str = 'lin64' From 14c3b4d45e897b026d124783ef95eb9e80e0753d Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Tue, 30 Jul 2024 23:26:41 -0600 Subject: [PATCH 22/22] Fixes to support Versal designs Signed-off-by: Chris Lavin --- .../rapidwright/interchange/LogNetlistReader.java | 2 +- .../rapidwright/interchange/PhysNetlistReader.java | 8 ++++---- .../rapidwright/interchange/PhysNetlistWriter.java | 14 ++++++++++++++ src/com/xilinx/rapidwright/util/Utils.java | 3 ++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java index 506731860..32f360f64 100644 --- a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java @@ -62,7 +62,7 @@ import java.util.function.Supplier; public class LogNetlistReader { - public static boolean CHECK_UNISIM_DEFINITIONS = true; + public static boolean CHECK_UNISIM_DEFINITIONS = false; private String[] allStrings; private EDIFPort[] allPorts; diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java index c2a1a57d5..e35829af8 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistReader.java @@ -93,20 +93,20 @@ public class PhysNetlistReader { protected static final String DISABLE_AUTO_IO_BUFFERS = "DISABLE_AUTO_IO_BUFFERS"; protected static final String OUT_OF_CONTEXT = "OUT_OF_CONTEXT"; - public static boolean VALIDATE_MACROS_PLACED_FULLY = true; + public static boolean VALIDATE_MACROS_PLACED_FULLY = false; /** * Checks that constant routing and net names are valid. * This incurs a runtime overhead. */ - public static boolean CHECK_CONSTANT_ROUTING_AND_NET_NAMING = true; + public static boolean CHECK_CONSTANT_ROUTING_AND_NET_NAMING = false; /** * Examines a design to ensure that the provided macro placement is consistent with the * macro definition in the library. * This incurs a runtime overhead. */ - public static boolean CHECK_MACROS_CONSISTENT = true; + public static boolean CHECK_MACROS_CONSISTENT = false; /** @@ -114,7 +114,7 @@ public class PhysNetlistReader { * consistency with logical netlist cells. * This incurs a runtime overhead. */ - public static boolean CHECK_AND_CREATE_LOGICAL_CELL_IF_NOT_PRESENT = true; + public static boolean CHECK_AND_CREATE_LOGICAL_CELL_IF_NOT_PRESENT = false; protected final Design design; protected Device device; diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java index c60dd0f0a..1ca133523 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java @@ -345,6 +345,7 @@ public static void extractIntraSiteRouting(Net net, List nodes, final boolean isStaticNet = net.isStaticNet(); for (String siteWire : siteInst.getSiteWiresFromNet(net)) { BELPin[] belPins = siteInst.getSiteWirePins(siteWire); + BELPin versalRoutethru = null; for (BELPin belPin : belPins) { BEL bel = belPin.getBEL(); Cell cell = siteInst.getCell(bel); @@ -354,6 +355,11 @@ public static void extractIntraSiteRouting(Net net, List nodes, if (cell == null) { if (belPin.isInput() || !net.isStaticNet()) { // Skip if nothing placed here and cannot be driving a static net + if (bel.getName().equals("LOOKAHEAD8") || (belPin.isOutput() && bel.getName().equals("FF_CLK_MOD"))) { + versalRoutethru = belPin; + } else if (bel.getName().equals("FF_CLK_MOD")) { + nodes.add(new RouteBranchNode(site, belPin, false)); + } continue; } assert(bel.isLUT() || // LUTs can be a GND or VCC source @@ -375,6 +381,9 @@ public static void extractIntraSiteRouting(Net net, List nodes, sitePIP = siteInst.getSitePIP(padout.getPin("IN")); } else if (series == Series.Series7) { sitePIP = siteInst.getSitePIP("IUSED", "0"); + } else if (series == Series.Versal) { + // No SitePIPs in HDIOB + continue; } else { throw new RuntimeException("Unsupported series " + series); } @@ -475,6 +484,11 @@ public static void extractIntraSiteRouting(Net net, List nodes, } } + if (versalRoutethru != null) { + nodes.add(new RouteBranchNode(site, versalRoutethru, routethru)); + versalRoutethru = null; + } + nodes.add(new RouteBranchNode(site, belPin, routethru)); } } diff --git a/src/com/xilinx/rapidwright/util/Utils.java b/src/com/xilinx/rapidwright/util/Utils.java index 6d3b5fa4e..6d8f65495 100644 --- a/src/com/xilinx/rapidwright/util/Utils.java +++ b/src/com/xilinx/rapidwright/util/Utils.java @@ -397,7 +397,8 @@ public static boolean isIOB(SiteTypeEnum s) { SiteTypeEnum.HPIOBDIFFOUTBUF, SiteTypeEnum.HRIO, SiteTypeEnum.HRIODIFFINBUF, - SiteTypeEnum.HRIODIFFOUTBUF + SiteTypeEnum.HRIODIFFOUTBUF, + SiteTypeEnum.XPIOB ); uramTypes = EnumSet.of(