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(); + } + + } + + } +}