Adding missing java files.
diff --git a/dump_io.java b/dump_io.java
new file mode 100644
index 0000000..6bfa143
--- /dev/null
+++ b/dump_io.java
@@ -0,0 +1,559 @@
+// Copyright 2020 Project U-Ray Authors
+//
+// 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 dev.fpga.rapidwright;
+
+import com.xilinx.rapidwright.design.*;
+import com.xilinx.rapidwright.design.tools.LUTTools;
+import com.xilinx.rapidwright.device.*;
+import com.xilinx.rapidwright.edif.*;
+import org.json.Property;
+import org.python.antlr.ast.Str;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.math.BigInteger;
+import java.util.*;
+
+public class dump_io {
+
+ static boolean is_hpio(SiteTypeEnum ste) {
+ return ste == SiteTypeEnum.HPIOB || ste == SiteTypeEnum.HPIOB_S || ste == SiteTypeEnum.HPIOB_SNGL || ste ==
+ SiteTypeEnum.HPIOB_M;
+ }
+ static boolean is_hdio(SiteTypeEnum ste) {
+ return ste == SiteTypeEnum.HDIOB_M || ste == SiteTypeEnum.HDIOB_S;
+ }
+ static boolean is_hdiol(SiteTypeEnum ste) {
+ return ste == SiteTypeEnum.HDIOLOGIC_M || ste == SiteTypeEnum.HDIOLOGIC_S;
+ }
+
+ static String site_index_in_tile(Tile t, Site s) {
+ int min_x = s.getInstanceX(), min_y = s.getInstanceY();
+ for (Site s2 : t.getSites()) {
+ if (s2.getSiteTypeEnum() == s.getSiteTypeEnum() ||
+ (is_hpio(s2.getSiteTypeEnum()) && is_hpio(s.getSiteTypeEnum())) ||
+ (is_hdio(s2.getSiteTypeEnum()) && is_hdio(s.getSiteTypeEnum())) ||
+ (is_hdiol(s2.getSiteTypeEnum()) && is_hdiol(s.getSiteTypeEnum())))
+ {
+ min_x = Math.min(min_x, s2.getInstanceX());
+ min_y = Math.min(min_y, s2.getInstanceY());
+ }
+ }
+ return s.getSiteTypeEnum().toString() + "_X" + (s.getInstanceX() - min_x) + "Y" + (s.getInstanceY() - min_y);
+ }
+ public static String clean_value(String orig) {
+ if (orig.startsWith("1'b"))
+ return orig.substring(3);
+ else
+ return orig;
+ }
+
+ static HashSet<String> inverted_pips = new HashSet<>();
+
+ static boolean is_sink_inverted(SitePinInst spi) {
+ Net n = spi.getNet();
+ HashMap<Node, PIP> pip_uphill = new HashMap<>();
+ for (PIP p : n.getPIPs()) {
+ pip_uphill.putIfAbsent(p.getEndNode(), p);
+ if (p.isBidirectional()) {
+ pip_uphill.putIfAbsent(p.getStartNode(), p);
+ }
+ }
+ boolean inv = false;
+ Node cursor = spi.getConnectedNode();
+ while (pip_uphill.containsKey(cursor)) {
+ PIP p = pip_uphill.get(cursor);
+ String name = p.getTile().getName() + "/" + p.getTile().getTileTypeEnum().toString() + "." + p.getStartWireName() + (p.isBidirectional() ? "<<->>" : "->>") + p.getEndWireName();
+ if (inverted_pips.contains(name))
+ inv = !inv;
+ //System.out.println(name + " " + inv);
+ if (p.isBidirectional() && p.getStartNode().equals(cursor))
+ cursor = p.getEndNode();
+ else
+ cursor = p.getStartNode();
+ }
+ return inv;
+ }
+
+
+ public static boolean process_inv(ArrayList<String> features, String prefix, String feature, Cell c, String value) {
+ if (!feature.endsWith("INVERTED"))
+ return false;
+ int p0 = feature.indexOf('_'), p1 = feature.lastIndexOf('_');
+ String port = feature.substring(p0 + 1, p1);
+ String phys = c.getPhysicalPinMapping(port);
+ if (phys == null)
+ return true;
+ String site_wire = c.getSiteWireNameFromPhysicalPin(phys);
+ if (site_wire == null)
+ return true;
+ Net n = c.getSiteInst().getNetFromSiteWire(site_wire);
+ if (n == null)
+ return true;
+ if (n.isStaticNet() || n.getLogicalNet() == null)
+ return true;
+ int prop_value = Integer.parseInt(clean_value(value));
+ ArrayList<String> sw = new ArrayList<>();
+ if (is_sink_inverted((c.getSitePinFromLogicalPin(port, sw))))
+ prop_value ^= 1;
+ features.add(prefix + "." + feature + "." + prop_value);
+ return true;
+ }
+ public static void add_oserdes(ArrayList<String> features, String prefix, Cell c) {
+ if (c.getType().equals("<LOCKED>"))
+ return;
+
+ features.add(prefix + ".USED");
+ String cprefix = prefix + "." + c.getType();
+ features.add(cprefix + ".USED");
+ String[] basic_props = {"ODDR_MODE", "OSERDES_D_BYPASS", "OSERDES_T_BYPASS", "INIT",
+ "IS_CLKDIV_INVERTED", "IS_CLK_INVERTED", "IS_RST_INVERTED", "DATA_WIDTH"};
+ for (var prop : basic_props) {
+ var value = c.getProperty(prop);
+ if (value == null)
+ continue;
+ if (process_inv(features, cprefix, prop, c, value.getValue()))
+ continue;
+ features.add(cprefix + "." + prop + "." + clean_value(value.getValue()));
+ }
+ }
+ public static void add_iserdes(ArrayList<String> features, String prefix, Cell c) {
+ if (c.getType().equals("<LOCKED>"))
+ return;
+ features.add(prefix + ".USED");
+ String cprefix = prefix + "." + c.getType();
+ features.add(cprefix + ".USED");
+ String[] basic_props = {"IDDR_MODE", "DDR_CLK_EDGE",
+ "IS_CLK_B_INVERTED", "IS_CLK_INVERTED",
+ "IS_RST_INVERTED", "DATA_WIDTH"};
+ for (var prop : basic_props) {
+ var value = c.getProperty(prop);
+ if (value == null)
+ continue;
+ if (process_inv(features, cprefix, prop, c, value.getValue()))
+ continue;
+ features.add(cprefix + "." + prop + "." + clean_value(value.getValue()));
+ }
+ process_inv(features, cprefix, "IS_CLKDIV_INVERTED", c, "1'b0");
+ }
+ public static void add_iddr(ArrayList<String> features, String prefix, Cell c) {
+ if (c.getType().equals("<LOCKED>"))
+ return;
+ features.add(prefix + ".USED");
+ String cprefix = prefix + "." + c.getType();
+ features.add(cprefix + ".USED");
+ String[] basic_props = {"DDR_CLK_EDGE",
+ "IS_C_INVERTED", "IS_CB_INVERTED", "IS_RST_INVERTED"};
+ for (var prop : basic_props) {
+ var value = c.getProperty(prop);
+ if (value == null)
+ continue;
+ if (process_inv(features, cprefix, prop, c, value.getValue()))
+ continue;
+ features.add(cprefix + "." + prop + "." + clean_value(value.getValue()));
+ }
+ }
+ public static void add_delay(ArrayList<String> features, String prefix, Cell c) {
+ if (c.getType().equals("<LOCKED>"))
+ return;
+ features.add(prefix + ".USED");
+ String[] basic_props = {"DELAY_FORMAT", "DELAY_SRC",
+ "DELAY_TYPE", "IS_CLK_INVERTED", "IS_RST_INVERTED", "LOOPBACK",
+ "UPDATE_MODE"};
+ for (var prop : basic_props) {
+ var value = c.getProperty(prop);
+ if (value == null)
+ continue;
+ if (process_inv(features, prefix, prop, c, value.getValue()))
+ continue;
+ features.add(prefix + "." + prop + "." + clean_value(value.getValue()));
+ }
+ if (c.getProperty("DELAY_FORMAT") != null && c.getProperty("DELAY_FORMAT").getValue().equals("COUNT")) {
+ var counts = c.getProperty("DELAY_VALUE");
+ if (counts != null) {
+ int x = Integer.parseInt(counts.getValue());
+ for (int i = 0; i < 9; i++) {
+ if (((x >> i) & 0x1) == 0x1)
+ features.add(prefix + ".DELAY_VALUE[" + i + "]");
+ }
+ }
+ } else if (c.getProperty("DELAY_FORMAT") != null && c.getProperty("DELAY_FORMAT").getValue().equals("TIME")) {
+ var del = c.getProperty("DELAY_VALUE");
+ if (del != null) {
+ int ps = Integer.parseInt(del.getValue());
+ if (ps >= 8) {
+ int refdiv = Math.min(511, (int)Math.floor((2000000.0/300.0) / ((double)ps)));
+ for (int i = 0; i < 9; i++) {
+ if (((refdiv >> i) & 0x1) == 0x1)
+ features.add(prefix + ".REFCLK_MULT[" + i + "]");
+ }
+ }
+ }
+ }
+ }
+ public static void add_ff(ArrayList<String> features, String prefix, Cell c) {
+ String ct = c.getType();
+ if (!ct.equals("FDRE") && !ct.equals("FDPE") && !ct.equals("FDCE") && !ct.equals("FDSE"))
+ return;
+ features.add(prefix + ".USED");
+ features.add(prefix + "." + c.getType());
+ var init = c.getProperty("INIT");
+ if (init != null)
+ features.add(prefix + ".INIT." + init.getIntValue().toString());
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ Scanner scanner = new Scanner(new File("mig/invpips.txt"));
+ while (scanner.hasNextLine()) {
+ String nl = scanner.nextLine().trim();
+ inverted_pips.add(nl);
+ }
+
+ File folder = new File("mig/specimen_io");
+ File[] listOfFiles = folder.listFiles();
+ for (File f : listOfFiles) {
+ if (f.getName().endsWith(".dcp")) {
+ Design des = Design.readCheckpoint(f.getAbsolutePath());
+ HashMap<String, ArrayList<String>> pips_by_tile = new HashMap<>();
+ for (Net n : des.getNets()) {
+
+ HashMap<Node, PIP> uphill = new HashMap<>();
+ HashSet<Node> allnodes = new HashSet<>();
+
+ if (n.getSource() != null)
+ uphill.put(n.getSource().getConnectedNode(), null);
+ for (PIP p : n.getPIPs()) {
+ uphill.put(p.getEndNode(), p);
+ allnodes.add(p.getStartNode());
+ allnodes.add(p.getEndNode());
+ }
+
+
+ for (PIP p : n.getPIPs()) {
+
+ String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
+ TileTypeEnum ptt = p.getTile().getTileTypeEnum();
+
+ if (!pips_by_tile.containsKey(tile))
+ pips_by_tile.put(tile, new ArrayList<>());
+
+ String startName = p.getStartWireName(), endName = p.getEndWireName();
+ if (ptt == TileTypeEnum.XIPHY_BYTE_L) {
+ if (!endName.contains("ODT") && (startName.contains("CLB2PHY") || endName.contains("CLB2PHY")))
+ continue;
+ if (endName.contains("CLK_PIN") || endName.contains("CLKDIV_PIN") || endName.contains("D_PIN"))
+ continue;
+ SitePin sp = p.getEndNode().getSitePin();
+ if (sp != null) {
+ Site s = sp.getSite();
+ if (s.getSiteTypeEnum() == SiteTypeEnum.BITSLICE_RX_TX && endName.contains("Q5")) {
+ SiteInst si = des.getSiteInstFromSite(s);
+ boolean bypass = true;
+ if (si != null) {
+ for (Cell c : si.getCells()) {
+ if (!c.getType().equals("<LOCKED>")) {
+ bypass = false;
+ break;
+ }
+ }
+ }
+ if (bypass) {
+ String sn = site_index_in_tile(s.getTile(), s);
+ pips_by_tile.get(tile).add(sn + ".BYPASS." + sp.getPinName());
+ }
+ }
+ }
+ }
+
+ if (p.isBidirectional()) {
+ boolean is_fwd = uphill.containsKey(p.getStartNode());
+ pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName() + (is_fwd ? ".FWD" : ".REV"));
+ } else {
+ pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName());
+ }
+ }
+ }
+ HashMap<String, ArrayList<String>> sitefeatures_by_tile = new HashMap<>();
+ for (SiteInst si : des.getSiteInsts()) {
+ SiteTypeEnum ste = si.getSiteTypeEnum();
+ if (ste != SiteTypeEnum.HPIOB &&
+ ste != SiteTypeEnum.HPIOB_M &&
+ ste != SiteTypeEnum.HPIOB_S &&
+ ste != SiteTypeEnum.HPIOB_SNGL &&
+ ste != SiteTypeEnum.HDIOB_M && ste != SiteTypeEnum.HDIOB_S)
+ continue;
+ String tile = si.getTile().getName() + ":" + si.getTile().getTileTypeEnum().toString();
+ String sn = site_index_in_tile(si.getTile(), si.getSite());
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ Net ionet = si.getNetFromSiteWire("OUTBUF_O");
+ if (ionet == null)
+ continue;
+ Cell pad = si.getCell(si.getBEL("PAD"));
+ if (pad == null)
+ continue;
+ EDIFPort p = des.getTopEDIFCell().getPort(pad.getName());
+ var prop = des.getTopEDIFCell().getNet(pad.getName()).getProperties();
+ var pprop = p.getProperties();
+ String iostd = prop.get(new EDIFName("IOSTANDARD")).getValue();
+ String prefix = sn + "." + iostd;
+ tfeat.add(sn + ".USED");
+ tfeat.add(prefix + ".USED");
+ Cell inbuf = si.getCell(si.getBEL("INBUF"));
+ Cell outbuf = si.getCell(si.getBEL("OUTBUF"));
+ Cell pull = si.getCell(si.getBEL("PULL"));
+ if (pull != null)
+ System.out.println(pull.getType());
+
+ if (inbuf != null) {
+ tfeat.add(sn + ".IN");
+ tfeat.add(prefix + ".IN");
+ if (outbuf == null) {
+ tfeat.add(sn + ".IN_ONLY");
+ tfeat.add(prefix + ".IN_ONLY");
+ }
+ if (iostd.startsWith("SSTL") || iostd.startsWith("POD") || iostd.startsWith("HSUL") || iostd.startsWith("HSTL"))
+ {
+ if (pprop.containsKey(new EDIFName("X_internal_vref"))) {
+ double vref = Double.parseDouble(pprop.get(new EDIFName("X_internal_vref")).getValue());
+ tfeat.add("VREF.INTERNAL." + (int)(1000 * vref) + "_MV");
+ } else if (!pprop.containsKey(new EDIFName("X_internal_vref")) && !pprop.containsKey(new EDIFName("X_int_vref"))) {
+ tfeat.add("VREF.EXTERNAL");
+ }
+ }
+ if (iostd.endsWith("DCI") && (si.getTile().getTileYCoordinate() % 60) == 0) {
+ tfeat.add("VRP_USED");
+ }
+ Cell ibufctrl = si.getCell(si.getBEL("IBUFCTRL"));
+ if (ibufctrl != null && ibufctrl.getLogicalPinMapping("IBUFDISABLE") != null)
+ tfeat.add(sn + ".IBUFDISABLE_USED");
+ }
+ if (outbuf != null) {
+ tfeat.add(sn + ".OUT");
+ tfeat.add(prefix + ".OUT");
+ if (inbuf != null) {
+ tfeat.add(sn + ".IN_OUT");
+ tfeat.add(prefix + ".IN_OUT");
+ }
+ if (iostd.endsWith("DCI") && (si.getTile().getTileYCoordinate() % 60) == 0) {
+ tfeat.add("VRP_USED");
+ }
+ if (outbuf.getLogicalPinMapping("DCITERMDISABLE") != null) {
+ tfeat.add(sn + ".DCITERMDISABLE_USED");
+ }
+ }
+
+ if (pprop.containsKey(new EDIFName("X_PULLTYPE")))
+ tfeat.add(sn + ".PULLTYPE." + pprop.get(new EDIFName("X_PULLTYPE")).getValue());
+ if (pprop.containsKey(new EDIFName("X_DRIVE")))
+ tfeat.add(prefix + ".DRIVE." + pprop.get(new EDIFName("X_DRIVE")).getValue());
+ if (pprop.containsKey(new EDIFName("X_SLEW")) && outbuf != null) {
+ if (pprop.containsKey(new EDIFName("X_DRIVE"))) {
+ tfeat.add(prefix + ".DRIVE." + pprop.get(new EDIFName("X_DRIVE")).getValue() + ".SLEW." + pprop.get(new EDIFName("X_SLEW")).getValue());
+ }else {
+ tfeat.add(prefix + ".SLEW." + pprop.get(new EDIFName("X_SLEW")).getValue());
+ }
+ }
+ if (pprop.containsKey(new EDIFName("X_OUTPUT_IMPEDANCE")) && outbuf != null)
+ tfeat.add(prefix + ".OUTPUT_IMPEDANCE." + pprop.get(new EDIFName("X_OUTPUT_IMPEDANCE")).getValue());
+ if (pprop.containsKey(new EDIFName("X_EQUALIZATION")))
+ tfeat.add(prefix + ".EQUALIZATION." + pprop.get(new EDIFName("X_EQUALIZATION")).getValue());
+ if (pprop.containsKey(new EDIFName("X_ODT")))
+ tfeat.add(prefix + ".ODT." + pprop.get(new EDIFName("X_ODT")).getValue());
+ for (SitePIP pip : si.getUsedSitePIPs()) {
+ if (pip.getBEL().getBELType().contains("INV"))
+ continue;
+ tfeat.add(sn + "." + pip.getBEL().getName() + "." + pip.getInputPinName());
+ }
+ }
+ for (SiteInst si : des.getSiteInsts()) {
+ SiteTypeEnum ste = si.getSiteTypeEnum();
+ if (ste != SiteTypeEnum.HPIOBDIFFINBUF && ste != SiteTypeEnum.HPIOBDIFFOUTBUF)
+ continue;
+ String tile = si.getTile().getName() + ":" + si.getTile().getTileTypeEnum().toString();
+ String sn = site_index_in_tile(si.getTile(), si.getSite());
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ boolean used = false;
+ for (Cell c : si.getCells())
+ if (!c.getType().equals("<LOCKED>"))
+ used = true;
+ if (!used)
+ continue;;
+ if (ste == SiteTypeEnum.HPIOBDIFFINBUF) {
+ Node cursor = si.getSite().getConnectedNode("PAD_RES_0");
+ while (cursor.getSitePin() == null || cursor.getSitePin().getSite().getSiteTypeEnum() != SiteTypeEnum.HPIOB_M) {
+ for (Wire w : cursor.getAllWiresInNode()) {
+ if (w.getBackwardPIPs().isEmpty())
+ continue;
+ cursor = w.getBackwardPIPs().get(0).getStartNode();
+ break;
+ }
+ }
+ Site m = cursor.getSitePin().getSite();
+ SiteInst m_si = des.getSiteInstFromSite(m);
+ Cell pad = m_si.getCell(m_si.getBEL("PAD"));
+ EDIFPort p = des.getTopEDIFCell().getPort(pad.getName());
+ var prop = des.getTopEDIFCell().getNet(pad.getName()).getProperties();
+ var pprop = p.getProperties();
+ String iostd = prop.get(new EDIFName("IOSTANDARD")).getValue();
+ tfeat.add(sn + "." + iostd + ".DIFF_IN");
+ if (pprop.containsKey(new EDIFName("X_DIFF_TERM_ADV")))
+ tfeat.add(sn + "." + iostd + ".DIFF_TERM_ADV." + pprop.get(new EDIFName("X_DIFF_TERM_ADV")).getValue());
+ } else if (ste == SiteTypeEnum.HPIOBDIFFOUTBUF) {
+ Node cursor = si.getSite().getConnectedNode("AOUT");
+ while (cursor.getSitePin() == null || cursor.getSitePin().getSite().getSiteTypeEnum() != SiteTypeEnum.HPIOB_M) {
+ for (Wire w : cursor.getAllWiresInNode()) {
+ if (w.getForwardPIPs().isEmpty())
+ continue;
+ cursor = w.getForwardPIPs().get(0).getEndNode();
+ break;
+ }
+ }
+ Site m = cursor.getSitePin().getSite();
+ SiteInst m_si = des.getSiteInstFromSite(m);
+ Cell pad = m_si.getCell(m_si.getBEL("PAD"));
+ EDIFPort p = des.getTopEDIFCell().getPort(pad.getName());
+ var prop = des.getTopEDIFCell().getNet(pad.getName()).getProperties();
+ var pprop = p.getProperties();
+ String iostd = prop.get(new EDIFName("IOSTANDARD")).getValue();
+ tfeat.add(sn + "." + iostd + ".DIFF_OUT");
+ }
+ }
+ for (SiteInst si : des.getSiteInsts()) {
+ String tile = si.getTile().getName() + ":" + si.getTile().getTileTypeEnum().toString();
+ if (si.getSiteTypeEnum() == SiteTypeEnum.BITSLICE_COMPONENT_RX_TX) {
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ String sp = site_index_in_tile(si.getTile(), si.getSite()) + ".";
+ boolean only_locked = true;
+ for (Cell c : si.getCells())
+ if (!c.getType().equals("<LOCKED>"))
+ only_locked = false;
+ if (!only_locked)
+ tfeat.add(sp + "COMPONENT_MODE");
+ else
+ continue;
+ Cell idelay = si.getCell("IDELAY");
+ if (idelay != null)
+ add_delay(tfeat, sp + "IDELAY", idelay);
+ Cell odelay = si.getCell("ODELAY");
+ if (odelay != null)
+ add_delay(tfeat, sp + "ODELAY", odelay);
+ Cell iserdes = si.getCell("ISERDES");
+ if (iserdes != null)
+ add_iserdes(tfeat, sp + "ISERDES", iserdes);
+ Cell oserdes = si.getCell("OSERDES");
+ if (oserdes != null)
+ add_oserdes(tfeat, sp + "OSERDES", oserdes);
+ Cell iff = si.getCell("IN_FF");
+ if (iff != null)
+ add_ff(tfeat, sp + "IN_FF", iff);
+ Cell off = si.getCell("OUT_FF");
+ if (off != null)
+ add_ff(tfeat, sp + "OUT_FF", off);
+ for (SitePIP pip : si.getUsedSitePIPs()) {
+ if (pip.getBEL().getBELType().contains("INV"))
+ continue;
+ tfeat.add(sp + pip.getBEL().getName() + "." + pip.getInputPinName());
+ }
+ if (odelay != null && oserdes == null && off == null && si.getNetFromSiteWire("OSERDES_OQ") != null)
+ tfeat.add(sp + "OSERDES.BYPASSED");
+ if (idelay == null && si.getNetFromSiteWire("IDELAY_DATAOUT") != null)
+ tfeat.add(sp + "IDELAY.BYPASSED");
+ String[] used_sitewires = {"OSERDES_OQ", "TX_Q", "RX_D"};
+ for (String sw : used_sitewires) {
+ boolean active = false;
+ if (si.getNetFromSiteWire(sw) != null)
+ active = true;
+ for (SitePIP p : si.getUsedSitePIPs())
+ if (p.getInputPin().getSiteWireName().equals(sw))
+ active = true;
+ if (active)
+ tfeat.add(sp + sw + ".USED");
+ }
+ } else if (si.getSiteTypeEnum() == SiteTypeEnum.BITSLICE_CONTROL) {
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ String sp = site_index_in_tile(si.getTile(), si.getSite()) + ".";
+ for (Cell c : si.getCells()) {
+ if (c.getType().equals("IDELAYCTRL")) {
+ tfeat.add(sp + "IDELAYCTRL.USED");
+ }
+ }
+ } else if (si.getSiteTypeEnum() == SiteTypeEnum.HDIOLOGIC_M || si.getSiteTypeEnum() == SiteTypeEnum.HDIOLOGIC_S) {
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ String sp = site_index_in_tile(si.getTile(), si.getSite()) + ".";
+ boolean only_locked = true;
+ for (Cell c : si.getCells())
+ if (!c.getType().equals("<LOCKED>"))
+ only_locked = false;
+ if (!only_locked)
+ tfeat.add(sp + "USED");
+ else
+ continue;
+ Cell iff = si.getCell("IFF");
+ if (iff != null)
+ add_ff(tfeat, sp + "IFF", iff);
+ Cell off = si.getCell("OPFF");
+ if (off != null)
+ add_ff(tfeat, sp + "OPFF", off);
+ Cell tff = si.getCell("TFF");
+ if (tff != null)
+ add_ff(tfeat, sp + "TFF", tff);
+
+ Cell iddr = si.getCell("IDDR");
+ if (iddr != null)
+ add_iddr(tfeat, sp + "IDDR", iddr);
+ Cell optff = si.getCell("OPTFF");
+ if (optff != null)
+ add_oserdes(tfeat, sp + "OPTFF", optff);
+ }
+ }
+
+
+ FileWriter vf = new FileWriter(f.getAbsolutePath().replace(".dcp", ".features"), false);
+ PrintWriter v = new PrintWriter(vf);
+ for (Tile t : des.getDevice().getAllTiles()) {
+ TileTypeEnum tt = t.getTileTypeEnum();
+ if (tt == TileTypeEnum.HPIO_L || tt == TileTypeEnum.HPIO_RIGHT || tt == TileTypeEnum.HDIO_TOP_RIGHT
+ || tt == TileTypeEnum.HDIO_BOT_RIGHT || tt == TileTypeEnum.XIPHY_BYTE_L) {
+ String tname = t.getName() + ":" + tt.toString();
+ if (sitefeatures_by_tile.containsKey(tname) || pips_by_tile.containsKey(tname)) {
+ v.println(".tile " + tname);
+ if (sitefeatures_by_tile.containsKey(tname))
+ for (String sf : sitefeatures_by_tile.get(tname))
+ v.println(sf);
+ if (pips_by_tile.containsKey(tname))
+ for (String pip : pips_by_tile.get(tname))
+ v.println(pip);
+ }
+ }
+ }
+ v.close();
+ vf.close();
+ }
+ }
+ }
+}
diff --git a/dump_laguna.java b/dump_laguna.java
new file mode 100644
index 0000000..0575628
--- /dev/null
+++ b/dump_laguna.java
@@ -0,0 +1,227 @@
+// Copyright 2020 Project U-Ray Authors
+//
+// 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 dev.fpga.rapidwright;
+
+import com.xilinx.rapidwright.design.Cell;
+import com.xilinx.rapidwright.design.Design;
+import com.xilinx.rapidwright.design.Net;
+import com.xilinx.rapidwright.design.SiteInst;
+import com.xilinx.rapidwright.device.*;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Scanner;
+
+public class dump_laguna {
+
+ static String site_index_in_tile(Tile t, Site s) {
+ int min_x = s.getInstanceX(), min_y = s.getInstanceY();
+ for (Site s2 : t.getSites()) {
+ if (s2.getSiteTypeEnum() == s.getSiteTypeEnum()) {
+ min_x = Math.min(min_x, s2.getInstanceX());
+ min_y = Math.min(min_y, s2.getInstanceY());
+ }
+ }
+ return s.getSiteTypeEnum().toString() + "_X" + (s.getInstanceX() - min_x) + "Y" + (s.getInstanceY() - min_y);
+ }
+
+ public static void main(String[] args) throws IOException {
+
+
+ File folder = new File("specimen_lag");
+ File[] listOfFiles = folder.listFiles();
+ for (File f : listOfFiles) {
+ if (f.getName().endsWith(".dcp")) {
+ Design des = Design.readCheckpoint(f.getAbsolutePath());
+ HashMap<String, ArrayList<String>> pips_by_tile = new HashMap<>();
+ HashMap<String, ArrayList<String>> sitefeatures_by_tile = new HashMap<>();
+ HashSet<Node> usednodes = new HashSet<>();
+ for (Net n : des.getNets()) {
+ HashMap<Node, PIP> uphill = new HashMap<>();
+
+ if (n.getSource() != null)
+ uphill.put(n.getSource().getConnectedNode(), null);
+ for (PIP p : n.getPIPs()) {
+ if (!p.isBidirectional()) {
+ uphill.put(p.getEndNode(), p);
+ }
+
+ usednodes.add(p.getStartNode());
+ usednodes.add(p.getEndNode());
+ }
+ for (PIP p : n.getPIPs()) {
+
+ String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
+ if (p.getTile().getTileTypeEnum() == TileTypeEnum.BRAM || p.getTile().getTileTypeEnum() == TileTypeEnum.INT)
+ continue;
+ if (!pips_by_tile.containsKey(tile))
+ pips_by_tile.put(tile, new ArrayList<>());
+ if (p.isBidirectional()) {
+ Node cursor = p.getStartNode();
+ boolean is_fwd = false;
+ if (uphill.containsKey(p.getStartNode())) {
+ is_fwd = true;
+ uphill.put(p.getEndNode(), p);
+ } else if (uphill.containsKey(p.getEndNode())) {
+ is_fwd = false;
+ uphill.put(p.getStartNode(), p);
+ } else {
+ continue;
+ }
+ pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName() + (is_fwd ? ".FWD" : ".REV"));
+ } else {
+ pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName());
+ SitePin sp = p.getEndNode().getSitePin();
+ if (sp != null && p.isRouteThru() && sp.getSite().getSiteTypeEnum() == SiteTypeEnum.LAGUNA && sp.getPinName().startsWith("RXQ")) {
+ String prefix = site_index_in_tile(p.getTile(), sp.getSite());
+ String pin = sp.getPinName();
+ pips_by_tile.get(tile).add(prefix + ".RX_REG" + pin.charAt(pin.length()-1) + ".BYPASS");
+ }
+ }
+ }
+ }
+
+ for (Tile t : des.getDevice().getAllTiles()) {
+ if (t.getTileTypeEnum() == TileTypeEnum.LAG_LAG) {
+ String tile = t.getName() + ":" + t.getTileTypeEnum().toString();
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ for (Site s : t.getSites()) {
+ if (s.getSiteTypeEnum() != SiteTypeEnum.LAGUNA)
+ continue;
+ boolean[] no_rx_used = {true, true, true, true, true, true};
+ SiteInst si = des.getSiteInstFromSite(s);
+ if (si != null) {
+ for (BEL b : si.getBELs()) {
+ if (!b.getName().startsWith("RX_REG"))
+ continue;
+ if (si.getCell(b) != null && si.getCell(b).getType() != null && !si.getCell(b).getType().equals("<LOCKED>")) {
+ String qw = si.getCell(b).getSiteWireNameFromLogicalPin("Q");
+ if (qw != null && si.getNetFromSiteWire(qw) != null && !si.getNetFromSiteWire(qw).getSinkPins().isEmpty())
+ no_rx_used[Integer.parseInt(b.getName().substring(6))] = false;
+ }
+ }
+ }
+ String prefix = site_index_in_tile(t, s);
+ for (int i = 0; i < 6; i++)
+ if (no_rx_used[i])
+ tfeat.add(prefix + ".RX_REG" + i + ".BYPASS");
+
+ }
+ }
+ }
+ for (SiteInst si : des.getSiteInsts()) {
+ if (si.getSiteTypeEnum() != SiteTypeEnum.LAGUNA)
+ continue;
+ String prefix = site_index_in_tile(si.getTile(), si.getSite());
+ String tile = si.getTile().getName() + ":" + si.getTile().getTileTypeEnum().toString();
+ if (!sitefeatures_by_tile.containsKey(tile))
+ sitefeatures_by_tile.put(tile, new ArrayList<>());
+ ArrayList<String> tfeat = sitefeatures_by_tile.get(tile);
+ for (BEL b : si.getBELs()) {
+ Cell c = si.getCell(b);
+ if (c != null && c.getType() != null && !c.getType().equals("<LOCKED>")) {
+ boolean is_latch = false, is_sync = false, srval = false;
+ String clkpin, srpin, cepin;
+ if (c.getType().equals("FDPE")) {
+ is_sync = false;
+ srval = true;
+ clkpin = "C";
+ cepin = "CE";
+ srpin = "PRE";
+ } else if (c.getType().equals("FDCE")) {
+ is_sync = false;
+ srval = false;
+ clkpin = "C";
+ cepin = "CE";
+ srpin = "CLR";
+ } else if (c.getType().equals("FDSE")) {
+ is_sync = true;
+ srval = true;
+ clkpin = "C";
+ cepin = "CE";
+ srpin = "S";
+ } else if (c.getType().equals("FDRE")) {
+ is_sync = true;
+ srval = false;
+ clkpin = "C";
+ cepin = "CE";
+ srpin = "R";
+ } else {
+ continue;
+ }
+ String group = b.getName().substring(0, 6);
+ tfeat.add(prefix + "." + group + ".USED");
+ if (is_sync)
+ tfeat.add(prefix + "." + group + ".SYNC");
+ else
+ tfeat.add(prefix + "." + group + ".ASYNC");
+ tfeat.add(prefix + "." + b.getName() + ".SRVAL." + (srval ? "1" : "0"));
+ if (c.getProperty("INIT") != null) {
+ String init = c.getProperty("INIT").getValue();
+ tfeat.add(prefix + "." + b.getName() + ".INIT." + init.substring(init.length() - 1));
+ }
+ String clk = c.getSiteWireNameFromLogicalPin(clkpin);
+ if (clk != null && si.getNetFromSiteWire(clk) != null && !si.getNetFromSiteWire(clk).isStaticNet()) {
+ if (c.getProperty("IS_C_INVERTED") != null) {
+ String init = c.getProperty("IS_C_INVERTED").getValue();
+ tfeat.add(prefix + "." + group + ".CLKINV." + init.substring(init.length() - 1));
+ }
+ }
+ String srw = c.getSiteWireNameFromLogicalPin(srpin);
+ if (srw != null && si.getNetFromSiteWire(srw) != null && !si.getNetFromSiteWire(srw).isStaticNet()) {
+ if (c.getProperty("IS_" + srpin + "_INVERTED") != null) {
+ String init = c.getProperty("IS_" + srpin + "_INVERTED").getValue();
+ tfeat.add(prefix + "." + group + ".SRINV." + init.substring(init.length() - 1));
+ }
+ tfeat.add(prefix + "." + group + ".SRUSED");
+ }
+ String cew = c.getSiteWireNameFromLogicalPin(cepin);
+ if (cew != null && si.getNetFromSiteWire(srw) != null && !si.getNetFromSiteWire(srw).isStaticNet()) {
+ tfeat.add(prefix + "." + group + ".CEUSED");
+ }
+ }
+ }
+ }
+ FileWriter vf = new FileWriter(f.getAbsolutePath().replace(".dcp", ".features"), false);
+ PrintWriter v = new PrintWriter(vf);
+ for (Tile t : des.getDevice().getAllTiles()) {
+ TileTypeEnum tt = t.getTileTypeEnum();
+ if (tt == TileTypeEnum.LAG_LAG) {
+ String tname = t.getName() + ":" + tt.toString();
+ if (!pips_by_tile.containsKey(tname) && !sitefeatures_by_tile.containsKey(tname))
+ continue;
+ v.println(".tile " + tname);
+ if (pips_by_tile.containsKey(tname))
+ for (String p : pips_by_tile.get(tname))
+ v.println(p);
+ if (sitefeatures_by_tile.containsKey(tname))
+ for (String sf : sitefeatures_by_tile.get(tname))
+ v.println(sf);
+ }
+ }
+ vf.close();
+ }
+
+ }
+
+ }
+}