blob: 501a66c098485758a902b9b19dac7d9c5f114e38 [file] [log] [blame]
// 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();
}
}
}
}