From f803bdc8749c085c95ad939309119e04bd37152b Mon Sep 17 00:00:00 2001 From: eddieh-xlnx Date: Mon, 9 Dec 2024 11:05:04 -0800 Subject: [PATCH] RWRoute preprocessing fixes (#1119) * Create MMCM.CLKFBIN and .CLKIN2 SPIs on VCC if no SPI exists DesignTools.createMissingSitePinInsts() does not do this since sitewires are not always painted with VCC Signed-off-by: Eddie Hung * [RouterHelper] Emulate Vivado's behaviour to not invert BRAM.CLK* on Versal too Signed-off-by: Eddie Hung * Revert "[RouterHelper] Emulate Vivado's behaviour to not invert BRAM.CLK* on Versal too" This reverts commit e78a38623e90ba6079c2a91a4126a315927013f5. Signed-off-by: Eddie Hung * [RouterHelper] Unroute intra-site net when inverting (and do not reroute) Signed-off-by: Eddie Hung * Paint/unpaint on add since diff between LUTs and other pins Signed-off-by: Eddie Hung * [DesignTools] createA1A6ToStaticNets() to ignore existing SPIs for SRL16E Signed-off-by: Eddie Hung * More stringent assert Signed-off-by: Eddie Hung * Fix tests caused by createA1A6ToStaticNets() Signed-off-by: Eddie Hung * Relax assertion Signed-off-by: Eddie Hung * Relax assertion further Signed-off-by: Eddie Hung --------- Signed-off-by: Eddie Hung --- .../rapidwright/design/DesignTools.java | 128 ++++++++++-------- .../rwroute/GlobalSignalRouting.java | 4 +- .../rapidwright/rwroute/RouterHelper.java | 14 +- 3 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index cb1954231..382c16eda 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -3312,8 +3312,8 @@ public static void createA1A6ToStaticNets(Design design) { BEL lut6Bel = (fiveOrSix == '5') ? si.getBEL(belName.charAt(0) + "6LUT") : bel; Net a6Net = si.getNetFromSiteWire(lut6Bel.getPin("A6").getSiteWireName()); - boolean expectGndNet = false; if ("SRL16E".equals(cell.getType())) { + // SRL16s require A1 to be VCC String pinName = belName.charAt(0) + "1"; SitePinInst spi = si.getSitePinInst(pinName); if (spi == null) { @@ -3322,18 +3322,25 @@ public static void createA1A6ToStaticNets(Design design) { // SRL16Es that have been transformed from SRLC32E require GND on their A6 pin if ("SRLC32E".equals(cell.getPropertyValueString("XILINX_LEGACY_PRIM"))) { - expectGndNet = true; staticNet = gndNet; // Expect sitewire to be VCC or GND if (!a6Net.isStaticNet()) { throw new RuntimeException("ERROR: Site pin " + si.getSiteName() + "/" + belName.charAt(0) + "6 is not a static net"); } } - } - // Tie A6 to staticNet only if sitewire says so - if (a6Net != staticNet && !expectGndNet) { - continue; + spi = si.getSitePinInst(belName.charAt(0) + "6"); + if (spi != null) { + // [A-H]6 input already a static net (which may not match the sitewire) + assert(spi.getNet().isStaticNet()); + assert(a6Net.isStaticNet()); + continue; + } + } else { + // Tie A6 to staticNet only if sitewire says so + if (a6Net != staticNet) { + continue; + } } if (cell.getLogicalPinMapping("O5") != null) { @@ -3385,74 +3392,77 @@ public static void createCeSrRstPinsToVCC(Design design) { // In Versal, sitewires for a SLICE's CE pins are not assigned to the VCC net // Assume that the lack of sitewire for a placed FF indicates VCC for (SiteInst si : design.getSiteInsts()) { - if (!Utils.isSLICE(si)) { - continue; - } - for (Cell cell : si.getCells()) { - BEL bel = cell.getBEL(); - if (bel == null || !bel.isFF()) { - continue; - } - - if (!bel.getBELType().equals("FF")) { - assert(bel.getBELType().matches("(SLICE_IMI|SLICE[LM]_IMC)_FF(_T)?")); - continue; - } + if (Utils.isSLICE(si)) { + for (Cell cell : si.getCells()) { + BEL bel = cell.getBEL(); + if (bel == null || !bel.isFF()) { + continue; + } - Pair sitePinNames = pinMapping.get(bel.getName()); - for (String belPinName : belPinNames) { - String sitePinName = (belPinName == CE) ? sitePinNames.getFirst() : sitePinNames.getSecond(); - SitePinInst spi = si.getSitePinInst(sitePinName); - if (spi != null) { - if (belPinName == CE) { - // CE - continue; - } - // SR - if (!spi.getNet().isGNDNet()) { - continue; - } + if (!bel.getBELType().equals("FF")) { + assert(bel.getBELType().matches("(SLICE_IMI|SLICE[LM]_IMC)_FF(_T)?")); + continue; } - Net net = si.getNetFromSiteWire(sitePinName); - if (net != null) { - if (belPinName == CE) { - if (!net.isVCCNet()) { + Pair sitePinNames = pinMapping.get(bel.getName()); + for (String belPinName : belPinNames) { + String sitePinName = (belPinName == CE) ? sitePinNames.getFirst() : sitePinNames.getSecond(); + SitePinInst spi = si.getSitePinInst(sitePinName); + if (spi != null) { + if (belPinName == CE) { + // CE continue; } - // CE: it is possible for sitewire to be assigned to a non VCC net, but a SitePinInst to not yet exist - } else { - assert(belPinName == SR); - if (!net.isStaticNet()) { + // SR + if (!spi.getNet().isGNDNet()) { continue; } - // SR: it is possible for sitewire to be assigned the GND net, yet still be routed to VCC } - } - if (assertionsEnabled) { - BELPin belPin = bel.getPin(belPinName); - Net belPinNet = si.getNetFromSiteWire(belPin.getSiteWireName()); - if (belPinNet != null) { + Net net = si.getNetFromSiteWire(sitePinName); + if (net != null) { if (belPinName == CE) { - // CE - assert(belPinNet.isVCCNet()); + if (!net.isVCCNet()) { + continue; + } + // CE: it is possible for sitewire to be assigned to a non VCC net, but a SitePinInst to not yet exist } else { - // SR - assert(belPinNet.isStaticNet()); + assert(belPinName == SR); + if (!net.isStaticNet()) { + continue; + } + // SR: it is possible for sitewire to be assigned the GND net, yet still be routed to VCC } } - } - if (spi != null) { - assert(belPinName == SR); - // Move the SR pin from GND to VCC - spi.setNet(vccNet); - } else { - spi = new SitePinInst(false, sitePinName, si); + if (assertionsEnabled) { + BELPin belPin = bel.getPin(belPinName); + Net belPinNet = si.getNetFromSiteWire(belPin.getSiteWireName()); + if (belPinNet != null) { + if (belPinName == CE) { + // CE + assert(belPinNet.isVCCNet()); + } else { + // SR + assert(belPinNet.isStaticNet()); + } + } + } + + if (spi != null) { + assert(belPinName == SR); + // Move the SR pin from GND to VCC + spi.setNet(vccNet); + } else { + spi = new SitePinInst(false, sitePinName, si); + } + boolean updateSiteRouting = false; + vccNet.addPin(spi, updateSiteRouting); } - boolean updateSiteRouting = false; - vccNet.addPin(spi, updateSiteRouting); + } + } else if (si.getSiteTypeEnum() == SiteTypeEnum.MMCM) { + for (String sitePinName : new String[]{"CLKFBIN", "CLKIN2"}) { + maybeCreateVccPin(si, sitePinName, vccNet); } } } diff --git a/src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java b/src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java index 81df02ba7..3ee91a7bb 100644 --- a/src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java +++ b/src/com/xilinx/rapidwright/rwroute/GlobalSignalRouting.java @@ -427,7 +427,9 @@ public static void routeStaticNet(List pins, assertIntentCodeOfPoppedNodesOnVcc = EnumSet.of( IntentCode.NODE_PINFEED, IntentCode.NODE_PINBOUNCE, - IntentCode.INTENT_DEFAULT); + IntentCode.INTENT_DEFAULT, + IntentCode.NODE_GLOBAL_GCLK // e.g. MMCM_CLKIN2, MMCM_CLKFBIN + ); boolean isVersal = false; if (series == Series.UltraScale) { // On UltraScale, certain site pins (e.g. SLICE/CKEN_B1[1-4], SLICE/SRST_B[12]) diff --git a/src/com/xilinx/rapidwright/rwroute/RouterHelper.java b/src/com/xilinx/rapidwright/rwroute/RouterHelper.java index dcdafc4c6..65e237349 100644 --- a/src/com/xilinx/rapidwright/rwroute/RouterHelper.java +++ b/src/com/xilinx/rapidwright/rwroute/RouterHelper.java @@ -348,7 +348,8 @@ public static Set invertPossibleGndPinsToVccPins(Design design, List pins, boolean invertLutInputs) { final boolean isVersal = (design.getSeries() == Series.Versal); - Net gndNet = design.getGndNet(); + final Net gndNet = design.getGndNet(); + final Net vccNet = design.getVccNet(); Set toInvertPins = new HashSet<>(); nextSitePin: for (SitePinInst spi : pins) { if (!spi.getNet().equals(gndNet)) @@ -408,6 +409,9 @@ public static Set invertPossibleGndPinsToVccPins(Design design, } toInvertPins.add(spi); + // Re-paint the intra-site routing from GND to VCC + // (no intra site routing will occur during Net.addPin() later) + si.routeIntraSiteNet(vccNet, spi.getBELPin(), spiBelPin); for (Cell cell : connectedCells) { // Find the logical pin name @@ -449,6 +453,8 @@ public static Set invertPossibleGndPinsToVccPins(Design design, continue; } toInvertPins.add(spi); + // Unpaint the sitewire ahead of pin being added below + si.unrouteIntraSiteNet(spi.getBELPin(), spi.getBELPin()); } } } @@ -460,10 +466,10 @@ public static Set invertPossibleGndPinsToVccPins(Design design, // as we are simply moving the SPI from one net to another gndNet.getPins().removeAll(toInvertPins); - Net vccNet = design.getVccNet(); - for (SitePinInst toinvert:toInvertPins) { + for (SitePinInst toinvert : toInvertPins) { assert(toinvert.getSiteInst() != null); - if (!vccNet.addPin(toinvert)) { + boolean updateSiteRouting = false; + if (!vccNet.addPin(toinvert, updateSiteRouting)) { throw new RuntimeException("ERROR: Couldn't invert site pin " + toinvert); }