From cbcd2ea3acaf257bf39b25a38d9f591e82a66f37 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Jun 2018 14:12:39 +0200 Subject: Rename chip.h to arch.h Signed-off-by: Clifford Wolf --- common/nextpnr.h | 2 +- dummy/arch.cc | 179 +++++++++++++ dummy/arch.h | 128 ++++++++++ dummy/chip.cc | 179 ------------- dummy/chip.h | 128 ---------- ice40/arch.cc | 419 ++++++++++++++++++++++++++++++ ice40/arch.h | 757 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ice40/chip.cc | 419 ------------------------------ ice40/chip.h | 757 ------------------------------------------------------- 9 files changed, 1484 insertions(+), 1484 deletions(-) create mode 100644 dummy/arch.cc create mode 100644 dummy/arch.h delete mode 100644 dummy/chip.cc delete mode 100644 dummy/chip.h create mode 100644 ice40/arch.cc create mode 100644 ice40/arch.h delete mode 100644 ice40/chip.cc delete mode 100644 ice40/chip.h diff --git a/common/nextpnr.h b/common/nextpnr.h index 8acb1554..3d505844 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -141,7 +141,7 @@ struct GraphicElement NEXTPNR_NAMESPACE_END -#include "chip.h" +#include "arch.h" #include "design.h" #endif diff --git a/dummy/arch.cc b/dummy/arch.cc new file mode 100644 index 00000000..5bbf36e3 --- /dev/null +++ b/dummy/arch.cc @@ -0,0 +1,179 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +Arch::Arch(ArchArgs) {} + +std::string Arch::getChipName() { return "Dummy"; } + +void IdString::initialize_chip() {} + +// --------------------------------------------------------------- + +BelId Arch::getBelByName(IdString name) const { return BelId(); } + +IdString Arch::getBelName(BelId bel) const { return IdString(); } + +void Arch::bindBel(BelId bel, IdString cell) {} + +void Arch::unbindBel(BelId bel) {} + +bool Arch::checkBelAvail(BelId bel) const { return false; } + +IdString Arch::getBelCell(BelId bel, bool conflicting) const +{ + return IdString(); +} + +const std::vector &Arch::getBels() const +{ + static std::vector ret; + return ret; +} + +const std::vector &Arch::getBelsByType(BelType type) const +{ + static std::vector ret; + return ret; +} + +BelType Arch::getBelType(BelId bel) const { return BelType(); } + +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return WireId(); } + +BelPin Arch::getBelPinUphill(WireId wire) const { return BelPin(); } + +const std::vector &Arch::getBelPinsDownhill(WireId wire) const +{ + static std::vector ret; + return ret; +} + +// --------------------------------------------------------------- + +WireId Arch::getWireByName(IdString name) const { return WireId(); } + +IdString Arch::getWireName(WireId wire) const { return IdString(); } + +void Arch::bindWire(WireId wire, IdString net) {} + +void Arch::unbindWire(WireId wire) {} + +bool Arch::checkWireAvail(WireId wire) const { return false; } + +IdString Arch::getWireNet(WireId wire, bool conflicting) const +{ + return IdString(); +} + +const std::vector &Arch::getWires() const +{ + static std::vector ret; + return ret; +} + +// --------------------------------------------------------------- + +PipId Arch::getPipByName(IdString name) const { return PipId(); } + +IdString Arch::getPipName(PipId pip) const { return IdString(); } + +void Arch::bindPip(PipId pip, IdString net) {} + +void Arch::unbindPip(PipId pip) {} + +bool Arch::checkPipAvail(PipId pip) const { return false; } + +IdString Arch::getPipNet(PipId pip, bool conflicting) const +{ + return IdString(); +} + +const std::vector &Arch::getPips() const +{ + static std::vector ret; + return ret; +} + +WireId Arch::getPipSrcWire(PipId pip) const { return WireId(); } + +WireId Arch::getPipDstWire(PipId pip) const { return WireId(); } + +DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); } + +const std::vector &Arch::getPipsDownhill(WireId wire) const +{ + static std::vector ret; + return ret; +} + +const std::vector &Arch::getPipsUphill(WireId wire) const +{ + static std::vector ret; + return ret; +} + +const std::vector &Arch::getWireAliases(WireId wire) const +{ + static std::vector ret; + return ret; +} + +// --------------------------------------------------------------- + +bool Arch::estimatePosition(BelId bel, int &x, int &y) const +{ + x = 0.0; + y = 0.0; + return false; +} + +delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0.0; } + +// --------------------------------------------------------------- + +std::vector Arch::getFrameGraphics() const +{ + static std::vector ret; + return ret; +} + +std::vector Arch::getBelGraphics(BelId bel) const +{ + static std::vector ret; + return ret; +} + +std::vector Arch::getWireGraphics(WireId wire) const +{ + static std::vector ret; + return ret; +} + +std::vector Arch::getPipGraphics(PipId pip) const +{ + static std::vector ret; + return ret; +} + +NEXTPNR_NAMESPACE_END diff --git a/dummy/arch.h b/dummy/arch.h new file mode 100644 index 00000000..40aceff2 --- /dev/null +++ b/dummy/arch.h @@ -0,0 +1,128 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef CHIP_H +#define CHIP_H + +#ifndef NEXTPNR_H +#error Include "arch.h" via "nextpnr.h" only. +#endif + +NEXTPNR_NAMESPACE_BEGIN + +typedef float delay_t; + +struct DelayInfo +{ + delay_t delay = 0; + + delay_t raiseDelay() const { return delay; } + delay_t fallDelay() const { return delay; } + delay_t avgDelay() const { return delay; } + + DelayInfo operator+(const DelayInfo &other) const + { + DelayInfo ret; + ret.delay = this->delay + other.delay; + return ret; + } +}; + +typedef IdString BelType; +typedef IdString PortPin; + +static inline IdString belTypeToId(BelType type) { return type; } +static inline IdString portPinToId(PortPin type) { return type; } + +static inline BelType belTypeFromId(IdString id) { return id; } +static inline PortPin portPinFromId(IdString id) { return id; } + +typedef IdString BelId; +typedef IdString WireId; +typedef IdString PipId; + +struct BelPin +{ + BelId bel; + PortPin pin; +}; + +struct ArchArgs +{ +}; + +struct Arch +{ + Arch(ArchArgs args); + + std::string getChipName(); + + BelId getBelByName(IdString name) const; + IdString getBelName(BelId bel) const; + void bindBel(BelId bel, IdString cell); + void unbindBel(BelId bel); + bool checkBelAvail(BelId bel) const; + IdString getBelCell(BelId bel, bool conflicting = false) const; + const std::vector &getBels() const; + const std::vector &getBelsByType(BelType type) const; + BelType getBelType(BelId bel) const; + WireId getWireBelPin(BelId bel, PortPin pin) const; + BelPin getBelPinUphill(WireId wire) const; + const std::vector &getBelPinsDownhill(WireId wire) const; + + WireId getWireByName(IdString name) const; + IdString getWireName(WireId wire) const; + void bindWire(WireId wire, IdString net); + void unbindWire(WireId wire); + bool checkWireAvail(WireId wire) const; + IdString getWireNet(WireId wire, bool conflicting = false) const; + const std::vector &getWires() const; + + PipId getPipByName(IdString name) const; + IdString getPipName(PipId pip) const; + void bindPip(PipId pip, IdString net); + void unbindPip(PipId pip); + bool checkPipAvail(PipId pip) const; + IdString getPipNet(PipId pip, bool conflicting = false) const; + const std::vector &getPips() const; + WireId getPipSrcWire(PipId pip) const; + WireId getPipDstWire(PipId pip) const; + DelayInfo getPipDelay(PipId pip) const; + const std::vector &getPipsDownhill(WireId wire) const; + const std::vector &getPipsUphill(WireId wire) const; + const std::vector &getWireAliases(WireId wire) const; + + bool estimatePosition(BelId bel, int &x, int &y) const; + delay_t estimateDelay(WireId src, WireId dst) const; + + std::vector getFrameGraphics() const; + std::vector getBelGraphics(BelId bel) const; + std::vector getWireGraphics(WireId wire) const; + std::vector getPipGraphics(PipId pip) const; + + bool allGraphicsReload = false; + bool frameGraphicsReload = false; + std::unordered_set belGraphicsReload; + std::unordered_set wireGraphicsReload; + std::unordered_set pipGraphicsReload; +}; + +NEXTPNR_NAMESPACE_END + +#endif diff --git a/dummy/chip.cc b/dummy/chip.cc deleted file mode 100644 index 5bbf36e3..00000000 --- a/dummy/chip.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -Arch::Arch(ArchArgs) {} - -std::string Arch::getChipName() { return "Dummy"; } - -void IdString::initialize_chip() {} - -// --------------------------------------------------------------- - -BelId Arch::getBelByName(IdString name) const { return BelId(); } - -IdString Arch::getBelName(BelId bel) const { return IdString(); } - -void Arch::bindBel(BelId bel, IdString cell) {} - -void Arch::unbindBel(BelId bel) {} - -bool Arch::checkBelAvail(BelId bel) const { return false; } - -IdString Arch::getBelCell(BelId bel, bool conflicting) const -{ - return IdString(); -} - -const std::vector &Arch::getBels() const -{ - static std::vector ret; - return ret; -} - -const std::vector &Arch::getBelsByType(BelType type) const -{ - static std::vector ret; - return ret; -} - -BelType Arch::getBelType(BelId bel) const { return BelType(); } - -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return WireId(); } - -BelPin Arch::getBelPinUphill(WireId wire) const { return BelPin(); } - -const std::vector &Arch::getBelPinsDownhill(WireId wire) const -{ - static std::vector ret; - return ret; -} - -// --------------------------------------------------------------- - -WireId Arch::getWireByName(IdString name) const { return WireId(); } - -IdString Arch::getWireName(WireId wire) const { return IdString(); } - -void Arch::bindWire(WireId wire, IdString net) {} - -void Arch::unbindWire(WireId wire) {} - -bool Arch::checkWireAvail(WireId wire) const { return false; } - -IdString Arch::getWireNet(WireId wire, bool conflicting) const -{ - return IdString(); -} - -const std::vector &Arch::getWires() const -{ - static std::vector ret; - return ret; -} - -// --------------------------------------------------------------- - -PipId Arch::getPipByName(IdString name) const { return PipId(); } - -IdString Arch::getPipName(PipId pip) const { return IdString(); } - -void Arch::bindPip(PipId pip, IdString net) {} - -void Arch::unbindPip(PipId pip) {} - -bool Arch::checkPipAvail(PipId pip) const { return false; } - -IdString Arch::getPipNet(PipId pip, bool conflicting) const -{ - return IdString(); -} - -const std::vector &Arch::getPips() const -{ - static std::vector ret; - return ret; -} - -WireId Arch::getPipSrcWire(PipId pip) const { return WireId(); } - -WireId Arch::getPipDstWire(PipId pip) const { return WireId(); } - -DelayInfo Arch::getPipDelay(PipId pip) const { return DelayInfo(); } - -const std::vector &Arch::getPipsDownhill(WireId wire) const -{ - static std::vector ret; - return ret; -} - -const std::vector &Arch::getPipsUphill(WireId wire) const -{ - static std::vector ret; - return ret; -} - -const std::vector &Arch::getWireAliases(WireId wire) const -{ - static std::vector ret; - return ret; -} - -// --------------------------------------------------------------- - -bool Arch::estimatePosition(BelId bel, int &x, int &y) const -{ - x = 0.0; - y = 0.0; - return false; -} - -delay_t Arch::estimateDelay(WireId src, WireId dst) const { return 0.0; } - -// --------------------------------------------------------------- - -std::vector Arch::getFrameGraphics() const -{ - static std::vector ret; - return ret; -} - -std::vector Arch::getBelGraphics(BelId bel) const -{ - static std::vector ret; - return ret; -} - -std::vector Arch::getWireGraphics(WireId wire) const -{ - static std::vector ret; - return ret; -} - -std::vector Arch::getPipGraphics(PipId pip) const -{ - static std::vector ret; - return ret; -} - -NEXTPNR_NAMESPACE_END diff --git a/dummy/chip.h b/dummy/chip.h deleted file mode 100644 index c0803510..00000000 --- a/dummy/chip.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef CHIP_H -#define CHIP_H - -#ifndef NEXTPNR_H -#error Include "chip.h" via "nextpnr.h" only. -#endif - -NEXTPNR_NAMESPACE_BEGIN - -typedef float delay_t; - -struct DelayInfo -{ - delay_t delay = 0; - - delay_t raiseDelay() const { return delay; } - delay_t fallDelay() const { return delay; } - delay_t avgDelay() const { return delay; } - - DelayInfo operator+(const DelayInfo &other) const - { - DelayInfo ret; - ret.delay = this->delay + other.delay; - return ret; - } -}; - -typedef IdString BelType; -typedef IdString PortPin; - -static inline IdString belTypeToId(BelType type) { return type; } -static inline IdString portPinToId(PortPin type) { return type; } - -static inline BelType belTypeFromId(IdString id) { return id; } -static inline PortPin portPinFromId(IdString id) { return id; } - -typedef IdString BelId; -typedef IdString WireId; -typedef IdString PipId; - -struct BelPin -{ - BelId bel; - PortPin pin; -}; - -struct ArchArgs -{ -}; - -struct Arch -{ - Arch(ArchArgs args); - - std::string getChipName(); - - BelId getBelByName(IdString name) const; - IdString getBelName(BelId bel) const; - void bindBel(BelId bel, IdString cell); - void unbindBel(BelId bel); - bool checkBelAvail(BelId bel) const; - IdString getBelCell(BelId bel, bool conflicting = false) const; - const std::vector &getBels() const; - const std::vector &getBelsByType(BelType type) const; - BelType getBelType(BelId bel) const; - WireId getWireBelPin(BelId bel, PortPin pin) const; - BelPin getBelPinUphill(WireId wire) const; - const std::vector &getBelPinsDownhill(WireId wire) const; - - WireId getWireByName(IdString name) const; - IdString getWireName(WireId wire) const; - void bindWire(WireId wire, IdString net); - void unbindWire(WireId wire); - bool checkWireAvail(WireId wire) const; - IdString getWireNet(WireId wire, bool conflicting = false) const; - const std::vector &getWires() const; - - PipId getPipByName(IdString name) const; - IdString getPipName(PipId pip) const; - void bindPip(PipId pip, IdString net); - void unbindPip(PipId pip); - bool checkPipAvail(PipId pip) const; - IdString getPipNet(PipId pip, bool conflicting = false) const; - const std::vector &getPips() const; - WireId getPipSrcWire(PipId pip) const; - WireId getPipDstWire(PipId pip) const; - DelayInfo getPipDelay(PipId pip) const; - const std::vector &getPipsDownhill(WireId wire) const; - const std::vector &getPipsUphill(WireId wire) const; - const std::vector &getWireAliases(WireId wire) const; - - bool estimatePosition(BelId bel, int &x, int &y) const; - delay_t estimateDelay(WireId src, WireId dst) const; - - std::vector getFrameGraphics() const; - std::vector getBelGraphics(BelId bel) const; - std::vector getWireGraphics(WireId wire) const; - std::vector getPipGraphics(PipId pip) const; - - bool allGraphicsReload = false; - bool frameGraphicsReload = false; - std::unordered_set belGraphicsReload; - std::unordered_set wireGraphicsReload; - std::unordered_set pipGraphicsReload; -}; - -NEXTPNR_NAMESPACE_END - -#endif diff --git a/ice40/arch.cc b/ice40/arch.cc new file mode 100644 index 00000000..b269a3e3 --- /dev/null +++ b/ice40/arch.cc @@ -0,0 +1,419 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include +#include "log.h" +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +// ----------------------------------------------------------------------- + +IdString belTypeToId(BelType type) +{ + if (type == TYPE_ICESTORM_LC) + return "ICESTORM_LC"; + if (type == TYPE_ICESTORM_RAM) + return "ICESTORM_RAM"; + if (type == TYPE_SB_IO) + return "SB_IO"; + if (type == TYPE_SB_GB) + return "SB_GB"; + return IdString(); +} + +BelType belTypeFromId(IdString id) +{ + if (id == "ICESTORM_LC") + return TYPE_ICESTORM_LC; + if (id == "ICESTORM_RAM") + return TYPE_ICESTORM_RAM; + if (id == "SB_IO") + return TYPE_SB_IO; + if (id == "SB_GB") + return TYPE_SB_GB; + return TYPE_NONE; +} + +// ----------------------------------------------------------------------- + +void IdString::initialize_chip() +{ +#define X(t) initialize_add(#t, PIN_##t); +#include "portpins.inc" +#undef X +} + +IdString portPinToId(PortPin type) +{ + IdString ret; + if (type > 0 && type < PIN_MAXIDX) + ret.index = type; + return ret; +} + +PortPin portPinFromId(IdString id) +{ + if (id.index > 0 && id.index < PIN_MAXIDX) + return PortPin(id.index); + return PIN_NONE; +} + +// ----------------------------------------------------------------------- + +Arch::Arch(ArchArgs args) : args(args) +{ +#ifdef ICE40_HX1K_ONLY + if (args.type == ArchArgs::HX1K) { + chip_info = + reinterpret_cast *>(chipdb_blob_1k) + ->get(); + } else { + log_error("Unsupported iCE40 chip type.\n"); + } +#else + if (args.type == ArchArgs::LP384) { + chip_info = + reinterpret_cast *>(chipdb_blob_384) + ->get(); + } else if (args.type == ArchArgs::LP1K || args.type == ArchArgs::HX1K) { + chip_info = + reinterpret_cast *>(chipdb_blob_1k) + ->get(); + } else if (args.type == ArchArgs::UP5K) { + chip_info = + reinterpret_cast *>(chipdb_blob_5k) + ->get(); + } else if (args.type == ArchArgs::LP8K || args.type == ArchArgs::HX8K) { + chip_info = + reinterpret_cast *>(chipdb_blob_8k) + ->get(); + } else { + log_error("Unsupported iCE40 chip type.\n"); + } +#endif + + package_info = nullptr; + for (int i = 0; i < chip_info->num_packages; i++) { + if (chip_info->packages_data[i].name.get() == args.package) { + package_info = &(chip_info->packages_data[i]); + break; + } + } + if (package_info == nullptr) + log_error("Unsupported package '%s'.\n", args.package.c_str()); + + bel_to_cell.resize(chip_info->num_bels); + wire_to_net.resize(chip_info->num_wires); + pip_to_net.resize(chip_info->num_pips); + switches_locked.resize(chip_info->num_switches); +} + +// ----------------------------------------------------------------------- + +std::string Arch::getChipName() +{ +#ifdef ICE40_HX1K_ONLY + if (args.type == ArchArgs::HX1K) { + return "Lattice LP1K"; + } else { + log_error("Unsupported iCE40 chip type.\n"); + } +#else + if (args.type == ArchArgs::LP384) { + return "Lattice LP384"; + } else if (args.type == ArchArgs::LP1K) { + return "Lattice LP1K"; + } else if (args.type == ArchArgs::HX1K) { + return "Lattice HX1K"; + } else if (args.type == ArchArgs::UP5K) { + return "Lattice UP5K"; + } else if (args.type == ArchArgs::LP8K) { + return "Lattice LP8K"; + } else if (args.type == ArchArgs::HX8K) { + return "Lattice HX8K"; + } else { + log_error("Unknown chip\n"); + } +#endif +} + +// ----------------------------------------------------------------------- + +BelId Arch::getBelByName(IdString name) const +{ + BelId ret; + + if (bel_by_name.empty()) { + for (int i = 0; i < chip_info->num_bels; i++) + bel_by_name[chip_info->bel_data[i].name.get()] = i; + } + + auto it = bel_by_name.find(name); + if (it != bel_by_name.end()) + ret.index = it->second; + + return ret; +} + +BelRange Arch::getBelsAtSameTile(BelId bel) const +{ + BelRange br; + assert(bel != BelId()); + // This requires Bels at the same tile are consecutive + int x = chip_info->bel_data[bel.index].x; + int y = chip_info->bel_data[bel.index].y; + int start = bel.index, end = bel.index; + while (start >= 0 && chip_info->bel_data[start].x == x && + chip_info->bel_data[start].y == y) + start--; + start++; + br.b.cursor = start; + while (end < chip_info->num_bels && chip_info->bel_data[end].x == x && + chip_info->bel_data[end].y == y) + end++; + br.e.cursor = end; + return br; +} + +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +{ + WireId ret; + + 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.get(); + + for (int i = 0; i < num_bel_wires; i++) + if (bel_wires[i].port == pin) { + ret.index = bel_wires[i].wire_index; + break; + } + + return ret; +} + +// ----------------------------------------------------------------------- + +WireId Arch::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.get()] = i; + } + + auto it = wire_by_name.find(name); + if (it != wire_by_name.end()) + ret.index = it->second; + + return ret; +} + +// ----------------------------------------------------------------------- + +PipId Arch::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; +} + +IdString Arch::getPipName(PipId pip) const +{ + assert(pip != PipId()); + + int x = chip_info->pip_data[pip.index].x; + int y = chip_info->pip_data[pip.index].y; + + std::string src_name = + chip_info->wire_data[chip_info->pip_data[pip.index].src].name.get(); + std::replace(src_name.begin(), src_name.end(), '/', '.'); + + std::string dst_name = + chip_info->wire_data[chip_info->pip_data[pip.index].dst].name.get(); + std::replace(dst_name.begin(), dst_name.end(), '/', '.'); + + return "X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + + ".->." + dst_name; +} + +// ----------------------------------------------------------------------- + +BelId Arch::getPackagePinBel(const std::string &pin) const +{ + for (int i = 0; i < package_info->num_pins; i++) { + if (package_info->pins[i].name.get() == pin) { + BelId id; + id.index = package_info->pins[i].bel_index; + return id; + } + } + return BelId(); +} + +std::string Arch::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.get()); + } + } + return ""; +} +// ----------------------------------------------------------------------- + +bool Arch::estimatePosition(BelId bel, int &x, int &y) const +{ + assert(bel != BelId()); + x = chip_info->bel_data[bel.index].x; + y = chip_info->bel_data[bel.index].y; + + return chip_info->bel_data[bel.index].type != TYPE_SB_GB; +} + +delay_t Arch::estimateDelay(WireId src, WireId dst) const +{ + assert(src != WireId()); + delay_t x1 = chip_info->wire_data[src.index].x; + delay_t y1 = chip_info->wire_data[src.index].y; + + assert(dst != WireId()); + delay_t x2 = chip_info->wire_data[dst.index].x; + delay_t y2 = chip_info->wire_data[dst.index].y; + + return fabsf(x1 - x2) + fabsf(y1 - y2); +} + +// ----------------------------------------------------------------------- + +std::vector Arch::getFrameGraphics() const +{ + std::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; +} + +std::vector Arch::getBelGraphics(BelId bel) const +{ + std::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; +} + +std::vector Arch::getWireGraphics(WireId wire) const +{ + std::vector ret; + // FIXME + return ret; +} + +std::vector Arch::getPipGraphics(PipId pip) const +{ + std::vector ret; + // FIXME + return ret; +} + +NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h new file mode 100644 index 00000000..9e811ba9 --- /dev/null +++ b/ice40/arch.h @@ -0,0 +1,757 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef CHIP_H +#define CHIP_H + +#ifndef NEXTPNR_H +#error Include "arch.h" via "nextpnr.h" only. +#endif + +NEXTPNR_NAMESPACE_BEGIN + +typedef int delay_t; + +struct DelayInfo +{ + delay_t delay = 0; + + delay_t raiseDelay() const { return delay; } + delay_t fallDelay() const { return delay; } + delay_t avgDelay() const { return delay; } + + DelayInfo operator+(const DelayInfo &other) const + { + DelayInfo ret; + ret.delay = this->delay + other.delay; + return ret; + } +}; + +// ----------------------------------------------------------------------- + +enum BelType : int32_t +{ + TYPE_NONE, + TYPE_ICESTORM_LC, + TYPE_ICESTORM_RAM, + TYPE_SB_IO, + TYPE_SB_GB +}; + +IdString belTypeToId(BelType type); +BelType belTypeFromId(IdString id); + +enum PortPin : int32_t +{ + PIN_NONE, +#define X(t) PIN_##t, +#include "portpins.inc" +#undef X + PIN_MAXIDX +}; + +IdString portPinToId(PortPin type); +PortPin portPinFromId(IdString id); + +// ----------------------------------------------------------------------- + +/**** Everything in this section must be kept in sync with chipdb.py ****/ + +template struct RelPtr +{ + int32_t offset; + + // void set(const T *ptr) { + // offset = reinterpret_cast(ptr) - + // reinterpret_cast(this); + // } + + const T *get() const + { + return reinterpret_cast( + reinterpret_cast(this) + offset); + } + + const T &operator[](size_t index) const { return get()[index]; } + + const T &operator*() const { return *(get()); } + + const T *operator->() const { return get(); } +}; + +struct BelWirePOD +{ + int32_t wire_index; + PortPin port; +} __attribute__((packed)); + +struct BelInfoPOD +{ + RelPtr name; + BelType type; + int32_t num_bel_wires; + RelPtr bel_wires; + int8_t x, y, z; + int8_t padding_0; +} __attribute__((packed)); + +struct BelPortPOD +{ + int32_t bel_index; + PortPin port; +} __attribute__((packed)); + +struct PipInfoPOD +{ + int32_t src, dst; + int32_t delay; + int8_t x, y; + int16_t switch_mask; + int32_t switch_index; +} __attribute__((packed)); + +struct WireInfoPOD +{ + RelPtr name; + int32_t num_uphill, num_downhill; + RelPtr pips_uphill, pips_downhill; + + int32_t num_bels_downhill; + BelPortPOD bel_uphill; + RelPtr bels_downhill; + + int16_t x, y; +} __attribute__((packed)); + +struct PackagePinPOD +{ + RelPtr name; + int32_t bel_index; +} __attribute__((packed)); + +struct PackageInfoPOD +{ + RelPtr name; + int32_t num_pins; + RelPtr pins; +} __attribute__((packed)); + +enum TileType : uint32_t +{ + TILE_NONE = 0, + TILE_LOGIC = 1, + TILE_IO = 2, + TILE_RAMB = 3, + TILE_RAMT = 4, +}; + +struct ConfigBitPOD +{ + int8_t row, col; +} __attribute__((packed)); + +struct ConfigEntryPOD +{ + RelPtr name; + int32_t num_bits; + RelPtr bits; +} __attribute__((packed)); + +struct TileInfoPOD +{ + int8_t cols, rows; + int16_t num_config_entries; + RelPtr entries; +} __attribute__((packed)); + +static const int max_switch_bits = 5; + +struct SwitchInfoPOD +{ + int32_t num_bits; + int8_t x, y; + ConfigBitPOD cbits[max_switch_bits]; +} __attribute__((packed)); + +struct IerenInfoPOD +{ + int8_t iox, ioy, ioz; + int8_t ierx, iery, ierz; +} __attribute__((packed)); + +struct BitstreamInfoPOD +{ + int32_t num_switches, num_ierens; + RelPtr tiles_nonrouting; + RelPtr switches; + RelPtr ierens; +} __attribute__((packed)); + +struct ChipInfoPOD +{ + int32_t width, height; + int32_t num_bels, num_wires, num_pips; + int32_t num_switches, num_packages; + RelPtr bel_data; + RelPtr wire_data; + RelPtr pip_data; + RelPtr tile_grid; + RelPtr bits_info; + RelPtr packages_data; +} __attribute__((packed)); + +extern const char chipdb_blob_384[]; +extern const char chipdb_blob_1k[]; +extern const char chipdb_blob_5k[]; +extern const char chipdb_blob_8k[]; + +/************************ End of chipdb section. ************************/ + +// ----------------------------------------------------------------------- + +struct BelId +{ + int32_t index = -1; + + bool operator==(const BelId &other) const { return index == other.index; } + bool operator!=(const BelId &other) const { return index != other.index; } +}; + +struct WireId +{ + int32_t index = -1; + + 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 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; +}; + +NEXTPNR_NAMESPACE_END + +namespace std { +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const + noexcept + { + return bel.index; + } +}; + +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const + noexcept + { + return wire.index; + } +}; + +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &wire) const + noexcept + { + return wire.index; + } +}; +} // namespace std + +NEXTPNR_NAMESPACE_BEGIN + +// ----------------------------------------------------------------------- + +struct BelIterator +{ + int cursor; + + BelIterator operator++() + { + cursor++; + return *this; + } + BelIterator operator++(int) + { + BelIterator prior(*this); + cursor++; + return prior; + } + + bool operator!=(const BelIterator &other) const + { + return cursor != other.cursor; + } + + bool operator==(const BelIterator &other) const + { + return cursor == other.cursor; + } + + BelId operator*() const + { + BelId ret; + ret.index = cursor; + return ret; + } +}; + +struct BelRange +{ + BelIterator b, e; + BelIterator begin() const { return b; } + BelIterator end() const { return e; } +}; + +// ----------------------------------------------------------------------- + +struct BelPinIterator +{ + const BelPortPOD *ptr = nullptr; + + void operator++() { ptr++; } + bool operator!=(const BelPinIterator &other) const + { + return ptr != other.ptr; + } + + BelPin operator*() const + { + BelPin ret; + ret.bel.index = ptr->bel_index; + ret.pin = ptr->port; + return ret; + } +}; + +struct BelPinRange +{ + BelPinIterator b, e; + BelPinIterator begin() const { return b; } + BelPinIterator end() const { return e; } +}; + +// ----------------------------------------------------------------------- + +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 +{ + const 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 ArchArgs +{ + enum + { + NONE, + LP384, + LP1K, + LP8K, + HX1K, + HX8K, + UP5K + } type = NONE; + std::string package; +}; + +struct Arch +{ + const ChipInfoPOD *chip_info; + const PackageInfoPOD *package_info; + + mutable std::unordered_map bel_by_name; + mutable std::unordered_map wire_by_name; + mutable std::unordered_map pip_by_name; + + std::vector bel_to_cell; + std::vector wire_to_net; + std::vector pip_to_net; + std::vector switches_locked; + + ArchArgs args; + Arch(ArchArgs args); + + std::string getChipName(); + + // ------------------------------------------------- + + BelId getBelByName(IdString name) const; + + IdString getBelName(BelId bel) const + { + assert(bel != BelId()); + return chip_info->bel_data[bel.index].name.get(); + } + + void bindBel(BelId bel, IdString cell) + { + assert(bel != BelId()); + assert(bel_to_cell[bel.index] == IdString()); + bel_to_cell[bel.index] = cell; + } + + void unbindBel(BelId bel) + { + assert(bel != BelId()); + assert(bel_to_cell[bel.index] != IdString()); + bel_to_cell[bel.index] = IdString(); + } + + bool checkBelAvail(BelId bel) const + { + assert(bel != BelId()); + return bel_to_cell[bel.index] == IdString(); + } + + IdString getBelCell(BelId bel, bool conflicting = false) const + { + assert(bel != BelId()); + return bel_to_cell[bel.index]; + } + + BelRange getBels() const + { + BelRange range; + range.b.cursor = 0; + range.e.cursor = chip_info->num_bels; + return range; + } + + BelRange getBelsByType(BelType type) const + { + BelRange range; +// FIXME +#if 0 + if (type == "TYPE_A") { + range.b.cursor = bels_type_a_begin; + range.e.cursor = bels_type_a_end; + } + ... +#endif + return range; + } + + BelRange getBelsAtSameTile(BelId bel) const; + + BelType getBelType(BelId bel) const + { + assert(bel != BelId()); + return chip_info->bel_data[bel.index].type; + } + + WireId getWireBelPin(BelId bel, PortPin pin) const; + + BelPin getBelPinUphill(WireId wire) const + { + BelPin ret; + assert(wire != WireId()); + + 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; + } + + BelPinRange getBelPinsDownhill(WireId wire) const + { + BelPinRange range; + assert(wire != WireId()); + range.b.ptr = chip_info->wire_data[wire.index].bels_downhill.get(); + 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 != WireId()); + return chip_info->wire_data[wire.index].name.get(); + } + + void bindWire(WireId wire, IdString net) + { + assert(wire != WireId()); + assert(wire_to_net[wire.index] == IdString()); + wire_to_net[wire.index] = net; + } + + void unbindWire(WireId wire) + { + assert(wire != WireId()); + assert(wire_to_net[wire.index] != IdString()); + wire_to_net[wire.index] = IdString(); + } + + bool checkWireAvail(WireId wire) const + { + assert(wire != WireId()); + return wire_to_net[wire.index] == IdString(); + } + + IdString getWireNet(WireId wire, bool conflicting = false) const + { + assert(wire != WireId()); + return wire_to_net[wire.index]; + } + + 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; + + void bindPip(PipId pip, IdString net) + { + assert(pip != PipId()); + assert(pip_to_net[pip.index] == IdString()); + assert(switches_locked[chip_info->pip_data[pip.index].switch_index] == + IdString()); + pip_to_net[pip.index] = net; + switches_locked[chip_info->pip_data[pip.index].switch_index] = net; + } + + void unbindPip(PipId pip) + { + assert(pip != PipId()); + assert(pip_to_net[pip.index] != IdString()); + assert(switches_locked[chip_info->pip_data[pip.index].switch_index] != + IdString()); + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = + IdString(); + } + + bool checkPipAvail(PipId pip) const + { + assert(pip != PipId()); + if (args.type == ArchArgs::UP5K) { + int x = chip_info->pip_data[pip.index].x; + if (x == 0 || x == (chip_info->width - 1)) + return false; + } + return switches_locked[chip_info->pip_data[pip.index].switch_index] == + IdString(); + } + + IdString getPipNet(PipId pip, bool conflicting = false) const + { + assert(pip != PipId()); + if (conflicting) + return switches_locked[chip_info->pip_data[pip.index].switch_index]; + return pip_to_net[pip.index]; + } + + 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 != PipId()); + wire.index = chip_info->pip_data[pip.index].src; + return wire; + } + + WireId getPipDstWire(PipId pip) const + { + WireId wire; + assert(pip != PipId()); + wire.index = chip_info->pip_data[pip.index].dst; + return wire; + } + + DelayInfo getPipDelay(PipId pip) const + { + DelayInfo delay; + assert(pip != PipId()); + delay.delay = chip_info->pip_data[pip.index].delay; + return delay; + } + + PipRange getPipsDownhill(WireId wire) const + { + PipRange range; + assert(wire != WireId()); + range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get(); + 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 != WireId()); + range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get(); + 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 != WireId()); + range.b.cursor = nullptr; + range.e.cursor = nullptr; + return range; + } + + BelId getPackagePinBel(const std::string &pin) const; + std::string getBelPackagePin(BelId bel) const; + + // ------------------------------------------------- + + bool estimatePosition(BelId bel, int &x, int &y) const; + delay_t estimateDelay(WireId src, WireId dst) const; + + // ------------------------------------------------- + + std::vector getFrameGraphics() const; + std::vector getBelGraphics(BelId bel) const; + std::vector getWireGraphics(WireId wire) const; + std::vector getPipGraphics(PipId pip) const; + + bool allGraphicsReload = false; + bool frameGraphicsReload = false; + std::unordered_set belGraphicsReload; + std::unordered_set wireGraphicsReload; + std::unordered_set pipGraphicsReload; +}; + +NEXTPNR_NAMESPACE_END + +namespace std { +template <> struct hash +{ + std::size_t operator()(NEXTPNR_NAMESPACE_PREFIX BelType bt) const noexcept + { + return std::hash()(int(bt)); + } +}; +} // namespace std + +#endif diff --git a/ice40/chip.cc b/ice40/chip.cc deleted file mode 100644 index b269a3e3..00000000 --- a/ice40/chip.cc +++ /dev/null @@ -1,419 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include -#include -#include "log.h" -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -// ----------------------------------------------------------------------- - -IdString belTypeToId(BelType type) -{ - if (type == TYPE_ICESTORM_LC) - return "ICESTORM_LC"; - if (type == TYPE_ICESTORM_RAM) - return "ICESTORM_RAM"; - if (type == TYPE_SB_IO) - return "SB_IO"; - if (type == TYPE_SB_GB) - return "SB_GB"; - return IdString(); -} - -BelType belTypeFromId(IdString id) -{ - if (id == "ICESTORM_LC") - return TYPE_ICESTORM_LC; - if (id == "ICESTORM_RAM") - return TYPE_ICESTORM_RAM; - if (id == "SB_IO") - return TYPE_SB_IO; - if (id == "SB_GB") - return TYPE_SB_GB; - return TYPE_NONE; -} - -// ----------------------------------------------------------------------- - -void IdString::initialize_chip() -{ -#define X(t) initialize_add(#t, PIN_##t); -#include "portpins.inc" -#undef X -} - -IdString portPinToId(PortPin type) -{ - IdString ret; - if (type > 0 && type < PIN_MAXIDX) - ret.index = type; - return ret; -} - -PortPin portPinFromId(IdString id) -{ - if (id.index > 0 && id.index < PIN_MAXIDX) - return PortPin(id.index); - return PIN_NONE; -} - -// ----------------------------------------------------------------------- - -Arch::Arch(ArchArgs args) : args(args) -{ -#ifdef ICE40_HX1K_ONLY - if (args.type == ArchArgs::HX1K) { - chip_info = - reinterpret_cast *>(chipdb_blob_1k) - ->get(); - } else { - log_error("Unsupported iCE40 chip type.\n"); - } -#else - if (args.type == ArchArgs::LP384) { - chip_info = - reinterpret_cast *>(chipdb_blob_384) - ->get(); - } else if (args.type == ArchArgs::LP1K || args.type == ArchArgs::HX1K) { - chip_info = - reinterpret_cast *>(chipdb_blob_1k) - ->get(); - } else if (args.type == ArchArgs::UP5K) { - chip_info = - reinterpret_cast *>(chipdb_blob_5k) - ->get(); - } else if (args.type == ArchArgs::LP8K || args.type == ArchArgs::HX8K) { - chip_info = - reinterpret_cast *>(chipdb_blob_8k) - ->get(); - } else { - log_error("Unsupported iCE40 chip type.\n"); - } -#endif - - package_info = nullptr; - for (int i = 0; i < chip_info->num_packages; i++) { - if (chip_info->packages_data[i].name.get() == args.package) { - package_info = &(chip_info->packages_data[i]); - break; - } - } - if (package_info == nullptr) - log_error("Unsupported package '%s'.\n", args.package.c_str()); - - bel_to_cell.resize(chip_info->num_bels); - wire_to_net.resize(chip_info->num_wires); - pip_to_net.resize(chip_info->num_pips); - switches_locked.resize(chip_info->num_switches); -} - -// ----------------------------------------------------------------------- - -std::string Arch::getChipName() -{ -#ifdef ICE40_HX1K_ONLY - if (args.type == ArchArgs::HX1K) { - return "Lattice LP1K"; - } else { - log_error("Unsupported iCE40 chip type.\n"); - } -#else - if (args.type == ArchArgs::LP384) { - return "Lattice LP384"; - } else if (args.type == ArchArgs::LP1K) { - return "Lattice LP1K"; - } else if (args.type == ArchArgs::HX1K) { - return "Lattice HX1K"; - } else if (args.type == ArchArgs::UP5K) { - return "Lattice UP5K"; - } else if (args.type == ArchArgs::LP8K) { - return "Lattice LP8K"; - } else if (args.type == ArchArgs::HX8K) { - return "Lattice HX8K"; - } else { - log_error("Unknown chip\n"); - } -#endif -} - -// ----------------------------------------------------------------------- - -BelId Arch::getBelByName(IdString name) const -{ - BelId ret; - - if (bel_by_name.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_name[chip_info->bel_data[i].name.get()] = i; - } - - auto it = bel_by_name.find(name); - if (it != bel_by_name.end()) - ret.index = it->second; - - return ret; -} - -BelRange Arch::getBelsAtSameTile(BelId bel) const -{ - BelRange br; - assert(bel != BelId()); - // This requires Bels at the same tile are consecutive - int x = chip_info->bel_data[bel.index].x; - int y = chip_info->bel_data[bel.index].y; - int start = bel.index, end = bel.index; - while (start >= 0 && chip_info->bel_data[start].x == x && - chip_info->bel_data[start].y == y) - start--; - start++; - br.b.cursor = start; - while (end < chip_info->num_bels && chip_info->bel_data[end].x == x && - chip_info->bel_data[end].y == y) - end++; - br.e.cursor = end; - return br; -} - -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const -{ - WireId ret; - - 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.get(); - - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin) { - ret.index = bel_wires[i].wire_index; - break; - } - - return ret; -} - -// ----------------------------------------------------------------------- - -WireId Arch::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.get()] = i; - } - - auto it = wire_by_name.find(name); - if (it != wire_by_name.end()) - ret.index = it->second; - - return ret; -} - -// ----------------------------------------------------------------------- - -PipId Arch::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; -} - -IdString Arch::getPipName(PipId pip) const -{ - assert(pip != PipId()); - - int x = chip_info->pip_data[pip.index].x; - int y = chip_info->pip_data[pip.index].y; - - std::string src_name = - chip_info->wire_data[chip_info->pip_data[pip.index].src].name.get(); - std::replace(src_name.begin(), src_name.end(), '/', '.'); - - std::string dst_name = - chip_info->wire_data[chip_info->pip_data[pip.index].dst].name.get(); - std::replace(dst_name.begin(), dst_name.end(), '/', '.'); - - return "X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + - ".->." + dst_name; -} - -// ----------------------------------------------------------------------- - -BelId Arch::getPackagePinBel(const std::string &pin) const -{ - for (int i = 0; i < package_info->num_pins; i++) { - if (package_info->pins[i].name.get() == pin) { - BelId id; - id.index = package_info->pins[i].bel_index; - return id; - } - } - return BelId(); -} - -std::string Arch::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.get()); - } - } - return ""; -} -// ----------------------------------------------------------------------- - -bool Arch::estimatePosition(BelId bel, int &x, int &y) const -{ - assert(bel != BelId()); - x = chip_info->bel_data[bel.index].x; - y = chip_info->bel_data[bel.index].y; - - return chip_info->bel_data[bel.index].type != TYPE_SB_GB; -} - -delay_t Arch::estimateDelay(WireId src, WireId dst) const -{ - assert(src != WireId()); - delay_t x1 = chip_info->wire_data[src.index].x; - delay_t y1 = chip_info->wire_data[src.index].y; - - assert(dst != WireId()); - delay_t x2 = chip_info->wire_data[dst.index].x; - delay_t y2 = chip_info->wire_data[dst.index].y; - - return fabsf(x1 - x2) + fabsf(y1 - y2); -} - -// ----------------------------------------------------------------------- - -std::vector Arch::getFrameGraphics() const -{ - std::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; -} - -std::vector Arch::getBelGraphics(BelId bel) const -{ - std::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; -} - -std::vector Arch::getWireGraphics(WireId wire) const -{ - std::vector ret; - // FIXME - return ret; -} - -std::vector Arch::getPipGraphics(PipId pip) const -{ - std::vector ret; - // FIXME - return ret; -} - -NEXTPNR_NAMESPACE_END diff --git a/ice40/chip.h b/ice40/chip.h deleted file mode 100644 index 3b4f19d1..00000000 --- a/ice40/chip.h +++ /dev/null @@ -1,757 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef CHIP_H -#define CHIP_H - -#ifndef NEXTPNR_H -#error Include "chip.h" via "nextpnr.h" only. -#endif - -NEXTPNR_NAMESPACE_BEGIN - -typedef int delay_t; - -struct DelayInfo -{ - delay_t delay = 0; - - delay_t raiseDelay() const { return delay; } - delay_t fallDelay() const { return delay; } - delay_t avgDelay() const { return delay; } - - DelayInfo operator+(const DelayInfo &other) const - { - DelayInfo ret; - ret.delay = this->delay + other.delay; - return ret; - } -}; - -// ----------------------------------------------------------------------- - -enum BelType : int32_t -{ - TYPE_NONE, - TYPE_ICESTORM_LC, - TYPE_ICESTORM_RAM, - TYPE_SB_IO, - TYPE_SB_GB -}; - -IdString belTypeToId(BelType type); -BelType belTypeFromId(IdString id); - -enum PortPin : int32_t -{ - PIN_NONE, -#define X(t) PIN_##t, -#include "portpins.inc" -#undef X - PIN_MAXIDX -}; - -IdString portPinToId(PortPin type); -PortPin portPinFromId(IdString id); - -// ----------------------------------------------------------------------- - -/**** Everything in this section must be kept in sync with chipdb.py ****/ - -template struct RelPtr -{ - int32_t offset; - - // void set(const T *ptr) { - // offset = reinterpret_cast(ptr) - - // reinterpret_cast(this); - // } - - const T *get() const - { - return reinterpret_cast( - reinterpret_cast(this) + offset); - } - - const T &operator[](size_t index) const { return get()[index]; } - - const T &operator*() const { return *(get()); } - - const T *operator->() const { return get(); } -}; - -struct BelWirePOD -{ - int32_t wire_index; - PortPin port; -} __attribute__((packed)); - -struct BelInfoPOD -{ - RelPtr name; - BelType type; - int32_t num_bel_wires; - RelPtr bel_wires; - int8_t x, y, z; - int8_t padding_0; -} __attribute__((packed)); - -struct BelPortPOD -{ - int32_t bel_index; - PortPin port; -} __attribute__((packed)); - -struct PipInfoPOD -{ - int32_t src, dst; - int32_t delay; - int8_t x, y; - int16_t switch_mask; - int32_t switch_index; -} __attribute__((packed)); - -struct WireInfoPOD -{ - RelPtr name; - int32_t num_uphill, num_downhill; - RelPtr pips_uphill, pips_downhill; - - int32_t num_bels_downhill; - BelPortPOD bel_uphill; - RelPtr bels_downhill; - - int16_t x, y; -} __attribute__((packed)); - -struct PackagePinPOD -{ - RelPtr name; - int32_t bel_index; -} __attribute__((packed)); - -struct PackageInfoPOD -{ - RelPtr name; - int32_t num_pins; - RelPtr pins; -} __attribute__((packed)); - -enum TileType : uint32_t -{ - TILE_NONE = 0, - TILE_LOGIC = 1, - TILE_IO = 2, - TILE_RAMB = 3, - TILE_RAMT = 4, -}; - -struct ConfigBitPOD -{ - int8_t row, col; -} __attribute__((packed)); - -struct ConfigEntryPOD -{ - RelPtr name; - int32_t num_bits; - RelPtr bits; -} __attribute__((packed)); - -struct TileInfoPOD -{ - int8_t cols, rows; - int16_t num_config_entries; - RelPtr entries; -} __attribute__((packed)); - -static const int max_switch_bits = 5; - -struct SwitchInfoPOD -{ - int32_t num_bits; - int8_t x, y; - ConfigBitPOD cbits[max_switch_bits]; -} __attribute__((packed)); - -struct IerenInfoPOD -{ - int8_t iox, ioy, ioz; - int8_t ierx, iery, ierz; -} __attribute__((packed)); - -struct BitstreamInfoPOD -{ - int32_t num_switches, num_ierens; - RelPtr tiles_nonrouting; - RelPtr switches; - RelPtr ierens; -} __attribute__((packed)); - -struct ChipInfoPOD -{ - int32_t width, height; - int32_t num_bels, num_wires, num_pips; - int32_t num_switches, num_packages; - RelPtr bel_data; - RelPtr wire_data; - RelPtr pip_data; - RelPtr tile_grid; - RelPtr bits_info; - RelPtr packages_data; -} __attribute__((packed)); - -extern const char chipdb_blob_384[]; -extern const char chipdb_blob_1k[]; -extern const char chipdb_blob_5k[]; -extern const char chipdb_blob_8k[]; - -/************************ End of chipdb section. ************************/ - -// ----------------------------------------------------------------------- - -struct BelId -{ - int32_t index = -1; - - bool operator==(const BelId &other) const { return index == other.index; } - bool operator!=(const BelId &other) const { return index != other.index; } -}; - -struct WireId -{ - int32_t index = -1; - - 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 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; -}; - -NEXTPNR_NAMESPACE_END - -namespace std { -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const - noexcept - { - return bel.index; - } -}; - -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const - noexcept - { - return wire.index; - } -}; - -template <> struct hash -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &wire) const - noexcept - { - return wire.index; - } -}; -} // namespace std - -NEXTPNR_NAMESPACE_BEGIN - -// ----------------------------------------------------------------------- - -struct BelIterator -{ - int cursor; - - BelIterator operator++() - { - cursor++; - return *this; - } - BelIterator operator++(int) - { - BelIterator prior(*this); - cursor++; - return prior; - } - - bool operator!=(const BelIterator &other) const - { - return cursor != other.cursor; - } - - bool operator==(const BelIterator &other) const - { - return cursor == other.cursor; - } - - BelId operator*() const - { - BelId ret; - ret.index = cursor; - return ret; - } -}; - -struct BelRange -{ - BelIterator b, e; - BelIterator begin() const { return b; } - BelIterator end() const { return e; } -}; - -// ----------------------------------------------------------------------- - -struct BelPinIterator -{ - const BelPortPOD *ptr = nullptr; - - void operator++() { ptr++; } - bool operator!=(const BelPinIterator &other) const - { - return ptr != other.ptr; - } - - BelPin operator*() const - { - BelPin ret; - ret.bel.index = ptr->bel_index; - ret.pin = ptr->port; - return ret; - } -}; - -struct BelPinRange -{ - BelPinIterator b, e; - BelPinIterator begin() const { return b; } - BelPinIterator end() const { return e; } -}; - -// ----------------------------------------------------------------------- - -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 -{ - const 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 ArchArgs -{ - enum - { - NONE, - LP384, - LP1K, - LP8K, - HX1K, - HX8K, - UP5K - } type = NONE; - std::string package; -}; - -struct Arch -{ - const ChipInfoPOD *chip_info; - const PackageInfoPOD *package_info; - - mutable std::unordered_map bel_by_name; - mutable std::unordered_map wire_by_name; - mutable std::unordered_map pip_by_name; - - std::vector bel_to_cell; - std::vector wire_to_net; - std::vector pip_to_net; - std::vector switches_locked; - - ArchArgs args; - Arch(ArchArgs args); - - std::string getChipName(); - - // ------------------------------------------------- - - BelId getBelByName(IdString name) const; - - IdString getBelName(BelId bel) const - { - assert(bel != BelId()); - return chip_info->bel_data[bel.index].name.get(); - } - - void bindBel(BelId bel, IdString cell) - { - assert(bel != BelId()); - assert(bel_to_cell[bel.index] == IdString()); - bel_to_cell[bel.index] = cell; - } - - void unbindBel(BelId bel) - { - assert(bel != BelId()); - assert(bel_to_cell[bel.index] != IdString()); - bel_to_cell[bel.index] = IdString(); - } - - bool checkBelAvail(BelId bel) const - { - assert(bel != BelId()); - return bel_to_cell[bel.index] == IdString(); - } - - IdString getBelCell(BelId bel, bool conflicting = false) const - { - assert(bel != BelId()); - return bel_to_cell[bel.index]; - } - - BelRange getBels() const - { - BelRange range; - range.b.cursor = 0; - range.e.cursor = chip_info->num_bels; - return range; - } - - BelRange getBelsByType(BelType type) const - { - BelRange range; -// FIXME -#if 0 - if (type == "TYPE_A") { - range.b.cursor = bels_type_a_begin; - range.e.cursor = bels_type_a_end; - } - ... -#endif - return range; - } - - BelRange getBelsAtSameTile(BelId bel) const; - - BelType getBelType(BelId bel) const - { - assert(bel != BelId()); - return chip_info->bel_data[bel.index].type; - } - - WireId getWireBelPin(BelId bel, PortPin pin) const; - - BelPin getBelPinUphill(WireId wire) const - { - BelPin ret; - assert(wire != WireId()); - - 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; - } - - BelPinRange getBelPinsDownhill(WireId wire) const - { - BelPinRange range; - assert(wire != WireId()); - range.b.ptr = chip_info->wire_data[wire.index].bels_downhill.get(); - 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 != WireId()); - return chip_info->wire_data[wire.index].name.get(); - } - - void bindWire(WireId wire, IdString net) - { - assert(wire != WireId()); - assert(wire_to_net[wire.index] == IdString()); - wire_to_net[wire.index] = net; - } - - void unbindWire(WireId wire) - { - assert(wire != WireId()); - assert(wire_to_net[wire.index] != IdString()); - wire_to_net[wire.index] = IdString(); - } - - bool checkWireAvail(WireId wire) const - { - assert(wire != WireId()); - return wire_to_net[wire.index] == IdString(); - } - - IdString getWireNet(WireId wire, bool conflicting = false) const - { - assert(wire != WireId()); - return wire_to_net[wire.index]; - } - - 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; - - void bindPip(PipId pip, IdString net) - { - assert(pip != PipId()); - assert(pip_to_net[pip.index] == IdString()); - assert(switches_locked[chip_info->pip_data[pip.index].switch_index] == - IdString()); - pip_to_net[pip.index] = net; - switches_locked[chip_info->pip_data[pip.index].switch_index] = net; - } - - void unbindPip(PipId pip) - { - assert(pip != PipId()); - assert(pip_to_net[pip.index] != IdString()); - assert(switches_locked[chip_info->pip_data[pip.index].switch_index] != - IdString()); - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = - IdString(); - } - - bool checkPipAvail(PipId pip) const - { - assert(pip != PipId()); - if (args.type == ArchArgs::UP5K) { - int x = chip_info->pip_data[pip.index].x; - if (x == 0 || x == (chip_info->width - 1)) - return false; - } - return switches_locked[chip_info->pip_data[pip.index].switch_index] == - IdString(); - } - - IdString getPipNet(PipId pip, bool conflicting = false) const - { - assert(pip != PipId()); - if (conflicting) - return switches_locked[chip_info->pip_data[pip.index].switch_index]; - return pip_to_net[pip.index]; - } - - 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 != PipId()); - wire.index = chip_info->pip_data[pip.index].src; - return wire; - } - - WireId getPipDstWire(PipId pip) const - { - WireId wire; - assert(pip != PipId()); - wire.index = chip_info->pip_data[pip.index].dst; - return wire; - } - - DelayInfo getPipDelay(PipId pip) const - { - DelayInfo delay; - assert(pip != PipId()); - delay.delay = chip_info->pip_data[pip.index].delay; - return delay; - } - - PipRange getPipsDownhill(WireId wire) const - { - PipRange range; - assert(wire != WireId()); - range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get(); - 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 != WireId()); - range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get(); - 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 != WireId()); - range.b.cursor = nullptr; - range.e.cursor = nullptr; - return range; - } - - BelId getPackagePinBel(const std::string &pin) const; - std::string getBelPackagePin(BelId bel) const; - - // ------------------------------------------------- - - bool estimatePosition(BelId bel, int &x, int &y) const; - delay_t estimateDelay(WireId src, WireId dst) const; - - // ------------------------------------------------- - - std::vector getFrameGraphics() const; - std::vector getBelGraphics(BelId bel) const; - std::vector getWireGraphics(WireId wire) const; - std::vector getPipGraphics(PipId pip) const; - - bool allGraphicsReload = false; - bool frameGraphicsReload = false; - std::unordered_set belGraphicsReload; - std::unordered_set wireGraphicsReload; - std::unordered_set pipGraphicsReload; -}; - -NEXTPNR_NAMESPACE_END - -namespace std { -template <> struct hash -{ - std::size_t operator()(NEXTPNR_NAMESPACE_PREFIX BelType bt) const noexcept - { - return std::hash()(int(bt)); - } -}; -} // namespace std - -#endif -- cgit v1.2.3