diff --git a/common/design.h b/common/design.h index 564d5ce5..314c2fd7 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/dummy/chip.cc b/dummy/chip.cc index df7590ee..51a6a840 100644 --- a/dummy/chip.cc +++ b/dummy/chip.cc @@ -22,13 +22,3 @@ Chip::Chip(ChipArgs) { } - -BelRange Chip::getBels() const -{ - return BelRange(); -} - -IdString Chip::getBelName(BelId bel) const -{ - return "*unknown*"; -} diff --git a/dummy/chip.h b/dummy/chip.h index f403552f..054e822b 100644 --- a/dummy/chip.h +++ b/dummy/chip.h @@ -39,104 +39,9 @@ static inline IdString portPinToId(PortPin type) { return type; } static inline BelType belTypeFromId(IdString id) { return id; } static inline PortPin portPinFromId(IdString id) { return id; } -struct BelId -{ - uint8_t tile_x = 0, tile_y = 0; - uint16_t index = 0; - - bool nil() const { - return !tile_x && !tile_y && !index; - } -} __attribute__((packed)); - -struct WireId -{ - uint8_t tile_x = 0, tile_y = 0; - uint16_t index = 0; - - bool nil() const { - return !tile_x && !tile_y && !index; - } -} __attribute__((packed)); - -namespace std -{ - template<> struct hash - { - std::size_t operator()(const BelId &bel) const noexcept - { - std::size_t result = std::hash{}(bel.index); - result ^= std::hash{}(bel.tile_x) + 0x9e3779b9 + (result << 6) + (result >> 2); - result ^= std::hash{}(bel.tile_y) + 0x9e3779b9 + (result << 6) + (result >> 2); - return result; - } - }; - - template<> struct hash - { - std::size_t operator()(const WireId &wire) const noexcept - { - std::size_t result = std::hash{}(wire.index); - result ^= std::hash{}(wire.tile_x) + 0x9e3779b9 + (result << 6) + (result >> 2); - result ^= std::hash{}(wire.tile_y) + 0x9e3779b9 + (result << 6) + (result >> 2); - return result; - } - }; -} - -struct BelIterator -{ - BelId *ptr = nullptr; - - void operator++() { ptr++; } - bool operator!=(const BelIterator &other) const { return ptr != other.ptr; } - BelId operator*() const { return *ptr; } -}; - -struct BelRange -{ - BelIterator b, e; - BelIterator begin() const { return b; } - BelIterator end() const { return e; } -}; - -struct WireIterator -{ - WireId *ptr = nullptr; - - void operator++() { ptr++; } - bool operator!=(const WireIterator &other) const { return ptr != other.ptr; } - WireId operator*() const { return *ptr; } -}; - -struct WireRange -{ - WireIterator b, e; - WireIterator begin() const { return b; } - WireIterator end() const { return e; } -}; - -struct WireDelay -{ - WireId wire; - DelayInfo delay; -}; - -struct WireDelayIterator -{ - WireDelay *ptr = nullptr; - - void operator++() { ptr++; } - bool operator!=(const WireDelayIterator &other) const { return ptr != other.ptr; } - WireDelay operator*() const { return *ptr; } -}; - -struct WireDelayRange -{ - WireDelayIterator b, e; - WireDelayIterator begin() const { return b; } - WireDelayIterator end() const { return e; } -}; +typedef IdString BelId; +typedef IdString WireId; +typedef IdString PipId; struct BelPin { @@ -144,61 +49,54 @@ struct BelPin PortPin pin; }; -struct BelPinIterator -{ - BelPin *ptr = nullptr; - - void operator++() { ptr++; } - bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; } - BelPin operator*() const { return *ptr; } -}; - -struct BelPinRange -{ - BelPinIterator b, e; - BelPinIterator begin() const { return b; } - BelPinIterator end() const { return e; } -}; - struct ChipArgs { - // ... }; struct Chip { - // ... - Chip(ChipArgs args); - void setBelActive(BelId bel, bool active); - bool getBelActive(BelId bel); - BelId getBelByName(IdString name) const; - WireId getWireByName(IdString name) const; + IdString getBelName(BelId bel) const; - IdString getWireName(WireId wire) const; - - BelRange getBels() const; - BelRange getBelsByType(BelType type) const; + void bindBel(BelId bel, IdString cell); + void unbindBel(BelId bel); + bool checkBelAvail(BelId bel) const; + const vector &getBels() const; + const vector &getBelsByType(BelType type) const; BelType getBelType(BelId bel) const; - - // void getBelPosition(BelId bel, float &x, float &y) const; - // void getWirePosition(WireId wire, float &x, float &y) const; - // vector getBelGuiLines(BelId bel) const; - // vector getWireGuiLines(WireId wire) const; - - WireRange getWires() const; - WireDelayRange getWiresUphill(WireId wire) const; - WireDelayRange getWiresDownhill(WireId wire) const; - WireDelayRange getWiresBidir(WireId wire) const; - WireDelayRange getWireAliases(WireId wire) const; - - // the following will only operate on / return "active" BELs - // multiple active uphill BELs for a wire will cause a runtime error WireId getWireBelPin(BelId bel, PortPin pin) const; BelPin getBelPinUphill(WireId wire) const; - BelPinRange getBelPinsDownhill(WireId wire) const; + const vector &getBelPinsDownhill(WireId wire) const; + + WireId getWireByName(IdString name) const; + IdString getWireName(WireId wire) const; + void bindWire(WireId bel, IdString net); + void unbindWire(WireId bel); + bool checkWireAvail(WireId bel) const; + const vector &getWires() const; + + PipId getPipByName(IdString name) const; + IdString getPipName(PipId pip) const; + void bindPip(PipId bel, IdString net); + void unbindPip(PipId bel); + bool checkPipAvail(PipId bel) const; + const vector &getPips() const; + WireId getPipSrcWire(PipId pip) const; + WireId getPipDstWire(PipId pip) const; + DelayInfo getPipDelay(PipId pip) const; + const vector &getPipsDownhill(WireId wire) const; + const vector &getPipsUphill(WireId wire) const; + const vector &getWireAliases(WireId wire) const; + + void getBelPosition(BelId bel, float &x, float &y) const; + void getWirePosition(WireId wire, float &x, float &y) const; + void getPipPosition(PipId pip, 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/dummy/main.cc b/dummy/main.cc index be4b47a9..5c36a961 100644 --- a/dummy/main.cc +++ b/dummy/main.cc @@ -25,9 +25,6 @@ int main(int argc, char *argv[]) { Design design(ChipArgs{}); - for (auto bel : design.chip.getBels()) - printf("%s\n", design.chip.getBelName(bel).c_str()); - QApplication a(argc, argv); MainWindow w; w.show(); diff --git a/dummy/pybindings.cc b/dummy/pybindings.cc index affa768a..a19479a0 100644 --- a/dummy/pybindings.cc +++ b/dummy/pybindings.cc @@ -24,5 +24,4 @@ void arch_wrap_python() { class_("ChipArgs"); - WRAP_RANGE(Wire); } diff --git a/ice40/chip.cc b/ice40/chip.cc index 4cdd98ff..d1226b3a 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,168 @@ 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 +{ + assert(!bel.nil()); + x = chip_info.bel_data[bel.index].x; + y = chip_info.bel_data[bel.index].y; +} + +void Chip::getWirePosition(WireId wire, float &x, float &y) const +{ + assert(!wire.nil()); + x = chip_info.wire_data[wire.index].x; + y = chip_info.wire_data[wire.index].y; +} + +void Chip::getPipPosition(PipId pip, float &x, float &y) const +{ + assert(!pip.nil()); + x = chip_info.pip_data[pip.index].x; + y = chip_info.pip_data[pip.index].y; +} + +vector Chip::getBelGraphics(BelId bel) const +{ + vector ret; + + auto bel_type = getBelType(bel); + + if (bel_type == TYPE_ICESTORM_LC) { + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.x1 = chip_info.bel_data[bel.index].x + 0.1; + el.x2 = chip_info.bel_data[bel.index].x + 0.9; + el.y1 = chip_info.bel_data[bel.index].y + 0.10 + (chip_info.bel_data[bel.index].z) * (0.8/8); + el.y2 = chip_info.bel_data[bel.index].y + 0.18 + (chip_info.bel_data[bel.index].z) * (0.8/8); + el.z = 0; + ret.push_back(el); + } + + if (bel_type == TYPE_SB_IO) { + if (chip_info.bel_data[bel.index].x == 0 || chip_info.bel_data[bel.index].x == chip_info.width-1) + { + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.x1 = chip_info.bel_data[bel.index].x + 0.1; + el.x2 = chip_info.bel_data[bel.index].x + 0.9; + if (chip_info.bel_data[bel.index].z == 0) { + el.y1 = chip_info.bel_data[bel.index].y + 0.10; + el.y2 = chip_info.bel_data[bel.index].y + 0.45; + } else { + el.y1 = chip_info.bel_data[bel.index].y + 0.55; + el.y2 = chip_info.bel_data[bel.index].y + 0.90; + } + el.z = 0; + ret.push_back(el); + } + else + { + GraphicElement el; + el.type = GraphicElement::G_BOX; + if (chip_info.bel_data[bel.index].z == 0) { + el.x1 = chip_info.bel_data[bel.index].x + 0.10; + el.x2 = chip_info.bel_data[bel.index].x + 0.45; + } else { + el.x1 = chip_info.bel_data[bel.index].x + 0.55; + el.x2 = chip_info.bel_data[bel.index].x + 0.90; + } + el.y1 = chip_info.bel_data[bel.index].y + 0.1; + el.y2 = chip_info.bel_data[bel.index].y + 0.9; + el.z = 0; + ret.push_back(el); + } + } + + if (bel_type == TYPE_ICESTORM_RAM) { + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.x1 = chip_info.bel_data[bel.index].x + 0.1; + el.x2 = chip_info.bel_data[bel.index].x + 0.9; + el.y1 = chip_info.bel_data[bel.index].y + 0.1; + el.y2 = chip_info.bel_data[bel.index].y + 1.9; + el.z = 0; + ret.push_back(el); + } + + 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; + + for (int x = 0; x <= chip_info.width; x++) + for (int y = 0; y <= chip_info.height; y++) + { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0; + ret.push_back(el); + el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0; + ret.push_back(el); + } + + return ret; +} diff --git a/ice40/chip.h b/ice40/chip.h index 6113a869..2f0a1284 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -164,12 +164,7 @@ struct BelInfoPOD { const char *name; BelType type; -}; - -struct WireDelayPOD -{ - int32_t wire_index; - float delay; + int8_t x, y, z; }; struct BelPortPOD @@ -178,36 +173,39 @@ struct BelPortPOD PortPin port; }; +struct PipInfoPOD +{ + int32_t src, dst; + float delay; + int8_t x, y; +}; + 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; + + float x, y; }; -extern int num_bels_384; -extern int num_bels_1k; -extern int num_bels_5k; -extern int num_bels_8k; +struct ChipInfoPOD +{ + int width, height; + 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; // ----------------------------------------------------------------------- @@ -218,6 +216,9 @@ struct BelId bool nil() const { return index < 0; } + + bool operator==(const BelId &other) const { return index == other.index; } + bool operator!=(const BelId &other) const { return index != other.index; } }; struct WireId @@ -227,6 +228,27 @@ struct WireId bool nil() const { return index < 0; } + + bool operator==(const WireId &other) const { return index == other.index; } + bool operator!=(const WireId &other) const { return index != other.index; } +}; + +struct PipId +{ + int32_t index = -1; + + bool nil() const { + return index < 0; + } + + bool operator==(const PipId &other) const { return index == other.index; } + bool operator!=(const PipId &other) const { return index != other.index; } +}; + +struct BelPin +{ + BelId bel; + PortPin pin; }; namespace std @@ -246,6 +268,14 @@ namespace std return wire.index; } }; + + template<> struct hash + { + std::size_t operator()(const PipId &wire) const noexcept + { + return wire.index; + } + }; } // ----------------------------------------------------------------------- @@ -273,65 +303,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 +327,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 +411,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 +465,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 +474,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 +487,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(PipId pip, 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..58dd0dd2 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -11,16 +11,18 @@ tiles = dict() wire_uphill = dict() wire_downhill = dict() -wire_bidir = dict() +pip_xy = dict() bel_name = list() bel_type = list() +bel_pos = list() wire_uphill_belport = dict() wire_downhill_belports = dict() wire_names = dict() wire_names_r = dict() +wire_xy = dict() def cmp_wire_names(newname, oldname): return newname < oldname @@ -46,11 +48,11 @@ with open(sys.argv[1], "r") as f: continue if line[0] == ".buffer": - mode = ("buffer", int(line[3])) + mode = ("buffer", int(line[3]), int(line[1]), int(line[2])) continue if line[0] == ".routing": - mode = ("routing", int(line[3])) + mode = ("routing", int(line[3]), int(line[1]), int(line[2])) continue if line[0] == ".io_tile": @@ -82,6 +84,9 @@ with open(sys.argv[1], "r") as f: wire_names[wname] = mode[1] if (mode[1] not in wire_names_r) or cmp_wire_names(wname, wire_names_r[mode[1]]): wire_names_r[mode[1]] = wname + if mode[1] not in wire_xy: + wire_xy[mode[1]] = list() + wire_xy[mode[1]].append((int(line[0]), int(line[1]))) continue if mode[0] == "buffer": @@ -93,17 +98,28 @@ with open(sys.argv[1], "r") as f: wire_uphill[wire_b] = set() wire_downhill[wire_a].add(wire_b) wire_uphill[wire_b].add(wire_a) + pip_xy[(wire_a, wire_b)] = (mode[2], mode[3]) continue 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) + pip_xy[(wire_a, wire_b)] = (mode[2], mode[3]) + + 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) + pip_xy[(wire_b, wire_a)] = (mode[2], mode[3]) continue def add_bel_input(bel, wire, port): @@ -119,6 +135,7 @@ def add_bel_lc(x, y, z): bel = len(bel_name) bel_name.append("%d_%d_lc%d" % (x, y, z)) bel_type.append("ICESTORM_LC") + bel_pos.append((x, y, z)) wire_cen = wire_names[(x, y, "lutff_global/cen")] wire_clk = wire_names[(x, y, "lutff_global/clk")] @@ -157,6 +174,7 @@ def add_bel_io(x, y, z): bel = len(bel_name) bel_name.append("%d_%d_lc%d" % (x, y, z)) bel_type.append("SB_IO") + bel_pos.append((x, y, z)) wire_cen = wire_names[(x, y, "io_global/cen")] wire_iclk = wire_names[(x, y, "io_global/inclk")] @@ -185,6 +203,7 @@ def add_bel_ram(x, y): bel = len(bel_name) bel_name.append("%d_%d_ram" % (x, y)) bel_type.append("ICESTORM_RAM") + bel_pos.append((x, y, 0)) if (x, y, "ram/WE") in wire_names: # iCE40 1K-style memories @@ -222,63 +241,86 @@ 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(" {\"%s\", TYPE_%s, %d, %d, %d}%s" % (bel_name[bel], bel_type[bel], + bel_pos[bel][0], bel_pos[bel][1], bel_pos[bel][2], + "," 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, %d, %d}" % (src, wire, pip_xy[(src, wire)][0], pip_xy[(src, wire)][1])) + 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, %d, %d}" % (wire, dst, pip_xy[(wire, dst)][0], pip_xy[(wire, dst)][1])) + 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] else: info += "{-1, PIN_NIL}, " - info += ("wire%d_downbels" % wire) if num_bels_downhill > 0 else "nullptr" - info += "}" + info += ("wire%d_downbels, " % wire) if num_bels_downhill > 0 else "nullptr, " + + avg_x, avg_y = 0, 0 + if wire in wire_xy: + for x, y in wire_xy[wire]: + avg_x += x + avg_y += y + avg_x /= len(wire_xy[wire]) + avg_y /= len(wire_xy[wire]) + + info += "%f, %f}" % (avg_x, avg_y) 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, %d, %d," % (dev_width, dev_height, 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/main.cc b/ice40/main.cc index e02930bb..185c7f53 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -24,6 +24,22 @@ #include #include "pybindings.h" +void svg_dump_el(const GraphicElement &el) +{ + float scale = 10.0, offset = 10.0; + std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; + + if (el.type == GraphicElement::G_BOX) { + std::cout << "\n"; + } + + if (el.type == GraphicElement::G_LINE) { + std::cout << "\n"; + } +} + int main(int argc, char *argv[]) { namespace po = boost::program_options; @@ -32,10 +48,17 @@ int main(int argc, char *argv[]) po::options_description options("Allowed options"); options.add_options()("help,h","show help"); - options.add_options()("debug","just a check"); + options.add_options()("test","just a check"); options.add_options()("gui","start gui"); + options.add_options()("svg","dump SVG file"); options.add_options()("file", po::value(), "python file to execute"); options.add_options()("version,v","show version"); + options.add_options()("lp384","set device type to iCE40LP384"); + options.add_options()("lp1k","set device type to iCE40LP1K"); + options.add_options()("lp8k","set device type to iCE40LP8K"); + options.add_options()("hx1k","set device type to iCE40HX1K"); + options.add_options()("hx8k","set device type to iCE40HX8K"); + options.add_options()("up5k","set device type to iCE40UP5K"); po::positional_options_description pos; pos.add("file", -1); @@ -71,6 +94,29 @@ int main(int argc, char *argv[]) return 1; } + ChipArgs chipArgs; + chipArgs.type = ChipArgs::HX1K; + + if (vm.count("lp384")) + chipArgs.type = ChipArgs::LP384; + + if (vm.count("lp1k")) + chipArgs.type = ChipArgs::LP1K; + + if (vm.count("lp8k")) + chipArgs.type = ChipArgs::LP8K; + + if (vm.count("hx1k")) + chipArgs.type = ChipArgs::HX1K; + + if (vm.count("hx8k")) + chipArgs.type = ChipArgs::HX8K; + + if (vm.count("up5k")) + chipArgs.type = ChipArgs::UP5K; + + Design design(chipArgs); + if (vm.count("gui")) { QApplication a(argc, argv); @@ -80,17 +126,79 @@ int main(int argc, char *argv[]) return a.exec(); } - if (vm.count("debug")) + if (vm.count("test")) { - ChipArgs chipArgs; - chipArgs.type = ChipArgs::LP384; + int bel_count = 0, wire_count = 0, pip_count = 0; + + std::cout << "Checking bel names.\n"; + for (auto bel : design.chip.getBels()) { + auto name = design.chip.getBelName(bel); + assert(bel == design.chip.getBelByName(name)); + bel_count++; + } + std::cout << " checked " << bel_count << " bels.\n"; + + std::cout << "Checking wire names.\n"; + for (auto wire : design.chip.getWires()) { + auto name = design.chip.getWireName(wire); + assert(wire == design.chip.getWireByName(name)); + wire_count++; + } + std::cout << " checked " << wire_count << " wires.\n"; + + std::cout << "Checking pip names.\n"; + for (auto pip : design.chip.getPips()) { + auto name = design.chip.getPipName(pip); + assert(pip == design.chip.getPipByName(name)); + pip_count++; + } + std::cout << " checked " << pip_count << " pips.\n"; + + std::cout << "Checking uphill -> downhill consistency.\n"; + for (auto dst : design.chip.getWires()) { + for (auto uphill_pip : design.chip.getPipsUphill(dst)) { + bool found_downhill = false; + for (auto downhill_pip : design.chip.getPipsDownhill(design.chip.getPipSrcWire(uphill_pip))) { + if (uphill_pip == downhill_pip) { + assert(!found_downhill); + found_downhill = true; + } + } + assert(found_downhill); + } + } + + std::cout << "Checking downhill -> uphill consistency.\n"; + for (auto dst : design.chip.getWires()) { + for (auto downhill_pip : design.chip.getPipsDownhill(dst)) { + bool found_uphill = false; + for (auto uphill_pip : design.chip.getPipsUphill(design.chip.getPipDstWire(downhill_pip))) { + if (uphill_pip == downhill_pip) { + assert(!found_uphill); + found_uphill = true; + } + } + assert(found_uphill); + } + } - Design design(chipArgs); - for (auto bel : design.chip.getBels()) - printf("%s\n", design.chip.getBelName(bel).c_str()); return 0; } + if (vm.count("svg")) + { + std::cout << "\n"; + for (auto bel : design.chip.getBels()) { + std::cout << "\n"; + for (auto &el : design.chip.getBelGraphics(bel)) + svg_dump_el(el); + } + std::cout << "\n"; + for (auto &el : design.chip.getFrameGraphics()) + svg_dump_el(el); + std::cout << "\n"; + } + if (vm.count("file")) { std::string filename = vm["file"].as(); 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); }