diff options
author | gatecat <gatecat@ds0.me> | 2021-02-25 10:22:45 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-25 10:22:45 +0000 |
commit | ab8dfcfba4544c6733d074b24b0529d431b66d29 (patch) | |
tree | af212992fee7cd0a8fb27d19d0137587402fdc1b /fpga_interchange/arch.h | |
parent | e2cdaa653c805f9bfb6f0ab36295858e5dd3179d (diff) | |
parent | a30043c8da1b1cc46a2dcfb90aa3a06d4f4ed4e9 (diff) | |
download | nextpnr-ab8dfcfba4544c6733d074b24b0529d431b66d29.tar.gz nextpnr-ab8dfcfba4544c6733d074b24b0529d431b66d29.tar.bz2 nextpnr-ab8dfcfba4544c6733d074b24b0529d431b66d29.zip |
Merge pull request #591 from litghost/add_constant_network
Add constant network support to FPGA interchange arch
Diffstat (limited to 'fpga_interchange/arch.h')
-rw-r--r-- | fpga_interchange/arch.h | 150 |
1 files changed, 107 insertions, 43 deletions
diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 1118a96b..13cab02f 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -29,6 +29,8 @@ #include <iostream> #include "constraints.h" +#include "dedicated_interconnect.h" +#include "site_router.h" NEXTPNR_NAMESPACE_BEGIN @@ -67,7 +69,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD { int16_t site; int16_t site_variant; // some sites have alternative types int16_t category; - int16_t padding; + int16_t synthetic; RelPtr<int32_t> pin_map; // Index into CellMapPOD::cell_bel_map }); @@ -120,8 +122,6 @@ NPNR_PACKED_STRUCT(struct ConstraintTagPOD { NPNR_PACKED_STRUCT(struct TileTypeInfoPOD { int32_t name; // Tile type constid - int32_t number_sites; - RelSlice<BelInfoPOD> bel_data; RelSlice<TileWireInfoPOD> wire_data; @@ -129,6 +129,8 @@ NPNR_PACKED_STRUCT(struct TileTypeInfoPOD { RelSlice<PipInfoPOD> pip_data; RelSlice<ConstraintTagPOD> tags; + + RelSlice<int32_t> site_types; // constid }); NPNR_PACKED_STRUCT(struct SiteInstInfoPOD { @@ -147,7 +149,7 @@ NPNR_PACKED_STRUCT(struct TileInstInfoPOD { // Index into root.tile_types. int32_t type; - // This array is root.tile_types[type].number_sites long. + // This array is root.tile_types[type].site_types.size() long. // Index into root.sites RelSlice<int32_t> sites; @@ -207,6 +209,29 @@ NPNR_PACKED_STRUCT(struct PackagePOD { 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; @@ -224,6 +249,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { RelSlice<int32_t> bel_buckets; RelPtr<CellMapPOD> cell_map; + RelPtr<ConstantsPOD> constants; // Constid string data. RelPtr<RelSlice<RelPtr<char>>> constids; @@ -748,6 +774,15 @@ struct ArchRanges using BucketBelRangeT = FilteredBelRange; }; +static constexpr size_t kMaxState = 8; + +struct TileStatus +{ + std::vector<ExclusiveStateGroup<kMaxState>> tags; + std::vector<CellInfo *> boundcells; + std::vector<SiteRouter> sites; +}; + struct Arch : ArchAPI<ArchRanges> { boost::iostreams::mapped_file_source blob_file; @@ -759,38 +794,13 @@ struct Arch : ArchAPI<ArchRanges> std::unordered_map<WireId, NetInfo *> wire_to_net; std::unordered_map<PipId, NetInfo *> pip_to_net; - std::unordered_map<WireId, std::pair<int, int>> driving_pip_loc; - std::unordered_map<WireId, NetInfo *> reserved_wires; - - static constexpr size_t kMaxState = 8; - - struct TileStatus; - struct SiteRouter - { - SiteRouter(int16_t site) : site(site), dirty(false), site_ok(true) {} - - std::unordered_set<CellInfo *> cells_in_site; - const int16_t site; - - mutable bool dirty; - mutable bool site_ok; - - void bindBel(CellInfo *cell); - void unbindBel(CellInfo *cell); - bool checkSiteRouting(const Context *ctx, const TileStatus &tile_status) const; - }; - - struct TileStatus - { - std::vector<ExclusiveStateGroup<kMaxState>> tags; - std::vector<CellInfo *> boundcells; - std::vector<SiteRouter> sites; - }; + DedicatedInterconnect dedicated_interconnect; std::unordered_map<int32_t, TileStatus> tileStatus; ArchArgs args; Arch(ArchArgs args); + void init(); std::string getChipName() const override; @@ -822,7 +832,7 @@ struct Arch : ArchAPI<ArchRanges> } int getTilePipDimZ(int x, int y) const override { - return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].number_sites; + return chip_info->tile_types[chip_info->tiles[get_tile_index(x, y)].type].site_types.size(); } char getNameDelimiter() const override { return '/'; } @@ -844,7 +854,7 @@ struct Arch : ArchAPI<ArchRanges> uint32_t getBelChecksum(BelId bel) const override { return bel.index; } - void map_cell_pins(CellInfo *cell, int32_t mapping) const; + void map_cell_pins(CellInfo *cell, int32_t mapping, bool bind_constants); void map_port_pins(BelId bel, CellInfo *cell) const; TileStatus &get_tile_status(int32_t tile) @@ -855,8 +865,8 @@ struct Arch : ArchAPI<ArchRanges> result.first->second.boundcells.resize(tile_type.bel_data.size()); result.first->second.tags.resize(default_tags.size()); - result.first->second.sites.reserve(tile_type.number_sites); - for (size_t i = 0; i < (size_t)tile_type.number_sites; ++i) { + result.first->second.sites.reserve(tile_type.site_types.size()); + for (size_t i = 0; i < tile_type.site_types.size(); ++i) { result.first->second.sites.push_back(SiteRouter(i)); } } @@ -874,6 +884,24 @@ struct Arch : ArchAPI<ArchRanges> return tile_status.sites.at(bel_data.site); } + BelId get_vcc_bel() const + { + auto &constants = *chip_info->constants; + BelId bel; + bel.tile = constants.vcc_bel_tile; + bel.index = constants.vcc_bel_index; + return bel; + } + + BelId get_gnd_bel() const + { + auto &constants = *chip_info->constants; + BelId bel; + bel.tile = constants.gnd_bel_tile; + bel.index = constants.gnd_bel_index; + return bel; + } + void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) override { NPNR_ASSERT(bel != BelId()); @@ -886,10 +914,13 @@ struct Arch : ArchAPI<ArchRanges> if (io_port_types.count(cell->type) == 0) { int32_t mapping = bel_info(chip_info, bel).pin_map[get_cell_type_index(cell->type)]; + if (mapping < 0) { + report_invalid_bel(bel, cell); + } NPNR_ASSERT(mapping >= 0); if (cell->cell_mapping != mapping) { - map_cell_pins(cell, mapping); + map_cell_pins(cell, mapping, /*bind_constants=*/false); } constraints.bindBel(tile_status.tags.data(), get_cell_constraints(bel, cell->type)); } else { @@ -1033,10 +1064,7 @@ struct Arch : ArchAPI<ArchRanges> return str_range; } - const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override - { - return cell_info->cell_bel_pins.at(pin); - } + const std::vector<IdString> &getBelPinsForCellPin(const CellInfo *cell_info, IdString pin) const override; // ------------------------------------------------- @@ -1194,9 +1222,6 @@ struct Arch : ArchAPI<ArchRanges> NPNR_ASSERT(wire_to_net[dst] == nullptr || wire_to_net[dst] == net); pip_to_net[pip] = net; - std::pair<int, int> loc; - get_tile_x_y(pip.tile, &loc.first, &loc.second); - driving_pip_loc[dst] = loc; wire_to_net[dst] = net; net->wires[dst].pip = pip; @@ -1467,6 +1492,10 @@ struct Arch : ArchAPI<ArchRanges> if (cell == nullptr) { return true; } else { + if (!dedicated_interconnect.isBelLocationValid(bel, cell)) { + return false; + } + if (io_port_types.count(cell->type)) { // FIXME: Probably need to actually constraint io port cell/bel, // but the current BBA emission doesn't support that. This only @@ -1642,6 +1671,41 @@ struct Arch : ArchAPI<ArchRanges> auto &pip_data = pip_info(chip_info, pip); return site_inst_info(chip_info, pip.tile, pip_data.site); } + + // Is this bel synthetic (e.g. added during import process)? + // + // This is generally used for constant networks, but can also be used for + // static partitions. + bool is_bel_synthetic(BelId bel) const + { + const BelInfoPOD &bel_data = bel_info(chip_info, bel); + + return bel_data.synthetic != 0; + } + + // Is this pip synthetic (e.g. added during import process)? + // + // This is generally used for constant networks, but can also be used for + // static partitions. + bool is_pip_synthetic(PipId pip) const + { + auto &pip_data = pip_info(chip_info, pip); + if (pip_data.site == -1) { + return pip_data.extra_data == -1; + } else { + BelId bel; + bel.tile = pip.tile; + bel.index = pip_data.bel; + return is_bel_synthetic(bel); + } + } + + void merge_constant_nets(); + void report_invalid_bel(BelId bel, CellInfo *cell) const; + + std::vector<IdString> no_pins; + IdString gnd_cell_pin; + IdString vcc_cell_pin; }; NEXTPNR_NAMESPACE_END |