diff --git a/common/design.h b/common/design.h index 3e4091c3..4ff28855 100644 --- a/common/design.h +++ b/common/design.h @@ -21,6 +21,7 @@ #define DESIGN_H #include +#include #include #include #include diff --git a/common/pybindings.cc b/common/pybindings.cc index 4986c549..556e838e 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -36,11 +36,6 @@ void arch_wrap_python(); BOOST_PYTHON_MODULE (MODULE_NAME) { - // From Chip.h - WRAP_RANGE(Bel); - WRAP_RANGE(WireDelay); - WRAP_RANGE(BelPin); - arch_wrap_python(); } diff --git a/ice40/chip.cc b/ice40/chip.cc index 4cdd98ff..05dbe7e8 100644 --- a/ice40/chip.cc +++ b/ice40/chip.cc @@ -278,10 +278,16 @@ PortPin PortPinFromId(IdString id) Chip::Chip(ChipArgs args) { if (args.type == ChipArgs::LP384) { - num_bels = 0; - bel_data = nullptr; - num_wires = num_wires_384; - wire_data = wire_data_384; + chip_info = chip_info_384; + return; + } else if (args.type == ChipArgs::LP1K || args.type == ChipArgs::HX1K) { + 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; } else { fprintf(stderr, "Unsupported chip type\n"); @@ -291,13 +297,15 @@ Chip::Chip(ChipArgs args) abort(); } +// ----------------------------------------------------------------------- + BelId Chip::getBelByName(IdString name) const { BelId ret; if (bel_by_name.empty()) { - for (int i = 0; i < num_bels; i++) - bel_by_name[bel_data[i].name] = i; + for (int i = 0; i < chip_info.num_bels; i++) + bel_by_name[chip_info.bel_data[i].name] = i; } auto it = bel_by_name.find(name); @@ -307,24 +315,92 @@ BelId Chip::getBelByName(IdString name) const 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 { // FIXME 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 Chip::getBelGraphics(BelId bel) const +{ + vector ret; + // FIXME + return ret; +} + +vector Chip::getWireGraphics(WireId wire) const +{ + vector ret; + // FIXME + return ret; +} + +vector Chip::getPipGraphics(PipId pip) const +{ + vector ret; + // FIXME + return ret; +} + +vector Chip::getFrameGraphics() const +{ + vector ret; + // FIXME + return ret; +} diff --git a/ice40/chip.h b/ice40/chip.h index 6113a869..370fcc02 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -166,48 +166,41 @@ struct BelInfoPOD BelType type; }; -struct WireDelayPOD -{ - int32_t wire_index; - float delay; -}; - struct BelPortPOD { int32_t bel_index; PortPin port; }; +struct PipInfoPOD +{ + int32_t src, dst; + float delay; +}; + struct WireInfoPOD { const char *name; - int num_uphill, num_downhill, num_bidir; - WireDelayPOD *wires_uphill, *wires_downhill, *wires_bidir; + int num_uphill, num_downhill; + int *pips_uphill, *pips_downhill; int num_bels_downhill; BelPortPOD bel_uphill; BelPortPOD *bels_downhill; }; -extern int num_bels_384; -extern int num_bels_1k; -extern int num_bels_5k; -extern int num_bels_8k; +struct ChipInfoPOD +{ + int num_bels, num_wires, num_pips; + BelInfoPOD *bel_data; + WireInfoPOD *wire_data; + PipInfoPOD *pip_data; +}; -extern BelInfoPOD bel_data_384[]; -extern BelInfoPOD bel_data_1k[]; -extern BelInfoPOD bel_data_5k[]; -extern BelInfoPOD bel_data_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[]; +extern ChipInfoPOD chip_info_384; +extern ChipInfoPOD chip_info_1k; +extern ChipInfoPOD chip_info_5k; +extern ChipInfoPOD chip_info_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 { template<> struct hash @@ -246,6 +254,14 @@ namespace std return wire.index; } }; + + template<> struct hash + { + 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 { 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 { enum { @@ -371,36 +397,41 @@ struct ChipArgs struct Chip { - int num_bels, num_wires; - BelInfoPOD *bel_data; - WireInfoPOD *wire_data; + ChipInfoPOD chip_info; - mutable dict wire_by_name; mutable dict bel_by_name; + mutable dict wire_by_name; + mutable dict pip_by_name; Chip(ChipArgs args); - void setBelActive(BelId, bool) { } - bool getBelActive(BelId) { return true; } + // ------------------------------------------------- BelId getBelByName(IdString name) const; - WireId getWireByName(IdString name) 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 range; range.b.cursor = 0; - range.e.cursor = num_bels; + range.e.cursor = chip_info.num_bels; return range; } @@ -420,52 +451,8 @@ struct Chip BelType getBelType(BelId bel) const { - return 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 getBelGraphics(BelId bel) const; - // FIXME: vector getWireGraphics(WireId wire) const; - // FIXME: vector getPipGraphics(WireId src, WireId dst) const; - // FIXME: vector 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; + assert(!bel.nil()); + return chip_info.bel_data[bel.index].type; } WireId getWireBelPin(BelId bel, PortPin pin) const; @@ -473,10 +460,11 @@ struct Chip BelPin getBelPinUphill(WireId wire) const { BelPin ret; + assert(!wire.nil()); - if (wire_data[wire.index].bel_uphill.bel_index >= 0) { - ret.bel.index = wire_data[wire.index].bel_uphill.bel_index; - ret.pin = wire_data[wire.index].bel_uphill.port; + if (chip_info.wire_data[wire.index].bel_uphill.bel_index >= 0) { + ret.bel.index = chip_info.wire_data[wire.index].bel_uphill.bel_index; + ret.pin = chip_info.wire_data[wire.index].bel_uphill.port; } return ret; @@ -485,10 +473,134 @@ struct Chip BelPinRange getBelPinsDownhill(WireId wire) const { BelPinRange range; - range.b.ptr = wire_data[wire.index].bels_downhill; - range.e.ptr = wire_data[wire.index].bels_downhill + wire_data[wire.index].num_bels_downhill; + assert(!wire.nil()); + 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; } + + // ------------------------------------------------- + + 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 getBelGraphics(BelId bel) const; + vector getWireGraphics(WireId wire) const; + vector getPipGraphics(PipId pip) const; + vector getFrameGraphics() const; }; #endif diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 3b71a6b4..a106b78f 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -11,7 +11,6 @@ tiles = dict() wire_uphill = dict() wire_downhill = dict() -wire_bidir = dict() bel_name = list() bel_type = list() @@ -98,12 +97,20 @@ with open(sys.argv[1], "r") as f: if mode[0] == "routing": wire_a = int(line[1]) wire_b = mode[1] - if wire_a not in wire_bidir: - wire_bidir[wire_a] = set() - if wire_b not in wire_bidir: - wire_bidir[wire_b] = set() - wire_bidir[wire_a].add(wire_b) - wire_bidir[wire_b].add(wire_b) + + if wire_a not in wire_downhill: + wire_downhill[wire_a] = set() + if wire_b not in wire_uphill: + wire_uphill[wire_b] = set() + 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 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("int num_bels_%s = %d;" % (dev_name, num_wires)) -print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, num_wires)) +print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, 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("};") wireinfo = list() +pipinfo = list() +pipcache = dict() for wire in range(num_wires): - num_uphill = 0 - num_downhill = 0 - num_bidir = 0 - num_bels_downhill = 0 - if wire in wire_uphill: - num_uphill = len(wire_uphill[wire]) - print("static WireDelayPOD wire%d_uphill[] = {" % wire) - print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_uphill[wire]])) - print("};") + pips = list() + for src in wire_uphill[wire]: + if (src, wire) not in pipcache: + 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: - num_downhill = len(wire_downhill[wire]) - print("static WireDelayPOD wire%d_downhill[] = {" % wire) - print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_downhill[wire]])) - print("};") - - if wire in wire_bidir: - num_bidir = len(wire_bidir[wire]) - print("static WireDelayPOD wire%d_bidir[] = {" % wire) - print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_bidir[wire]])) - print("};") + pips = list() + for dst in wire_downhill[wire]: + if (wire, dst) not in pipcache: + pipcache[(wire, dst)] = len(pipinfo) + pipinfo.append(" {%d, %d, 1.0}" % (wire, dst)) + pips.append("%d" % pipcache[(wire, dst)]) + num_downhill = len(pips) + list_downhill = "wire%d_downpips" % wire + print("static int wire%d_downpips[] = {%s};" % (wire, ", ".join(pips))) + else: + num_downhill = 0 + list_downhill = "nullptr" if wire in wire_downhill_belports: num_bels_downhill = len(wire_downhill_belports[wire]) print("static BelPortPOD wire%d_downbels[] = {" % wire) print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]])) print("};") + else: + num_bels_downhill = 0 info = " {" info += "\"%d_%d_%s\", " % wire_names_r[wire] - info += "%d, %d, %d, " % (num_uphill, num_downhill, num_bidir) - 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) + info += "%d, %d, %s, %s, %d, " % (num_uphill, num_downhill, list_uphill, list_downhill, num_bels_downhill) if wire in wire_uphill_belport: info += "{%d, PIN_%s}, " % wire_uphill_belport[wire] @@ -278,7 +289,15 @@ for wire in range(num_wires): wireinfo.append(info) -print("int num_wires_%s = %d;" % (dev_name, num_wires)) -print("WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires)) +print("static WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires)) print(",\n".join(wireinfo)) 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("};") diff --git a/ice40/pybindings.cc b/ice40/pybindings.cc index 2dd558d1..dc13f849 100644 --- a/ice40/pybindings.cc +++ b/ice40/pybindings.cc @@ -52,6 +52,9 @@ void arch_wrap_python() { .def("getBels", &Chip::getBels) .def("getWires", &Chip::getWires); - WRAP_RANGE(AllWire); - + WRAP_RANGE(Bel); + WRAP_RANGE(BelPin); + WRAP_RANGE(Wire); + WRAP_RANGE(AllPip); + WRAP_RANGE(Pip); }