// 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.EDIFName;
import com.xilinx.rapidwright.edif.EDIFPort;
import com.xilinx.rapidwright.edif.EDIFPortInst;
import org.python.bouncycastle.crypto.tls.DefaultTlsCipherFactory;

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

        File folder = new File("/specimen_clk");
        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<>();
                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.getName().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.getAbsolutePath().replace(".dcp", ".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();
            }
        }

    }
}
