Refactor Chip API and iCE40 database

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-06-06 15:13:41 +02:00
parent d3f19cc27e
commit 5ff9aafb20
6 changed files with 417 additions and 211 deletions

View File

@ -21,6 +21,7 @@
#define DESIGN_H #define DESIGN_H
#include <stdint.h> #include <stdint.h>
#include <assert.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>

View File

@ -36,11 +36,6 @@
void arch_wrap_python(); void arch_wrap_python();
BOOST_PYTHON_MODULE (MODULE_NAME) { BOOST_PYTHON_MODULE (MODULE_NAME) {
// From Chip.h
WRAP_RANGE(Bel);
WRAP_RANGE(WireDelay);
WRAP_RANGE(BelPin);
arch_wrap_python(); arch_wrap_python();
} }

View File

@ -278,10 +278,16 @@ PortPin PortPinFromId(IdString id)
Chip::Chip(ChipArgs args) Chip::Chip(ChipArgs args)
{ {
if (args.type == ChipArgs::LP384) { if (args.type == ChipArgs::LP384) {
num_bels = 0; chip_info = chip_info_384;
bel_data = nullptr; return;
num_wires = num_wires_384; } else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) {
wire_data = wire_data_384; chip_info = chip_info_1k;
return;
} else if (args.type == ChipArgs::UP5K) {
chip_info = chip_info_5k;
return;
} else if (args.type == ChipArgs::LP8K || args.type == ChipArgs::HX8K) {
chip_info = chip_info_8k;
return; return;
} else { } else {
fprintf(stderr, "Unsupported chip type\n"); fprintf(stderr, "Unsupported chip type\n");
@ -291,13 +297,15 @@ Chip::Chip(ChipArgs args)
abort(); abort();
} }
// -----------------------------------------------------------------------
BelId Chip::getBelByName(IdString name) const BelId Chip::getBelByName(IdString name) const
{ {
BelId ret; BelId ret;
if (bel_by_name.empty()) { if (bel_by_name.empty()) {
for (int i = 0; i < num_bels; i++) for (int i = 0; i < chip_info.num_bels; i++)
bel_by_name[bel_data[i].name] = i; bel_by_name[chip_info.bel_data[i].name] = i;
} }
auto it = bel_by_name.find(name); auto it = bel_by_name.find(name);
@ -307,24 +315,92 @@ BelId Chip::getBelByName(IdString name) const
return ret; return ret;
} }
WireId Chip::getWireByName(IdString name) const
{
WireId ret;
if (wire_by_name.empty()) {
for (int i = 0; i < num_wires; i++)
wire_by_name[wire_data[i].name] = i;
}
auto it = wire_by_name.find(name);
if (it != wire_by_name.end())
ret.index = it->second;
return ret;
}
WireId Chip::getWireBelPin(BelId bel, PortPin pin) const WireId Chip::getWireBelPin(BelId bel, PortPin pin) const
{ {
// FIXME // FIXME
return WireId(); return WireId();
} }
// -----------------------------------------------------------------------
WireId Chip::getWireByName(IdString name) const
{
WireId ret;
if (wire_by_name.empty()) {
for (int i = 0; i < chip_info.num_wires; i++)
wire_by_name[chip_info.wire_data[i].name] = i;
}
auto it = wire_by_name.find(name);
if (it != wire_by_name.end())
ret.index = it->second;
return ret;
}
// -----------------------------------------------------------------------
PipId Chip::getPipByName(IdString name) const
{
PipId ret;
if (pip_by_name.empty()) {
for (int i = 0; i < chip_info.num_pips; i++) {
PipId pip;
pip.index = i;
pip_by_name[getPipName(pip)] = i;
}
}
auto it = pip_by_name.find(name);
if (it != pip_by_name.end())
ret.index = it->second;
return ret;
}
// -----------------------------------------------------------------------
void Chip::getBelPosition(BelId bel, float &x, float &y) const
{
// FIXME
}
void Chip::getWirePosition(WireId wire, float &x, float &y) const
{
// FIXME
}
void Chip::getPipPosition(WireId wire, float &x, float &y) const
{
// FIXME
}
vector<GraphicElement> Chip::getBelGraphics(BelId bel) const
{
vector<GraphicElement> ret;
// FIXME
return ret;
}
vector<GraphicElement> Chip::getWireGraphics(WireId wire) const
{
vector<GraphicElement> ret;
// FIXME
return ret;
}
vector<GraphicElement> Chip::getPipGraphics(PipId pip) const
{
vector<GraphicElement> ret;
// FIXME
return ret;
}
vector<GraphicElement> Chip::getFrameGraphics() const
{
vector<GraphicElement> ret;
// FIXME
return ret;
}

View File

@ -166,48 +166,41 @@ struct BelInfoPOD
BelType type; BelType type;
}; };
struct WireDelayPOD
{
int32_t wire_index;
float delay;
};
struct BelPortPOD struct BelPortPOD
{ {
int32_t bel_index; int32_t bel_index;
PortPin port; PortPin port;
}; };
struct PipInfoPOD
{
int32_t src, dst;
float delay;
};
struct WireInfoPOD struct WireInfoPOD
{ {
const char *name; const char *name;
int num_uphill, num_downhill, num_bidir; int num_uphill, num_downhill;
WireDelayPOD *wires_uphill, *wires_downhill, *wires_bidir; int *pips_uphill, *pips_downhill;
int num_bels_downhill; int num_bels_downhill;
BelPortPOD bel_uphill; BelPortPOD bel_uphill;
BelPortPOD *bels_downhill; BelPortPOD *bels_downhill;
}; };
extern int num_bels_384; struct ChipInfoPOD
extern int num_bels_1k; {
extern int num_bels_5k; int num_bels, num_wires, num_pips;
extern int num_bels_8k; BelInfoPOD *bel_data;
WireInfoPOD *wire_data;
PipInfoPOD *pip_data;
};
extern BelInfoPOD bel_data_384[]; extern ChipInfoPOD chip_info_384;
extern BelInfoPOD bel_data_1k[]; extern ChipInfoPOD chip_info_1k;
extern BelInfoPOD bel_data_5k[]; extern ChipInfoPOD chip_info_5k;
extern BelInfoPOD bel_data_8k[]; extern ChipInfoPOD chip_info_8k;
extern int num_wires_384;
extern int num_wires_1k;
extern int num_wires_5k;
extern int num_wires_8k;
extern WireInfoPOD wire_data_384[];
extern WireInfoPOD wire_data_1k[];
extern WireInfoPOD wire_data_5k[];
extern WireInfoPOD wire_data_8k[];
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -229,6 +222,21 @@ struct WireId
} }
}; };
struct PipId
{
int32_t index = -1;
bool nil() const {
return index < 0;
}
};
struct BelPin
{
BelId bel;
PortPin pin;
};
namespace std namespace std
{ {
template<> struct hash<BelId> template<> struct hash<BelId>
@ -246,6 +254,14 @@ namespace std
return wire.index; return wire.index;
} }
}; };
template<> struct hash<PipId>
{
std::size_t operator()(const PipId &wire) const noexcept
{
return wire.index;
}
};
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -273,65 +289,6 @@ struct BelRange
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
struct AllWireIterator
{
int cursor;
void operator++() { cursor++; }
bool operator!=(const AllWireIterator &other) const { return cursor != other.cursor; }
WireId operator*() const {
WireId ret;
ret.index = cursor;
return ret;
}
};
struct AllWireRange
{
AllWireIterator b, e;
AllWireIterator begin() const { return b; }
AllWireIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct WireDelay
{
WireId wire;
DelayInfo delay;
};
struct WireDelayIterator
{
WireDelayPOD *ptr = nullptr;
void operator++() { ptr++; }
bool operator!=(const WireDelayIterator &other) const { return ptr != other.ptr; }
WireDelay operator*() const {
WireDelay ret;
ret.wire.index = ptr->wire_index;
ret.delay.delay = ptr->delay;
return ret;
}
};
struct WireDelayRange
{
WireDelayIterator b, e;
WireDelayIterator begin() const { return b; }
WireDelayIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct BelPin
{
BelId bel;
PortPin pin;
};
struct BelPinIterator struct BelPinIterator
{ {
BelPortPOD *ptr = nullptr; BelPortPOD *ptr = nullptr;
@ -356,6 +313,75 @@ struct BelPinRange
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
struct WireIterator
{
int cursor = -1;
void operator++() { cursor++; }
bool operator!=(const WireIterator &other) const { return cursor != other.cursor; }
WireId operator*() const {
WireId ret;
ret.index = cursor;
return ret;
}
};
struct WireRange
{
WireIterator b, e;
WireIterator begin() const { return b; }
WireIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct AllPipIterator
{
int cursor = -1;
void operator++() { cursor++; }
bool operator!=(const AllPipIterator &other) const { return cursor != other.cursor; }
PipId operator*() const {
PipId ret;
ret.index = cursor;
return ret;
}
};
struct AllPipRange
{
AllPipIterator b, e;
AllPipIterator begin() const { return b; }
AllPipIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct PipIterator
{
int *cursor = nullptr;
void operator++() { cursor++; }
bool operator!=(const PipIterator &other) const { return cursor != other.cursor; }
PipId operator*() const {
PipId ret;
ret.index = *cursor;
return ret;
}
};
struct PipRange
{
PipIterator b, e;
PipIterator begin() const { return b; }
PipIterator end() const { return e; }
};
// -----------------------------------------------------------------------
struct ChipArgs struct ChipArgs
{ {
enum { enum {
@ -371,36 +397,41 @@ struct ChipArgs
struct Chip struct Chip
{ {
int num_bels, num_wires; ChipInfoPOD chip_info;
BelInfoPOD *bel_data;
WireInfoPOD *wire_data;
mutable dict<IdString, int> wire_by_name;
mutable dict<IdString, int> bel_by_name; mutable dict<IdString, int> bel_by_name;
mutable dict<IdString, int> wire_by_name;
mutable dict<IdString, int> pip_by_name;
Chip(ChipArgs args); Chip(ChipArgs args);
void setBelActive(BelId, bool) { } // -------------------------------------------------
bool getBelActive(BelId) { return true; }
BelId getBelByName(IdString name) const; BelId getBelByName(IdString name) const;
WireId getWireByName(IdString name) const;
IdString getBelName(BelId bel) const IdString getBelName(BelId bel) const
{ {
return bel_data[bel.index].name; assert(!bel.nil());
return chip_info.bel_data[bel.index].name;
} }
IdString getWireName(WireId wire) const void bindBel(BelId bel, IdString cell)
{
}
void unbindBel(BelId bel)
{
}
bool checkBelAvail(BelId bel) const
{ {
return wire_data[wire.index].name;
} }
BelRange getBels() const BelRange getBels() const
{ {
BelRange range; BelRange range;
range.b.cursor = 0; range.b.cursor = 0;
range.e.cursor = num_bels; range.e.cursor = chip_info.num_bels;
return range; return range;
} }
@ -420,52 +451,8 @@ struct Chip
BelType getBelType(BelId bel) const BelType getBelType(BelId bel) const
{ {
return bel_data[bel.index].type; assert(!bel.nil());
} return chip_info.bel_data[bel.index].type;
// FIXME: void getBelPosition(BelId bel, float &x, float &y) const;
// FIXME: void getWirePosition(WireId wire, float &x, float &y) const;
// FIXME: vector<GraphicElement> getBelGraphics(BelId bel) const;
// FIXME: vector<GraphicElement> getWireGraphics(WireId wire) const;
// FIXME: vector<GraphicElement> getPipGraphics(WireId src, WireId dst) const;
// FIXME: vector<GraphicElement> getFrameGraphics() const;
AllWireRange getWires() const
{
AllWireRange range;
range.b.cursor = 0;
range.e.cursor = num_wires;
return range;
}
WireDelayRange getWiresUphill(WireId wire) const
{
WireDelayRange range;
range.b.ptr = wire_data[wire.index].wires_uphill;
range.e.ptr = wire_data[wire.index].wires_uphill + wire_data[wire.index].num_uphill;
return range;
}
WireDelayRange getWiresDownhill(WireId wire) const
{
WireDelayRange range;
range.b.ptr = wire_data[wire.index].wires_downhill;
range.e.ptr = wire_data[wire.index].wires_downhill + wire_data[wire.index].num_downhill;
return range;
}
WireDelayRange getWiresBidir(WireId wire) const
{
WireDelayRange range;
range.b.ptr = wire_data[wire.index].wires_bidir;
range.e.ptr = wire_data[wire.index].wires_bidir + wire_data[wire.index].num_bidir;
return range;
}
WireDelayRange getWireAliases(WireId wire) const
{
WireDelayRange range;
return range;
} }
WireId getWireBelPin(BelId bel, PortPin pin) const; WireId getWireBelPin(BelId bel, PortPin pin) const;
@ -473,10 +460,11 @@ struct Chip
BelPin getBelPinUphill(WireId wire) const BelPin getBelPinUphill(WireId wire) const
{ {
BelPin ret; BelPin ret;
assert(!wire.nil());
if (wire_data[wire.index].bel_uphill.bel_index >= 0) { if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) {
ret.bel.index = wire_data[wire.index].bel_uphill.bel_index; ret.bel.index = chip_info.wire_data[wire.index].bel_uphill.bel_index;
ret.pin = wire_data[wire.index].bel_uphill.port; ret.pin = chip_info.wire_data[wire.index].bel_uphill.port;
} }
return ret; return ret;
@ -485,10 +473,134 @@ struct Chip
BelPinRange getBelPinsDownhill(WireId wire) const BelPinRange getBelPinsDownhill(WireId wire) const
{ {
BelPinRange range; BelPinRange range;
range.b.ptr = wire_data[wire.index].bels_downhill; assert(!wire.nil());
range.e.ptr = wire_data[wire.index].bels_downhill + wire_data[wire.index].num_bels_downhill; range.b.ptr = chip_info.wire_data[wire.index].bels_downhill;
range.e.ptr = range.b.ptr + chip_info.wire_data[wire.index].num_bels_downhill;
return range; return range;
} }
// -------------------------------------------------
WireId getWireByName(IdString name) const;
IdString getWireName(WireId wire) const
{
assert(!wire.nil());
return chip_info.wire_data[wire.index].name;
}
void bindWire(WireId bel, IdString net)
{
}
void unbindWire(WireId bel)
{
}
bool checkWireAvail(WireId bel) const
{
}
WireRange getWires() const
{
WireRange range;
range.b.cursor = 0;
range.e.cursor = chip_info.num_wires;
return range;
}
// -------------------------------------------------
PipId getPipByName(IdString name) const;
IdString getPipName(PipId pip) const
{
assert(!pip.nil());
std::string src_name = chip_info.wire_data[chip_info.pip_data[pip.index].src].name;
std::string dst_name = chip_info.wire_data[chip_info.pip_data[pip.index].dst].name;
return src_name + "->" + dst_name;
}
void bindPip(PipId bel, IdString net)
{
}
void unbindPip(PipId bel)
{
}
bool checkPipAvail(PipId bel) const
{
}
AllPipRange getPips() const
{
AllPipRange range;
range.b.cursor = 0;
range.e.cursor = chip_info.num_pips;
return range;
}
WireId getPipSrcWire(PipId pip) const
{
WireId wire;
assert(!pip.nil());
wire.index = chip_info.pip_data[pip.index].src;
return wire;
}
WireId getPipDstWire(PipId pip) const
{
WireId wire;
assert(!pip.nil());
wire.index = chip_info.pip_data[pip.index].dst;
return wire;
}
DelayInfo getPipDelay(PipId pip) const
{
DelayInfo delay;
assert(!pip.nil());
delay.delay = chip_info.pip_data[pip.index].delay;
return delay;
}
PipRange getPipsDownhill(WireId wire) const
{
PipRange range;
assert(!wire.nil());
range.b.cursor = chip_info.wire_data[wire.index].pips_downhill;
range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_downhill;
return range;
}
PipRange getPipsUphill(WireId wire) const
{
PipRange range;
assert(!wire.nil());
range.b.cursor = chip_info.wire_data[wire.index].pips_uphill;
range.e.cursor = range.b.cursor + chip_info.wire_data[wire.index].num_uphill;
return range;
}
PipRange getWireAliases(WireId wire) const
{
PipRange range;
assert(!wire.nil());
range.b.cursor = nullptr;
range.e.cursor = nullptr;
return range;
}
// -------------------------------------------------
void getBelPosition(BelId bel, float &x, float &y) const;
void getWirePosition(WireId wire, float &x, float &y) const;
void getPipPosition(WireId wire, float &x, float &y) const;
vector<GraphicElement> getBelGraphics(BelId bel) const;
vector<GraphicElement> getWireGraphics(WireId wire) const;
vector<GraphicElement> getPipGraphics(PipId pip) const;
vector<GraphicElement> getFrameGraphics() const;
}; };
#endif #endif

View File

@ -11,7 +11,6 @@ tiles = dict()
wire_uphill = dict() wire_uphill = dict()
wire_downhill = dict() wire_downhill = dict()
wire_bidir = dict()
bel_name = list() bel_name = list()
bel_type = list() bel_type = list()
@ -98,12 +97,20 @@ with open(sys.argv[1], "r") as f:
if mode[0] == "routing": if mode[0] == "routing":
wire_a = int(line[1]) wire_a = int(line[1])
wire_b = mode[1] wire_b = mode[1]
if wire_a not in wire_bidir:
wire_bidir[wire_a] = set() if wire_a not in wire_downhill:
if wire_b not in wire_bidir: wire_downhill[wire_a] = set()
wire_bidir[wire_b] = set() if wire_b not in wire_uphill:
wire_bidir[wire_a].add(wire_b) wire_uphill[wire_b] = set()
wire_bidir[wire_b].add(wire_b) wire_downhill[wire_a].add(wire_b)
wire_uphill[wire_b].add(wire_a)
if wire_b not in wire_downhill:
wire_downhill[wire_b] = set()
if wire_a not in wire_uphill:
wire_uphill[wire_a] = set()
wire_downhill[wire_b].add(wire_a)
wire_uphill[wire_a].add(wire_b)
continue continue
def add_bel_input(bel, wire, port): def add_bel_input(bel, wire, port):
@ -222,51 +229,55 @@ for tile_xy, tile_type in sorted(tiles.items()):
print('#include "chip.h"') print('#include "chip.h"')
print("int num_bels_%s = %d;" % (dev_name, num_wires)) print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, len(bel_name)))
print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, num_wires))
for bel in range(len(bel_name)): for bel in range(len(bel_name)):
print(" {\"%s\", TYPE_%s}%s" % (bel_name[bel], bel_type[bel], "," if bel+1 < len(bel_name) else "")) print(" {\"%s\", TYPE_%s}%s" % (bel_name[bel], bel_type[bel], "," if bel+1 < len(bel_name) else ""))
print("};") print("};")
wireinfo = list() wireinfo = list()
pipinfo = list()
pipcache = dict()
for wire in range(num_wires): for wire in range(num_wires):
num_uphill = 0
num_downhill = 0
num_bidir = 0
num_bels_downhill = 0
if wire in wire_uphill: if wire in wire_uphill:
num_uphill = len(wire_uphill[wire]) pips = list()
print("static WireDelayPOD wire%d_uphill[] = {" % wire) for src in wire_uphill[wire]:
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_uphill[wire]])) if (src, wire) not in pipcache:
print("};") pipcache[(src, wire)] = len(pipinfo)
pipinfo.append(" {%d, %d, 1.0}" % (src, wire))
pips.append("%d" % pipcache[(src, wire)])
num_uphill = len(pips)
list_uphill = "wire%d_uppips" % wire
print("static int wire%d_uppips[] = {%s};" % (wire, ", ".join(pips)))
else:
num_uphill = 0
list_uphill = "nullptr"
if wire in wire_downhill: if wire in wire_downhill:
num_downhill = len(wire_downhill[wire]) pips = list()
print("static WireDelayPOD wire%d_downhill[] = {" % wire) for dst in wire_downhill[wire]:
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_downhill[wire]])) if (wire, dst) not in pipcache:
print("};") pipcache[(wire, dst)] = len(pipinfo)
pipinfo.append(" {%d, %d, 1.0}" % (wire, dst))
if wire in wire_bidir: pips.append("%d" % pipcache[(wire, dst)])
num_bidir = len(wire_bidir[wire]) num_downhill = len(pips)
print("static WireDelayPOD wire%d_bidir[] = {" % wire) list_downhill = "wire%d_downpips" % wire
print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_bidir[wire]])) print("static int wire%d_downpips[] = {%s};" % (wire, ", ".join(pips)))
print("};") else:
num_downhill = 0
list_downhill = "nullptr"
if wire in wire_downhill_belports: if wire in wire_downhill_belports:
num_bels_downhill = len(wire_downhill_belports[wire]) num_bels_downhill = len(wire_downhill_belports[wire])
print("static BelPortPOD wire%d_downbels[] = {" % wire) print("static BelPortPOD wire%d_downbels[] = {" % wire)
print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]])) print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]]))
print("};") print("};")
else:
num_bels_downhill = 0
info = " {" info = " {"
info += "\"%d_%d_%s\", " % wire_names_r[wire] info += "\"%d_%d_%s\", " % wire_names_r[wire]
info += "%d, %d, %d, " % (num_uphill, num_downhill, num_bidir) info += "%d, %d, %s, %s, %d, " % (num_uphill, num_downhill, list_uphill, list_downhill, num_bels_downhill)
info += ("wire%d_uphill, " % wire) if num_uphill > 0 else "nullptr, "
info += ("wire%d_downhill, " % wire) if num_downhill > 0 else "nullptr, "
info += ("wire%d_bidir, " % wire) if num_bidir > 0 else "nullptr, "
info += "%d, " % (num_bels_downhill)
if wire in wire_uphill_belport: if wire in wire_uphill_belport:
info += "{%d, PIN_%s}, " % wire_uphill_belport[wire] info += "{%d, PIN_%s}, " % wire_uphill_belport[wire]
@ -278,7 +289,15 @@ for wire in range(num_wires):
wireinfo.append(info) wireinfo.append(info)
print("int num_wires_%s = %d;" % (dev_name, num_wires)) print("static WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires))
print("WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires))
print(",\n".join(wireinfo)) print(",\n".join(wireinfo))
print("};") print("};")
print("static PipInfoPOD pip_data_%s[%d] = {" % (dev_name, len(pipinfo)))
print(",\n".join(pipinfo))
print("};")
print("ChipInfoPOD chip_info_%s = {" % dev_name)
print(" %d, %d, %d," % (len(bel_name), num_wires, len(pipinfo)))
print(" bel_data_%s, wire_data_%s, pip_data_%s" % (dev_name, dev_name, dev_name))
print("};")

View File

@ -52,6 +52,9 @@ void arch_wrap_python() {
.def("getBels", &Chip::getBels) .def("getBels", &Chip::getBels)
.def("getWires", &Chip::getWires); .def("getWires", &Chip::getWires);
WRAP_RANGE(AllWire); WRAP_RANGE(Bel);
WRAP_RANGE(BelPin);
WRAP_RANGE(Wire);
WRAP_RANGE(AllPip);
WRAP_RANGE(Pip);
} }