// 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.

import com.xilinx.rapidwright.design.*;
import com.xilinx.rapidwright.design.tools.LUTTools;
import com.xilinx.rapidwright.device.*;
import com.xilinx.rapidwright.edif.EDIFName;
import com.xilinx.rapidwright.edif.EDIFPort;
import com.xilinx.rapidwright.edif.EDIFPortInst;

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_clocking {
    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);
    }

    static HashSet<String> inverted_pips = new HashSet<>();

    static boolean is_sink_inverted(SitePinInst spi) {
        if (spi == null || spi.getNet() == null)
            return false;
        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;
    }

    static boolean is_node_inverted(Net n, Node cursor) {
        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;
       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;
    }

    static int get_clock_depth(Net n, Node cursor) {
        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);
            }
        }
        int distr_count = 0;
        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();
           // System.out.println("   " + name);
            if (p.isBidirectional() && p.getStartNode().equals(cursor))
                cursor = p.getEndNode();
            else
                cursor = p.getStartNode();
            if (cursor.getWireName().contains("DISTR"))
                distr_count++;
            //System.out.println(" <---" + cursor.getTile().getName() + "/" + cursor.getWireName());
        }
        //System.out.println("distr count: " + distr_count);
        return distr_count;
    }



    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(new File("invpips.txt"));
        while (scanner.hasNextLine()) {
            String nl = scanner.nextLine().trim();
            inverted_pips.add(nl);
        }

        for (String f : args) {
            Design des = Design.readCheckpoint(f);
            HashMap<String, ArrayList<String>> pips_by_tile = new HashMap<>();
            HashMap<String, ArrayList<String>> sitefeatures_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);
                int max_distr_depth = 0;
                for (PIP p : n.getPIPs()) {
                    if (!p.isBidirectional()) {
                        uphill.put(p.getEndNode(), p);
                    }

                    allnodes.add(p.getStartNode());
                    allnodes.add(p.getEndNode());

                    TileTypeEnum ptt = p.getTile().getTileTypeEnum();
                    if (ptt == TileTypeEnum.RCLK_INT_L || ptt == TileTypeEnum.RCLK_INT_R) {
                        if (p.getEndWireName().startsWith("CLK_LEAF_SITES_") && p.getEndWireName().endsWith("_CLK_LEAF")) {
                            String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
                            if (!pips_by_tile.containsKey(tile))
                                pips_by_tile.put(tile, new ArrayList<>());
                            pips_by_tile.get(tile).add("WIRE." + p.getEndWireName() + ".DRIVEN");
                            if (p.getStartWireName().endsWith("_CLK_IN") && p.isRouteThru()) {
                                String site = site_index_in_tile(p.getTile(), p.getStartNode().getSitePin().getSite());
                                if (!sitefeatures_by_tile.containsKey(tile))
                                    sitefeatures_by_tile.put(tile, new ArrayList<>());
                                sitefeatures_by_tile.get(tile).add(site + ".BUFCE_LEAF.IN_USE");


                                if (n.getName().startsWith("leaf_delay_")) {
                                    int count = 0;
                                    for (PIP p2 : n.getPIPs()) {
                                        if (p2.getEndWireName().startsWith("CLK_LEAF_SITES_") && p2.getEndWireName().endsWith("_CLK_LEAF") && p2.getStartWireName().endsWith("_CLK_IN"))
                                            ++count;
                                    }
                                    if (count == 1) {
                                        int value = Integer.parseInt(n.getName().split("_")[2]);
                                        sitefeatures_by_tile.get(tile).add(site + ".BUFCE_LEAF.DELAY_TAP_" + value);
                                    }
                                    if (is_node_inverted(n, p.getStartNode())) {
                                        sitefeatures_by_tile.get(tile).add(site + ".BUFCE_LEAF.IINV.1");
                                    }
                                }
                            }
                        }
                    }
                    if (p.getStartWire().getWireName().contains("BUFCE_ROW_FSR") && p.getStartWire().getWireName().endsWith("CLK_IN")) {
                        max_distr_depth = Math.max(max_distr_depth, get_clock_depth(n, p.getStartNode()));
                    }
                }

                for (Node node : allnodes) {
                    for (Wire w : node.getAllWiresInNode()) {
                        TileTypeEnum wtt = w.getTile().getTileTypeEnum();
                        if (wtt == TileTypeEnum.RCLK_BRAM_INTF_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_TD_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_TD_R ||
                                wtt == TileTypeEnum.RCLK_CLEL_L_L || wtt == TileTypeEnum.RCLK_CLEL_L || wtt == TileTypeEnum.RCLK_CLEL_L_R ||
                                wtt == TileTypeEnum.RCLK_CLEM_CLKBUF_L || wtt == TileTypeEnum.RCLK_CLEM_L || wtt == TileTypeEnum.RCLK_DSP_INTF_L ||
                                wtt == TileTypeEnum.RCLK_DSP_INTF_R || wtt == TileTypeEnum.RCLK_RCLK_URAM_INTF_L_FT ||
                                wtt == TileTypeEnum.RCLK_CLEM_R || wtt == TileTypeEnum.RCLK_CLEL_R || wtt == TileTypeEnum.GTH_QUAD_RIGHT) {
                            if (w.getWireName().startsWith("CLK_TEST_BUF_SITE_") || w.getWireName().startsWith("CLK_HROUTE_CORE_OPT") ||
                                w.getWireName().startsWith("CLK_VDISTR_BOT") || w.getWireName().startsWith("CLK_VDISTR_TOP") ||
                                    w.getWireName().startsWith("CLK_VROUTE_BOT") || w.getWireName().startsWith("CLK_VROUTE_TOP")) {
                                String tile = w.getTile().getName() + ":" + w.getTile().getTileTypeEnum().toString();
                                if (!pips_by_tile.containsKey(tile))
                                    pips_by_tile.put(tile, new ArrayList<>());
                                pips_by_tile.get(tile).add("WIRE." + w.getWireName() + ".USED");
                            }
                        }
                        if (wtt == TileTypeEnum.RCLK_DSP_INTF_CLKBUF_L || wtt == TileTypeEnum.RCLK_CLEM_CLKBUF_L || wtt == TileTypeEnum.RCLK_BRAM_INTF_L ||
                            wtt == TileTypeEnum.RCLK_RCLK_XIPHY_INNER_FT || wtt == TileTypeEnum.RCLK_HDIO  || wtt == TileTypeEnum.GTH_QUAD_RIGHT) {
                            if (w.getWireName().startsWith("CLK_HROUTE") || w.getWireName().startsWith("CLK_HDISTR")) {
                                String tile = w.getTile().getName() + ":" + w.getTile().getTileTypeEnum().toString();
                                if (!pips_by_tile.containsKey(tile))
                                    pips_by_tile.put(tile, new ArrayList<>());
                                pips_by_tile.get(tile).add("WIRE." + w.getWireName() + ".USED");
                            }
                        }
                        if (wtt == TileTypeEnum.CMT_L) {
                            //CLK_HROUTE_
                            if (w.getWireName().startsWith("CLK_HROUTE_") || w.getWireName().startsWith("CLK_HDISTR_") || w.getWireName().startsWith("CLK_VDISTR_") ||
                                    w.getWireName().startsWith("CLK_TEST_BUF_SITE_")) {
                                String tile = w.getTile().getName() + ":" + w.getTile().getTileTypeEnum().toString();
                                if (!pips_by_tile.containsKey(tile))
                                    pips_by_tile.put(tile, new ArrayList<>());
                                pips_by_tile.get(tile).add("WIRE." + w.getWireName() + ".USED");
                            }
                        }
                    }
                }

                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());
                    }
                    if (n.getName().contains("clk_dly_fuzz") && p.getStartWire().getWireName().contains("BUFCE_ROW_FSR") && p.getStartWire().getWireName().endsWith("CLK_IN")) {
                        int depth = get_clock_depth(n, p.getStartNode());
                        int tap = max_distr_depth - depth;
                        String bufce_name = site_index_in_tile(p.getTile(), p.getStartNode().getSitePin().getSite());
                        for (int i = 0; i < 3; i++) {
                            if (((tap >> i) & 0x1) == 1) {
                                pips_by_tile.get(tile).add(bufce_name + ".COMP_DELAY_TAP[" + i + "]");
                            }
                        }
                    }
                }
            }
            for (SiteInst si : des.getSiteInsts()) {
                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);
                if (si.getSiteTypeEnum() == SiteTypeEnum.BUFCE_LEAF) {
                    String name = site_index_in_tile(si.getTile(), si.getSite());
                    for (Cell c : si.getCells()) {
                        if (c.getType() != null && c.getType().equals("BUFCE_LEAF")) {
                            tfeat.add(name + ".BUFCE_LEAF.IN_USE");
                            if (c.getProperty("CE_TYPE") != null)
                                tfeat.add(name + ".BUFCE_LEAF.CE_TYPE." + c.getProperty("CE_TYPE").getValue());
                            var all_props = c.getProperties();
                            for (var e : all_props.entrySet()) {
                                String propname = e.getKey().getName();
                                if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                                    String pinname = propname.substring(3, propname.length() - 9);
                                    String v = e.getValue().getValue();
                                    int base_pos = v.indexOf("'b");
                                    if (base_pos != -1)
                                        v = v.substring(base_pos + 2);
                                    if (pinname.equals("I"))
                                        if (is_sink_inverted(si.getSitePinInst("CLK_IN")))
                                            v = (v.equals("1") ? "0" : "1");
                                    tfeat.add(name + ".BUFCE_LEAF." + pinname + "INV." + v);
                                }
                            }
                        }
                    }
                } else if (si.getSiteTypeEnum() == SiteTypeEnum.BUFCE_ROW_FSR) {
                    for (Cell c : si.getCells()) {
                        if (c.getType().equals("<LOCKED>"))
                            System.out.println(c.getBELName());
                    }
                } else if (si.getSiteTypeEnum() == SiteTypeEnum.BUFGCE || si.getSiteTypeEnum() == SiteTypeEnum.BUFGCE_DIV) {
                    String name = site_index_in_tile(si.getTile(), si.getSite());
                    for (Cell c : si.getCells()) {
                        if (c.getType() != null && c.getType().startsWith("BUFGCE")) {
                            tfeat.add(name + "." + c.getType() + ".IN_USE");
                            var all_props = c.getProperties();
                            for (var e : all_props.entrySet()) {
                                String propname = e.getKey().getName();
                                String v = e.getValue().getValue();
                                int base_pos = v.indexOf("'b");
                                if (base_pos != -1)
                                    v = v.substring(base_pos + 2);
                                if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                                    String pinname = propname.substring(3, propname.length() - 9);
                                    if (pinname.equals("I")) {
                                        if (is_sink_inverted(si.getSitePinInst("CLK_IN")))
                                            v = (v.equals("1") ? "0" : "1");
                                        String sw = c.getSiteWireNameFromLogicalPin(pinname);
                                        if (sw == null || si.getNetFromSiteWire(sw) == null || si.getNetFromSiteWire(sw).isStaticNet())
                                            continue;
                                    }
                                    tfeat.add(name + "." + si.getSiteTypeEnum().toString() + "." + pinname + "INV." + v);
                                } else if ((si.getSiteTypeEnum() == SiteTypeEnum.BUFGCE && propname.equals("CE_TYPE")) || propname.equals("BUFGCE_DIVIDE")) {
                                    tfeat.add(name +  "." + si.getSiteTypeEnum().toString() + "." + propname + "." + v);
                                }
                            }
                        }
                    }
                } else if (si.getSiteTypeEnum() == SiteTypeEnum.BUFGCTRL) {
                    String name = site_index_in_tile(si.getTile(), si.getSite());
                    for (Cell c : si.getCells()) {
                        if (c.getType() != null && c.getType().startsWith("BUFGCTRL")) {
                            tfeat.add(name + "." + c.getType() + ".IN_USE");
                            var all_props = c.getProperties();
                            for (var e : all_props.entrySet()) {
                                String propname = e.getKey().getName();
                                String v = e.getValue().getValue();
                                int base_pos = v.indexOf("'b");
                                if (base_pos != -1)
                                    v = v.substring(base_pos + 2);
                                if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                                    String pinname = propname.substring(3, propname.length() - 9);
                                    if (pinname.equals("I0") || pinname.equals("I1")) {
                                        String sw = c.getSiteWireNameFromLogicalPin(pinname);
                                        if (sw == null || si.getNetFromSiteWire(sw) == null || si.getNetFromSiteWire(sw).isStaticNet())
                                            continue;
                                        if (is_sink_inverted(si.getSitePinInst("CLK_" + pinname)))
                                            v = (v.equals("1") ? "0" : "1");
                                    }
                                    tfeat.add(name + "." + si.getSiteTypeEnum().toString() + "." + pinname + "INV." + v);
                                } else if (propname.equals("INIT_OUT") || propname.startsWith("PRESELECT_")) {
                                    tfeat.add(name +  "." + si.getSiteTypeEnum().toString() + "." + propname + "." + v);
                                }
                            }
                        }
                    }
                } else if (si.getSiteTypeEnum() == SiteTypeEnum.MMCM) {
                    String name = site_index_in_tile(si.getTile(), si.getSite());
                    Cell c = si.getCell("MMCM");
                    if (c == null || c.getType() == null)
                        continue;
                    tfeat.add(name + ".IN_USE");
                    var all_props = c.getProperties();
                    for (var e : all_props.entrySet()) {
                        String propname = e.getKey().getName();
                        String v = e.getValue().getValue();
                        int base_pos = v.indexOf("'b");
                        if (base_pos != -1)
                            v = v.substring(base_pos + 2);
                        if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                            String pinname = propname.substring(3, propname.length() - 9);
                            if (pinname.equals("CLKIN1") || pinname.equals("CLKIN2") || pinname.equals("CLKFBIN"))
                                continue;
                            String sw = c.getSiteWireNameFromLogicalPin(pinname);
                            if (sw == null || si.getNetFromSiteWire(sw) == null || si.getNetFromSiteWire(sw).isStaticNet())
                                continue;
                            tfeat.add(name + "." + si.getSiteTypeEnum().toString() + "." + pinname + "INV." + v);
                        } else if (propname.equals("COMPENSATION")) {
                            tfeat.add(name +  "." + si.getSiteTypeEnum().toString() + "." + propname + "." + v);
                        }
                    }
                } else if (si.getSiteTypeEnum() == SiteTypeEnum.PLL) {
                    String name = site_index_in_tile(si.getTile(), si.getSite());
                    Cell c = si.getCell("PLL");
                    if (c == null || c.getType() == null)
                        continue;
                    tfeat.add(name + ".IN_USE");
                    var all_props = c.getProperties();
                    for (var e : all_props.entrySet()) {
                        String propname = e.getKey().getName();
                        String v = e.getValue().getValue();
                        int base_pos = v.indexOf("'b");
                        if (base_pos != -1)
                            v = v.substring(base_pos + 2);
                        if (propname.startsWith("IS_") && propname.endsWith("_INVERTED")) {
                            String pinname = propname.substring(3, propname.length() - 9);
                            if (pinname.equals("CLKIN") || pinname.equals("CLKFBIN"))
                                continue;
                            String sw = c.getSiteWireNameFromLogicalPin(pinname);
                            if (sw == null || si.getNetFromSiteWire(sw) == null || si.getNetFromSiteWire(sw).isStaticNet())
                                continue;
                            tfeat.add(name + "." + si.getSiteTypeEnum().toString() + "." + pinname + "INV." + v);
                        } else if (propname.equals("COMPENSATION")) {
                            tfeat.add(name +  "." + si.getSiteTypeEnum().toString() + "." + propname + "." + v);
                        }
                    }
                }
            }
            for (Tile t : des.getDevice().getAllTiles()) {
                if (t.getTileTypeEnum() != TileTypeEnum.RCLK_HPIO_L)
                    continue;
                boolean dci_used = false;
                Tile[] io_tiles = {des.getDevice().getTile(t.getRow()+30, t.getColumn()), des.getDevice().getTile(t.getRow()-1, t.getColumn())};
                for (Tile iot : io_tiles) {
                    for (Site s : iot.getSites()) {
                        SiteInst si = des.getSiteInstFromSite(s);
                        if (si == null)
                            continue;
                        Cell pad = si.getCell(si.getBEL("PAD"));
                        if (pad == null)
                            continue;
                        EDIFPort p = des.getTopEDIFCell().getPort(pad.getName());
                        if (des.getTopEDIFCell().getNet(pad.getName()) == null)
                            continue;
                        var prop = des.getTopEDIFCell().getNet(pad.getName()).getProperties();
                        if (prop == null || !prop.containsKey(new EDIFName("IOSTANDARD")))
                            continue;
                        String iostd = prop.get(new EDIFName("IOSTANDARD")).getValue();
                        if (iostd.contains("POD12_DCI") && !f.contains("ipi")) // FIXME: find out why this loses bits
                            dci_used = true;
                    }
                }
                if (dci_used) {
                    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);
                    tfeat.add("POD12_DCI_USED");
                }
            }
            FileWriter vf = new FileWriter(f.replace(".dcp", "_o2.features"), false);
            PrintWriter v = new PrintWriter(vf);
            for (Tile t : des.getDevice().getAllTiles()) {
                TileTypeEnum tt = t.getTileTypeEnum();
                if (tt == TileTypeEnum.RCLK_INT_L|| tt == TileTypeEnum.RCLK_CLEM_L || tt == TileTypeEnum.RCLK_INT_R || tt == TileTypeEnum.RCLK_CLEM_CLKBUF_L || tt == TileTypeEnum.RCLK_CLEM_R ||
                        tt == TileTypeEnum.RCLK_DSP_INTF_L || tt == TileTypeEnum.RCLK_BRAM_L || tt == TileTypeEnum.RCLK_BRAM_R || tt == TileTypeEnum.RCLK_BRAM_INTF_L ||
                        tt == TileTypeEnum.RCLK_DSP_INTF_R || tt == TileTypeEnum.RCLK_DSP_CLKBUF_L || tt == TileTypeEnum.RCLK_RCLK_XIPHY_INNER_FT || tt == TileTypeEnum.RCLK_RCLK_INTF_XIPHY_LEFT_L_FT ||
                        tt == TileTypeEnum.RCLK_HDIO || tt == TileTypeEnum.RCLK_HPIO_L || tt == TileTypeEnum.RCLK_HPIO_R ||
                        tt == TileTypeEnum.RCLK_CLEL_L || tt == TileTypeEnum.RCLK_CLEL_R || tt == TileTypeEnum.RCLK_CLEL_L_L || tt == TileTypeEnum.RCLK_CLEL_L_R ||
                        tt == TileTypeEnum.RCLK_DSP_INTF_CLKBUF_L || tt == TileTypeEnum.RCLK_BRAM_INTF_TD_L || tt == TileTypeEnum.RCLK_BRAM_INTF_TD_R || tt == TileTypeEnum.CMT_L || tt == TileTypeEnum.CMT_RIGHT ||
                        tt == TileTypeEnum.RCLK_RCLK_URAM_INTF_L_FT || tt == TileTypeEnum.GTH_QUAD_RIGHT) {
                    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();
        }
    }
}
