blob: 381a4deb7ef6afd933f5ecc823d445019161437a [file] [log] [blame] [edit]
// 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 + "]");
}
}
}
}
boolean pins_used = false, d_grounded = true;
for (EDIFPortInst epi : eci.getPortInsts()) {
if (epi.isOutput() && epi.getNet() != null) {
tfeat.add(name + "." + epi.getName() + ".USED");
}
}
for (SitePinInst spi : si.getSitePinInsts()) {
if (!spi.getName().startsWith("DIN"))
continue;
if (spi.getNet() != null) {
pins_used = true;
if (!spi.getNet().isStaticNet())
d_grounded = false;
}
}
if (pins_used && d_grounded)
tfeat.add(name + ".D_NOT_USED");
//if (c_grounded)
// tfeat.add(name + ".C_NOT_USED");
break;
}
}
} else if (si.getSiteTypeEnum() == SiteTypeEnum.URAM288) {
Cell c = si.getCell("URAM_288K_INST");
if (c == null || c.getType() == null)
continue;
String name = site_index_in_tile(si.getTile(), si.getSite());
tfeat.add("URAM.IN_USE");
tfeat.add(name + ".IN_USE");
String[] enum_props = {"BWE_MODE_A", "BWE_MODE_B", "EN_AUTO_SLEEP_MODE", "EN_ECC_RD_A", "EN_ECC_RD_B",
"EN_ECC_WR_A", "EN_ECC_WR_B", "IREG_PRE_A", "IREG_PRE_B", "OREG_A", "OREG_B", "OREG_ECC_A", "OREG_ECC_B", "REG_CAS_A",
"REG_CAS_B", "RST_MODE_A", "RST_MODE_B", "USE_EXT_CE_A", "USE_EXT_CE_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);
tfeat.add(name + "." + p + "." + v);
}
var all_props = c.getProperties();
for (var e : all_props.entrySet()) {
String prop_name = e.getKey().getName();
if (prop_name.startsWith("IS_") && prop_name.endsWith("_INVERTED")) {
String pinname = prop_name.substring(3, prop_name.length() - 9);
if (c.getLogicalPinMapping(pinname) == null)
continue;
Net n = si.getNetFromSiteWire(c.getSiteWireNameFromLogicalPin(pinname));
if (n == null || n.isStaticNet())
continue;
String v = e.getValue().getValue();
int base_pos = v.indexOf("'b");
if (base_pos != -1)
v = v.substring(base_pos + 2);
tfeat.add(name + "." + pinname + "INV." + v);
}
}
String[] word_props = {"SELF_ADDR_A", "SELF_ADDR_B", "SELF_MASK_A", "SELF_MASK_B"};
for (String p : word_props) {
if (c.getProperty(p) != null) {
long lval = LUTTools.getInitValue(c.getProperty(p).getValue());
for (int i = 0; i < 11; i++) {
boolean is_inv = p.contains("_MASK_");
if (((lval >> i) & 0x1) == (is_inv ? 0 : 1))
tfeat.add(name + "." + p + (is_inv ? "_INV" : "") + "[" + i + "]");
}
}
}
EDIFPropertyValue asl = c.getProperty("AUTO_SLEEP_LATENCY");
if (asl != null) {
int a = Integer.parseInt(asl.getValue());
for (int i = 0; i < 4; i++)
if (((a >> i) & 0x1) == 1) {
tfeat.add(name + ".AUTO_SLEEP_LATENCY[" + i + "]");
}
}
for (EDIFPortInst epi : c.getEDIFCellInst().getPortInsts()) {
if (epi.isOutput() && epi.getNet() != null)
tfeat.add(name + "." + epi.getName() + ".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.BRAM || tt == TileTypeEnum.DSP || tt == TileTypeEnum.DSP_L || tt == TileTypeEnum.DSP_R ||
tt == TileTypeEnum.URAM_URAM_FT || tt == TileTypeEnum.URAM_URAM_DELAY_FT) {
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();
}
}
}
}