From 7cec5122cab9359b532701dd97bafd74b2a94baa Mon Sep 17 00:00:00 2001 From: Chris Lavin Date: Wed, 13 Sep 2023 20:36:37 -0600 Subject: [PATCH] 2023.1.3 Release (#812) * rc1 Signed-off-by: Chris Lavin * Test BEL.isSliceFFClkMod() Signed-off-by: Eddie Hung * PhysNetlistWriter.writePlacement() more careful looking for multi cells Signed-off-by: Eddie Hung * DesignTools.createCeClkOfRoutethruFFToVCC() to use Cell.isFFRoutethruCell() Signed-off-by: Eddie Hung * Add TestCell.testFFRoutethruCell() Signed-off-by: Eddie Hung * Fix test Signed-off-by: Eddie Hung * Remove Signed-off-by: Eddie Hung * Add test for Design.movePinsToNewNetDeleteOldNet() (#796) * Add TestDesign.testMovePinsToNewNetDeleteOldNet{,IntraSiteOnly()} Signed-off-by: Eddie Hung * Remove sitewire merge from DesignTools.makePhysNetNameConsistent() Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung Signed-off-by: Chris Lavin Co-authored-by: Chris Lavin * Test Cell.getAllCorrespondingSitePinNames() works for multi-outputs (#792) * Test Cell.getAllCorrespondingSitePinNames() works for multi-outputs Signed-off-by: Eddie Hung * Apply suggestions from code review Signed-off-by: eddieh-xlnx --------- Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Chris Lavin * rc2 Signed-off-by: Chris Lavin * rc3 Signed-off-by: Chris Lavin * rc4 Signed-off-by: Chris Lavin * 2023.1.3 release jar Signed-off-by: Chris Lavin --------- Signed-off-by: Chris Lavin Signed-off-by: Eddie Hung Signed-off-by: eddieh-xlnx Co-authored-by: Eddie Hung --- .classpath | 4 +- .github/workflows/build.yml | 2 +- RELEASE_NOTES.TXT | 59 +++++++++++++++++ .../rapidwright/design/DesignTools.java | 63 +++++++------------ .../interchange/PhysNetlistWriter.java | 6 +- .../xilinx/rapidwright/design/TestCell.java | 28 +++++++++ .../xilinx/rapidwright/design/TestDesign.java | 59 +++++++++++++++++ .../xilinx/rapidwright/device/TestBEL.java | 11 ++++ 8 files changed, 188 insertions(+), 44 deletions(-) diff --git a/.classpath b/.classpath index 2d3b8d481..c65d6cbe3 100644 --- a/.classpath +++ b/.classpath @@ -33,9 +33,9 @@ - + - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ea24d7dcb..051969714 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: pull_request: env: - RAPIDWRIGHT_VERSION: v2023.1.2-beta + RAPIDWRIGHT_VERSION: v2023.1.3-beta jobs: build: diff --git a/RELEASE_NOTES.TXT b/RELEASE_NOTES.TXT index e755b24d0..1b82ecf44 100644 --- a/RELEASE_NOTES.TXT +++ b/RELEASE_NOTES.TXT @@ -1,3 +1,62 @@ +============= RapidWright 2023.1.3-beta released on 2023-09-13 ================ +Notes: + - Fix DesignTools.getConnectionPIPs() (#809) + - [PhysNetlistWriter] RouteBranchNode.getDrivers() to return input BelPin (#800) + - Adds site pins to example code generation for nets. (#807) + - Update to fixed microblazeAndILA_3pblocks.dcp (#808) + - [LogNetlistWriter] Refactor writeStrings method to be public static (#804) + - [VivadoTools] ReportRouteStatusResult to parse more stats (#805) + - EDIF improvements (#806) + - RWRoute improvements (#803) + - Adds a createBitstream() method to VivadoTools (#801) + - Small DesignTools improvements (#797) + - added static function that helps produce test nets (including PIPs) (#784) + - Add reference copy methods (#794) + - [RWRoute] Add alternate source pins and set source routed flags (#787) + - Adds support for RouteThru LUT equations and makes LUTEquationEvaluator public (#795) + - Fix TestDCPLoad to prevent issues with parallel testing (#793) + - [PhysNetlistWriter] Fix route tree construction for bidir PIPs (#791) + - VivadoTools.reportRouteStatus() to handle encrypted cells (#777) + - [PhysNetlistWriter] Insert site port BELPin before site pin (#790) + - fixed null pointer exception in getPhysicalNetFromPin() (#775) + - LUT cell companion helper methods (#764) + - Check for error situation RAPIDWRIGHT_PATH set but not CLASSPATH (#772) + - Set reversed flag on bi-directional PIPs used from end->start (#774) + - Fix RouterHelper.projectOutputPinToINTNode() for depop pins (#779) + - Make PartialRouter.getUnroutedPins() public (#778) + - FileTools.runCommand() - Adds ability to choose run directory (#769) + - [GlobalSignalRouting] Static router to not create site pin if exists (#768) + - RouteThru support for FFs in UltraScale architecture + - Fixes minor SitePinInst creation when reading a DCP + - Improvements to Net.rename() when tracking changes + - Design.detachNetlist() to detach routethru cells + - Adds reference copy APIs and ability to keep copies of modified + SiteInsts and Nets + - Improvements to DCP reading compatibility for different flows + within Vivado +- API Additions: + - com.xilinx.rapidwright.bitstream.BitLocation "public int hashCode()" + - com.xilinx.rapidwright.bitstream.BitLocation "public boolean equals(Object obj)" + - com.xilinx.rapidwright.bitstream.Bitstream "public static Bitstream readBitstream(Path fileName)" + - com.xilinx.rapidwright.bitstream.Block "public int getBit(BitLocation bit, Tile tile)" + - com.xilinx.rapidwright.bitstream.Block "public boolean updateBit(BitLocation bit, Tile tile, int value, Block golden)" + - com.xilinx.rapidwright.bitstream.ConfigRow "public ConfigRow(int configRowIdx)" + - com.xilinx.rapidwright.bitstream.FAR "public Block getConfigBlock(int slrCfgOrder)" + - com.xilinx.rapidwright.bitstream.Packet "public int hashCode()" + - com.xilinx.rapidwright.bitstream.Packet "public boolean equals(Object obj)" + - com.xilinx.rapidwright.design.Cell "public static final String FF_ROUTETHRU_TYPE" + - com.xilinx.rapidwright.design.Cell "public Cell getReferenceCopy()" + - com.xilinx.rapidwright.design.Cell "public boolean isFFRoutethruCell()" + - com.xilinx.rapidwright.design.Design "public boolean isCopyingOriginalNetsRouting()" + - com.xilinx.rapidwright.design.Design "public void setCopyingOriginalNetsRouting(boolean copyOrigNets)" + - com.xilinx.rapidwright.design.Design "public Map> getOriginalNetRouting()" + - com.xilinx.rapidwright.design.Design "public boolean isCopyingOriginalSiteInsts()" + - com.xilinx.rapidwright.design.Design "public void setCopyingOriginalSiteInsts(boolean copyOrigSiteInsts)" + - com.xilinx.rapidwright.design.Design "public Map getOriginalSiteInsts()" + - com.xilinx.rapidwright.design.Net "public List getCopyOfPIPs()" + - com.xilinx.rapidwright.design.SiteInst "public void addPin(SitePinInst sitePinInst)" + - com.xilinx.rapidwright.design.SiteInst "public SiteInst getReferenceCopy()" + ============= RapidWright 2023.1.2-beta released on 2023-07-24 ================ Notes: - Shell creation improvements to enable lock_design and timing closure preservation (#760) diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index c0b9517ed..e6ad154fa 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -3039,15 +3039,6 @@ public static void makePhysNetNamesConsistent(Design design) { } if (parentPhysNet != null) { - // Merge both physical nets together - for (SiteInst si : new ArrayList<>(net.getSiteInsts())) { - List siteWires = new ArrayList<>(si.getSiteWiresFromNet(net)); - for (String siteWire : siteWires) { - BELPin[] pins = si.getSiteWirePins(siteWire); - si.unrouteIntraSiteNet(pins[0], pins[0]); - si.routeIntraSiteNet(parentPhysNet, pins[0], pins[0]); - } - } design.movePinsToNewNetDeleteOldNet(net, parentPhysNet, true); } } @@ -3065,38 +3056,30 @@ public static void createCeClkOfRoutethruFFToVCC(Design design) { for (SiteInst si : design.getSiteInsts()) { if (!Utils.isSLICE(si)) continue; for (BEL bel : si.getBELs()) { - if (si.getCell(bel) != null) continue; - BELPin q = bel.getPin("Q"); - if (q != null) { - Net netQ = si.getNetFromSiteWire(q.getSiteWireName()); - if (netQ == null) continue; - BELPin dPin = bel.getPin("D"); - if (dPin != null) { - Net netD = si.getNetFromSiteWire(dPin.getSiteWireName()); - if (netQ == netD) { - //System.out.println(si.getSiteName() + "/" + bel + ": " + netQ); - // Need VCC at CE - BELPin ceInput = bel.getPin("CE"); - String ceInputSitePinName = ceInput.getConnectedSitePinName(); - SitePinInst ceSitePin = si.getSitePinInst(ceInputSitePinName); - if (ceSitePin == null) { - ceSitePin = vcc.createPin(ceInputSitePinName, si); - } - si.routeIntraSiteNet(vcc, ceSitePin.getBELPin(), ceInput); - // ...and GND at CLK - BELPin clkInput = bel.getPin("CLK"); - BELPin clkInvOut = clkInput.getSourcePin(); - si.routeIntraSiteNet(gnd, clkInvOut, clkInput); - BELPin clkInvIn = clkInvOut.getBEL().getPin(0); - String clkInputSitePinName = clkInvIn.getConnectedSitePinName(); - SitePinInst clkInputSitePin = si.getSitePinInst(clkInputSitePinName); - if (clkInputSitePin == null) { - clkInputSitePin = vcc.createPin(clkInputSitePinName, si); - } - si.routeIntraSiteNet(vcc, clkInputSitePin.getBELPin(), clkInvIn); - } - } + Cell cell = si.getCell(bel); + if (cell == null || !cell.isFFRoutethruCell()) { + continue; } + + // Need VCC at CE + BELPin ceInput = bel.getPin("CE"); + String ceInputSitePinName = ceInput.getConnectedSitePinName(); + SitePinInst ceSitePin = si.getSitePinInst(ceInputSitePinName); + if (ceSitePin == null) { + ceSitePin = vcc.createPin(ceInputSitePinName, si); + } + si.routeIntraSiteNet(vcc, ceSitePin.getBELPin(), ceInput); + // ...and GND at CLK + BELPin clkInput = bel.getPin("CLK"); + BELPin clkInvOut = clkInput.getSourcePin(); + si.routeIntraSiteNet(gnd, clkInvOut, clkInput); + BELPin clkInvIn = clkInvOut.getBEL().getPin(0); + String clkInputSitePinName = clkInvIn.getConnectedSitePinName(); + SitePinInst clkInputSitePin = si.getSitePinInst(clkInputSitePinName); + if (clkInputSitePin == null) { + clkInputSitePin = vcc.createPin(clkInputSitePinName, si); + } + si.routeIntraSiteNet(vcc, clkInputSitePin.getBELPin(), clkInvIn); } } } diff --git a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java index 76ba7a76c..d36b597d6 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/PhysNetlistWriter.java @@ -136,7 +136,11 @@ public static void writePlacement(PhysNetlist.Builder physNetlist, Design design if (!cell.isPlaced()) continue; String cellName = cell.getName(); if (cellName.equals(PhysNetlistWriter.LOCKED)) continue; - if (!design.getCell(cellName).getBELName().equals(cell.getBELName())) { + Cell multiCell = design.getCell(cellName); + if (multiCell == null) { + assert(cell.isFFRoutethruCell()); + } + else if (!multiCell.getBELName().equals(cell.getBELName())) { multiBelCells.computeIfAbsent(cellName, (k) -> new ArrayList<>()) .add(cell); // Don't add multi-bel cells, store relevant info in pin placements diff --git a/test/src/com/xilinx/rapidwright/design/TestCell.java b/test/src/com/xilinx/rapidwright/design/TestCell.java index 773961271..4fdba7031 100644 --- a/test/src/com/xilinx/rapidwright/design/TestCell.java +++ b/test/src/com/xilinx/rapidwright/design/TestCell.java @@ -25,6 +25,9 @@ import com.xilinx.rapidwright.device.Device; +import com.xilinx.rapidwright.support.RapidWrightDCP; +import com.xilinx.rapidwright.util.FileTools; +import com.xilinx.rapidwright.util.VivadoTools; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -35,10 +38,17 @@ public class TestCell { @ParameterizedTest @CsvSource({ + // Input pins (many site pin options for single logical pin) "xcvu3p,SLICE_X0Y0,CARRY8,S[4],S4,'[E1, E2, E3, E4, E5, E6]'", // SLICEL "xcvu3p,SLICE_X0Y0,CARRY8,DI[2],DI2,'[C1, C2, C3, C4, C5]'", "xcvu3p,SLICE_X1Y0,CARRY8,S[7],S7,'[H1, H2, H3, H4, H5, H6]'", // SLICEM "xcvu3p,SLICE_X1Y0,CARRY8,DI[3],DI3,'[D1, D2, D3, D4, D5]'", + + // Output pins (single logical pin has options to drive many site pins) + "xcvu3p,SLICE_X0Y0,E6LUT,O,O6,'[E_O, EMUX]'", + "xcvu3p,SLICE_X0Y0,CARRY8,O[7],O7,'[HMUX]'", + "xcvu3p,SLICE_X0Y0,CARRY8,CO[7],CO7,'[COUT, HMUX]'", + "xcvu3p,SLICE_X1Y0,A5LUT,O,O5,'[AMUX]'", }) public void testGetAllCorrespondingSitePinNames(String deviceName, String siteName, @@ -81,4 +91,22 @@ public void testGetPropertyNoEDIFCellInst() { Assertions.assertNull(cell.getEDIFCellInst()); Assertions.assertNull(cell.getProperty("any_property")); } + + @Test + public void testFFRoutethruCell() { + Design d = RapidWrightDCP.loadDCP("optical-flow.dcp"); + SiteInst si = d.getSiteInstFromSiteName("SLICE_X72Y144"); + Cell rtCell = si.getCell("CFF"); + Assertions.assertNotNull(rtCell); + Assertions.assertTrue(rtCell.isRoutethru()); + Assertions.assertTrue(rtCell.isFFRoutethruCell()); + Assertions.assertEquals("D", rtCell.getLogicalPinMapping("D")); + Assertions.assertEquals("Q", rtCell.getLogicalPinMapping("Q")); + + Assertions.assertNull(d.getCell(rtCell.getName())); + + if (FileTools.isVivadoOnPath()) { + Assertions.assertEquals(0, VivadoTools.reportRouteStatus(d).netsWithRoutingErrors); + } + } } diff --git a/test/src/com/xilinx/rapidwright/design/TestDesign.java b/test/src/com/xilinx/rapidwright/design/TestDesign.java index 7f3f81ebf..449d8ccae 100644 --- a/test/src/com/xilinx/rapidwright/design/TestDesign.java +++ b/test/src/com/xilinx/rapidwright/design/TestDesign.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.HashSet; +import com.xilinx.rapidwright.device.Series; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; @@ -325,4 +326,62 @@ public void testFindDualOutputSitePins() { Assertions.assertNotNull(net.getAlternateSource()); } } + + @Test + public void testMovePinsToNewNetDeleteOldNet() { + Design d = new Design("testMovePinsToNewNetDeleteOldNet", "xcvu3p"); + SiteInst si = d.createSiteInst(d.getDevice().getSite("SLICE_X32Y73")); + Unisim unisim = Unisim.CARRY8; + d.createAndPlaceCell("carry", unisim, si.getSiteName() + "/" + unisim); + + Net oldNet = d.createNet("oldNet"); + oldNet.createPin("A1", si); + oldNet.createPin("HQ", si); + Assertions.assertTrue(si.routeIntraSiteNet(oldNet, si.getBELPin("A1", "A1"), + si.getBELPin(unisim.toString(), "DI0"))); + Assertions.assertEquals("[IN SLICE_X32Y73.A1, OUT SLICE_X32Y73.HQ]", oldNet.getPins().toString()); + Assertions.assertEquals("[A1, HQ, A5LUT_O5]", si.getSiteWiresFromNet(oldNet).toString()); + + Net newNet = d.createNet("newNet"); + SitePinInst h6 = newNet.createPin("H6", si); + newNet.addPIP(h6.getConnectedNode().getAllUphillPIPs().get(0)); + Assertions.assertEquals("[IN SLICE_X32Y73.H6]", newNet.getPins().toString()); + Assertions.assertEquals("[H6]", si.getSiteWiresFromNet(newNet).toString()); + Assertions.assertEquals("[INT_X21Y73/INT.VCC_WIRE->>IMUX_E47]", newNet.getPIPs().toString()); + + d.movePinsToNewNetDeleteOldNet(oldNet, newNet, true); + + Assertions.assertNull(d.getNet(oldNet.getName())); + Assertions.assertSame(newNet, d.getNet(newNet.getName())); + Assertions.assertEquals("[IN SLICE_X32Y73.H6, IN SLICE_X32Y73.A1, OUT SLICE_X32Y73.HQ]", newNet.getPins().toString()); + Assertions.assertEquals("[H6, A1, HQ, A5LUT_O5]", si.getSiteWiresFromNet(newNet).toString()); + Assertions.assertEquals("[INT_X21Y73/INT.VCC_WIRE->>IMUX_E47]", newNet.getPIPs().toString()); + } + + @Test + public void testMovePinsToNewNetDeleteOldNetIntraSiteOnly() { + Design d = new Design("testMovePinsToNewNetDeleteOldNetIntraSiteOnly", "xcvu3p"); + SiteInst si = d.createSiteInst(d.getDevice().getSite("SLICE_X32Y73")); + + Net oldNet = d.createNet("oldNet"); + // Note that oldNet has no site pins or inter-site routing + Assertions.assertTrue(si.routeIntraSiteNet(oldNet, si.getBELPin("B6LUT", "O6"), + si.getBELPin("BFF", "D"))); + Assertions.assertEquals("[B_O, FFMUXB1_OUT1]", si.getSiteWiresFromNet(oldNet).toString()); + + Net newNet = d.createNet("newNet"); + SitePinInst h6 = newNet.createPin("H6", si); + newNet.addPIP(h6.getConnectedNode().getAllUphillPIPs().get(0)); + Assertions.assertEquals("[IN SLICE_X32Y73.H6]", newNet.getPins().toString()); + Assertions.assertEquals("[H6]", si.getSiteWiresFromNet(newNet).toString()); + Assertions.assertEquals("[INT_X21Y73/INT.VCC_WIRE->>IMUX_E47]", newNet.getPIPs().toString()); + + d.movePinsToNewNetDeleteOldNet(oldNet, newNet, false); + + Assertions.assertNull(d.getNet(oldNet.getName())); + Assertions.assertSame(newNet, d.getNet(newNet.getName())); + Assertions.assertEquals("[IN SLICE_X32Y73.H6]", newNet.getPins().toString()); + Assertions.assertEquals("[H6, B_O, FFMUXB1_OUT1]", si.getSiteWiresFromNet(newNet).toString()); + Assertions.assertTrue(newNet.getPIPs().isEmpty()); + } } diff --git a/test/src/com/xilinx/rapidwright/device/TestBEL.java b/test/src/com/xilinx/rapidwright/device/TestBEL.java index de8e97a95..99ed65ed8 100644 --- a/test/src/com/xilinx/rapidwright/device/TestBEL.java +++ b/test/src/com/xilinx/rapidwright/device/TestBEL.java @@ -24,6 +24,7 @@ package com.xilinx.rapidwright.device; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -59,4 +60,14 @@ public void testIsFF(String deviceName, String siteName) { } } } + + @Test + public void testIsSliceFFClkMod() { + Device d = Device.getDevice("xcvc1902"); + Site s = d.getSite("SLICE_X290Y265"); + BEL b = s.getBEL("FF_CLK_MOD"); + Assertions.assertNotNull(b); + Assertions.assertTrue(b.isSliceFFClkMod()); + Assertions.assertFalse(b.isFF()); + } }