aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-06-16 17:53:09 +0200
committerClifford Wolf <clifford@clifford.at>2018-06-16 17:53:09 +0200
commitf0edb625e3280237aba2d73e950a8dbaf91e9427 (patch)
tree899f10d606399eeacb223d6c30d060ea5566c763
parentad0df6cea898d5d524ea90040e21298a5567b635 (diff)
downloadnextpnr-f0edb625e3280237aba2d73e950a8dbaf91e9427.tar.gz
nextpnr-f0edb625e3280237aba2d73e950a8dbaf91e9427.tar.bz2
nextpnr-f0edb625e3280237aba2d73e950a8dbaf91e9427.zip
Progress with chipdb refactoring
Signed-off-by: Clifford Wolf <clifford@clifford.at>
-rw-r--r--ice40/chip.cc4
-rw-r--r--ice40/chip.h45
-rw-r--r--ice40/chipdb.py159
3 files changed, 175 insertions, 33 deletions
diff --git a/ice40/chip.cc b/ice40/chip.cc
index 1255dfc8..82200758 100644
--- a/ice40/chip.cc
+++ b/ice40/chip.cc
@@ -153,7 +153,7 @@ BelId Chip::getBelByName(IdString name) const
if (bel_by_name.empty()) {
for (int i = 0; i < chip_info.num_bels; i++)
- bel_by_name[chip_info.bel_data[i].name] = i;
+ bel_by_name[chip_info.bel_data[i].name.ptr()] = i;
}
auto it = bel_by_name.find(name);
@@ -190,7 +190,7 @@ WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
assert(bel != BelId());
int num_bel_wires = chip_info.bel_data[bel.index].num_bel_wires;
- BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires;
+ BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires.ptr();
for (int i = 0; i < num_bel_wires; i++)
if (bel_wires[i].port == pin) {
diff --git a/ice40/chip.h b/ice40/chip.h
index 5eeca5e9..66924022 100644
--- a/ice40/chip.h
+++ b/ice40/chip.h
@@ -72,7 +72,6 @@ PortPin portPinFromId(IdString id);
// -----------------------------------------------------------------------
-#if 0
template <typename T>
struct RelPtr {
int offset;
@@ -87,16 +86,17 @@ struct RelPtr {
T*operator->() {
return reinterpret_cast<T*>(reinterpret_cast<char*>(this) + offset);
}
+
+ T*ptr() {
+ return reinterpret_cast<T*>(reinterpret_cast<char*>(this) + offset);
+ }
};
-#else
-template <typename T> using RelPtr = T *;
-#endif
struct BelWirePOD
{
int32_t wire_index;
PortPin port;
-};
+} __attribute__((packed));
struct BelInfoPOD
{
@@ -105,13 +105,14 @@ struct BelInfoPOD
int32_t num_bel_wires;
RelPtr<BelWirePOD> bel_wires;
int8_t x, y, z;
-};
+ int8_t filler_0;
+} __attribute__((packed));
struct BelPortPOD
{
int32_t bel_index;
PortPin port;
-};
+} __attribute__((packed));
struct PipInfoPOD
{
@@ -120,33 +121,33 @@ struct PipInfoPOD
int8_t x, y;
int16_t switch_mask;
int32_t switch_index;
-};
+} __attribute__((packed));
struct WireInfoPOD
{
- RelPtr<char> name;
+ const char *name;
int32_t num_uphill, num_downhill;
- RelPtr<int32_t> pips_uphill, pips_downhill;
+ int32_t *pips_uphill, *pips_downhill;
int32_t num_bels_downhill;
BelPortPOD bel_uphill;
- RelPtr<BelPortPOD> bels_downhill;
+ BelPortPOD *bels_downhill;
int8_t x, y;
-};
+} __attribute__((packed));
struct PackagePinPOD
{
const char *name;
int32_t bel_index;
-};
+} __attribute__((packed));
struct PackageInfoPOD
{
const char *name;
int num_pins;
PackagePinPOD *pins;
-};
+} __attribute__((packed));
enum TileType
{
@@ -160,21 +161,21 @@ enum TileType
struct ConfigBitPOD
{
int8_t row, col;
-};
+} __attribute__((packed));
struct ConfigEntryPOD
{
const char *name;
int num_bits;
ConfigBitPOD *bits;
-};
+} __attribute__((packed));
struct TileInfoPOD
{
int8_t cols, rows;
int num_config_entries;
ConfigEntryPOD *entries;
-};
+} __attribute__((packed));
static const int max_switch_bits = 5;
@@ -183,13 +184,13 @@ struct SwitchInfoPOD
int8_t x, y;
int num_bits;
ConfigBitPOD cbits[max_switch_bits];
-};
+} __attribute__((packed));
struct IerenInfoPOD
{
int8_t iox, ioy, ioz;
int8_t ierx, iery, ierz;
-};
+} __attribute__((packed));
struct BitstreamInfoPOD
{
@@ -197,7 +198,7 @@ struct BitstreamInfoPOD
TileInfoPOD *tiles_nonrouting;
SwitchInfoPOD *switches;
IerenInfoPOD *ierens;
-};
+} __attribute__((packed));
struct ChipInfoPOD
{
@@ -210,7 +211,7 @@ struct ChipInfoPOD
TileType *tile_grid;
BitstreamInfoPOD *bits_info;
PackageInfoPOD *packages_data;
-};
+} __attribute__((packed));
extern ChipInfoPOD chip_info_384;
extern ChipInfoPOD chip_info_1k;
@@ -476,7 +477,7 @@ struct Chip
IdString getBelName(BelId bel) const
{
assert(bel != BelId());
- return chip_info.bel_data[bel.index].name;
+ return chip_info.bel_data[bel.index].name.ptr();
}
void bindBel(BelId bel, IdString cell)
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index f8fe8b5d..2d09c22e 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -4,6 +4,8 @@ import sys
import re
import textwrap
+endianness = "le"
+
dev_name = None
dev_width = None
dev_height = None
@@ -39,6 +41,25 @@ tile_bits = [[] for _ in range(num_tile_types)]
cbit_re = re.compile(r'B(\d+)\[(\d+)\]')
+portpins = dict()
+beltypes = dict()
+
+with open("ice40/portpins.inc") as f:
+ for line in f:
+ line = line.replace("(", " ")
+ line = line.replace(")", " ")
+ line = line.split()
+ if len(line) == 0:
+ continue
+ assert len(line) == 2
+ assert line[0] == "X"
+ idx = len(portpins) + 1
+ portpins[line[1]] = idx
+
+beltypes["ICESTORM_LC"] = 1
+beltypes["ICESTORM_RAM"] = 2
+beltypes["SB_IO"] = 3
+beltypes["SB_GB"] = 4
def maj_wire_name(name):
if re.match(r"lutff_\d/(in|out)", name[2]):
@@ -344,24 +365,144 @@ elif dev_name == "384":
add_bel_gb( 3, 0, 5)
add_bel_gb( 3, 9, 4)
+class BinaryBlobAssembler:
+ def __init__(self):
+ self.data = bytearray()
+ self.comments = dict()
+ self.labels = dict()
+ self.labels_byaddr = dict()
+ self.ltypes_byaddr = dict()
+ self.refs = dict()
+
+ def l(self, name, ltype = None):
+ assert name not in self.labels
+ assert len(self.data) not in self.labels_byaddr
+ self.labels[name] = len(self.data)
+ if ltype is not None:
+ self.ltypes_byaddr[len(self.data)] = ltype
+ self.labels_byaddr[len(self.data)] = name
+
+ def r(self, name, comment):
+ assert len(self.data) not in self.refs
+ self.refs[len(self.data)] = (name, comment)
+ self.data.append(0)
+ self.data.append(0)
+ self.data.append(0)
+ self.data.append(0)
+
+ def s(self, v, comment):
+ for i in range(len(v)):
+ self.data.append(ord(v[i]))
+ self.data.append(0)
+ self.comments[len(self.data)] = comment
+
+ def u8(self, v, comment):
+ self.data.append(v)
+ self.comments[len(self.data)] = comment
+
+ def u16(self, v, comment):
+ if endianness == "le":
+ self.data.append(v & 255)
+ self.data.append((v >> 8) & 255)
+ elif endianness == "be":
+ self.data.append((v >> 8) & 255)
+ self.data.append(v & 255)
+ else:
+ assert 0
+ self.comments[len(self.data)] = comment
+
+ def u32(self, v, comment):
+ if endianness == "le":
+ self.data.append(v & 255)
+ self.data.append((v >> 8) & 255)
+ self.data.append((v >> 16) & 255)
+ self.data.append((v >> 24) & 255)
+ elif endianness == "be":
+ self.data.append((v >> 24) & 255)
+ self.data.append((v >> 16) & 255)
+ self.data.append((v >> 8) & 255)
+ self.data.append(v & 255)
+ else:
+ assert 0
+ self.comments[len(self.data)] = comment
+
+ def write_c(self, f):
+ cursor = 0
+ bytecnt = 0
+ while cursor < len(self.data):
+ if cursor in self.comments:
+ if bytecnt == 0:
+ print(" ", end="")
+ print(" // %s" % self.comments[cursor])
+ bytecnt = 0
+ if cursor in self.labels_byaddr:
+ if bytecnt != 0:
+ print()
+ if cursor in self.ltypes_byaddr:
+ print("#define %s ((%s*)(binblob_%s+%d))" % (self.labels_byaddr[cursor], self.ltypes_byaddr[cursor], dev_name, cursor))
+ else:
+ print(" // [%d] %s" % (cursor, self.labels_byaddr[cursor]))
+ bytecnt = 0
+ if cursor in self.refs:
+ v = self.labels[self.refs[cursor][0]] - cursor
+ if bytecnt != 0:
+ print()
+ print(" ", end="")
+ if endianness == "le":
+ print(" %3d," % (v & 255), end="")
+ print(" %3d," % ((v >> 8) & 255), end="")
+ print(" %3d," % ((v >> 16) & 255), end="")
+ print(" %3d," % ((v >> 24) & 255), end="")
+ elif endianness == "be":
+ print(" %3d," % (v & 255), end="")
+ print(" %3d," % ((v >> 8) & 255), end="")
+ print(" %3d," % ((v >> 16) & 255), end="")
+ print(" %3d," % ((v >> 24) & 255), end="")
+ else:
+ assert 0
+ print(" // [%d] %s (reference to %s)" % (cursor, self.refs[cursor][1], self.refs[cursor][0]))
+ bytecnt = 0
+ cursor += 4
+ else:
+ if bytecnt == 0:
+ print(" ", end="")
+ print(" %3d," % self.data[cursor], end=("" if bytecnt < 15 else "\n"))
+ bytecnt = (bytecnt + 1) & 15
+ cursor += 1
+ if bytecnt != 0:
+ print()
+
+bba = BinaryBlobAssembler()
+
print('#include "nextpnr.h"')
print('namespace {')
print('USING_NEXTPNR_NAMESPACE')
index = 0
-print("static BelWirePOD bel_wires[] = {")
for bel in range(len(bel_name)):
- print("#define bel_wires_%d (bel_wires+%d)" % (bel, index))
+ bba.l("bel_wires_%d" % bel, "BelWirePOD")
for i in range(len(bel_wires[bel])):
- print(" {%d, PIN_%s}," % bel_wires[bel][i])
+ bba.u32(bel_wires[bel][i][0], "wire_index")
+ bba.u32(portpins[bel_wires[bel][i][1]], "port")
index += 1
-print("};")
-print("static BelInfoPOD bel_data_%s[%d] = {" % (dev_name, len(bel_name)))
for bel in range(len(bel_name)):
- print(" {\"%s\", TYPE_%s, %d, bel_wires_%d, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel],
- len(bel_wires[bel]), bel, bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2],
- "," if bel+1 < len(bel_name) else ""))
+ bba.l("bel_name_%d" % bel, "char")
+ bba.s(bel_name[bel], "name: %s" % bel_name[bel])
+
+bba.l("bel_data", "BelInfoPOD")
+for bel in range(len(bel_name)):
+ bba.r("bel_name_%d" % bel, "name")
+ bba.u32(beltypes[bel_type[bel]], "type")
+ bba.u32(len(bel_wires[bel]), "num_bel_wires")
+ bba.r("bel_wires_%d" % bel, "bel_wires")
+ bba.u8(bel_pos[bel][0], "x")
+ bba.u8(bel_pos[bel][1], "y")
+ bba.u8(bel_pos[bel][2], "z")
+ bba.u8(0, "filler")
+
+print("static uint8_t binblob_%s[] = {" % dev_name)
+bba.write_c(sys.stdout)
print("};")
wireinfo = list()
@@ -540,7 +681,7 @@ print('NEXTPNR_NAMESPACE_BEGIN')
print("ChipInfoPOD chip_info_%s = {" % dev_name)
print(" %d, %d, %d, %d, %d, %d, %d," % (dev_width, dev_height, len(bel_name), num_wires, len(pipinfo), len(switchinfo), len(packageinfo)))
-print(" bel_data_%s, wire_data_%s, pip_data_%s," % (dev_name, dev_name, dev_name))
+print(" bel_data, wire_data_%s, pip_data_%s," % (dev_name, dev_name))
print(" tile_grid_%s, &bits_info_%s, package_info_%s" % (dev_name, dev_name, dev_name))
print("};")