Minor refactoring of BinaryBlobAssembler, fix alignments
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
69e5bc5030
commit
84defd3fee
@ -31,7 +31,7 @@ const ConfigEntryPOD &find_config(const TileInfoPOD &tile,
|
||||
const std::string &name)
|
||||
{
|
||||
for (int i = 0; i < tile.num_config_entries; i++) {
|
||||
if (std::string(tile.entries[i].name.ptr()) == name) {
|
||||
if (std::string(tile.entries[i].name.get()) == name) {
|
||||
return tile.entries[i];
|
||||
}
|
||||
}
|
||||
|
@ -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.ptr()] = i;
|
||||
bel_by_name[chip_info.bel_data[i].name.get()] = 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;
|
||||
const BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires.ptr();
|
||||
const BelWirePOD *bel_wires = chip_info.bel_data[bel.index].bel_wires.get();
|
||||
|
||||
for (int i = 0; i < num_bel_wires; i++)
|
||||
if (bel_wires[i].port == pin) {
|
||||
@ -264,7 +264,7 @@ IdString Chip::getPipName(PipId pip) const
|
||||
BelId Chip::getPackagePinBel(const std::string &pin) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pins[i].name.ptr() == pin) {
|
||||
if (package_info->pins[i].name.get() == pin) {
|
||||
BelId id;
|
||||
id.index = package_info->pins[i].bel_index;
|
||||
return id;
|
||||
@ -277,7 +277,7 @@ std::string Chip::getBelPackagePin(BelId bel) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pins[i].bel_index == bel.index) {
|
||||
return std::string(package_info->pins[i].name.ptr());
|
||||
return std::string(package_info->pins[i].name.get());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
29
ice40/chip.h
29
ice40/chip.h
@ -72,27 +72,30 @@ PortPin portPinFromId(IdString id);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**** Everything in this section must be kept in sync with chipdb.py ****/
|
||||
|
||||
template <typename T>
|
||||
struct RelPtr {
|
||||
int offset;
|
||||
int32_t offset;
|
||||
|
||||
// RelPtr(const T *ptr) : offset(reinterpret_cast<const char*>(ptr) -
|
||||
// reinterpret_cast<const char*>(this)) {}
|
||||
// void set(const T *ptr) {
|
||||
// offset = reinterpret_cast<const char*>(ptr) - reinterpret_cast<const char*>(this);
|
||||
// }
|
||||
|
||||
const T*get() const {
|
||||
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) + offset);
|
||||
}
|
||||
|
||||
const T&operator[](size_t index) const {
|
||||
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) + offset)[index];
|
||||
return get()[index];
|
||||
}
|
||||
|
||||
const T&operator*() const {
|
||||
return *reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) + offset);
|
||||
return *(get());
|
||||
}
|
||||
|
||||
const T*operator->() const {
|
||||
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) + offset);
|
||||
}
|
||||
|
||||
const T*ptr() const {
|
||||
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) + offset);
|
||||
return get();
|
||||
}
|
||||
};
|
||||
|
||||
@ -109,7 +112,7 @@ struct BelInfoPOD
|
||||
int32_t num_bel_wires;
|
||||
RelPtr<BelWirePOD> bel_wires;
|
||||
int8_t x, y, z;
|
||||
int8_t filler_0;
|
||||
int8_t padding_0;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct BelPortPOD
|
||||
@ -222,6 +225,8 @@ extern ChipInfoPOD chip_info_1k;
|
||||
extern ChipInfoPOD chip_info_5k;
|
||||
extern ChipInfoPOD chip_info_8k;
|
||||
|
||||
/************************ End of chipdb section. ************************/
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
struct BelId
|
||||
@ -481,7 +486,7 @@ struct Chip
|
||||
IdString getBelName(BelId bel) const
|
||||
{
|
||||
assert(bel != BelId());
|
||||
return chip_info.bel_data[bel.index].name.ptr();
|
||||
return chip_info.bel_data[bel.index].name.get();
|
||||
}
|
||||
|
||||
void bindBel(BelId bel, IdString cell)
|
||||
|
188
ice40/chipdb.py
188
ice40/chipdb.py
@ -5,6 +5,7 @@ import re
|
||||
import textwrap
|
||||
|
||||
endianness = "le"
|
||||
compact_output = True
|
||||
|
||||
dev_name = None
|
||||
dev_width = None
|
||||
@ -366,23 +367,36 @@ elif dev_name == "384":
|
||||
add_bel_gb( 3, 9, 4)
|
||||
|
||||
class BinaryBlobAssembler:
|
||||
def __init__(self):
|
||||
def __init__(self, cname, endianness, ctype = "unsigned char"):
|
||||
assert endianness in ["le", "be"]
|
||||
self.cname = cname
|
||||
self.ctype = ctype
|
||||
self.endianness = endianness
|
||||
self.finalized = False
|
||||
self.data = bytearray()
|
||||
self.comments = dict()
|
||||
self.labels = dict()
|
||||
self.exports = set()
|
||||
self.labels_byaddr = dict()
|
||||
self.ltypes_byaddr = dict()
|
||||
self.strings = dict()
|
||||
self.refs = dict()
|
||||
|
||||
def l(self, name, ltype = None):
|
||||
def l(self, name, ltype = None, export = False):
|
||||
assert not self.finalized
|
||||
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
|
||||
if export:
|
||||
assert ltype is not None
|
||||
self.exports.add(len(self.data))
|
||||
|
||||
def r(self, name, comment):
|
||||
assert not self.finalized
|
||||
assert len(self.data) % 4 == 0
|
||||
assert len(self.data) not in self.refs
|
||||
self.refs[len(self.data)] = (name, comment)
|
||||
self.data.append(0)
|
||||
@ -390,23 +404,28 @@ class BinaryBlobAssembler:
|
||||
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)
|
||||
if comment is not None:
|
||||
self.comments[len(self.data)] = comment
|
||||
def s(self, s, comment):
|
||||
assert not self.finalized
|
||||
if s not in self.strings:
|
||||
index = len(self.strings)
|
||||
self.strings[s] = index
|
||||
else:
|
||||
index = self.strings[s]
|
||||
self.r("str%d" % index, '%s: "%s"' % (comment, s))
|
||||
|
||||
def u8(self, v, comment):
|
||||
assert not self.finalized
|
||||
self.data.append(v)
|
||||
if comment is not None:
|
||||
self.comments[len(self.data)] = comment
|
||||
|
||||
def u16(self, v, comment):
|
||||
if endianness == "le":
|
||||
assert not self.finalized
|
||||
assert len(self.data) % 2 == 0
|
||||
if self.endianness == "le":
|
||||
self.data.append(v & 255)
|
||||
self.data.append((v >> 8) & 255)
|
||||
elif endianness == "be":
|
||||
elif self.endianness == "be":
|
||||
self.data.append((v >> 8) & 255)
|
||||
self.data.append(v & 255)
|
||||
else:
|
||||
@ -415,12 +434,14 @@ class BinaryBlobAssembler:
|
||||
self.comments[len(self.data)] = comment
|
||||
|
||||
def u32(self, v, comment):
|
||||
if endianness == "le":
|
||||
assert not self.finalized
|
||||
assert len(self.data) % 4 == 0
|
||||
if self.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":
|
||||
elif self.endianness == "be":
|
||||
self.data.append((v >> 24) & 255)
|
||||
self.data.append((v >> 16) & 255)
|
||||
self.data.append((v >> 8) & 255)
|
||||
@ -430,53 +451,95 @@ class BinaryBlobAssembler:
|
||||
if comment is not None:
|
||||
self.comments[len(self.data)] = comment
|
||||
|
||||
def write_c(self, f):
|
||||
def finalize(self):
|
||||
assert not self.finalized
|
||||
for s, index in self.strings.items():
|
||||
self.l("str%d" % index, "char")
|
||||
for c in s:
|
||||
self.data.append(ord(c))
|
||||
self.data.append(0)
|
||||
self.finalized = True
|
||||
cursor = 0
|
||||
while cursor < len(self.data):
|
||||
if cursor in self.refs:
|
||||
v = self.labels[self.refs[cursor][0]] - cursor
|
||||
if self.endianness == "le":
|
||||
self.data[cursor+0] = (v & 255)
|
||||
self.data[cursor+1] = ((v >> 8) & 255)
|
||||
self.data[cursor+2] = ((v >> 16) & 255)
|
||||
self.data[cursor+3] = ((v >> 24) & 255)
|
||||
elif self.endianness == "be":
|
||||
self.data[cursor+0] = ((v >> 24) & 255)
|
||||
self.data[cursor+1] = ((v >> 16) & 255)
|
||||
self.data[cursor+2] = ((v >> 8) & 255)
|
||||
self.data[cursor+3] = (v & 255)
|
||||
else:
|
||||
assert 0
|
||||
cursor += 4
|
||||
else:
|
||||
cursor += 1
|
||||
|
||||
def write_verbose_c(self, f):
|
||||
assert self.finalized
|
||||
print("%s %s[%d] = {" % (self.ctype, self.cname, len(self.data)), file=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])
|
||||
print(" ", end="", file=f)
|
||||
print(" // %s" % self.comments[cursor], file=f)
|
||||
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))
|
||||
print(file=f)
|
||||
if cursor in self.exports:
|
||||
print("#define %s ((%s*)(%s+%d))" % (self.labels_byaddr[cursor], self.ltypes_byaddr[cursor], self.cname, cursor), file=f)
|
||||
else:
|
||||
print(" // [%d] %s" % (cursor, self.labels_byaddr[cursor]))
|
||||
print(" // [%d] %s" % (cursor, self.labels_byaddr[cursor]), file=f)
|
||||
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]))
|
||||
print(file=f)
|
||||
print(" ", end="", file=f)
|
||||
print(" %-4s" % ("%d," % self.data[cursor+0]), end="", file=f)
|
||||
print(" %-4s" % ("%d," % self.data[cursor+1]), end="", file=f)
|
||||
print(" %-4s" % ("%d," % self.data[cursor+2]), end="", file=f)
|
||||
print(" %-4s" % ("%d," % self.data[cursor+3]), end="", file=f)
|
||||
print(" // [%d] %s (reference to %s)" % (cursor, self.refs[cursor][1], self.refs[cursor][0]), file=f)
|
||||
bytecnt = 0
|
||||
cursor += 4
|
||||
else:
|
||||
if bytecnt == 0:
|
||||
print(" ", end="")
|
||||
print(" %3d," % self.data[cursor], end=("" if bytecnt < 15 else "\n"))
|
||||
print(" ", end="", file=f)
|
||||
print(" %-4s" % ("%d," % self.data[cursor]), end=("" if bytecnt < 15 else "\n"), file=f)
|
||||
bytecnt = (bytecnt + 1) & 15
|
||||
cursor += 1
|
||||
if bytecnt != 0:
|
||||
print()
|
||||
print(file=f)
|
||||
print("};", file=f)
|
||||
|
||||
bba = BinaryBlobAssembler()
|
||||
def write_compact_c(self, f):
|
||||
assert self.finalized
|
||||
print("%s %s[%d] = {" % (self.ctype, self.cname, len(self.data)), file=f)
|
||||
column = 0
|
||||
for v in self.data:
|
||||
if column == 0:
|
||||
print(" ", end="", file=f)
|
||||
column += 2
|
||||
s = "%d," % v
|
||||
print(s, end="", file=f)
|
||||
column += len(s)
|
||||
if column > 75:
|
||||
print(file=f)
|
||||
column = 0
|
||||
if column != 0:
|
||||
print(file=f)
|
||||
for cursor in self.exports:
|
||||
print("#define %s ((%s*)(%s+%d))" % (self.labels_byaddr[cursor], self.ltypes_byaddr[cursor], self.cname, cursor), file=f)
|
||||
print("};", file=f)
|
||||
|
||||
bba = BinaryBlobAssembler("binblob_%s" % dev_name, endianness, "static uint8_t")
|
||||
|
||||
print('#include "nextpnr.h"')
|
||||
print('namespace {')
|
||||
@ -490,20 +553,16 @@ for bel in range(len(bel_name)):
|
||||
bba.u32(portpins[bel_wires[bel][i][1]], "port")
|
||||
index += 1
|
||||
|
||||
bba.l("bel_data", "BelInfoPOD", export=True)
|
||||
for bel in range(len(bel_name)):
|
||||
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.s(bel_name[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")
|
||||
bba.u8(0, "padding")
|
||||
|
||||
wireinfo = list()
|
||||
pipinfo = list()
|
||||
@ -519,7 +578,7 @@ for wire in range(num_wires):
|
||||
pips.append(pipcache[(src, wire)])
|
||||
num_uphill = len(pips)
|
||||
list_uphill = "wire%d_uppips" % wire
|
||||
bba.l(list_uphill, "int32_t")
|
||||
bba.l(list_uphill, "int32_t", export=True)
|
||||
for p in pips:
|
||||
bba.u32(p, None)
|
||||
else:
|
||||
@ -535,7 +594,7 @@ for wire in range(num_wires):
|
||||
pips.append(pipcache[(wire, dst)])
|
||||
num_downhill = len(pips)
|
||||
list_downhill = "wire%d_downpips" % wire
|
||||
bba.l(list_downhill, "int32_t")
|
||||
bba.l(list_downhill, "int32_t", export=True)
|
||||
for p in pips:
|
||||
bba.u32(p, None)
|
||||
else:
|
||||
@ -544,7 +603,7 @@ for wire in range(num_wires):
|
||||
|
||||
if wire in wire_downhill_belports:
|
||||
num_bels_downhill = len(wire_downhill_belports[wire])
|
||||
bba.l("wire%d_downbels" % wire, "BelPortPOD")
|
||||
bba.l("wire%d_downbels" % wire, "BelPortPOD", export=True)
|
||||
for belport in wire_downhill_belports[wire]:
|
||||
bba.u32(belport[0], "bel_index")
|
||||
bba.u32(portpins[belport[1]], "port")
|
||||
@ -585,12 +644,9 @@ for package in packages:
|
||||
pin_bel = "X%d/Y%d/io%d" % (x, y, z)
|
||||
bel_idx = bel_name.index(pin_bel)
|
||||
pins_info.append((pinname, bel_idx))
|
||||
bba.l("package_%s_pins" % safename, "PackagePinPOD", export=True)
|
||||
for pi in pins_info:
|
||||
bba.l("package_%s_pins_%s" % (safename, pi[0]), "char")
|
||||
bba.s(pi[0], None)
|
||||
bba.l("package_%s_pins" % safename, "PackagePinPOD")
|
||||
for pi in pins_info:
|
||||
bba.r("package_%s_pins_%s" % (safename, pi[0]), "name")
|
||||
bba.s(pi[0], "name")
|
||||
bba.u32(pi[1], "bel_index")
|
||||
packageinfo.append('{"%s", %d, package_%s_pins}' % (name, len(pins_info), safename))
|
||||
|
||||
@ -613,24 +669,24 @@ for t in range(num_tile_types):
|
||||
bba.u8(row, "row")
|
||||
bba.u8(col, "col")
|
||||
if len(bits) == 0:
|
||||
bba.u8(0, "dummy")
|
||||
bba.u32(0, "padding")
|
||||
elif len(bits) % 2 == 1:
|
||||
bba.u16(0, "padding")
|
||||
centries_info.append((name, len(bits), t, safename))
|
||||
for name, _, t, safename in centries_info:
|
||||
if ("str_%s" % safename) not in bba.labels:
|
||||
bba.l("str_%s" % safename, "char")
|
||||
bba.s(name, None)
|
||||
bba.l("tile%d_config" % t, "ConfigEntryPOD")
|
||||
for _, num_bits, t, safename in centries_info:
|
||||
bba.r("str_%s" % safename, "name")
|
||||
bba.l("tile%d_config" % t, "ConfigEntryPOD", export=True)
|
||||
for name, num_bits, t, safename in centries_info:
|
||||
bba.s(name, "name")
|
||||
bba.u32(num_bits, "num_bits")
|
||||
bba.r("tile%d_%s_bits" % (t, safename), "num_bits")
|
||||
if len(centries_info) == 0:
|
||||
bba.u8(0, "dummy")
|
||||
bba.u32(0, "padding")
|
||||
tileinfo.append("{%d, %d, %d, tile%d_config}" % (tile_sizes[t][0], tile_sizes[t][1], len(centries_info), t))
|
||||
|
||||
print("static uint8_t binblob_%s[] = {" % dev_name)
|
||||
bba.write_c(sys.stdout)
|
||||
print("};")
|
||||
bba.finalize()
|
||||
if compact_output:
|
||||
bba.write_compact_c(sys.stdout)
|
||||
else:
|
||||
bba.write_verbose_c(sys.stdout)
|
||||
|
||||
switchinfo = []
|
||||
switchid = 0
|
||||
|
Loading…
Reference in New Issue
Block a user