diff options
author | gatecat <gatecat@ds0.me> | 2021-03-22 09:30:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-22 09:30:38 +0000 |
commit | 68ca923bfefde24fa2b7cbc8c6f9817f1d93e1e5 (patch) | |
tree | bad29dce65cf448e36704e6d7b1773d8dfd573a2 /fpga_interchange/arch.h | |
parent | f52b5229642cdb54d61b54f5ab9a7478a119298e (diff) | |
parent | 22c6754bcd08f66b6f8e87a58dc09ed260c72c25 (diff) | |
download | nextpnr-68ca923bfefde24fa2b7cbc8c6f9817f1d93e1e5.tar.gz nextpnr-68ca923bfefde24fa2b7cbc8c6f9817f1d93e1e5.tar.bz2 nextpnr-68ca923bfefde24fa2b7cbc8c6f9817f1d93e1e5.zip |
Merge pull request #635 from litghost/refactor_headers
Refactor header structures in FPGA interchange Arch.
Diffstat (limited to 'fpga_interchange/arch.h')
-rw-r--r-- | fpga_interchange/arch.h | 1036 |
1 files changed, 160 insertions, 876 deletions
diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 05bc1a94..84c0b7c8 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -27,739 +27,19 @@ #include <iostream> #include <regex> +#include "PhysicalNetlist.capnp.h" #include "arch_api.h" #include "constraints.h" #include "nextpnr_types.h" #include "relptr.h" +#include "arch_iterators.h" +#include "chipdb.h" #include "dedicated_interconnect.h" #include "site_router.h" NEXTPNR_NAMESPACE_BEGIN -/**** Everything in this section must be kept in sync with chipdb.py ****/ - -// Flattened site indexing. -// -// To enable flat BelId.z spaces, every tile and sites within that tile are -// flattened. -// -// This has implications on BelId's, WireId's and PipId's. -// The flattened site space works as follows: -// - Objects that belong to the tile are first. BELs are always part of Sites, -// so no BEL objects are in this category. -// - All site alternative modes are exposed as a "full" site. -// - Each site appends it's BEL's, wires (site wires) and PIP's. -// - Sites add two types of pips. Sites will add pip data first for site -// pips, and then for site pin edges. -// 1. The first type is site pips, which connect site wires to other site -// wires. -// 2. The second type is site pin edges, which connect site wires to tile -// wires (or vise-versa). - -NPNR_PACKED_STRUCT(struct BelInfoPOD { - int32_t name; // bel name (in site) constid - int32_t type; // Type name constid - int32_t bel_bucket; // BEL bucket constid. - - int32_t num_bel_wires; - RelPtr<int32_t> ports; // port name constid - RelPtr<int32_t> types; // port type (IN/OUT/BIDIR) - RelPtr<int32_t> wires; // connected wire index in tile, or -1 if NA - - int16_t site; - int16_t site_variant; // some sites have alternative types - int16_t category; - int8_t synthetic; - int8_t lut_element; - - RelPtr<int32_t> pin_map; // Index into CellMapPOD::cell_bel_map -}); - -enum BELCategory -{ - // BEL is a logic element - BEL_CATEGORY_LOGIC = 0, - // BEL is a site routing mux - BEL_CATEGORY_ROUTING = 1, - // BEL is a site port, e.g. boundry between site and routing graph. - BEL_CATEGORY_SITE_PORT = 2 -}; - -NPNR_PACKED_STRUCT(struct BelPortPOD { - int32_t bel_index; - int32_t port; -}); - -NPNR_PACKED_STRUCT(struct TileWireInfoPOD { - int32_t name; // wire name constid - - // Pip index inside tile - RelSlice<int32_t> pips_uphill; - - // Pip index inside tile - RelSlice<int32_t> pips_downhill; - - // Bel index inside tile - RelSlice<BelPortPOD> bel_pins; - - int16_t site; // site index in tile - int16_t site_variant; // site variant index in tile -}); - -NPNR_PACKED_STRUCT(struct PipInfoPOD { - int32_t src_index, dst_index; - int16_t site; // site index in tile - int16_t site_variant; // site variant index in tile - int16_t bel; // BEL this pip belongs to if site pip. - int16_t extra_data; -}); - -NPNR_PACKED_STRUCT(struct ConstraintTagPOD { - int32_t tag_prefix; // constid - int32_t default_state; // constid - RelSlice<int32_t> states; // constid -}); - -NPNR_PACKED_STRUCT(struct LutBelPOD { - uint32_t name; // constid - RelSlice<int32_t> pins; // constid - uint32_t low_bit; - uint32_t high_bit; -}); - -NPNR_PACKED_STRUCT(struct LutElementPOD { - int32_t width; - RelSlice<LutBelPOD> lut_bels; -}); - -NPNR_PACKED_STRUCT(struct TileTypeInfoPOD { - int32_t name; // Tile type constid - - RelSlice<BelInfoPOD> bel_data; - - RelSlice<TileWireInfoPOD> wire_data; - - RelSlice<PipInfoPOD> pip_data; - - RelSlice<ConstraintTagPOD> tags; - - RelSlice<LutElementPOD> lut_elements; - - RelSlice<int32_t> site_types; // constid -}); - -NPNR_PACKED_STRUCT(struct SiteInstInfoPOD { - RelPtr<char> name; - RelPtr<char> site_name; - - // Which site type is this site instance? - // constid - int32_t site_type; -}); - -NPNR_PACKED_STRUCT(struct TileInstInfoPOD { - // Name of this tile. - RelPtr<char> name; - - // Index into root.tile_types. - int32_t type; - - // This array is root.tile_types[type].site_types.size() long. - // Index into root.sites - RelSlice<int32_t> sites; - - // Number of tile wires; excluding any site-internal wires - // which come after general wires and are not stored here - // as they will never be nodal - // -1 if a tile-local wire; node index if nodal wire - RelSlice<int32_t> tile_wire_to_node; -}); - -NPNR_PACKED_STRUCT(struct TileWireRefPOD { - int32_t tile; - int32_t index; -}); - -NPNR_PACKED_STRUCT(struct NodeInfoPOD { RelSlice<TileWireRefPOD> tile_wires; }); - -NPNR_PACKED_STRUCT(struct CellBelPinPOD { - int32_t cell_pin; // constid - int32_t bel_pin; // constid -}); - -NPNR_PACKED_STRUCT(struct ParameterPinsPOD { - int32_t key; // constid - int32_t value; // constid - RelSlice<CellBelPinPOD> pins; -}); - -NPNR_PACKED_STRUCT(struct CellConstraintPOD { - int32_t tag; // Tag index - int32_t constraint_type; // Constraint::ConstraintType - RelSlice<int32_t> states; // State indicies -}); - -NPNR_PACKED_STRUCT(struct CellBelMapPOD { - RelSlice<CellBelPinPOD> common_pins; - RelSlice<ParameterPinsPOD> parameter_pins; - RelSlice<CellConstraintPOD> constraints; -}); - -NPNR_PACKED_STRUCT(struct LutCellPOD { - int32_t cell; // constid - RelSlice<int32_t> input_pins; // constids - int32_t parameter; -}); - -NPNR_PACKED_STRUCT(struct CellMapPOD { - // Cell names supported in this arch. - RelSlice<int32_t> cell_names; // constids - RelSlice<int32_t> cell_bel_buckets; // constids - - RelSlice<CellBelMapPOD> cell_bel_map; - - RelSlice<LutCellPOD> lut_cells; -}); - -NPNR_PACKED_STRUCT(struct PackagePinPOD { - int32_t package_pin; // constid - int32_t site; // constid - int32_t bel; // constid -}); - -NPNR_PACKED_STRUCT(struct PackagePOD { - int32_t package; // constid - RelSlice<PackagePinPOD> pins; -}); - -NPNR_PACKED_STRUCT(struct ConstantsPOD { - // Cell type and port for the GND and VCC global source. - int32_t gnd_cell_name; // constid - int32_t gnd_cell_port; // constid - - int32_t vcc_cell_name; // constid - int32_t vcc_cell_port; // constid - - int32_t gnd_bel_tile; - int32_t gnd_bel_index; - int32_t gnd_bel_pin; // constid - - int32_t vcc_bel_tile; - int32_t vcc_bel_index; - int32_t vcc_bel_pin; // constid - - // Name to use for the global GND constant net - int32_t gnd_net_name; // constid - - // Name to use for the global VCC constant net - int32_t vcc_net_name; // constid -}); - -NPNR_PACKED_STRUCT(struct ChipInfoPOD { - RelPtr<char> name; - RelPtr<char> generator; - - int32_t version; - int32_t width, height; - - RelSlice<TileTypeInfoPOD> tile_types; - RelSlice<SiteInstInfoPOD> sites; - RelSlice<TileInstInfoPOD> tiles; - RelSlice<NodeInfoPOD> nodes; - RelSlice<PackagePOD> packages; - - // BEL bucket constids. - RelSlice<int32_t> bel_buckets; - - RelPtr<CellMapPOD> cell_map; - RelPtr<ConstantsPOD> constants; - - // Constid string data. - RelPtr<RelSlice<RelPtr<char>>> constids; -}); - -/************************ End of chipdb section. ************************/ - -inline const TileTypeInfoPOD &tile_info(const ChipInfoPOD *chip_info, int32_t tile) -{ - return chip_info->tile_types[chip_info->tiles[tile].type]; -} - -template <typename Id> const TileTypeInfoPOD &loc_info(const ChipInfoPOD *chip_info, Id &id) -{ - return chip_info->tile_types[chip_info->tiles[id.tile].type]; -} - -inline const BelInfoPOD &bel_info(const ChipInfoPOD *chip_info, BelId bel) -{ - NPNR_ASSERT(bel != BelId()); - return loc_info(chip_info, bel).bel_data[bel.index]; -} - -inline const PipInfoPOD &pip_info(const ChipInfoPOD *chip_info, PipId pip) -{ - NPNR_ASSERT(pip != PipId()); - return loc_info(chip_info, pip).pip_data[pip.index]; -} - -inline const SiteInstInfoPOD &site_inst_info(const ChipInfoPOD *chip_info, int32_t tile, int32_t site) -{ - return chip_info->sites[chip_info->tiles[tile].sites[site]]; -} - -struct BelIterator -{ - const ChipInfoPOD *chip; - int cursor_index; - int cursor_tile; - - BelIterator operator++() - { - cursor_index++; - while (cursor_tile < chip->tiles.ssize() && cursor_index >= tile_info(chip, cursor_tile).bel_data.ssize()) { - 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.tile = cursor_tile; - ret.index = cursor_index; - return ret; - } -}; - -struct BelRange -{ - BelIterator b, e; - BelIterator begin() const { return b; } - BelIterator end() const { return e; } -}; - -struct FilteredBelIterator -{ - std::function<bool(BelId)> filter; - BelIterator b, e; - - FilteredBelIterator operator++() - { - ++b; - while (b != e) { - if (filter(*b)) { - break; - } - - ++b; - } - return *this; - } - - bool operator!=(const FilteredBelIterator &other) const - { - NPNR_ASSERT(e == other.e); - return b != other.b; - } - - bool operator==(const FilteredBelIterator &other) const - { - NPNR_ASSERT(e == other.e); - return b == other.b; - } - - BelId operator*() const - { - BelId bel = *b; - NPNR_ASSERT(filter(bel)); - return bel; - } -}; - -struct FilteredBelRange -{ - FilteredBelRange(BelIterator bel_b, BelIterator bel_e, std::function<bool(BelId)> filter) - { - b.filter = filter; - b.b = bel_b; - b.e = bel_e; - - if (b.b != b.e && !filter(*b.b)) { - ++b; - } - - e.b = bel_e; - e.e = bel_e; - - if (b != e) { - NPNR_ASSERT(filter(*b.b)); - } - } - - FilteredBelIterator b, e; - FilteredBelIterator begin() const { return b; } - FilteredBelIterator end() const { return e; } -}; - -// ----------------------------------------------------------------------- - -// Iterate over TileWires for a wire (will be more than one if nodal) -struct TileWireIterator -{ - const ChipInfoPOD *chip; - WireId baseWire; - int cursor = -1; - - void operator++() { cursor++; } - - bool operator==(const TileWireIterator &other) const { return cursor == other.cursor; } - bool operator!=(const TileWireIterator &other) const { return cursor != other.cursor; } - - // Returns a *denormalised* identifier always pointing to a tile wire rather than a node - WireId operator*() const - { - if (baseWire.tile == -1) { - WireId tw; - const auto &node_wire = chip->nodes[baseWire.index].tile_wires[cursor]; - tw.tile = node_wire.tile; - tw.index = node_wire.index; - return tw; - } else { - return baseWire; - } - } -}; - -struct TileWireRange -{ - TileWireIterator b, e; - TileWireIterator begin() const { return b; } - TileWireIterator end() const { return e; } -}; - -inline WireId canonical_wire(const ChipInfoPOD *chip_info, int32_t tile, int32_t wire) -{ - WireId id; - - if (wire >= chip_info->tiles[tile].tile_wire_to_node.ssize()) { - // Cannot be a nodal wire - id.tile = tile; - id.index = wire; - } else { - int32_t node = chip_info->tiles[tile].tile_wire_to_node[wire]; - if (node == -1) { - // Not a nodal wire - id.tile = tile; - id.index = wire; - } else { - // Is a nodal wire, set tile to -1 - id.tile = -1; - id.index = node; - } - } - - return id; -} - -// ----------------------------------------------------------------------- - -struct WireIterator -{ - const ChipInfoPOD *chip; - int cursor_index = 0; - int cursor_tile = -1; - - WireIterator operator++() - { - // Iterate over nodes first, then tile wires that aren't nodes - do { - cursor_index++; - if (cursor_tile == -1 && cursor_index >= chip->nodes.ssize()) { - cursor_tile = 0; - cursor_index = 0; - } - while (cursor_tile != -1 && cursor_tile < chip->tiles.ssize() && - cursor_index >= chip->tile_types[chip->tiles[cursor_tile].type].wire_data.ssize()) { - cursor_index = 0; - cursor_tile++; - } - - } while ((cursor_tile != -1 && cursor_tile < chip->tiles.ssize() && - cursor_index < chip->tiles[cursor_tile].tile_wire_to_node.ssize() && - chip->tiles[cursor_tile].tile_wire_to_node[cursor_index] != -1)); - - return *this; - } - WireIterator operator++(int) - { - WireIterator prior(*this); - ++(*this); - return prior; - } - - bool operator!=(const WireIterator &other) const - { - return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile; - } - - bool operator==(const WireIterator &other) const - { - return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile; - } - - WireId operator*() const - { - WireId ret; - ret.tile = cursor_tile; - ret.index = cursor_index; - return ret; - } -}; - -struct WireRange -{ - WireIterator b, e; - WireIterator begin() const { return b; } - WireIterator end() const { return e; } -}; - -// ----------------------------------------------------------------------- -struct AllPipIterator -{ - const ChipInfoPOD *chip; - int cursor_index; - int cursor_tile; - - AllPipIterator operator++() - { - cursor_index++; - while (cursor_tile < chip->tiles.ssize() && - cursor_index >= chip->tile_types[chip->tiles[cursor_tile].type].pip_data.ssize()) { - cursor_index = 0; - cursor_tile++; - } - return *this; - } - AllPipIterator operator++(int) - { - AllPipIterator prior(*this); - ++(*this); - return prior; - } - - bool operator!=(const AllPipIterator &other) const - { - return cursor_index != other.cursor_index || cursor_tile != other.cursor_tile; - } - - bool operator==(const AllPipIterator &other) const - { - return cursor_index == other.cursor_index && cursor_tile == other.cursor_tile; - } - - PipId operator*() const - { - PipId ret; - ret.tile = cursor_tile; - ret.index = cursor_index; - return ret; - } -}; - -struct AllPipRange -{ - AllPipIterator b, e; - AllPipIterator begin() const { return b; } - AllPipIterator end() const { return e; } -}; - -// ----------------------------------------------------------------------- - -struct UphillPipIterator -{ - const ChipInfoPOD *chip; - TileWireIterator twi, twi_end; - int cursor = -1; - - void operator++() - { - cursor++; - while (true) { - if (!(twi != twi_end)) - break; - WireId w = *twi; - auto &tile = chip->tile_types[chip->tiles[w.tile].type]; - if (cursor < tile.wire_data[w.index].pips_uphill.ssize()) - break; - ++twi; - cursor = 0; - } - } - bool operator!=(const UphillPipIterator &other) const { return twi != other.twi || cursor != other.cursor; } - - PipId operator*() const - { - PipId ret; - WireId w = *twi; - ret.tile = w.tile; - ret.index = chip->tile_types[chip->tiles[w.tile].type].wire_data[w.index].pips_uphill[cursor]; - return ret; - } -}; - -struct UphillPipRange -{ - UphillPipIterator b, e; - UphillPipIterator begin() const { return b; } - UphillPipIterator end() const { return e; } -}; - -struct DownhillPipIterator -{ - const ChipInfoPOD *chip; - TileWireIterator twi, twi_end; - int cursor = -1; - - void operator++() - { - cursor++; - while (true) { - if (!(twi != twi_end)) - break; - WireId w = *twi; - auto &tile = chip->tile_types[chip->tiles[w.tile].type]; - if (cursor < tile.wire_data[w.index].pips_downhill.ssize()) - break; - ++twi; - cursor = 0; - } - } - bool operator!=(const DownhillPipIterator &other) const { return twi != other.twi || cursor != other.cursor; } - - PipId operator*() const - { - PipId ret; - WireId w = *twi; - ret.tile = w.tile; - ret.index = chip->tile_types[chip->tiles[w.tile].type].wire_data[w.index].pips_downhill[cursor]; - return ret; - } -}; - -struct DownhillPipRange -{ - DownhillPipIterator b, e; - DownhillPipIterator begin() const { return b; } - DownhillPipIterator end() const { return e; } -}; - -struct BelPinIterator -{ - const ChipInfoPOD *chip; - TileWireIterator twi, twi_end; - int cursor = -1; - - void operator++() - { - cursor++; - - while (twi != twi_end) { - WireId w = *twi; - auto &tile = tile_info(chip, w.tile); - if (cursor < tile.wire_data[w.index].bel_pins.ssize()) - break; - - ++twi; - cursor = 0; - } - } - bool operator!=(const BelPinIterator &other) const { return twi != other.twi || cursor != other.cursor; } - - BelPin operator*() const - { - BelPin ret; - WireId w = *twi; - ret.bel.tile = w.tile; - ret.bel.index = tile_info(chip, w.tile).wire_data[w.index].bel_pins[cursor].bel_index; - ret.pin.index = tile_info(chip, w.tile).wire_data[w.index].bel_pins[cursor].port; - return ret; - } -}; - -struct BelPinRange -{ - BelPinIterator b, e; - BelPinIterator begin() const { return b; } - BelPinIterator end() const { return e; } -}; - -struct IdStringIterator : std::iterator<std::forward_iterator_tag, - /*T=*/IdString, - /*Distance=*/ptrdiff_t, - /*pointer=*/IdString *, - /*reference=*/IdString> -{ - const int32_t *cursor; - - void operator++() { cursor += 1; } - - bool operator!=(const IdStringIterator &other) const { return cursor != other.cursor; } - - bool operator==(const IdStringIterator &other) const { return cursor == other.cursor; } - - IdString operator*() const { return IdString(*cursor); } -}; - -struct IdStringRange -{ - IdStringIterator b, e; - IdStringIterator begin() const { return b; } - IdStringIterator end() const { return e; } -}; - -struct BelBucketIterator -{ - IdStringIterator cursor; - - void operator++() { ++cursor; } - - bool operator!=(const BelBucketIterator &other) const { return cursor != other.cursor; } - - bool operator==(const BelBucketIterator &other) const { return cursor == other.cursor; } - - BelBucketId operator*() const - { - BelBucketId bucket; - bucket.name = IdString(*cursor); - return bucket; - } -}; - -struct BelBucketRange -{ - BelBucketIterator b, e; - BelBucketIterator begin() const { return b; } - BelBucketIterator end() const { return e; } -}; - struct ArchArgs { std::string chipdb; @@ -813,6 +93,9 @@ struct Arch : ArchAPI<ArchRanges> const ChipInfoPOD *chip_info; int32_t package_index; + // Guard initialization of "by_name" maps if accessed from multiple + // threads on a "const Context *". + mutable std::mutex by_name_mutex; mutable std::unordered_map<IdString, int> tile_by_name; mutable std::unordered_map<IdString, std::pair<int, int>> site_by_name; @@ -824,13 +107,14 @@ struct Arch : ArchAPI<ArchRanges> ArchArgs args; Arch(ArchArgs args); + virtual ~Arch(); void init(); - std::string getChipName() const override; + std::string getChipName() const final; - IdString archId() const override { return id(chip_info->name.get()); } - ArchArgs archArgs() const override { return args; } - IdString archArgsToId(ArchArgs args) const override; + IdString archId() const final { return id(chip_info->name.get()); } + ArchArgs archArgs() const final { return args; } + IdString archArgsToId(ArchArgs args) const final; // ------------------------------------------------- @@ -848,17 +132,17 @@ struct Arch : ArchAPI<ArchRanges> get_tile_x_y(tile_index, &loc->x, &loc->y); } - int getGridDimX() const override { return chip_info->width; } - int getGridDimY() const override { return chip_info->height; } - int getTileBelDimZ(int x, int y) const override + int getGridDimX() const final { return chip_info->width; } + int getGridDimY() const final { return chip_info->height; } + int getTileBelDimZ(int x, int y) const final { return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].bel_data.size(); } - int getTilePipDimZ(int x, int y) const override + int getTilePipDimZ(int x, int y) const final { return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].site_types.size(); } - char getNameDelimiter() const override { return '/'; } + char getNameDelimiter() const final { return '/'; } std::string get_part() const; @@ -866,9 +150,9 @@ struct Arch : ArchAPI<ArchRanges> void setup_byname() const; - BelId getBelByName(IdStringList name) const override; + BelId getBelByName(IdStringList name) const final; - IdStringList getBelName(BelId bel) const override + IdStringList getBelName(BelId bel) const final { NPNR_ASSERT(bel != BelId()); const SiteInstInfoPOD &site = get_site_inst(bel); @@ -876,7 +160,7 @@ struct Arch : ArchAPI<ArchRanges> return IdStringList(ids); } - uint32_t getBelChecksum(BelId bel) const override { return bel.index; } + uint32_t getBelChecksum(BelId bel) const final { return bel.index; } void map_cell_pins(CellInfo *cell, int32_t mapping, bool bind_constants); void map_port_pins(BelId bel, CellInfo *cell) const; @@ -926,7 +210,19 @@ struct Arch : ArchAPI<ArchRanges> return bel; } - void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override + PhysicalNetlist::PhysNetlist::NetType get_net_type(NetInfo *net) const + { + NPNR_ASSERT(net->driver.cell != nullptr); + if (net->driver.cell->bel == get_gnd_bel()) { + return PhysicalNetlist::PhysNetlist::NetType::GND; + } else if (net->driver.cell->bel == get_vcc_bel()) { + return PhysicalNetlist::PhysNetlist::NetType::VCC; + } else { + return PhysicalNetlist::PhysNetlist::NetType::SIGNAL; + } + } + + void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) final { NPNR_ASSERT(bel != BelId()); @@ -964,7 +260,7 @@ struct Arch : ArchAPI<ArchRanges> refreshUiBel(bel); } - void unbindBel(BelId bel) override + void unbindBel(BelId bel) final { NPNR_ASSERT(bel != BelId()); @@ -990,14 +286,14 @@ struct Arch : ArchAPI<ArchRanges> refreshUiBel(bel); } - bool checkBelAvail(BelId bel) const override + bool checkBelAvail(BelId bel) const final { // FIXME: This could consult the constraint system to see if this BEL // is blocked (e.g. site type is wrong). return getBoundBelCell(bel) == nullptr; } - CellInfo *getBoundBelCell(BelId bel) const override + CellInfo *getBoundBelCell(BelId bel) const final { NPNR_ASSERT(bel != BelId()); auto iter = tileStatus.find(bel.tile); @@ -1008,7 +304,7 @@ struct Arch : ArchAPI<ArchRanges> } } - CellInfo *getConflictingBelCell(BelId bel) const override + CellInfo *getConflictingBelCell(BelId bel) const final { NPNR_ASSERT(bel != BelId()); // FIXME: This could consult the constraint system to see why this BEL @@ -1016,7 +312,7 @@ struct Arch : ArchAPI<ArchRanges> return getBoundBelCell(bel); } - BelRange getBels() const override + BelRange getBels() const final { BelRange range; range.b.cursor_tile = 0; @@ -1029,7 +325,7 @@ struct Arch : ArchAPI<ArchRanges> return range; } - Loc getBelLocation(BelId bel) const override + Loc getBelLocation(BelId bel) const final { NPNR_ASSERT(bel != BelId()); Loc loc; @@ -1038,24 +334,24 @@ struct Arch : ArchAPI<ArchRanges> return loc; } - BelId getBelByLocation(Loc loc) const override; - BelRange getBelsByTile(int x, int y) const override; + BelId getBelByLocation(Loc loc) const final; + BelRange getBelsByTile(int x, int y) const final; - bool getBelGlobalBuf(BelId bel) const override + bool getBelGlobalBuf(BelId bel) const final { // FIXME: This probably needs to be fixed! return false; } - bool getBelHidden(BelId bel) const override { return bel_info(chip_info, bel).category != BEL_CATEGORY_LOGIC; } + bool getBelHidden(BelId bel) const final { return bel_info(chip_info, bel).category != BEL_CATEGORY_LOGIC; } - IdString getBelType(BelId bel) const override + IdString getBelType(BelId bel) const final { NPNR_ASSERT(bel != BelId()); return IdString(bel_info(chip_info, bel).type); } - std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const override; + std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const final; int get_bel_pin_index(BelId bel, IdString pin) const { @@ -1071,10 +367,10 @@ struct Arch : ArchAPI<ArchRanges> return -1; } - WireId getBelPinWire(BelId bel, IdString pin) const override; - PortType getBelPinType(BelId bel, IdString pin) const override; + WireId getBelPinWire(BelId bel, IdString pin) const final; + PortType getBelPinType(BelId bel, IdString pin) const final; - IdStringRange getBelPins(BelId bel) const override + IdStringRange getBelPins(BelId bel) const final { NPNR_ASSERT(bel != BelId()); @@ -1088,11 +384,11 @@ struct Arch : ArchAPI<ArchRanges> return str_range; } - const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override; + const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const final; // ------------------------------------------------- - WireId getWireByName(IdStringList name) const override; + WireId getWireByName(IdStringList name) const final; const TileWireInfoPOD &wire_info(WireId wire) const { @@ -1104,7 +400,7 @@ struct Arch : ArchAPI<ArchRanges> } } - IdStringList getWireName(WireId wire) const override + IdStringList getWireName(WireId wire) const final { NPNR_ASSERT(wire != WireId()); if (wire.tile != -1) { @@ -1122,64 +418,44 @@ struct Arch : ArchAPI<ArchRanges> return IdStringList(ids); } - IdString getWireType(WireId wire) const override; - std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId wire) const override; + IdString getWireType(WireId wire) const final; + std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId wire) const final; - uint32_t getWireChecksum(WireId wire) const override { return wire.index; } + uint32_t getWireChecksum(WireId wire) const final { return wire.index; } - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) override - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] == nullptr); - wire_to_net[wire] = net; - net->wires[wire].pip = PipId(); - net->wires[wire].strength = strength; - refreshUiWire(wire); - } + void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) final; - void unbindWire(WireId wire) override + void unbindWire(WireId wire) final { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire] != nullptr); - - auto &net_wires = wire_to_net[wire]->wires; - auto it = net_wires.find(wire); - NPNR_ASSERT(it != net_wires.end()); - - auto pip = it->second.pip; - if (pip != PipId()) { - pip_to_net[pip] = nullptr; - } - - net_wires.erase(it); - wire_to_net[wire] = nullptr; + unassign_wire(wire); refreshUiWire(wire); } - bool checkWireAvail(WireId wire) const override + bool checkWireAvail(WireId wire) const final { NPNR_ASSERT(wire != WireId()); auto w2n = wire_to_net.find(wire); return w2n == wire_to_net.end() || w2n->second == nullptr; } - NetInfo *getBoundWireNet(WireId wire) const override + NetInfo *getBoundWireNet(WireId wire) const final { NPNR_ASSERT(wire != WireId()); auto w2n = wire_to_net.find(wire); return w2n == wire_to_net.end() ? nullptr : w2n->second; } - WireId getConflictingWireWire(WireId wire) const override { return wire; } + WireId getConflictingWireWire(WireId wire) const final { return wire; } - NetInfo *getConflictingWireNet(WireId wire) const override + NetInfo *getConflictingWireNet(WireId wire) const final { NPNR_ASSERT(wire != WireId()); auto w2n = wire_to_net.find(wire); return w2n == wire_to_net.end() ? nullptr : w2n->second; } - DelayQuad getWireDelay(WireId wire) const override { return DelayQuad(0); } + DelayQuad getWireDelay(WireId wire) const final { return DelayQuad(0); } TileWireRange get_tile_wire_range(WireId wire) const { @@ -1199,7 +475,7 @@ struct Arch : ArchAPI<ArchRanges> return range; } - BelPinRange getWireBelPins(WireId wire) const override + BelPinRange getWireBelPins(WireId wire) const final { BelPinRange range; NPNR_ASSERT(wire != WireId()); @@ -1218,7 +494,7 @@ struct Arch : ArchAPI<ArchRanges> return range; } - WireRange getWires() const override + WireRange getWires() const final { WireRange range; range.b.chip = chip_info; @@ -1232,65 +508,43 @@ struct Arch : ArchAPI<ArchRanges> // ------------------------------------------------- - PipId getPipByName(IdStringList name) const override; - IdStringList getPipName(PipId pip) const override; - IdString getPipType(PipId pip) const override; - std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const override; - - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] == nullptr); - - WireId dst = getPipDstWire(pip); - NPNR_ASSERT(wire_to_net[dst] == nullptr || wire_to_net[dst] == net); + PipId getPipByName(IdStringList name) const final; + IdStringList getPipName(PipId pip) const final; + IdString getPipType(PipId pip) const final; + std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const final; - pip_to_net[pip] = net; - - wire_to_net[dst] = net; - net->wires[dst].pip = pip; - net->wires[dst].strength = strength; - refreshUiPip(pip); - refreshUiWire(dst); - } + void assign_net_to_wire(WireId wire, NetInfo *net, const char *src, bool require_empty); - void unbindPip(PipId pip) override - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip] != nullptr); + void unassign_wire(WireId wire); - WireId dst = getPipDstWire(pip); - NPNR_ASSERT(wire_to_net[dst] != nullptr); - wire_to_net[dst] = nullptr; - pip_to_net[pip]->wires.erase(dst); + void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) final; - pip_to_net[pip] = nullptr; - refreshUiPip(pip); - refreshUiWire(dst); - } + void unbindPip(PipId pip) final; - bool checkPipAvail(PipId pip) const override - { - NPNR_ASSERT(pip != PipId()); - return pip_to_net.find(pip) == pip_to_net.end() || pip_to_net.at(pip) == nullptr; - } + bool checkPipAvail(PipId pip) const final; + bool check_pip_avail_for_net(PipId pip, NetInfo *) const; - NetInfo *getBoundPipNet(PipId pip) const override + NetInfo *getBoundPipNet(PipId pip) const final { NPNR_ASSERT(pip != PipId()); auto p2n = pip_to_net.find(pip); return p2n == pip_to_net.end() ? nullptr : p2n->second; } - WireId getConflictingPipWire(PipId pip) const override { return getPipDstWire(pip); } + WireId getConflictingPipWire(PipId pip) const final + { + // FIXME: This doesn't account for pseudo pips. + return getPipDstWire(pip); + } - NetInfo *getConflictingPipNet(PipId pip) const override + NetInfo *getConflictingPipNet(PipId pip) const final { + // FIXME: This doesn't account for pseudo pips. auto p2n = pip_to_net.find(pip); return p2n == pip_to_net.end() ? nullptr : p2n->second; } - AllPipRange getPips() const override + AllPipRange getPips() const final { AllPipRange range; range.b.cursor_tile = 0; @@ -1303,7 +557,7 @@ struct Arch : ArchAPI<ArchRanges> return range; } - Loc getPipLocation(PipId pip) const override + Loc getPipLocation(PipId pip) const final { Loc loc; get_tile_loc(pip.tile, &loc); @@ -1311,21 +565,25 @@ struct Arch : ArchAPI<ArchRanges> return loc; } - uint32_t getPipChecksum(PipId pip) const override { return pip.index; } + uint32_t getPipChecksum(PipId pip) const final { return pip.index; } - WireId getPipSrcWire(PipId pip) const override + WireId getPipSrcWire(PipId pip) const final NPNR_ALWAYS_INLINE { return canonical_wire(chip_info, pip.tile, loc_info(chip_info, pip).pip_data[pip.index].src_index); } - WireId getPipDstWire(PipId pip) const override + WireId getPipDstWire(PipId pip) const final NPNR_ALWAYS_INLINE { return canonical_wire(chip_info, pip.tile, loc_info(chip_info, pip).pip_data[pip.index].dst_index); } - DelayQuad getPipDelay(PipId pip) const override { return DelayQuad(0); } + DelayQuad getPipDelay(PipId pip) const final + { + // FIXME: Implement when adding timing-driven place and route. + return DelayQuad(100); + } - DownhillPipRange getPipsDownhill(WireId wire) const override + DownhillPipRange getPipsDownhill(WireId wire) const final { DownhillPipRange range; NPNR_ASSERT(wire != WireId()); @@ -1342,7 +600,7 @@ struct Arch : ArchAPI<ArchRanges> return range; } - UphillPipRange getPipsUphill(WireId wire) const override + UphillPipRange getPipsUphill(WireId wire) const final { UphillPipRange range; NPNR_ASSERT(wire != WireId()); @@ -1362,24 +620,24 @@ struct Arch : ArchAPI<ArchRanges> // ------------------------------------------------- // FIXME: Use groups to get access to sites. - GroupId getGroupByName(IdStringList name) const override { return GroupId(); } - IdStringList getGroupName(GroupId group) const override { return IdStringList(); } - std::vector<GroupId> getGroups() const override { return {}; } - std::vector<BelId> getGroupBels(GroupId group) const override { return {}; } - std::vector<WireId> getGroupWires(GroupId group) const override { return {}; } - std::vector<PipId> getGroupPips(GroupId group) const override { return {}; } - std::vector<GroupId> getGroupGroups(GroupId group) const override { return {}; } + GroupId getGroupByName(IdStringList name) const final { return GroupId(); } + IdStringList getGroupName(GroupId group) const final { return IdStringList(); } + std::vector<GroupId> getGroups() const final { return {}; } + std::vector<BelId> getGroupBels(GroupId group) const final { return {}; } + std::vector<WireId> getGroupWires(GroupId group) const final { return {}; } + std::vector<PipId> getGroupPips(GroupId group) const final { return {}; } + std::vector<GroupId> getGroupGroups(GroupId group) const final { return {}; } // ------------------------------------------------- - delay_t estimateDelay(WireId src, WireId dst) const override; - delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override; - ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override; - delay_t getDelayEpsilon() const override { return 20; } - delay_t getRipupDelayPenalty() const override { return 120; } - float getDelayNS(delay_t v) const override { return v * 0.001; } - delay_t getDelayFromNS(float ns) const override { return delay_t(ns * 1000); } - uint32_t getDelayChecksum(delay_t v) const override { return v; } - bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const override; + delay_t estimateDelay(WireId src, WireId dst) const final; + delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const final; + ArcBounds getRouteBoundingBox(WireId src, WireId dst) const final; + delay_t getDelayEpsilon() const final { return 20; } + delay_t getRipupDelayPenalty() const final { return 120; } + float getDelayNS(delay_t v) const final { return v * 0.001; } + delay_t getDelayFromNS(float ns) const final { return delay_t(ns * 1000); } + uint32_t getDelayChecksum(delay_t v) const final { return v; } + bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const final; // ------------------------------------------------- @@ -1387,31 +645,31 @@ struct Arch : ArchAPI<ArchRanges> std::unordered_set<CellInfo *> *placed_cells); void pack_ports(); void decode_lut_cells(); - bool pack() override; - bool place() override; - bool route() override; + bool pack() final; + bool place() final; + bool route() final; // ------------------------------------------------- - std::vector<GraphicElement> getDecalGraphics(DecalId decal) const override; + std::vector<GraphicElement> getDecalGraphics(DecalId decal) const final; - DecalXY getBelDecal(BelId bel) const override; - DecalXY getWireDecal(WireId wire) const override; - DecalXY getPipDecal(PipId pip) const override; - DecalXY getGroupDecal(GroupId group) const override; + DecalXY getBelDecal(BelId bel) const final; + DecalXY getWireDecal(WireId wire) const final; + DecalXY getPipDecal(PipId pip) const final; + DecalXY getGroupDecal(GroupId group) const final; // ------------------------------------------------- // Get the delay through a cell from one port to another, returning false // if no path exists. This only considers combinational delays, as required by the Arch API - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override; + bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const final; // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port - TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override; + TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const final; // Get the TimingClockingInfo of a port - TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override; + TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const final; // ------------------------------------------------- - const BelBucketRange getBelBuckets() const override + const BelBucketRange getBelBuckets() const final { BelBucketRange bel_bucket_range; bel_bucket_range.b.cursor.cursor = chip_info->bel_buckets.begin(); @@ -1419,14 +677,14 @@ struct Arch : ArchAPI<ArchRanges> return bel_bucket_range; } - BelBucketId getBelBucketForBel(BelId bel) const override + BelBucketId getBelBucketForBel(BelId bel) const final { BelBucketId bel_bucket; bel_bucket.name = IdString(bel_info(chip_info, bel).bel_bucket); return bel_bucket; } - const IdStringRange getCellTypes() const override + const IdStringRange getCellTypes() const final { const CellMapPOD &cell_map = *chip_info->cell_map; @@ -1437,9 +695,9 @@ struct Arch : ArchAPI<ArchRanges> return id_range; } - IdString getBelBucketName(BelBucketId bucket) const override { return bucket.name; } + IdString getBelBucketName(BelBucketId bucket) const final { return bucket.name; } - BelBucketId getBelBucketByName(IdString name) const override + BelBucketId getBelBucketByName(IdString name) const final { for (BelBucketId bel_bucket : getBelBuckets()) { if (bel_bucket.name == name) { @@ -1453,7 +711,7 @@ struct Arch : ArchAPI<ArchRanges> size_t get_cell_type_index(IdString cell_type) const; - BelBucketId getBelBucketForCellType(IdString cell_type) const override + BelBucketId getBelBucketForCellType(IdString cell_type) const final { if (io_port_types.count(cell_type)) { BelBucketId bucket; @@ -1467,7 +725,7 @@ struct Arch : ArchAPI<ArchRanges> return bucket; } - FilteredBelRange getBelsInBucket(BelBucketId bucket) const override + FilteredBelRange getBelsInBucket(BelBucketId bucket) const final { BelRange range = getBels(); FilteredBelRange filtered_range(range.begin(), range.end(), @@ -1476,7 +734,7 @@ struct Arch : ArchAPI<ArchRanges> return filtered_range; } - bool isValidBelForCellType(IdString cell_type, BelId bel) const override + bool isValidBelForCellType(IdString cell_type, BelId bel) const final { if (io_port_types.count(cell_type)) { return pads.count(bel) > 0; @@ -1506,7 +764,7 @@ struct Arch : ArchAPI<ArchRanges> } // Return true whether all Bels at a given location are valid - bool isBelLocationValid(BelId bel) const override + bool isBelLocationValid(BelId bel) const final { auto iter = tileStatus.find(bel.tile); if (iter == tileStatus.end()) { @@ -1541,7 +799,7 @@ struct Arch : ArchAPI<ArchRanges> std::unordered_map<WireId, Loc> sink_locs, source_locs; // ------------------------------------------------- - void assignArchInfo() override {} + void assignArchInfo() final {} // ------------------------------------------------- @@ -1599,21 +857,21 @@ struct Arch : ArchAPI<ArchRanges> const CellConstraintPOD *constraint; Constraint(const CellConstraintPOD *constraint) : constraint(constraint) {} - size_t tag() const override { return constraint->tag; } + size_t tag() const final { return constraint->tag; } - ArchConstraints::ConstraintType constraint_type() const override + ArchConstraints::ConstraintType constraint_type() const final { return Constraints<kMaxState>::ConstraintType(constraint->constraint_type); } - ArchConstraints::ConstraintStateType state() const override + ArchConstraints::ConstraintStateType state() const final { NPNR_ASSERT(constraint_type() == Constraints<kMaxState>::CONSTRAINT_TAG_IMPLIES); NPNR_ASSERT(constraint->states.size() == 1); return constraint->states[0]; } - StateRange states() const override + StateRange states() const final { StateRange range; range.b = constraint->states.get(); @@ -1725,6 +983,32 @@ struct Arch : ArchAPI<ArchRanges> } } + bool is_same_site(WireId wire_a, WireId wire_b) const + { + if (wire_a.tile == -1) { + return false; + } + + if (wire_a.tile != wire_b.tile) { + return false; + } + + auto &wire_a_data = wire_info(wire_a); + auto &wire_b_data = wire_info(wire_b); + + return wire_a_data.site == wire_b_data.site && wire_a_data.site != -1; + } + + bool is_wire_in_site(WireId wire) const + { + if (wire.tile == -1) { + return false; + } + + auto &wire_data = wire_info(wire); + return wire_data.site != -1; + } + void merge_constant_nets(); void report_invalid_bel(BelId bel, CellInfo *cell) const; |