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