// 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;
import java.util.Collections;
import java.util.List;

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

            List<String> tiles = new ArrayList<String>();
            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;
                    tiles.add(tname);
                }
            }

            Collections.sort(tiles);
            for(String tname : tiles) {
                v.println(".tile " + tname);
                if (pips_by_tile.containsKey(tname)) {
                    List<String> features = pips_by_tile.get(tname);
                    Collections.sort(features);
                    for (String p : features) {
                        v.println(p);
                    }
                }
                if (sitefeatures_by_tile.containsKey(tname)) {
                    List<String> features = sitefeatures_by_tile.get(tname);
                    Collections.sort(features);
                    for (String sf : features) {
                        v.println(sf);
                    }
                }
            }
            vf.close();
        }
    }
}
