diff --git a/interchange/fpga-interchange-schema b/interchange/fpga-interchange-schema index c985b4648..31e39fa20 160000 --- a/interchange/fpga-interchange-schema +++ b/interchange/fpga-interchange-schema @@ -1 +1 @@ -Subproject commit c985b4648e66414b250261c1ba4cbe45a2971b1c +Subproject commit 31e39fa20964143ba14bdd24b11916af97cf4461 diff --git a/src/com/xilinx/rapidwright/design/DesignTools.java b/src/com/xilinx/rapidwright/design/DesignTools.java index 10a053c61..eb528c15f 100644 --- a/src/com/xilinx/rapidwright/design/DesignTools.java +++ b/src/com/xilinx/rapidwright/design/DesignTools.java @@ -3333,7 +3333,7 @@ public static void createMissingStaticSitePins(BELPin belPin, SiteInst si, Cell //NOTE: SRL16E (reference name SRL16E, EDIFCell in RW) uses A2-A5, so we need to connect A1 & A6 to VCC, //however, when SitePinInsts (e.g. A3) are already in GND, adding those again will cause problems to A1 static String[] lut6BELPins = new String[] {"A1", "A6"}; - static HashSet unisimFlipFlopTypes; + public static HashSet unisimFlipFlopTypes; static { unisimFlipFlopTypes = new HashSet<>(); unisimFlipFlopTypes.add("FDSE");//S CE, logical cell diff --git a/src/com/xilinx/rapidwright/design/shapes/Shape.java b/src/com/xilinx/rapidwright/design/shapes/Shape.java new file mode 100644 index 000000000..23feaefa3 --- /dev/null +++ b/src/com/xilinx/rapidwright/design/shapes/Shape.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2024, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Chris Lavin, AMD Research and Advanced Development + * + * 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.design.shapes; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.xilinx.rapidwright.design.Cell; +import com.xilinx.rapidwright.design.Design; +import com.xilinx.rapidwright.device.BEL; +import com.xilinx.rapidwright.device.Device; +import com.xilinx.rapidwright.device.Site; +import com.xilinx.rapidwright.device.SiteTypeEnum; + +/** + * A set of cells that are intended to be placed together as a structured unit. + */ +public class Shape { + + private Map map; + + private Set tags; + + private int width; + + private int height; + + private Shape nextChain; + + public Shape() { + map = new LinkedHashMap<>(); + tags = new HashSet<>(); + width = 1; + height = 1; + } + + public Set getCells() { + return map.keySet(); + } + + public Map getCellMap() { + return map; + } + + protected void setCellMap(Map map) { + this.map = map; + } + + /** + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * @param width the width to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * @param height the height to set + */ + public void setHeight(int height) { + this.height = height; + } + + public Cell addCell(String name, Design design, int dx, int dy, String belName, String cellType) { + Cell cell = design.getCell(name); + if (cell == null) { + cell = new Cell(name); + cell.setType(cellType); + design.addCell(cell); + cell.setEDIFHierCellInst(design.getNetlist().getHierCellInstFromName(name)); + assert (cellType.equals(cell.getEDIFHierCellInst().getCellName())); + } else if (cell.getEDIFHierCellInst() == null) { + cell.setEDIFHierCellInst(design.getNetlist().getHierCellInstFromName(name)); + } + + Map> placements = cell.getCompatiblePlacements(); + + List compatibleSiteTypes = new ArrayList<>(); + for (Entry> e : placements.entrySet()) { + if (e.getValue().contains(belName)) { + compatibleSiteTypes.add(e.getKey()); + } + } + + ShapeLocation loc = new ShapeLocation(compatibleSiteTypes, belName, dx, dy); + map.put(cell, loc); + return cell; + } + + public Set getTags() { + return tags; + } + + public void setTags(Set tags) { + this.tags = tags; + } + + public boolean addTag(ShapeTag tag) { + return tags.add(tag); + } + + public boolean hasTag(ShapeTag tag) { + return tags.contains(tag); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + for (Entry e : map.entrySet()) { + sb.append("(" + e.getValue().getCompatibleSiteTypes() + "_X" + e.getValue().getDx() + "Y" + + e.getValue().getDy() + ", " + e.getValue().getBelName() + ")\t" + e.getKey().getName() + " (" + + e.getKey().getType() + ")\n"); + } + sb.append("Tags(s): " + getTags() + "\n"); + sb.append("WxH: " + getWidth() + "x" + getHeight() + "\n"); + return sb.toString(); + } + + protected Shape getNextChain() { + return nextChain; + } + + protected void setNextChain(Shape nextChain) { + this.nextChain = nextChain; + } + + /** + * Gets the highest/largest LUT letter name from the BEL names used in all the + * cells. Examines both 6LUT and 5LUT locations. + * + * @return The highest LUT letter used in the shape. + */ + public char getLargestLUTLetter() { + char c = Character.MIN_VALUE; + for (ShapeLocation loc : map.values()) { + String belName = loc.getBelName(); + if (belName.contains("LUT")) { + char lutLetter = belName.charAt(0); + if (c < lutLetter) { + c = lutLetter; + } + } + } + return c; + } +} diff --git a/src/com/xilinx/rapidwright/design/shapes/ShapeLocation.java b/src/com/xilinx/rapidwright/design/shapes/ShapeLocation.java new file mode 100644 index 000000000..c59fcff8d --- /dev/null +++ b/src/com/xilinx/rapidwright/design/shapes/ShapeLocation.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Chris Lavin, AMD Research and Advanced Development + * + * 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.design.shapes; + +import java.util.List; + +import com.xilinx.rapidwright.device.SiteTypeEnum; + +/** + * Set of attributes applied to a cell that is part of a shape. + */ +public class ShapeLocation { + + private List compatibleSiteTypes; + + private String belName; + + private int dx; + + private int dy; + + public ShapeLocation(List siteTypes, String belName, int dx, int dy) { + this.compatibleSiteTypes = siteTypes; + this.belName = belName; + this.dx = dx; + this.dy = dy; + } + + /** + * @return the compatibleSiteTypes + */ + public List getCompatibleSiteTypes() { + return compatibleSiteTypes; + } + + /** + * @return the belName + */ + public String getBelName() { + return belName; + } + + public void setBelName(String belName) { + this.belName = belName; + } + + /** + * @return the dx + */ + public int getDx() { + return dx; + } + + /** + * @return the dy + */ + public int getDy() { + return dy; + } + + public void setDx(int dx) { + this.dx = dx; + } + + public void setDy(int dy) { + this.dy = dy; + } + +} diff --git a/src/com/xilinx/rapidwright/design/shapes/ShapeTag.java b/src/com/xilinx/rapidwright/design/shapes/ShapeTag.java new file mode 100644 index 000000000..86ff4a055 --- /dev/null +++ b/src/com/xilinx/rapidwright/design/shapes/ShapeTag.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Chris Lavin, AMD Research and Advanced Development + * + * 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.design.shapes; + +import java.util.HashMap; +import java.util.Map; + +public enum ShapeTag { + + CLUSTER("Cluster"), + LUTNM("LUTNM"), + CARRY_CHAIN("Carry-chain"), + MUXF7("MuxF7"), + MUXF8("MuxF8"), + MUXF9("MuxF9"), + SRL("SRL"), + RAM32M16("RAM32M16"); + + private String name; + + public static Map values; + + static { + values = new HashMap<>(); + for (ShapeTag tag : values()) { + values.put(tag.name, tag); + values.put(tag.name(), tag); + } + } + + private ShapeTag(String name) { + this.name = name; + } + + public String toString() { + return name; + } + +} diff --git a/src/com/xilinx/rapidwright/design/shapes/ShapeTools.java b/src/com/xilinx/rapidwright/design/shapes/ShapeTools.java new file mode 100644 index 000000000..07ac7b287 --- /dev/null +++ b/src/com/xilinx/rapidwright/design/shapes/ShapeTools.java @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2024, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Chris Lavin, AMD Research and Advanced Development + * + * 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.design.shapes; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.Set; + +import com.xilinx.rapidwright.design.Cell; +import com.xilinx.rapidwright.design.ConstraintGroup; +import com.xilinx.rapidwright.design.Design; +import com.xilinx.rapidwright.design.DesignTools; +import com.xilinx.rapidwright.design.Net; +import com.xilinx.rapidwright.design.Unisim; +import com.xilinx.rapidwright.edif.EDIFCellInst; +import com.xilinx.rapidwright.edif.EDIFHierCellInst; +import com.xilinx.rapidwright.edif.EDIFHierNet; +import com.xilinx.rapidwright.edif.EDIFHierPortInst; +import com.xilinx.rapidwright.edif.EDIFLibrary; +import com.xilinx.rapidwright.edif.EDIFNet; +import com.xilinx.rapidwright.edif.EDIFNetlist; +import com.xilinx.rapidwright.edif.EDIFPortInst; +import com.xilinx.rapidwright.interchange.Interchange; +import com.xilinx.rapidwright.placer.dreamplacefpga.DREAMPlaceFPGA; +import com.xilinx.rapidwright.rwroute.RWRoute; +import com.xilinx.rapidwright.tests.CodePerfTracker; +import com.xilinx.rapidwright.util.FileTools; +import com.xilinx.rapidwright.util.MessageGenerator; +import com.xilinx.rapidwright.util.VivadoTools; + +/** + * Collection of APIs to handle netlist shapes to be used for placement. + */ +public class ShapeTools { + + private static final boolean SOURCE_SHAPES_FROM_FILE = false; + + private static Set chainPrims; + + private static Map carryPinMap; + + private static String[] writeAddressPinNames; + + static { + chainPrims = new HashSet<>(); + chainPrims.add(Unisim.CARRY4.name()); + chainPrims.add(Unisim.CARRY8.name()); + chainPrims.add(Unisim.LOOKAHEAD8.name()); + chainPrims.add(Unisim.DSP48.name()); + chainPrims.add(Unisim.DSP48A.name()); + chainPrims.add(Unisim.DSP48A1.name()); + chainPrims.add(Unisim.DSP48E.name()); + chainPrims.add(Unisim.DSP48E1.name()); + chainPrims.add(Unisim.DSP48E2.name()); + chainPrims.add(Unisim.DSP48E5.name()); + chainPrims.add(Unisim.DSP58.name()); + chainPrims.add(Unisim.DSP58C.name()); + + chainPrims.add(Unisim.RAMB18.name()); + chainPrims.add(Unisim.RAMB18E1.name()); + chainPrims.add(Unisim.RAMB18E2.name()); + chainPrims.add(Unisim.RAMB18E5.name()); + + carryPinMap = new HashMap<>(); + for (int i = 0; i < 8; i++) { + char letter = (char) ('A' + i); + carryPinMap.put("S[" + i + "]", letter + "6LUT"); + carryPinMap.put("DI[" + i + "]", letter + "5LUT"); + carryPinMap.put("O[" + i + "]", letter + "FF"); + carryPinMap.put("CO[" + i + "]", letter + "FF2"); + } + + writeAddressPinNames = new String[9]; + for (int i = 1; i <= 9; i++) { + writeAddressPinNames[i - 1] = "WA" + i; + } + } + + public static Collection getShapesFromFile(Design design, Path optionalShapeFile) { + Path shapeFile = null; + if (optionalShapeFile == null || !Files.exists(optionalShapeFile)) { + // Generate shapes file + final Path workdir = FileSystems.getDefault() + .getPath("vivadoToolsWorkdir" + FileTools.getUniqueProcessAndHostID()); + File workdirHandle = new File(workdir.toString()); + workdirHandle.mkdirs(); + + Path outputLog = workdir.resolve("outputLog.log"); + Path tcl = workdir.resolve("run.tcl"); + Path dcp = workdir.resolve("design.dcp"); + shapeFile = workdir.resolve("shapes.txt"); + + design.writeCheckpoint(dcp); + design.getNetlist().expandMacroUnisims(design.getDevice().getSeries()); + + List cmds = new ArrayList<>(); + cmds.add("open_checkpoint " + dcp); + cmds.add("set_param place.debugShape " + shapeFile); + cmds.add("place_design -directive Quick"); + FileTools.writeLinesToTextFile(cmds, tcl.toString()); + VivadoTools.runTcl(outputLog, "source " + tcl, true); + } else { + shapeFile = optionalShapeFile; + } + + List shapes = readDebugShapeFile(design, shapeFile); + sortShapesByBELName(shapes); + design.getNetlist().setShapes(shapes); + return shapes; + + } + + public static Collection extractShapes(Design design, Path optionalShapeFile) { + EDIFNetlist netlist = design.getNetlist(); + + if (SOURCE_SHAPES_FROM_FILE) { + // For now, we'll get the shapes from a shapes file + return getShapesFromFile(design, optionalShapeFile); + } + + List shapes = new ArrayList<>(); + Map cellShapeMap = new HashMap<>(); + + // Identify shape anchors + EDIFLibrary macros = Design.getMacroPrimitives(design.getDevice().getSeries()); + Set macroInsts = new HashSet<>(); + Set chainInsts = new HashSet<>(); + Map muxF9s = new HashMap<>(); + Map muxF8s = new HashMap<>(); + Map muxF7s = new HashMap<>(); + for (EDIFHierCellInst inst : design.getNetlist().getAllLeafHierCellInstances()) { + String instName = inst.getCellName(); + if (chainPrims.contains(instName)) { + chainInsts.add(inst); + } else if (instName.equals("MUXF9")) { + muxF9s.put(inst.getFullHierarchicalInstName(), inst); + } else if (instName.equals("MUXF8")) { + muxF8s.put(inst.getFullHierarchicalInstName(), inst); + } else if (instName.equals("MUXF7")) { + muxF7s.put(inst.getFullHierarchicalInstName(), inst); + } else { + EDIFHierCellInst parent = inst.getParent(); + if (macros.containsCell(parent.getCellName())) { + macroInsts.add(parent); + } + } + } + + for (EDIFHierCellInst i : macroInsts) { + Shape shape = createShapeFromMacro(design, i); + for (Cell cell : shape.getCells()) { + Shape prev = cellShapeMap.put(cell.getName(), shape); + if (prev != null) { + throw new RuntimeException("Unexpected overlap"); + } + } + shapes.add(shape); + } + + List chainStarts = new ArrayList<>(); + Map> physicalNetPinMap = netlist.getPhysicalNetPinMap(); + for (EDIFHierCellInst i : chainInsts) { + Unisim type = Unisim.valueOf(i.getCellName()); + Shape shape = new Shape(); + shapes.add(shape); + switch (type) { + case CARRY8: + Cell cell = shape.addCell(i.toString(), design, 0, 0, "CARRY8", type.name()); + cellShapeMap.put(cell.getName(), shape); + Map connMap = new HashMap<>(); + EDIFHierPortInst chainConn = null; + boolean hasCin = false; + for (EDIFPortInst pi : i.getInst().getPortInsts()) { + EDIFNet net = pi.getNet(); + if (net != null) { + EDIFHierNet hierNet = netlist.getParentNet(new EDIFHierNet(i.getParent(), net)); + for (EDIFHierPortInst conn : physicalNetPinMap.get(hierNet)) { + if (conn.getPortInst().equals(pi)) + continue; + String connType = conn.getCellType().getName(); + String pinName = pi.getName(); + if (pinName.equals("CO[7]")) { + chainConn = i.getPortInst(pi.getName()); + continue; + } else if ((pinName.startsWith("DI") || pinName.startsWith("S")) + && !connType.contains("LUT")) { + continue; + } else if ((pinName.startsWith("O") || pinName.startsWith("CO")) + && !DesignTools.unisimFlipFlopTypes.contains(connType)) { + continue; + } else if (pinName.equals("CIN")) { + hasCin = true; + continue; + } + connMap.put(pi.getName(), conn); + } + } + } + if (!hasCin && chainConn != null) { + chainStarts.add(chainConn); + } + for (Entry e : connMap.entrySet()) { + EDIFHierPortInst conn = e.getValue(); + if (e.getKey().startsWith("DI")) { + // Check the corresponding S port to see if the source cell is + // placement-compatible + String sum = e.getKey().replace("DI", "S"); + EDIFHierPortInst sumConn = connMap.get(sum); + if (sumConn != null && !lutPlacementCompatible(sumConn, conn, cellShapeMap)) { + continue; + } + } + + String belName = carryPinMap.get(e.getKey()); + if (belName != null) { + int dx = 0; + int dy = 0; + if (belName.equals("HFF2") && conn.getCellType().getName().equals("CARRY8")) { + continue; + } + String cellName = conn.getFullHierarchicalInstName(); + Shape testCollision = cellShapeMap.get(cellName); + if (testCollision != null && testCollision.hasTag(ShapeTag.CARRY_CHAIN)) { + continue; + } + Cell c = shape.addCell(cellName, design, dx, dy, belName, conn.getCellType().getName()); + Shape overlap = cellShapeMap.put(c.getName(), shape); + if (overlap != null && overlap != shape) { + shapes.remove(overlap); + // re orient LUT6_2 cells related to the CARRY (A*LUT -> approprate LUT) + for (ShapeTag tag : overlap.getTags()) { + shape.addTag(tag); + } + for (Entry e2 : overlap.getCellMap().entrySet()) { + if (overlap.getTags().size() == 1 && overlap.getTags().contains(ShapeTag.LUTNM)) { + // This is a LUT6_2, we need to align it to where the CARRY expects it to be + assert (belName.endsWith("LUT")); + e2.getValue() + .setBelName(belName.charAt(0) + e2.getValue().getBelName().substring(1)); + } + shape.getCellMap().put(e2.getKey(), e2.getValue()); + cellShapeMap.put(e2.getKey().getName(), shape); + + } + } + } + } + shape.addTag(ShapeTag.CARRY_CHAIN); + break; + case RAMB18E2: + EDIFHierPortInst portInst = i.getPortInst("CASDIMUXA"); + if (portInst != null && portInst.getNet() != null) { + // TODO handle RAMB18E2 cascades + } + break; + default: + throw new RuntimeException("ERROR: Unhandled chain-type instance: " + type + ", instance " + i); + } + } + + // Combine chain shapes into single shape + for (EDIFHierPortInst cout : chainStarts) { + EDIFHierPortInst currCout = cout; + Shape currShape = cellShapeMap.get(cout.getFullHierarchicalInstName()); + int currDy = 0; + while (currCout != null) { + String currCoutName = currCout.toString(); + for (EDIFHierPortInst conn : physicalNetPinMap.get(currCout.getHierarchicalNet())) { + if (conn.toString().equals(currCoutName)) + continue; + currCout = conn.getHierarchicalInst().getChild(conn.getPortInst().getCellInst()) + .getPortInst("CO[7]"); + String nextCarry = conn.getFullHierarchicalInstName(); + Shape nextShape = cellShapeMap.get(nextCarry); + if (nextShape != null) { + currShape.getTags().addAll(nextShape.getTags()); + for (Entry e : nextShape.getCellMap().entrySet()) { + ShapeLocation loc = e.getValue(); + currDy++; + loc.setDy(currDy); + currShape.getCellMap().put(e.getKey(), loc); + cellShapeMap.put(e.getKey().getName(), currShape); + } + shapes.remove(nextShape); + currShape.setHeight(currShape.getHeight() + 1); + } + } + } + } + + List clusterShapes = shapes.stream().filter(s -> s.getTags().contains(ShapeTag.CLUSTER)) + .collect(Collectors.toList()); + Set merged = new HashSet<>(); + // Cluster LUTRAMs into single SLICEs when sharing address lines + nextShape: for (Shape shape : clusterShapes) { + if (merged.contains(shape)) continue; + Shape other = null; + for (Cell c : shape.getCells()) { + for (String waPin : writeAddressPinNames) { + String pin = c.getLogicalPinMapping(waPin); + if (pin == null) + continue; + EDIFHierPortInst portInst = c.getEDIFHierCellInst().getPortInst(pin); + if (portInst != null) { + EDIFHierNet net = portInst.getHierarchicalNet(); + if (net.getNet().isGND() || net.getNet().isVCC()) { + continue; + } + for (EDIFHierPortInst otherPort : net.getLeafHierPortInsts()) { + if (portInst.equals(otherPort) || otherPort.isOutput()) + continue; + Shape test = cellShapeMap.get(otherPort.getFullHierarchicalInstName()); + if (test == shape) + continue; + if (test != null && test.getTags().contains(ShapeTag.CLUSTER)) { + if (other != null) { + if (other != test) { + continue nextShape; + } + } + other = test; + } + } + } + } + } + if (other != null) { + // We should join these shapes into one + shape.getTags().addAll(other.getTags()); + char highestLUTLetter = shape.getLargestLUTLetter(); + int lutOffset = highestLUTLetter - ('A' - 1); + for (Entry e : other.getCellMap().entrySet()) { + ShapeLocation loc = e.getValue(); + String belName = loc.getBelName(); + assert (belName.contains("LUT")); + belName = ((char) (belName.charAt(0) + lutOffset)) + belName.substring(1); + loc.setBelName(belName); + shape.getCellMap().put(e.getKey(), loc); + cellShapeMap.put(e.getKey().getName(), shape); + } + shapes.remove(other); + merged.add(shape); + merged.add(other); + + // Look for any flip-flops attached to LUTRAM and merge into shape + for (Entry e : new HashMap<>(shape.getCellMap()).entrySet()) { + EDIFHierPortInst output = e.getKey().getEDIFHierCellInst().getPortInst("O"); + // If there is high fanout, let the placer choose + Collection pins = output.getHierarchicalNet().getLeafHierPortInsts(); + if (pins.size() < 3) { + for (EDIFHierPortInst pin : pins) { + if (pin.isOutput()) + continue; + if (DesignTools.unisimFlipFlopTypes.contains(pin.getCellType().getName())) { + String ffBELName = e.getValue().getBelName().replace("6LUT", "FF").replace("5LUT", + "FF2"); + shape.addCell(pin.getFullHierarchicalInstName(), design, e.getValue().getDx(), + e.getValue().getDy(), ffBELName, pin.getCellType().getName()); + } + } + } + } + } + } + + for (Entry e : muxF9s.entrySet()) { + Shape shape = new Shape(); + shape.addCell(e.getKey(), design, 0, 0, "F9MUX", "F9MUX"); + shape.addTag(ShapeTag.MUXF9); + for (int i = 0; i < 2; i++) { + EDIFHierPortInst f8Driver = e.getValue().getPortInstDriver("I" + Integer.toString(i)); + assert (f8Driver.getCellType().getName().equals("F8MUX")); + Cell muxF8 = shape.addCell(f8Driver.getFullHierarchicalInstName(), design, 0, 0, + i == 0 ? "F8MUX_TOP" : "F8MUX_BOT", "F8MUX"); + muxF8s.remove(muxF8.getName()); + buildMuxF8Shape(design, muxF8, shape, i == 0, muxF7s); + } + shapes.add(shape); + } + + for (Entry e : muxF8s.entrySet()) { + Shape shape = new Shape(); + Cell muxF8 = shape.addCell(e.getKey(), design, 0, 0, "F8MUX_BOT", "F8MUX"); + shape.addTag(ShapeTag.MUXF8); + buildMuxF8Shape(design, muxF8, shape, false, muxF7s); + shapes.add(shape); + } + + for (Entry e : muxF7s.entrySet()) { + Shape shape = new Shape(); + Cell muxF7 = shape.addCell(e.getKey(), design, 0, 0, "F7MUX_AB", "F7MUX"); + shape.addTag(ShapeTag.MUXF7); + buildMuxF7Shape(design, muxF7, shape, "F7MUX_AB"); + shapes.add(shape); + } + + sortShapesByBELName(shapes); + return shapes; + } + + private static void buildMuxF8Shape(Design design, Cell muxf8, Shape shape, boolean isTop, + Map muxf7s) { + + EDIFHierPortInst ffSink = checkAndGetSingleSinkFlop(muxf8); + if (ffSink != null) { + shape.addCell(ffSink.getFullHierarchicalInstName(), design, 0, 0, isTop ? "GFF" : "CFF", + ffSink.getCellType().getName()); + } + for (int j = 0; j < 2; j++) { + EDIFHierPortInst f7Driver = muxf8.getEDIFHierCellInst().getPortInstDriver("I" + Integer.toString(j)); + assert (f7Driver.getCellType().getName().equals("F7MUX")); + String belName = "F7MUX_" + (isTop ? (j == 0 ? "GH" : "EF") : (j == 0 ? "CD" : "AB")); + Cell muxf7 = shape.addCell(f7Driver.getFullHierarchicalInstName(), design, 0, 0, belName, "F7MUX"); + muxf7s.remove(muxf7.getName()); + buildMuxF7Shape(design, muxf7, shape, belName); + } + } + + private static void buildMuxF7Shape(Design design, Cell muxf7, Shape shape, String f7BELName) { + EDIFHierPortInst ffSink = checkAndGetSingleSinkFlop(muxf7); + if (ffSink != null) { + shape.addCell(ffSink.getFullHierarchicalInstName(), design, 0, 0, f7BELName.charAt(0) + "FF", + ffSink.getCellType().getName()); + } + for (int k = 0; k < 2; k++) { + EDIFHierPortInst lutDriver = muxf7.getEDIFHierCellInst().getPortInstDriver("I" + Integer.toString(k)); + String lutBELName = f7BELName.charAt(6 + k) + "6LUT"; + String cellType = lutDriver.getCellType().getName(); + shape.addCell(lutDriver.getFullHierarchicalInstName(), design, 0, 0, lutBELName, cellType); + if (cellType.equals("SRLC32E")) { + shape.addTag(ShapeTag.SRL); + } + } + } + + /** + * Checks if the provided mux drives exactly one flip flop. If it does, it will + * return it, otherwise it returns null. + * + * @return The single flip flop input driven by the provided mux, null + * otherwise. + */ + private static EDIFHierPortInst checkAndGetSingleSinkFlop(Cell mux) { + EDIFHierNet outNet = mux.getEDIFHierCellInst().getPortInst("O").getHierarchicalNet(); + + if (outNet != null) { + List portInsts = outNet.getLeafHierPortInsts(false, true); + if (portInsts.size() == 1) { + EDIFHierPortInst sink = portInsts.get(0); + String cellType = sink.getCellType().getName(); + if (DesignTools.unisimFlipFlopTypes.contains(cellType)) { + return sink; + } + } + } + return null; + } + + private static boolean lutPlacementCompatible(EDIFHierPortInst sum, EDIFHierPortInst di, + Map cellShapeMap) { + String diType = di.getCellType().getName(); + String sumType = sum.getCellType().getName(); + Shape sumShape = cellShapeMap.get(sum.getFullHierarchicalInstName()); + Shape diShape = cellShapeMap.get(di.getFullHierarchicalInstName()); + if (sumShape != null && diShape != null && sumShape != diShape) { + return false; + } + if (sumShape != null || diShape != null) { + return false; + } + if (diType.equals("LUT6") && sumType.equals("LUT6")) { + return false; + } + return true; + } + + public static Shape createShapeFromMacro(Design design, EDIFHierCellInst macro) { + Unisim cellType = Unisim.valueOf(macro.getCellName()); + Shape shape = new Shape(); + switch (cellType) { + case LUT6_2: + shape.setHeight(1); + shape.setWidth(1); + for (EDIFCellInst i : macro.getCellType().getCellInsts()) { + String belName = "A" + (i.getCellName().charAt(i.getCellName().length() - 1) == '6' ? "6LUT" : "5LUT"); + shape.addCell(macro.getChild(i).toString(), design, 0, 0, belName, i.getCellName()); + } + shape.addTag(ShapeTag.LUTNM); + break; + case RAM64M: + shape.setHeight(1); + shape.setWidth(1); + for (EDIFCellInst i : macro.getCellType().getCellInsts()) { + String belName = i.getName().charAt(i.getName().length() - 1) + "6LUT"; + shape.addCell(macro.getChild(i).toString(), design, 0, 0, belName, i.getCellName()); + } + shape.addTag(ShapeTag.CLUSTER); + break; + case RAM32M: + shape.setHeight(1); + shape.setWidth(1); + for (EDIFCellInst i : macro.getCellType().getCellInsts()) { + String instName = i.getName(); + String suffix = instName.endsWith("_D1") ? "6LUT" : "5LUT"; + String belName = instName.charAt(3) + suffix; + shape.addCell(macro.getChild(i).toString(), design, 0, 0, belName, i.getCellName()); + } + shape.addTag(ShapeTag.CLUSTER); + break; + case RAM32M16: + shape.setHeight(1); + shape.setWidth(1); + for (EDIFCellInst i : macro.getCellType().getCellInsts()) { + String instName = i.getName(); + String suffix = instName.endsWith("_D1") ? "6LUT" : "5LUT"; + String belName = instName.charAt(3) + suffix; + shape.addCell(macro.getChild(i).toString(), design, 0, 0, belName, i.getCellName()); + } + shape.addTag(ShapeTag.RAM32M16); + break; + case RAM32X1D: + shape.setHeight(1); + shape.setWidth(1); + // TODO - These macros can be combined into a single if shared inputs + for (EDIFCellInst i : macro.getCellType().getCellInsts()) { + String instName = i.getName(); + String belName = instName.endsWith("SP") ? "H6LUT" : "G6LUT"; + shape.addCell(macro.getChild(i).toString(), design, 0, 0, belName, i.getCellName()); + } + shape.addTag(ShapeTag.CLUSTER); + break; + default: + throw new RuntimeException("ERROR: Unsupported shape for macro " + cellType + ", instance " + macro); + } + + return shape; + } + + public static List readDebugShapeFile(Design design, Path file) { + List shapes = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new FileReader(file.toString()))) { + String line = null; + boolean foundStart = false; + int shapeCount = -1; + Shape curr = null; + while((line = br.readLine()) != null) { + if (!foundStart) { + if (line.contains(" shape(s):")) { + shapeCount = Integer.parseInt(line.substring(0, line.indexOf(' '))); + foundStart = true; + } + continue; + } + if (line.trim().length() == 0) continue; + if (curr == null) { + curr = new Shape(); + } + if (line.startsWith("(")) { + int commaIdx = line.indexOf(','); + String relSiteName = line.substring(1, commaIdx); + int yIdx = relSiteName.lastIndexOf('Y'); + int dx = Integer.parseInt(relSiteName.substring(relSiteName.lastIndexOf("_X") + 2, yIdx)); + int dy = Integer.parseInt(relSiteName.substring(yIdx + 1)); + String belName = line.substring(commaIdx + 1, line.indexOf(')')).replace(", optional", "").trim(); + String cellName = line.substring(line.indexOf('\t') + 1, line.indexOf(" (")); + String cellType = line.substring(line.lastIndexOf('(') + 1, line.lastIndexOf(')')); + curr.addCell(cellName, design, dx, dy, belName, cellType); + } else if (line.startsWith("Tag(s): ")) { + String[] tags = line.split("\\s+"); + Set tagNames = new HashSet<>(); + for (int i = 1; i < tags.length; i++) { + tagNames.add(ShapeTag.values.get(tags[i])); + } + curr.setTags(tagNames); + } else if (line.startsWith("WxH: ")) { + int xIdx = line.lastIndexOf('x'); + int width = Integer.parseInt(line.substring(line.indexOf(' ') + 1, xIdx)); + int height = Integer.parseInt(line.substring(xIdx + 1)); + curr.setHeight(height); + curr.setWidth(width); + shapes.add(curr); + curr = null; + } + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return shapes; + } + + public static void sortShapesByBELName(Collection shapes) { + for (Shape s : shapes) { + Map cellOrderStrings = new HashMap<>(); + for (Entry e : s.getCellMap().entrySet()) { + ShapeLocation loc = e.getValue(); + String key = loc.getDx() + "_" + loc.getDy() + "_" + loc.getBelName(); + Cell collision = cellOrderStrings.put(key, e.getKey()); + if (collision != null) { + throw new RuntimeException("ERROR: Key collision with key: " + + key + ", cell=" + collision + "; In shape:\n" + s); + } + } + String[] keys = cellOrderStrings.keySet().toArray(new String[cellOrderStrings.size()]); + Arrays.sort(keys); + Map orderedMap = new LinkedHashMap<>(); + for (String key : keys) { + Cell cell = cellOrderStrings.get(key); + orderedMap.put(cell, s.getCellMap().get(cell)); + } + s.setCellMap(orderedMap); + } + } +} diff --git a/src/com/xilinx/rapidwright/edif/EDIFHierCellInst.java b/src/com/xilinx/rapidwright/edif/EDIFHierCellInst.java index e88ceb15c..52d0db5b1 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFHierCellInst.java +++ b/src/com/xilinx/rapidwright/edif/EDIFHierCellInst.java @@ -343,4 +343,20 @@ public boolean isUniquified() { } return true; } + + /** + * Gets the (first found) driver on the net net attached to the named port + * instance. + * + * @param portInstName Name of the port instance on this cell instance. + * @return The first driver found or null if port is invalid or an output. + */ + public EDIFHierPortInst getPortInstDriver(String portInstName) { + EDIFHierPortInst input = getPortInst(portInstName); + if (input == null || input.isOutput()) + return null; + EDIFHierNet net = input.getHierarchicalNet(); + List srcs = net.getLeafHierPortInsts(true, false); + return srcs.size() > 0 ? srcs.get(0) : null; + } } diff --git a/src/com/xilinx/rapidwright/edif/EDIFNetlist.java b/src/com/xilinx/rapidwright/edif/EDIFNetlist.java index 6952e83be..873d3100d 100644 --- a/src/com/xilinx/rapidwright/edif/EDIFNetlist.java +++ b/src/com/xilinx/rapidwright/edif/EDIFNetlist.java @@ -62,6 +62,7 @@ import com.xilinx.rapidwright.design.Net; import com.xilinx.rapidwright.design.NetType; import com.xilinx.rapidwright.design.Unisim; +import com.xilinx.rapidwright.design.shapes.Shape; import com.xilinx.rapidwright.device.Device; import com.xilinx.rapidwright.device.IOStandard; import com.xilinx.rapidwright.device.Series; @@ -111,6 +112,8 @@ public class EDIFNetlist extends EDIFName { private Map> modifiedCells = null; + private Collection shapes; + private boolean DEBUG = false; /** @@ -2055,6 +2058,14 @@ public void resetCellInstIOStandardFallbackMap() { cellInstIOStandardFallback = null; } + public Collection getShapes() { + return shapes; + } + + public void setShapes(Collection shapes) { + this.shapes = shapes; + } + public static void main(String[] args) throws FileNotFoundException { CodePerfTracker t = new CodePerfTracker("EDIF Import/Export", true); t.start("Read EDIF"); diff --git a/src/com/xilinx/rapidwright/interchange/Interchange.java b/src/com/xilinx/rapidwright/interchange/Interchange.java index 76d33e631..5cd4c5559 100644 --- a/src/com/xilinx/rapidwright/interchange/Interchange.java +++ b/src/com/xilinx/rapidwright/interchange/Interchange.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2022, Xilinx, Inc. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Chris Lavin, Xilinx Research Labs. @@ -94,7 +94,11 @@ public static Design readInterchangeDesign(Path filePath) { Path physFileName = lowerName.endsWith(PHYS_NETLIST_EXT) ? filePath : getExistingCompanionFile(filePath); if (logFileName == null) { - throw new RuntimeException("ERROR: Could not find logical netlist file: " + logFileName); + logFileName = Paths.get(filePath.toString() + LOG_NETLIST_EXT); + if (!Files.exists(logFileName)) { + throw new RuntimeException("ERROR: Could not find logical netlist file: " + logFileName); + } + physFileName = Paths.get(filePath.toString() + PHYS_NETLIST_EXT); } String xdcFileName = FileTools.replaceExtension(logFileName, ".xdc").toString(); diff --git a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java index 506731860..1810aa043 100644 --- a/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java +++ b/src/com/xilinx/rapidwright/interchange/LogNetlistReader.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2022, Xilinx, Inc. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Chris Lavin, Xilinx Research Labs. @@ -25,11 +25,16 @@ import com.xilinx.rapidwright.design.Design; import com.xilinx.rapidwright.design.Unisim; +import com.xilinx.rapidwright.design.shapes.Shape; +import com.xilinx.rapidwright.design.shapes.ShapeLocation; +import com.xilinx.rapidwright.design.shapes.ShapeTag; import com.xilinx.rapidwright.device.PartNameTools; +import com.xilinx.rapidwright.device.SiteTypeEnum; import com.xilinx.rapidwright.edif.EDIFCell; import com.xilinx.rapidwright.edif.EDIFCellInst; import com.xilinx.rapidwright.edif.EDIFDesign; import com.xilinx.rapidwright.edif.EDIFDirection; +import com.xilinx.rapidwright.edif.EDIFHierCellInst; import com.xilinx.rapidwright.edif.EDIFLibrary; import com.xilinx.rapidwright.edif.EDIFName; import com.xilinx.rapidwright.edif.EDIFNet; @@ -46,18 +51,23 @@ import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PortInstance; import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PortInstance.BusIdx; import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PropertyMap; +import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement; import com.xilinx.rapidwright.tests.CodePerfTracker; import org.capnproto.MessageReader; import org.capnproto.PrimitiveList; import org.capnproto.ReaderOptions; import org.capnproto.StructList; import org.capnproto.TextList; +import org.capnproto.PrimitiveList.Int; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; import java.util.function.Supplier; @@ -131,6 +141,46 @@ protected void readAllInsts(StructList.Reader instL } } + protected void readAllShapes(StructList.Reader shapesReader, EDIFNetlist n) { + List shapes = new ArrayList<>(shapesReader.size()); + + for (int i = 0; i < shapesReader.size(); i++) { + com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.Reader s = shapesReader.get(i); + Shape shape = new Shape(); + shape.setHeight(i); + shape.setWidth(i); + Int.Reader shapeTags = s.getTags(); + Set tags = new HashSet<>(shapeTags.size()); + for (int j = 0; j < shapeTags.size(); j++) { + tags.add(ShapeTag.valueOf(allStrings[shapeTags.get(j)])); + } + shape.setTags(tags); + Map map = shape.getCellMap(); + StructList.Reader elements = s.getCells(); + for (int j = 0; j < s.getCells().size(); j++) { + ShapeElement.Reader shapeElement = elements.get(j); + String cellName = allStrings[shapeElement.getCellName()]; + String belName = allStrings[shapeElement.getBelName()]; + int dx = shapeElement.getDx(); + int dy = shapeElement.getDy(); + Int.Reader types = shapeElement.getSiteTypes(); + List siteTypes = new ArrayList<>(types.size()); + for (int k = 0; k < types.size(); k++) { + siteTypes.add(SiteTypeEnum.valueOf(allStrings[types.get(k)])); + } + ShapeLocation loc = new ShapeLocation(siteTypes, belName, dx, dy); + + com.xilinx.rapidwright.design.Cell cell = new com.xilinx.rapidwright.design.Cell(cellName); + EDIFHierCellInst cellInst = n.getHierCellInstFromName(cellName); + cell.setType(cellInst.getCellName()); + cell.setEDIFHierCellInst(cellInst); + map.put(cell, loc); + } + } + + n.setShapes(shapes); + } + protected EDIFCellInst getInst(int i) { return allInsts[i]; } @@ -483,6 +533,15 @@ public EDIFNetlist readLogNetlist(Netlist.Reader netlist, boolean skipTopStuff, + " run manually with EDIFNetlist.expandMacroUnisims(Series)"); } } + if (netlist.hasShapeList()) { + if (expandMacros) { + t.stop().start("Read Shapes"); + readAllShapes(netlist.getShapeList(), n); + } else { + System.out.println("INFO: Not reading shapes as macros not expanded"); + } + } + t.stop().printSummary(); return n; diff --git a/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java b/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java index 3e21867ad..5979113f5 100644 --- a/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java +++ b/src/com/xilinx/rapidwright/interchange/LogNetlistWriter.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2020-2022, Xilinx, Inc. - * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. * All rights reserved. * * Author: Chris Lavin, Xilinx Research Labs. @@ -23,7 +23,11 @@ package com.xilinx.rapidwright.interchange; +import com.xilinx.rapidwright.design.shapes.Shape; +import com.xilinx.rapidwright.design.shapes.ShapeLocation; +import com.xilinx.rapidwright.design.shapes.ShapeTag; import com.xilinx.rapidwright.device.Device; +import com.xilinx.rapidwright.device.SiteTypeEnum; import com.xilinx.rapidwright.edif.EDIFCell; import com.xilinx.rapidwright.edif.EDIFCellInst; import com.xilinx.rapidwright.edif.EDIFLibrary; @@ -42,15 +46,19 @@ import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Port; import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PortInstance; import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.PropertyMap; +import com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement; import com.xilinx.rapidwright.tests.CodePerfTracker; import org.capnproto.MessageBuilder; import org.capnproto.PrimitiveList; +import org.capnproto.PrimitiveList.Int; import org.capnproto.StructList; import org.capnproto.Text; import org.capnproto.TextList; +import org.capnproto.TextList.Builder; import org.capnproto.Void; import java.io.IOException; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -169,6 +177,41 @@ protected void populateEnumerations(EDIFNetlist n) { } } + protected void writeShapes(EDIFNetlist n, Netlist.Builder netlist) { + Collection shapes = n.getShapes(); + if (shapes == null) return; + StructList.Builder shapeList = netlist + .initShapeList(shapes.size()); + int i = 0; + for (Shape s : shapes) { + com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.Builder curr = shapeList.get(i); + curr.setHeight(s.getHeight()); + curr.setWidth(s.getWidth()); + Int.Builder tags = curr.initTags(s.getTags().size()); + int t = 0; + for (ShapeTag tag : s.getTags()) { + tags.set(t, allStrings.getIndex(tag.toString())); + t++; + } + StructList.Builder shapeElements = curr.initCells(s.getCellMap().size()); + int j = 0; + for (Entry e : s.getCellMap().entrySet()) { + ShapeElement.Builder shapeElement = shapeElements.get(j); + shapeElement.setBelName(allStrings.getIndex(e.getValue().getBelName())); + shapeElement.setCellName(allStrings.getIndex(e.getKey().getName())); + shapeElement.setDx(e.getValue().getDx()); + shapeElement.setDy(e.getValue().getDy()); + List types = e.getValue().getCompatibleSiteTypes(); + Int.Builder elemSiteTypes = shapeElement.initSiteTypes(types.size()); + for (int k = 0; k < types.size(); k++) { + elemSiteTypes.set(k, allStrings.getIndex(types.get(k).name())); + } + j++; + } + i++; + } + } + /** * Populates Cap'n Proto message with netlist metadata such as name, top instance, top cell, * etc. @@ -353,6 +396,8 @@ public static void writeLogNetlist(EDIFNetlist n, String fileName, boolean colla writer.populateNetlistBuilder(n, netlist, t); t.start("Write Top"); writer.writeTopNetlistStuffToNetlistBuilder(n, netlist); + t.stop().start("Write Shapes"); + writer.writeShapes(n, netlist); t.stop().start("Write Strings"); writeStrings(netlist, writer.allStrings); t.stop().start("Write File"); diff --git a/src/com/xilinx/rapidwright/interchange/LogicalNetlist.java b/src/com/xilinx/rapidwright/interchange/LogicalNetlist.java index 0e2828a75..8c4963dd6 100644 --- a/src/com/xilinx/rapidwright/interchange/LogicalNetlist.java +++ b/src/com/xilinx/rapidwright/interchange/LogicalNetlist.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. @@ -49,7 +49,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -75,7 +75,7 @@ public final void setHide(boolean value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -117,7 +117,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -153,7 +153,7 @@ public final org.capnproto.Text.Builder initField(int size) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -200,7 +200,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -243,7 +243,7 @@ public final void setDepth(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -294,7 +294,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -337,7 +337,7 @@ public final void setDepth(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -388,7 +388,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -431,7 +431,7 @@ public final void setDepth(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -461,7 +461,7 @@ public final int getDepth() { public static class Netlist { - public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)0,(short)8); + public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)0,(short)9); public static final class Factory extends org.capnproto.StructFactory { public Factory() { } @@ -482,7 +482,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -581,10 +581,22 @@ public final void setCellList(org.capnproto.StructList.Reader initCellList(int size) { return _initPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Cell.listFactory, 7, size); } + public final boolean hasShapeList() { + return !_pointerFieldIsNull(8); + } + public final org.capnproto.StructList.Builder getShapeList() { + return _getPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.listFactory, 8, null, 0); + } + public final void setShapeList(org.capnproto.StructList.Reader value) { + _setPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.listFactory, 8, value); + } + public final org.capnproto.StructList.Builder initShapeList(int size) { + return _initPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.listFactory, 8, size); + } } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -644,6 +656,13 @@ public final org.capnproto.StructList.Reader getShapeList() { + return _getPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.listFactory, 8, null, 0); + } + } public static class CellDeclaration { @@ -668,7 +687,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -719,7 +738,7 @@ public final org.capnproto.PrimitiveList.Int.Builder initPorts(int size) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -776,7 +795,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -815,7 +834,7 @@ public final void setCell(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -865,7 +884,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -905,7 +924,7 @@ public final org.capnproto.StructList.Builder listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -991,7 +1010,7 @@ public final org.capnproto.StructList.Builder listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public Which which() { @@ -1112,7 +1131,7 @@ public final com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Bus.Build } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1203,7 +1222,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -1226,7 +1245,7 @@ public final void setBusEnd(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1265,7 +1284,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public Which which() { @@ -1322,7 +1341,7 @@ public final void setInst(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1388,7 +1407,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public Which which() { @@ -1429,7 +1448,7 @@ public final void setIdx(int value) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1493,7 +1512,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -1521,7 +1540,7 @@ public final org.capnproto.PrimitiveList.Byte.Builder initData(int size) { } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1563,7 +1582,7 @@ public final Reader asReader(Builder builder) { public static final org.capnproto.StructList.Factory listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public final Reader asReader() { @@ -1584,7 +1603,7 @@ public final org.capnproto.StructList.Builder listFactory = new org.capnproto.StructList.Factory(factory); public static final class Builder extends org.capnproto.StructBuilder { - Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount) { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ super(segment, data, pointers, dataSize, pointerCount); } public Which which() { @@ -1699,7 +1718,7 @@ public final com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Bitstring } public static final class Reader extends org.capnproto.StructReader { - Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit) { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ super(segment, data, pointers, dataSize, pointerCount, nestingLimit); } @@ -1770,6 +1789,209 @@ public enum Which { } + public static class Shape { + public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)1,(short)2); + public static final class Factory extends org.capnproto.StructFactory { + public Factory() { + } + public final Reader constructReader(org.capnproto.SegmentReader segment, int data,int pointers, int dataSize, short pointerCount, int nestingLimit) { + return new Reader(segment,data,pointers,dataSize,pointerCount,nestingLimit); + } + public final Builder constructBuilder(org.capnproto.SegmentBuilder segment, int data,int pointers, int dataSize, short pointerCount) { + return new Builder(segment, data, pointers, dataSize, pointerCount); + } + public final org.capnproto.StructSize structSize() { + return Netlist.Shape.STRUCT_SIZE; + } + public final Reader asReader(Builder builder) { + return builder.asReader(); + } + } + public static final Factory factory = new Factory(); + public static final org.capnproto.StructList.Factory listFactory = + new org.capnproto.StructList.Factory(factory); + public static final class Builder extends org.capnproto.StructBuilder { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ + super(segment, data, pointers, dataSize, pointerCount); + } + public final Reader asReader() { + return new Reader(segment, data, pointers, dataSize, pointerCount, 0x7fffffff); + } + public final boolean hasCells() { + return !_pointerFieldIsNull(0); + } + public final org.capnproto.StructList.Builder getCells() { + return _getPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement.listFactory, 0, null, 0); + } + public final void setCells(org.capnproto.StructList.Reader value) { + _setPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement.listFactory, 0, value); + } + public final org.capnproto.StructList.Builder initCells(int size) { + return _initPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement.listFactory, 0, size); + } + public final int getHeight() { + return _getIntField(0); + } + public final void setHeight(int value) { + _setIntField(0, value); + } + + public final int getWidth() { + return _getIntField(1); + } + public final void setWidth(int value) { + _setIntField(1, value); + } + + public final boolean hasTags() { + return !_pointerFieldIsNull(1); + } + public final org.capnproto.PrimitiveList.Int.Builder getTags() { + return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 1, null, 0); + } + public final void setTags(org.capnproto.PrimitiveList.Int.Reader value) { + _setPointerField(org.capnproto.PrimitiveList.Int.factory, 1, value); + } + public final org.capnproto.PrimitiveList.Int.Builder initTags(int size) { + return _initPointerField(org.capnproto.PrimitiveList.Int.factory, 1, size); + } + } + + public static final class Reader extends org.capnproto.StructReader { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ + super(segment, data, pointers, dataSize, pointerCount, nestingLimit); + } + + public final boolean hasCells() { + return !_pointerFieldIsNull(0); + } + public final org.capnproto.StructList.Reader getCells() { + return _getPointerField(com.xilinx.rapidwright.interchange.LogicalNetlist.Netlist.Shape.ShapeElement.listFactory, 0, null, 0); + } + + public final int getHeight() { + return _getIntField(0); + } + + public final int getWidth() { + return _getIntField(1); + } + + public final boolean hasTags() { + return !_pointerFieldIsNull(1); + } + public final org.capnproto.PrimitiveList.Int.Reader getTags() { + return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 1, null, 0); + } + + } + + public static class ShapeElement { + public static final org.capnproto.StructSize STRUCT_SIZE = new org.capnproto.StructSize((short)2,(short)1); + public static final class Factory extends org.capnproto.StructFactory { + public Factory() { + } + public final Reader constructReader(org.capnproto.SegmentReader segment, int data,int pointers, int dataSize, short pointerCount, int nestingLimit) { + return new Reader(segment,data,pointers,dataSize,pointerCount,nestingLimit); + } + public final Builder constructBuilder(org.capnproto.SegmentBuilder segment, int data,int pointers, int dataSize, short pointerCount) { + return new Builder(segment, data, pointers, dataSize, pointerCount); + } + public final org.capnproto.StructSize structSize() { + return Netlist.Shape.ShapeElement.STRUCT_SIZE; + } + public final Reader asReader(Builder builder) { + return builder.asReader(); + } + } + public static final Factory factory = new Factory(); + public static final org.capnproto.StructList.Factory listFactory = + new org.capnproto.StructList.Factory(factory); + public static final class Builder extends org.capnproto.StructBuilder { + Builder(org.capnproto.SegmentBuilder segment, int data, int pointers,int dataSize, short pointerCount){ + super(segment, data, pointers, dataSize, pointerCount); + } + public final Reader asReader() { + return new Reader(segment, data, pointers, dataSize, pointerCount, 0x7fffffff); + } + public final int getCellName() { + return _getIntField(0); + } + public final void setCellName(int value) { + _setIntField(0, value); + } + + public final int getBelName() { + return _getIntField(1); + } + public final void setBelName(int value) { + _setIntField(1, value); + } + + public final boolean hasSiteTypes() { + return !_pointerFieldIsNull(0); + } + public final org.capnproto.PrimitiveList.Int.Builder getSiteTypes() { + return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 0, null, 0); + } + public final void setSiteTypes(org.capnproto.PrimitiveList.Int.Reader value) { + _setPointerField(org.capnproto.PrimitiveList.Int.factory, 0, value); + } + public final org.capnproto.PrimitiveList.Int.Builder initSiteTypes(int size) { + return _initPointerField(org.capnproto.PrimitiveList.Int.factory, 0, size); + } + public final int getDx() { + return _getIntField(2); + } + public final void setDx(int value) { + _setIntField(2, value); + } + + public final int getDy() { + return _getIntField(3); + } + public final void setDy(int value) { + _setIntField(3, value); + } + + } + + public static final class Reader extends org.capnproto.StructReader { + Reader(org.capnproto.SegmentReader segment, int data, int pointers,int dataSize, short pointerCount, int nestingLimit){ + super(segment, data, pointers, dataSize, pointerCount, nestingLimit); + } + + public final int getCellName() { + return _getIntField(0); + } + + public final int getBelName() { + return _getIntField(1); + } + + public final boolean hasSiteTypes() { + return !_pointerFieldIsNull(0); + } + public final org.capnproto.PrimitiveList.Int.Reader getSiteTypes() { + return _getPointerField(org.capnproto.PrimitiveList.Int.factory, 0, null, 0); + } + + public final int getDx() { + return _getIntField(2); + } + + public final int getDy() { + return _getIntField(3); + } + + } + + } + + + } + + } @@ -2198,39 +2420,41 @@ public static final class Schemas { "\u00b1\u00bd\u006b\u00fd\u0096\u0042\u007e\u00e4" + "\u0015\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + "\u0067\u0029\u0091\u00aa\u0067\u00cd\u002c\u00cb" + - "\u0008\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + + "\u0009\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0015\u0000\u0000\u0000\u00ea\u0000\u0000\u0000" + - "\u0021\u0000\u0000\u0000\u00a7\u0000\u0000\u0000" + + "\u0021\u0000\u0000\u0000\u00b7\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00ad\u0000\u0000\u0000\u00c7\u0001\u0000\u0000" + + "\u00b9\u0000\u0000\u0000\u00ff\u0001\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u004c\u006f\u0067\u0069\u0063\u0061\u006c\u004e" + "\u0065\u0074\u006c\u0069\u0073\u0074\u002e\u0063" + "\u0061\u0070\u006e\u0070\u003a\u004e\u0065\u0074" + "\u006c\u0069\u0073\u0074\u0000\u0000\u0000\u0000" + - "\u0028\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u002c\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + "\u00d5\u00ef\u00c8\u006f\u00a7\u0059\u0014\u00e5" + - "\u0049\u0000\u0000\u0000\u0082\u0000\u0000\u0000" + + "\u0051\u0000\u0000\u0000\u0082\u0000\u0000\u0000" + "\u0062\u0045\u0049\u0050\u00ad\u000f\u0070\u00b2" + - "\u0049\u0000\u0000\u0000\u006a\u0000\u0000\u0000" + + "\u0051\u0000\u0000\u0000\u006a\u0000\u0000\u0000" + "\u009d\u0012\u00a3\u0036\u0094\u0063\u0010\u00fa" + - "\u0049\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + + "\u0051\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + "\u00b0\u0026\u0061\u00cf\u0079\u00ec\u0033\u00eb" + - "\u0045\u0000\u0000\u0000\"\u0000\u0000\u0000" + + "\u004d\u0000\u0000\u0000\"\u0000\u0000\u0000" + "\u005b\u00c4\u005d\u0070\u00b7\u001d\u008b\u009f" + - "\u0041\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + + "\u0049\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + "\u00a7\u004c\u00fa\u004c\u00e0\u0093\u002d\u009c" + - "\u003d\u0000\u0000\u0000\u0052\u0000\u0000\u0000" + + "\u0045\u0000\u0000\u0000\u0052\u0000\u0000\u0000" + "\u0086\u00a1\u000c\u00c4\u0018\u007c\u00de\u0099" + - "\u003d\u0000\u0000\u0000\"\u0000\u0000\u0000" + + "\u0045\u0000\u0000\u0000\"\u0000\u0000\u0000" + "\u0009\u0070\u00f5\u00bd\u00d3\u009f\u0078\u00bb" + - "\u0039\u0000\u0000\u0000\u006a\u0000\u0000\u0000" + + "\u0041\u0000\u0000\u0000\u006a\u0000\u0000\u0000" + "\u00d2\u0037\u0071\u004e\u0007\u001f\u000e\u00c1" + - "\u0039\u0000\u0000\u0000\u0052\u0000\u0000\u0000" + + "\u0041\u0000\u0000\u0000\u0052\u0000\u0000\u0000" + "\u0038\u0064\u00a3\u00bd\u00fb\u0057\u0028\u00c6" + - "\u0039\u0000\u0000\u0000\u0062\u0000\u0000\u0000" + + "\u0041\u0000\u0000\u0000\u0062\u0000\u0000\u0000" + + "\u0099\u00e6\u00c9\u008c\u002e\u0090\u0048\u0098" + + "\u0041\u0000\u0000\u0000\u0032\u0000\u0000\u0000" + "\u0043\u0065\u006c\u006c\u0044\u0065\u0063\u006c" + "\u0061\u0072\u0061\u0074\u0069\u006f\u006e\u0000" + "\u0043\u0065\u006c\u006c\u0049\u006e\u0073\u0074" + @@ -2247,63 +2471,71 @@ public static final class Schemas { "\u0067\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0050\u0072\u006f\u0070\u0065\u0072\u0074\u0079" + "\u004d\u0061\u0070\u0000\u0000\u0000\u0000\u0000" + - "\u0020\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + + "\u0053\u0068\u0061\u0070\u0065\u0000\u0000\u0000" + + "\u0024\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00d1\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + + "\u00ed\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00cc\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u00d8\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u00e8\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00f4\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0001\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00d5\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u00f1\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00d0\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u00dc\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u00ec\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00f8\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0002\u0000\u0000\u0000\u0002\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0002\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u00d9\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + - "\u00d9\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + - "\u00f8\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0014\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u00f5\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u00f5\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + + "\u0014\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0030\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0003\u0000\u0000\u0000\u0003\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0003\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0011\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + + "\u002d\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0010\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u002c\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u002c\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0048\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0004\u0000\u0000\u0000\u0004\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0029\u0001\u0000\u0000\u0052\u0000\u0000\u0000" + + "\u0045\u0001\u0000\u0000\u0052\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0028\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0044\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0044\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0060\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0005\u0000\u0000\u0000\u0005\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0005\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0041\u0001\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u005d\u0001\u0000\u0000\u0042\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u003c\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0048\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0058\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0064\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0006\u0000\u0000\u0000\u0006\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0006\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0045\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + + "\u0061\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u0044\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0060\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0060\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u007c\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u0007\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0001\u0000\u0007\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\u005d\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + + "\u0079\u0001\u0000\u0000\u004a\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + - "\\\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + - "\u0078\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0078\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0094\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0008\u0000\u0000\u0000\u0008\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0008\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0091\u0001\u0000\u0000\u0052\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0090\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00ac\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + "\u006e\u0061\u006d\u0065\u0000\u0000\u0000\u0000" + "\u000c\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + @@ -2400,6 +2632,19 @@ public static final class Schemas { "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0073\u0068\u0061\u0070\u0065\u004c\u0069\u0073" + + "\u0074\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0099\u00e6\u00c9\u008c\u002e\u0090\u0048\u0098" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ""); public static final org.capnproto.SegmentReader b_e51459a76fc8efd5 = org.capnproto.GeneratedClassSupport.decodeRawBytes( @@ -3388,6 +3633,242 @@ public static final class Schemas { "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ""); +public static final org.capnproto.SegmentReader b_9848902e8cc9e699 = + org.capnproto.GeneratedClassSupport.decodeRawBytes( + "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + + "\u0099\u00e6\u00c9\u008c\u002e\u0090\u0048\u0098" + + "\u001d\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u00b1\u00bd\u006b\u00fd\u0096\u0042\u007e\u00e4" + + "\u0002\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u001a\u0001\u0000\u0000" + + "\u0025\u0000\u0000\u0000\u0017\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0031\u0000\u0000\u0000\u00e7\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u004c\u006f\u0067\u0069\u0063\u0061\u006c\u004e" + + "\u0065\u0074\u006c\u0069\u0073\u0074\u002e\u0063" + + "\u0061\u0070\u006e\u0070\u003a\u004e\u0065\u0074" + + "\u006c\u0069\u0073\u0074\u002e\u0053\u0068\u0061" + + "\u0070\u0065\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0004\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u002a\u00b2\u0073\u00b0\u00f8\u001d\u0042\u00ff" + + "\u0001\u0000\u0000\u0000\u006a\u0000\u0000\u0000" + + "\u0053\u0068\u0061\u0070\u0065\u0045\u006c\u0065" + + "\u006d\u0065\u006e\u0074\u0000\u0000\u0000\u0000" + + "\u0010\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0061\u0000\u0000\u0000\u0032\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\\\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0078\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0075\u0000\u0000\u0000\u003a\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0070\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u007c\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0002\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0002\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0079\u0000\u0000\u0000\u0032\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0074\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0080\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0003\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0003\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u007d\u0000\u0000\u0000\u002a\u0000\u0000\u0000" + + "\u007d\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + + "\u00a0\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00bc\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0063\u0065\u006c\u006c\u0073\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u002a\u00b2\u0073\u00b0\u00f8\u001d\u0042\u00ff" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0068\u0065\u0069\u0067\u0068\u0074\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0077\u0069\u0064\u0074\u0068\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0074\u0061\u0067\u0073\u0000\u0000\u0000\u0000" + + "\u0004\u0000\u0000\u0000\u0001\u0000\u0002\u0000" + + "\u00e5\u0084\u0010\u002a\u009d\u008c\u0004\u0081" + + "\u0004\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0014\u0000\u0000\u0000\u0000\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ""); +public static final org.capnproto.SegmentReader b_ff421df8b073b22a = + org.capnproto.GeneratedClassSupport.decodeRawBytes( + "\u0000\u0000\u0000\u0000\u0005\u0000\u0006\u0000" + + "\u002a\u00b2\u0073\u00b0\u00f8\u001d\u0042\u00ff" + + "\u0023\u0000\u0000\u0000\u0001\u0000\u0002\u0000" + + "\u0099\u00e6\u00c9\u008c\u002e\u0090\u0048\u0098" + + "\u0001\u0000\u0007\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0015\u0000\u0000\u0000\u0082\u0001\u0000\u0000" + + "\u0029\u0000\u0000\u0000\u0007\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0025\u0000\u0000\u0000\u001f\u0001\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u004c\u006f\u0067\u0069\u0063\u0061\u006c\u004e" + + "\u0065\u0074\u006c\u0069\u0073\u0074\u002e\u0063" + + "\u0061\u0070\u006e\u0070\u003a\u004e\u0065\u0074" + + "\u006c\u0069\u0073\u0074\u002e\u0053\u0068\u0061" + + "\u0070\u0065\u002e\u0053\u0068\u0061\u0070\u0065" + + "\u0045\u006c\u0065\u006d\u0065\u006e\u0074\u0000" + + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u0014\u0000\u0000\u0000\u0003\u0000\u0004\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u007d\u0000\u0000\u0000\u004a\u0000\u0000\u0000" + + "\u0081\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + + "\u00a4\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00b0\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0001\u0000\u0000\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u00ad\u0000\u0000\u0000\u0042\u0000\u0000\u0000" + + "\u00ad\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + + "\u00d0\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u00dc\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0002\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0002\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u00d9\u0000\u0000\u0000\u0052\u0000\u0000\u0000" + + "\u00dd\u0000\u0000\u0000\u001f\u0000\u0000\u0000" + + "\u0000\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u001c\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0003\u0000\u0000\u0000\u0002\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0003\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0019\u0001\u0000\u0000\u001a\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0014\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0020\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0004\u0000\u0000\u0000\u0003\u0000\u0000\u0000" + + "\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u001d\u0001\u0000\u0000\u001a\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0018\u0001\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0024\u0001\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0063\u0065\u006c\u006c\u004e\u0061\u006d\u0065" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0004\u0000\u0000\u0000\u0001\u0000\u0002\u0000" + + "\u00e5\u0084\u0010\u002a\u009d\u008c\u0004\u0081" + + "\u0004\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0014\u0000\u0000\u0000\u0000\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0062\u0065\u006c\u004e\u0061\u006d\u0065\u0000" + + "\u0004\u0000\u0000\u0000\u0001\u0000\u0002\u0000" + + "\u00e5\u0084\u0010\u002a\u009d\u008c\u0004\u0081" + + "\u0004\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0014\u0000\u0000\u0000\u0000\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0073\u0069\u0074\u0065\u0054\u0079\u0070\u0065" + + "\u0073\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0004\u0000\u0000\u0000\u0001\u0000\u0002\u0000" + + "\u00e5\u0084\u0010\u002a\u009d\u008c\u0004\u0081" + + "\u0004\u0000\u0000\u0000\u0002\u0000\u0001\u0000" + + "\u0014\u0000\u0000\u0000\u0000\u0000\u0001\u0000" + + "\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0003\u0000\u0001\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0064\u0078\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0064\u0079\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000" + ""); } } diff --git a/src/com/xilinx/rapidwright/interchange/PhysicalNetlistToDcp.java b/src/com/xilinx/rapidwright/interchange/PhysicalNetlistToDcp.java index dd4851b94..e327cacb3 100644 --- a/src/com/xilinx/rapidwright/interchange/PhysicalNetlistToDcp.java +++ b/src/com/xilinx/rapidwright/interchange/PhysicalNetlistToDcp.java @@ -36,7 +36,7 @@ public class PhysicalNetlistToDcp { - private static final String MAKE_DCP_OUT_OF_CONTEXT = "--out_of_context"; + public static final String MAKE_DCP_OUT_OF_CONTEXT = "--out_of_context"; public static void main(String[] args) throws IOException { if (args.length != 4 && args.length != 5) { diff --git a/src/com/xilinx/rapidwright/placer/dreamplacefpga/DREAMPlaceFPGA.java b/src/com/xilinx/rapidwright/placer/dreamplacefpga/DREAMPlaceFPGA.java new file mode 100644 index 000000000..cf30966ce --- /dev/null +++ b/src/com/xilinx/rapidwright/placer/dreamplacefpga/DREAMPlaceFPGA.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2024, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Author: Chris Lavin, AMD Research and Advanced Development. + * + * 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.placer.dreamplacefpga; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.xilinx.rapidwright.design.Design; +import com.xilinx.rapidwright.design.shapes.ShapeTools; +import com.xilinx.rapidwright.edif.EDIFTools; +import com.xilinx.rapidwright.edif.EDIFNetlist; +import com.xilinx.rapidwright.interchange.DeviceResourcesWriter; +import com.xilinx.rapidwright.interchange.Interchange; +import com.xilinx.rapidwright.interchange.LogNetlistWriter; +import com.xilinx.rapidwright.interchange.PhysNetlistReader; +import com.xilinx.rapidwright.interchange.PhysicalNetlistToDcp; +import com.xilinx.rapidwright.tests.CodePerfTracker; +import com.xilinx.rapidwright.util.FileTools; + +/** + * Utility wrapper class to facilitate using DREAMPlaceFPGA as an external + * placer. + */ +public class DREAMPlaceFPGA { + + public static final String INTERCHANGE_NETLIST = "interchange_netlist"; + public static final String INTERCHANGE_DEVICE = "interchange_device"; + public static final String IO_PL = "io_pl"; + public static final String GPU = "gpu"; + public static final String NUM_BINS_X = "num_bins_x"; + public static final String NUM_BINS_Y = "num_bins_y"; + public static final String GLOBAL_PLACE_STAGES = "global_place_stages"; + public static final String TARGET_DENSITY = "target_density"; + public static final String DENSITY_WEIGHT = "density_weight"; + public static final String RANDOM_SEED = "random_seed"; + public static final String SCALE_FACTOR = "scale_factor"; + public static final String GLOBAL_PLACE_FLAG = "global_place_flag"; + public static final String PLACE_SOL = "place_sol"; + public static final String ROUTABILITY_OPT_FLAG = "routability_opt_flag"; + public static final String LEGALIZE_FLAG = "legalize_flag"; + public static final String DETAILED_PLACE_FLAG = "detailed_place_flag"; + public static final String DTYPE = "dtype"; + public static final String PLOT_FLAG = "plot_flag"; + public static final String NUM_THREADS = "num_threads"; + public static final String DETERMINISTIC_FLAG = "deterministic_flag"; + public static final String ENABLE_IF = "enable_if"; + public static final String ENABLE_SITE_ROUTING = "enable_site_routing"; + + public static final boolean GPU_DEFAULT = false; + public static final int NUM_BINS_X_DEFAULT = 512; + public static final int NUM_BINS_Y_DEFAULT = 512; + public static final String GLOBAL_PLACE_STAGES_DEFAULT = + "[\n{\"num_bins_x\" : 512," + + " \"num_bins_y\" : 512," + + " \"iteration\" : 2000," + + " \"learning_rate\" : 0.01," + + " \"wirelength\" : \"weighted_average\"," + + " \"optimizer\" : \"nesterov\"}\n]"; + public static final double TARGET_DENSITY_DEFAULT = 1.0; + public static final double DENSITY_WEIGHT_DEFAULT = 8e-5; + public static final int RANDOM_SEED_DEFAULT = 1000; + public static final double SCALE_FACTOR_DEFAULT = 1.0; + public static final boolean GLOBAL_PLACE_FLAG_DEFAULT = true; + public static final boolean ROUTABILITY_OPT_FLAG_DEFAULT = false; + public static final boolean LEGALIZE_FLAG_DEFAULT = true; + public static final boolean DETAILED_PLACE_FLAG_DEFAULT = false; + public static final String DTYPE_DEFAULT = "float32"; + public static final boolean PLOT_FLAG_DEFAULT = false; + public static final int NUM_THREADS_DEFAULT = 8; + public static final boolean DETERMINISTIC_FLAG_DEFAULT = true; + public static final boolean ENABLE_IF_DEFAULT = true; + public static final boolean ENABLE_SITE_ROUTING_DEFAULT = true; + + public static final String dreamPlaceFPGAExec = "python dreamplacefpga/Placer.py"; + + public static Map getSettingsMap() { + Map map = new HashMap<>(); + + map.put(GPU, GPU_DEFAULT); + map.put(NUM_BINS_X, NUM_BINS_X_DEFAULT); + map.put(NUM_BINS_Y, NUM_BINS_Y_DEFAULT); + map.put(GLOBAL_PLACE_STAGES, GLOBAL_PLACE_STAGES_DEFAULT); + map.put(TARGET_DENSITY, TARGET_DENSITY_DEFAULT); + map.put(DENSITY_WEIGHT, DENSITY_WEIGHT_DEFAULT); + map.put(RANDOM_SEED, RANDOM_SEED_DEFAULT); + map.put(SCALE_FACTOR, SCALE_FACTOR_DEFAULT); + map.put(GLOBAL_PLACE_FLAG, GLOBAL_PLACE_FLAG_DEFAULT); + map.put(ROUTABILITY_OPT_FLAG, ROUTABILITY_OPT_FLAG_DEFAULT); + map.put(LEGALIZE_FLAG, LEGALIZE_FLAG_DEFAULT); + map.put(DETAILED_PLACE_FLAG, DETAILED_PLACE_FLAG_DEFAULT); + map.put(DTYPE, DTYPE_DEFAULT); + map.put(PLOT_FLAG, PLOT_FLAG_DEFAULT); + map.put(NUM_THREADS, NUM_THREADS_DEFAULT); + map.put(DETERMINISTIC_FLAG, DETERMINISTIC_FLAG_DEFAULT); + map.put(ENABLE_IF, ENABLE_IF_DEFAULT); + map.put(ENABLE_SITE_ROUTING, ENABLE_SITE_ROUTING_DEFAULT); + + return map; + } + + public static void writeJSONForDREAMPlaceFPGA(Path jsonPath, Map attributes) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(jsonPath.toFile()))) { + bw.write("{\n"); + boolean first = true; + for (Entry e : attributes.entrySet()) { + if (first) { + first = false; + } else { + bw.write(",\n"); + } + bw.write(" \"" + e.getKey() + "\""); + bw.write(" : "); + if (e.getValue() instanceof String && !e.getKey().equals(GLOBAL_PLACE_STAGES)) { + bw.write("\"" + e.getValue().toString() + "\""); + } else if (e.getValue() instanceof Boolean) { + bw.write((boolean) e.getValue() ? "1" : "0"); + } else { + bw.write(e.getValue().toString() + ""); + } + + } + bw.write("\n}\n"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + } + + public static Design placeDesign(Design design, String ioPlacementFile, boolean makeOutOfContext, Path workDir) { + // Create interchange netlist file + String interchangeRootFile = workDir.toString() + File.separator + "design"; + EDIFNetlist flatNetlist = EDIFTools.createFlatNetlist(design.getNetlist(), design.getPartName()); + flatNetlist.setShapes(ShapeTools.extractShapes(design, null)); + try { + LogNetlistWriter.writeLogNetlist(flatNetlist, interchangeRootFile + Interchange.LOG_NETLIST_EXT); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + // Interchange.writeDesignToInterchange(design, interchangeRootFile); + + design.getNetlist().expandMacroUnisims(design.getDevice().getSeries()); + // Create device file if it doesn't already exist + String deviceName = design.getDevice().getName(); + Path deviceFile = workDir.resolve(deviceName + ".device"); + if (!Files.exists(deviceFile)) { + try { + DeviceResourcesWriter.writeDeviceResourcesFile(design.getPartName(), design.getDevice(), + new CodePerfTracker("Create IF Device"), deviceFile.toString(), true); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + // Create JSON file for DREAMPlaceFPGA + Path jsonFile = workDir.resolve("design.json"); + Map settings = getSettingsMap(); + settings.put(INTERCHANGE_DEVICE, deviceFile.toString()); + settings.put(INTERCHANGE_NETLIST, interchangeRootFile + Interchange.LOG_NETLIST_EXT); + settings.put(PLACE_SOL, ""); + settings.put(IO_PL, ioPlacementFile); + writeJSONForDREAMPlaceFPGA(jsonFile, settings); + + // Run DREAMPlaceFPGA + String exec = dreamPlaceFPGAExec + " " + jsonFile.toString(); + boolean verbose = true; + String[] environ = null; + Integer exitCode = FileTools.runCommand(exec, verbose, environ, workDir.toFile()); + if (exitCode != 0) { + throw new RuntimeException("DREAMPlaceFPGA with code: " + exitCode); + } + + // Load placed result + Design placedDesign = null; + String interchangeResultFile = workDir.toString() + File.separator + "results/design/design"; + try { + placedDesign = PhysNetlistReader.readPhysNetlist(interchangeResultFile + Interchange.PHYS_NETLIST_EXT, + design.getNetlist()); + if (makeOutOfContext) { + placedDesign.setAutoIOBuffers(false); + placedDesign.setDesignOutOfContext(true); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return placedDesign; + } + + public static void main(String[] args) { + // Usage: [IO placement file (.pl)] [work directory] + if (args.length < 2 || args.length > 4) { + System.out.println("USAGE: [IO placement file (.pl)] [work directory]"); + return; + } + Design input = Design.readCheckpoint(args[0]); + + boolean makeOutOfContext = true; + String ioPlacementFile = ""; + if (args.length >= 3) { + File file = new File(args[2]); + if (!file.isDirectory()) { + ioPlacementFile = args[2]; + makeOutOfContext = false; + } + } + + Path workDir = args.length == 4 ? Paths.get(args[3]) : args.length == 3 && makeOutOfContext ? Paths.get(args[2]) : Paths.get(System.getProperty("user.dir")); + Design placed = placeDesign(input, ioPlacementFile, makeOutOfContext, workDir); + placed.writeCheckpoint(args[1]); + } +}