// 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 jnr.ffi.annotations.In;
import org.json.Property;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class dump_bram {

    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_bram");
        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()) {
                    for (PIP p : n.getPIPs()) {
                        String tile = p.getTile().getName() + ":" + p.getTile().getTileTypeEnum().toString();
                        if (p.getTile().getTileTypeEnum() == TileTypeEnum.BRAM)
                            continue;
                        if (!pips_by_tile.containsKey(tile))
                            pips_by_tile.put(tile, new ArrayList<>());
                        pips_by_tile.get(tile).add("PIP." + p.getEndWireName() + "." + p.getStartWireName());
                    }
                }
                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.RAMB180 || si.getSiteTypeEnum() == SiteTypeEnum.RAMB181 || si.getSiteTypeEnum() == SiteTypeEnum.RAMB36) {
                        for (BEL b : si.getBELs()) {
                            String belName = b.getName();
                            Cell c = si.getCell(b);
                            if (c == null || c.getType() == null)
                                continue;
                            if ((si.getSiteTypeEnum() == SiteTypeEnum.RAMB36 && !c.getType().equals("RAMB36E2")) ||
                                    ((si.getSiteTypeEnum() == SiteTypeEnum.RAMB180 || si.getSiteTypeEnum() == SiteTypeEnum.RAMB181) && !c.getType().equals("RAMB18E2")))
                                continue;
                            int prim_width = si.getSiteTypeEnum() == SiteTypeEnum.RAMB36 ? 36 : 18;
                            tfeat.add("BRAM.IN_USE");
                            tfeat.add(belName + ".IN_USE");
                            boolean have_ecc = false;

                            boolean is_sdp = false;
                            if (c.getProperty("READ_WIDTH_A") != null && Integer.parseInt(c.getProperty("READ_WIDTH_A").getValue()) > prim_width)
                                is_sdp = true;
                            if (c.getProperty("WRITE_WIDTH_B") != null && Integer.parseInt(c.getProperty("WRITE_WIDTH_B").getValue()) > prim_width)
                                is_sdp = true;

                            String[] enum_props = {
                                    "CLOCK_DOMAINS",
                                    "DOA_REG", "DOB_REG",
                                    "READ_WIDTH_A", "READ_WIDTH_B", "WRITE_WIDTH_A", "WRITE_WIDTH_B",
                                    "WRITE_MODE_A", "WRITE_MODE_B",
                                    "ENADDRENA", "ENADDRENB", "RDADDRCHANGEA", "RDADDRCHANGEB",
                                    "RSTREG_PRIORITY_A", "RSTREG_PRIORITY_B",
                                    "SLEEP_ASYNC", "EN_ECC_PIPE", "EN_ECC_READ", "EN_ECC_WRITE",
                                    "CASCADE_ORDER_A", "CASCADE_ORDER_B"};
                            for (String p : enum_props) {
                                EDIFPropertyValue ep = c.getProperty(p);
                                if (ep == null)
                                    continue;
                                String v = ep.getValue();
                                int base_pos = v.indexOf("'b");
                                if (base_pos != -1)
                                    v = v.substring(base_pos + 2);
                                if (p.startsWith("RSTREG_") && is_sdp)
                                    continue;
                                tfeat.add(belName + "." + p + "." + v);
                                if (p.contains("EN_ECC") && v.equals("TRUE"))
                                    have_ecc = true;
                            }

                            var all_props = c.getProperties();
                            for (var e : all_props.entrySet()) {
                                String name = e.getKey().getName();
                                if (name.startsWith("IS_") && name.endsWith("_INVERTED")) {
                                    String pinname = name.substring(3, name.length() - 9);
                                    String v = e.getValue().getValue();
                                    int base_pos = v.indexOf("'b");
                                    if (base_pos != -1)
                                        v = v.substring(base_pos + 2);
                                    tfeat.add(belName + "." + pinname + "INV." + v);
                                }
                            }

                            String[] word_props = {"INIT_A", "INIT_B", "SRVAL_A", "SRVAL_B"};
                            for (String p : word_props) {
                                EDIFPropertyValue width = c.getProperty("READ_WIDTH_" + p.substring(p.length() - 1));
                                if (width == null || !width.getValue().equals(Integer.toString(prim_width)) || have_ecc)
                                    continue;
                                if (c.getProperty(p) != null) {
                                    long lval = LUTTools.getInitValue(c.getProperty(p).getValue());
                                    for (int i = 0; i < prim_width; i++) {
                                        if ((lval & (1L << i)) != 0)
                                            tfeat.add(belName + "." + p + "[" + i + "]");
                                    }
                                }
                            }
                            for (EDIFPortInst epi : c.getEDIFCellInst().getPortInsts()) {
                                if (epi.getName().startsWith("DOUT") && epi.getNet() != null)
                                    tfeat.add(belName + "." + epi.getName() + ".USED");
                            }
                        }
                    } else if (si.getSiteTypeEnum() == SiteTypeEnum.DSP48E2) {
                       for (Cell c : si.getCells()) {
                           if (!c.getName().contains("/"))
                               continue;
                           EDIFCellInst eci = des.getTopEDIFCell().getCellInst(c.getName().split("/")[0]);
                           if (eci == null)
                               continue;
                           if (eci.getCellType().getName() != null && eci.getCellType().getName().equals("DSP48E2")) {
                               String name = site_index_in_tile(si.getTile(), si.getSite());
                               tfeat.add("DSP.IN_USE");
                               tfeat.add(name + ".IN_USE");
                               boolean have_patdet = false;
                               if (eci.getProperty("USE_PATTERN_DETECT") != null && eci.getProperty("USE_PATTERN_DETECT").getValue().equals("PATDET"))
                                   have_patdet = true;
                               boolean have_xor = false;
                               if (eci.getProperty("USE_WIDEXOR") != null && eci.getProperty("USE_WIDEXOR").getValue().equals("TRUE"))
                                   have_xor = true;

                               String[] enum_props = {"ADREG", "ALUMODEREG", "AMULTSEL", "AREG", "AUTORESET_PATDET", "AUTORESET_PRIORITY",
                                    "BMULTSEL", "BREG", "CARRYINREG", "CARRYINSELREG", "CREG", "DREG", "INMODEREG", "MREG", "OPMODEREG",
                                       "PREADDINSEL", "PREG", "SEL_MASK", "SEL_PATTERN", "USE_PATTERN_DETECT", "USE_SIMD", "USE_WIDEXOR", "XORSIMD"};
                               for (String p : enum_props) {
                                   EDIFPropertyValue ep = eci.getProperty(p);
                                   if (ep == null)
                                       continue;
                                   if (!have_patdet && (p.equals("AUTORESET_PATDET") || p.equals("AUTORESET_PRIORITY") || p.equals("SEL_MASK") || p.equals("SEL_PATTERN")))
                                       continue;
                                   if (!have_xor && p.equals("XORSIMD"))
                                       continue;
                                   String v = ep.getValue();
                                   int base_pos = v.indexOf("'b");
                                   if (base_pos != -1)
                                       v = v.substring(base_pos + 2);
                                   tfeat.add(name + "." + p + "." + v);
                               }

                               var all_props = eci.getProperties();
                               for (var e : all_props.entrySet()) {
                                   String pname = e.getKey().getName();
                                   if (pname.startsWith("IS_") && pname.endsWith("_INVERTED")) {
                                       String pinname = pname.substring(3, pname.length() - 9);
                                       int width = 1;
                                       if (pinname.equals("ALUMODE"))
                                           width = 4;
                                       else if (pinname.equals("INMODE"))
                                           width = 5;
                                       else if (pinname.equals("OPMODE"))
                                           width = 9;
                                       if (pinname.contains("RST") && (eci.getPortInst(pinname).getNet() == null || eci.getPortInst(pinname).getNet().getName().contains("const")))
                                           continue;
                                       String v = e.getValue().getValue();
                                       if (width == 1) {
                                           int base_pos = v.indexOf("'b");
                                           if (base_pos != -1)
                                               v = v.substring(base_pos + 2);
                                           tfeat.add(name + "." + pinname + "INV." + v);
                                       } else {
                                           long lval = LUTTools.getInitValue(v);
                                           for (int i = 0; i < width; i++) {
                                               tfeat.add(name + "." + pinname + "INV" + "[" + i + "]." + (((lval & (1L << i)) != 0) ? "1" : "0"));
                                           }
                                       }

                                   }
                               }

                               if (/*have_patdet*/true) {
                                   String[] word_props = {"MASK", "PATTERN", "RND"};
                                   for (String p : word_props) {
                                       if (eci.getProperty(p) != null) {
                                           long lval = LUTTools.getInitValue(eci.getProperty(p).getValue());
                                           for (int i = 0; i < 48; i++) {
                                               if ((lval & (1L << i)) != 0 || (p.equals("MASK") && !have_patdet))
                                                   tfeat.add(name + "." + p + "[" + i + "]");
                                           }
                                       }
                                   }
                               }

                               for (EDIFPortInst epi : eci.getPortInsts()) {
                                   if (epi.isOutput() && epi.getNet() != null)
                                       tfeat.add(name + "." + epi.getName() + ".USED");
                               }

                               break;
                           }
                       }

                   }
                }
                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.BRAM || tt == TileTypeEnum.DSP || tt == TileTypeEnum.DSP_L || tt == TileTypeEnum.DSP_R) {
                        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();
            }
        }

    }
}
