From dc07054ee8c28b9c553be4a61562c5b294de0c06 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 5 Dec 2020 22:01:28 -0500 Subject: [PATCH] machxo2: Implement functions to get device utilization (throws std::out_of_range during place phase). --- machxo2/arch.cc | 6 +--- machxo2/arch.h | 85 ++++++++++++++++++++++++++++++++++++++++++++-- machxo2/archdefs.h | 52 +++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 9 deletions(-) diff --git a/machxo2/arch.cc b/machxo2/arch.cc index 0a3f345f..431fcc88 100644 --- a/machxo2/arch.cc +++ b/machxo2/arch.cc @@ -116,7 +116,7 @@ BelId Arch::getBelByName(IdString name) const return BelId(); } -IdString Arch::getBelName(BelId bel) const { return bel; } +IdString Arch::getBelName(BelId bel) const { return IdString(); } Loc Arch::getBelLocation(BelId bel) const { @@ -154,10 +154,6 @@ CellInfo *Arch::getBoundBelCell(BelId bel) const { return nullptr; } CellInfo *Arch::getConflictingBelCell(BelId bel) const { return nullptr; } -const std::vector &Arch::getBels() const { return bel_id_dummy; } - -IdString Arch::getBelType(BelId bel) const { return IdString(); } - const std::map &Arch::getBelAttrs(BelId bel) const { return attrs_dummy; } WireId Arch::getBelPinWire(BelId bel, IdString pin) const diff --git a/machxo2/arch.h b/machxo2/arch.h index 762412e2..1d62a84e 100644 --- a/machxo2/arch.h +++ b/machxo2/arch.h @@ -139,7 +139,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { int32_t num_tiles; int32_t num_packages, num_pios; int32_t const_id_count; - RelPtr locations; + RelPtr tiles; RelPtr> tiletype_names; RelPtr package_info; RelPtr pio_info; @@ -148,6 +148,59 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { /************************ End of chipdb section. ************************/ +// Iterators +struct BelIterator +{ + const ChipInfoPOD *chip; + int cursor_index; + int cursor_tile; + + BelIterator operator++() + { + cursor_index++; + while (cursor_tile < chip->num_tiles && + cursor_index >= chip->tiles[cursor_tile].num_bels) { + cursor_index = 0; + cursor_tile++; + } + return *this; + } + BelIterator operator++(int) + { + BelIterator prior(*this); + ++(*this); + return prior; + } + + bool operator!=(const BelIterator &other) const + { + return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile; + } + + bool operator==(const BelIterator &other) const + { + return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile; + } + + BelId operator*() const + { + BelId ret; + ret.location.x = cursor_tile % chip->width; + ret.location.y = cursor_tile / chip->width; + ret.index = cursor_index; + return ret; + } +}; + +struct BelRange +{ + BelIterator b, e; + BelIterator begin() const { return b; } + BelIterator end() const { return e; } +}; + +// ----------------------------------------------------------------------- + struct ArchArgs { enum ArchArgsTypes @@ -268,6 +321,12 @@ struct Arch : BaseCtx std::vector graphic_element_dummy; std::map attrs_dummy; + // Helpers + template const TileTypePOD *tileInfo(Id &id) const + { + return &(chip_info->tiles[id.location.y * chip_info->width + id.location.x]); + } + // --------------------------------------------------------------- // Common Arch API. Every arch must provide the following methods. @@ -299,8 +358,28 @@ struct Arch : BaseCtx bool checkBelAvail(BelId bel) const; CellInfo *getBoundBelCell(BelId bel) const; CellInfo *getConflictingBelCell(BelId bel) const; - const std::vector &getBels() const; - IdString getBelType(BelId bel) const; + + BelRange getBels() const + { + BelRange range; + range.b.cursor_tile = 0; + range.b.cursor_index = -1; + range.b.chip = chip_info; + ++range.b; //-1 and then ++ deals with the case of no Bels in the first tile + range.e.cursor_tile = chip_info->width * chip_info->height; + range.e.cursor_index = 0; + range.e.chip = chip_info; + return range; + } + + IdString getBelType(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); + IdString id; + id.index = tileInfo(bel)->bel_data[bel.index].type; + return id; + } + const std::map &getBelAttrs(BelId bel) const; WireId getBelPinWire(BelId bel, IdString pin) const; PortType getBelPinType(BelId bel, IdString pin) const; diff --git a/machxo2/archdefs.h b/machxo2/archdefs.h index 56b546da..d33a3a3d 100644 --- a/machxo2/archdefs.h +++ b/machxo2/archdefs.h @@ -62,7 +62,34 @@ enum ConstIds NPNR_PACKED_STRUCT(struct LocationPOD { int16_t x, y; }); -typedef IdString BelId; +struct Location +{ + int16_t x = -1, y = -1; + Location() : x(-1), y(-1){}; + Location(int16_t x, int16_t y) : x(x), y(y){}; + Location(const LocationPOD &pod) : x(pod.x), y(pod.y){}; + Location(const Location &loc) : x(loc.x), y(loc.y){}; + + bool operator==(const Location &other) const { return x == other.x && y == other.y; } + bool operator!=(const Location &other) const { return x != other.x || y != other.y; } + bool operator<(const Location &other) const { return y == other.y ? x < other.x : y < other.y; } +}; + +inline Location operator+(const Location &a, const Location &b) { return Location(a.x + b.x, a.y + b.y); } + +struct BelId +{ + Location location; + int32_t index = -1; + + bool operator==(const BelId &other) const { return index == other.index && location == other.location; } + bool operator!=(const BelId &other) const { return index != other.index || location != other.location; } + bool operator<(const BelId &other) const + { + return location == other.location ? index < other.index : location < other.location; + } +}; + typedef IdString WireId; typedef IdString PipId; typedef IdString GroupId; @@ -86,3 +113,26 @@ struct ArchCellInfo }; NEXTPNR_NAMESPACE_END + +namespace std { +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Location &loc) const noexcept + { + std::size_t seed = std::hash()(loc.x); + seed ^= std::hash()(loc.y) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const noexcept + { + std::size_t seed = std::hash()(bel.location); + seed ^= std::hash()(bel.index) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +}