diff options
author | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-03 13:37:58 -0800 |
---|---|---|
committer | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-04 16:38:33 -0800 |
commit | 78737ab01dd2723caed87481147a721650a0dd25 (patch) | |
tree | 4cac0768621756cd587b0dfd3f87066622a85e43 /fpga_interchange | |
parent | 083f6afb1cc37c8319eec2758df187f58e286250 (diff) | |
download | nextpnr-78737ab01dd2723caed87481147a721650a0dd25.tar.gz nextpnr-78737ab01dd2723caed87481147a721650a0dd25.tar.bz2 nextpnr-78737ab01dd2723caed87481147a721650a0dd25.zip |
Update FPGA interchange to use IdStringList.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'fpga_interchange')
-rw-r--r-- | fpga_interchange/arch.cc | 212 | ||||
-rw-r--r-- | fpga_interchange/arch.h | 57 |
2 files changed, 137 insertions, 132 deletions
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index 3c238220..2d1195b5 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -35,13 +35,6 @@ NEXTPNR_NAMESPACE_BEGIN -static std::pair<std::string, std::string> split_identifier_name(const std::string &name) -{ - size_t first_slash = name.find('/'); - NPNR_ASSERT(first_slash != std::string::npos); - return std::make_pair(name.substr(0, first_slash), name.substr(first_slash + 1)); -}; - static std::pair<std::string, std::string> split_identifier_name_dot(const std::string &name) { size_t first_dot = name.find('.'); @@ -103,7 +96,7 @@ void Arch::setup_byname() const { if (tile_by_name.empty()) { for (int i = 0; i < chip_info->num_tiles; i++) { - tile_by_name[chip_info->tiles[i].name.get()] = i; + tile_by_name[id(chip_info->tiles[i].name.get())] = i; } } @@ -113,24 +106,25 @@ void Arch::setup_byname() const auto &tile_type = chip_info->tile_types[tile.type]; for (int j = 0; j < tile_type.number_sites; j++) { auto &site = chip_info->sites[tile.sites[j]]; - site_by_name[site.name.get()] = std::make_pair(i, j); + site_by_name[id(site.name.get())] = std::make_pair(i, j); } } } } -BelId Arch::getBelByName(IdString name) const +BelId Arch::getBelByName(IdStringList name) const { BelId ret; + if(name.ids.size() != 2) { + return BelId(); + } setup_byname(); - auto split = split_identifier_name(name.str(this)); - int tile, site; - std::tie(tile, site) = site_by_name.at(split.first); + std::tie(tile, site) = site_by_name.at(name.ids[0]); auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - IdString belname = id(split.second); + IdString belname = name.ids[1]; for (int i = 0; i < tile_info.num_bels; i++) { if (tile_info.bel_data[i].site == site && tile_info.bel_data[i].name == belname.index) { ret.tile = tile; @@ -191,23 +185,22 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const // ----------------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const +WireId Arch::getWireByName(IdStringList name) const { - if (wire_by_name_cache.count(name)) - return wire_by_name_cache.at(name); - WireId ret; + if(name.ids.size() != 2) { + return WireId(); + } + setup_byname(); - const std::string &s = name.str(this); - auto sp = split_identifier_name(s); - auto iter = site_by_name.find(sp.first); + auto iter = site_by_name.find(name.ids[0]); if (iter != site_by_name.end()) { int tile; int site; std::tie(tile, site) = iter->second; auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - IdString wirename = id(sp.second); + IdString wirename = name.ids[1]; for (int i = 0; i < tile_info.num_wires; i++) { if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == wirename.index) { ret.tile = tile; @@ -216,9 +209,9 @@ WireId Arch::getWireByName(IdString name) const } } } else { - int tile = tile_by_name.at(sp.first); + int tile = tile_by_name.at(name.ids[0]); auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - IdString wirename = id(sp.second); + IdString wirename = name.ids[1]; for (int i = 0; i < tile_info.num_wires; i++) { if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == wirename.index) { int32_t node = chip_info->tiles[tile].tile_wire_to_node[i]; @@ -236,8 +229,6 @@ WireId Arch::getWireByName(IdString name) const } } - wire_by_name_cache[name] = ret; - return ret; } @@ -249,51 +240,58 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co // ----------------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const +PipId Arch::getPipByName(IdStringList name) const { // PIP name structure: // Tile PIP: <tile name>/<source wire name>.<destination wire name> // Site PIP: <site name>/<bel name>/<input bel pin name> // Site pin: <site name>/<bel name> + // Psuedo site PIP: <site name>/<source wire name>.<destination wire name> - PipId ret; setup_byname(); - const std::string &s = name.str(this); - auto sp = split_identifier_name(s); - auto iter = site_by_name.find(sp.first); - if (iter != site_by_name.end()) { - // This is either a site pip or site pin. + if(name.ids.size() == 3) { + // This is a Site PIP. + IdString site_name = name.ids[0]; + IdString belname = name.ids[1]; + IdString pinname = name.ids[2]; + int tile; int site; - std::tie(tile, site) = iter->second; + std::tie(tile, site) = site_by_name.at(site_name); auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - // psuedo site pips are <site>/<src site wire>.<dst site wire> - // site pips are <site>/<bel>/<pin> - // site pins are <site>/<bel> - auto split = sp.second.find('/'); - if(split != std::string::npos) { - // This is a site pip! - IdString belname = id(sp.second.substr(0, split)); - IdString pinname = id(sp.second.substr(split+1)); - BelId bel = getBelByName(id(sp.first + '/' + belname.str(this))); - NPNR_ASSERT(bel != BelId()); + std::array<IdString, 2> ids{name.ids[0], belname}; + BelId bel = getBelByName(IdStringList(ids)); + NPNR_ASSERT(bel != BelId()); - int pin_index = getBelPinIndex(bel, pinname); - NPNR_ASSERT(pin_index >= 0); + int pin_index = getBelPinIndex(bel, pinname); + NPNR_ASSERT(pin_index >= 0); - for (int i = 0; i < tile_info.num_pips; i++) { - if (tile_info.pip_data[i].site == site && - tile_info.pip_data[i].bel == bel.index && - tile_info.pip_data[i].extra_data == pin_index) { - ret.tile = tile; - ret.index = i; - break; - } + for (int i = 0; i < tile_info.num_pips; i++) { + if (tile_info.pip_data[i].site == site && + tile_info.pip_data[i].bel == bel.index && + tile_info.pip_data[i].extra_data == pin_index) { + + PipId ret; + ret.tile = tile; + ret.index = i; + return ret; } - } else { - auto split = sp.second.find('.'); + } + } else { + auto iter = site_by_name.find(name.ids[0]); + if (iter != site_by_name.end()) { + // This is either a site pin or a psuedo site pip. + // psuedo site pips are <site>/<src site wire>.<dst site wire> + // site pins are <site>/<bel> + int tile; + int site; + std::tie(tile, site) = iter->second; + auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; + + std::string pip_second = name.ids[1].str(this); + auto split = pip_second.find('.'); if(split == std::string::npos) { // This is a site pin! BelId bel = getBelByName(name); @@ -302,17 +300,20 @@ PipId Arch::getPipByName(IdString name) const for (int i = 0; i < tile_info.num_pips; i++) { if (tile_info.pip_data[i].site == site && tile_info.pip_data[i].bel == bel.index) { + + PipId ret; ret.tile = tile; ret.index = i; - break; + return ret; } } } else { // This is a psuedo site pip! - IdString src_site_wire = id(sp.second.substr(0, split)); - IdString dst_site_wire = id(sp.second.substr(split+1)); + IdString src_site_wire = id(pip_second.substr(0, split)); + IdString dst_site_wire = id(pip_second.substr(split+1)); int32_t src_index = -1; int32_t dst_index = -1; + for (int i = 0; i < tile_info.num_wires; i++) { if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == src_site_wire.index) { src_index = i; @@ -335,55 +336,60 @@ PipId Arch::getPipByName(IdString name) const if (tile_info.pip_data[i].site == site && tile_info.pip_data[i].src_index == src_index && tile_info.pip_data[i].dst_index == dst_index) { + + PipId ret; ret.tile = tile; ret.index = i; - break; + return ret; } } } - } - } else { - int tile = tile_by_name.at(sp.first); - auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - - auto spn = split_identifier_name_dot(sp.second); - auto src_wire_name = id(spn.first); - auto dst_wire_name = id(spn.second); - - int32_t src_index = -1; - int32_t dst_index = -1; - for (int i = 0; i < tile_info.num_wires; i++) { - if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == src_wire_name.index) { - src_index = i; - if(dst_index != -1) { - break; + } else { + int tile = tile_by_name.at(name.ids[0]); + auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; + + std::string pip_second = name.ids[1].str(this); + auto spn = split_identifier_name_dot(pip_second); + auto src_wire_name = id(spn.first); + auto dst_wire_name = id(spn.second); + + int32_t src_index = -1; + int32_t dst_index = -1; + for (int i = 0; i < tile_info.num_wires; i++) { + if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == src_wire_name.index) { + src_index = i; + if(dst_index != -1) { + break; + } } - } - if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == dst_wire_name.index) { - dst_index = i; - if(src_index != -1) { - break; + if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == dst_wire_name.index) { + dst_index = i; + if(src_index != -1) { + break; + } } } - } - NPNR_ASSERT(src_index != -1); - NPNR_ASSERT(dst_index != -1); + NPNR_ASSERT(src_index != -1); + NPNR_ASSERT(dst_index != -1); - for (int i = 0; i < tile_info.num_pips; i++) { - if (tile_info.pip_data[i].src_index == src_index && - tile_info.pip_data[i].dst_index == dst_index) { - ret.tile = tile; - ret.index = i; - break; + for (int i = 0; i < tile_info.num_pips; i++) { + if (tile_info.pip_data[i].src_index == src_index && + tile_info.pip_data[i].dst_index == dst_index) { + + PipId ret; + ret.tile = tile; + ret.index = i; + return ret; + } } } } - return ret; + return PipId(); } -IdString Arch::getPipName(PipId pip) const +IdStringList Arch::getPipName(PipId pip) const { // PIP name structure: // Tile PIP: <tile name>/<source wire name>.<destination wire name> @@ -401,24 +407,30 @@ IdString Arch::getPipName(PipId pip) const IdString bel_name(bel.name); if(bel.category == BEL_CATEGORY_LOGIC) { // This is a psuedo pip - IdString src_wire_name = IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].src_index].name); - IdString dst_wire_name = IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].dst_index].name); - return id(site.name.get() + std::string("/") + src_wire_name.str(this) + "." + dst_wire_name.str(this)); + IdString src_wire_name = IdString(tile_type.wire_data[pip_info.src_index].name); + IdString dst_wire_name = IdString(tile_type.wire_data[pip_info.dst_index].name); + IdString pip = id(src_wire_name.str(this) + "." + dst_wire_name.str(this)); + std::array<IdString, 2> ids{id(site.name.get()), pip}; + return IdStringList(ids); } else if(bel.category == BEL_CATEGORY_ROUTING) { // This is a site pip. IdString pin_name(bel.ports[pip_info.extra_data]); - return id(site.name.get() + std::string("/") + bel_name.str(this) + "/" + pin_name.str(this)); + std::array<IdString, 3> ids{id(site.name.get()), bel_name, pin_name}; + return IdStringList(ids); } else { NPNR_ASSERT(bel.category == BEL_CATEGORY_SITE_PORT); // This is a site pin, just the name of the BEL is a unique identifier. - return id(site.name.get() + std::string("/") + bel_name.str(this)); + std::array<IdString, 2> ids{id(site.name.get()), bel_name}; + return IdStringList(ids); } } else { // This is a tile pip. - return id(std::string(tile.name.get()) + "/" + - IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].src_index].name).str(this) + "." + - IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].dst_index].name).str(this)); + IdString src_wire_name = IdString(tile_type.wire_data[pip_info.src_index].name); + IdString dst_wire_name = IdString(tile_type.wire_data[pip_info.dst_index].name); + IdString pip = id(src_wire_name.str(this) + "." + dst_wire_name.str(this)); + std::array<IdString, 2> ids{id(std::string(tile.name.get())), pip}; + return IdStringList(ids); } } diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 666e1369..2f2cddfa 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -29,8 +29,6 @@ NEXTPNR_NAMESPACE_BEGIN -#include "fpga_interchange_generated_defs.h" - /**** Everything in this section must be kept in sync with chipdb.py ****/ template <typename T> struct RelPtr @@ -705,8 +703,8 @@ struct Arch : BaseCtx boost::iostreams::mapped_file_source blob_file; const ChipInfoPOD *chip_info; - mutable std::unordered_map<std::string, int> tile_by_name; - mutable std::unordered_map<std::string, std::pair<int, int>> site_by_name; + mutable std::unordered_map<IdString, int> tile_by_name; + mutable std::unordered_map<IdString, std::pair<int, int>> site_by_name; std::unordered_map<WireId, NetInfo *> wire_to_net; std::unordered_map<PipId, NetInfo *> pip_to_net; @@ -715,11 +713,10 @@ struct Arch : BaseCtx struct TileStatus { - std::bitset<kMaxNumberOfCells> bel_available; std::vector<CellInfo *> boundcells; }; - std::unordered_map<TileStatus> tileStatus; + std::vector<TileStatus> tileStatus; ArchArgs args; Arch(ArchArgs args); @@ -755,21 +752,22 @@ struct Arch : BaseCtx int getTilePipDimZ(int x, int y) const { return chip_info->tile_types[chip_info->tiles[getTileIndex(x, y)].type].number_sites; } + char getNameDelimiter() const { return '/'; } // ------------------------------------------------- void setup_byname() const; - BelId getBelByName(IdString name) const; + BelId getBelByName(IdStringList name) const; - IdString getBelName(BelId bel) const + IdStringList getBelName(BelId bel) const { NPNR_ASSERT(bel != BelId()); int site_index = locInfo(bel).bel_data[bel.index].site; NPNR_ASSERT(site_index >= 0); const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[bel.tile].sites[site_index]]; - return id(std::string(site.name.get()) + - "/" + IdString(locInfo(bel).bel_data[bel.index].name).str(this)); + std::array<IdString, 2> ids{id(site.name.get()), IdString(locInfo(bel).bel_data[bel.index].name)}; + return IdStringList(ids); } uint32_t getBelChecksum(BelId bel) const { return bel.index; } @@ -880,7 +878,7 @@ struct Arch : BaseCtx IdStringRange str_range; str_range.b.cursor = &ports[0]; - str_range.b.cursor = &ports[num_bel_wires-1]; + str_range.e.cursor = &ports[num_bel_wires-1]; return str_range; } @@ -889,9 +887,7 @@ struct Arch : BaseCtx // ------------------------------------------------- - mutable std::unordered_map<IdString, WireId> wire_by_name_cache; - - WireId getWireByName(IdString name) const; + WireId getWireByName(IdStringList name) const; const TileWireInfoPOD &wireInfo(WireId wire) const { @@ -903,20 +899,21 @@ struct Arch : BaseCtx } } - IdString getWireName(WireId wire) const + IdStringList getWireName(WireId wire) const { NPNR_ASSERT(wire != WireId()); if (wire.tile != -1 && locInfo(wire).wire_data[wire.index].site != -1) { int site_index = locInfo(wire).wire_data[wire.index].site; const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[wire.tile].sites[site_index]]; - return id(site.name.get() + - std::string("/") + IdString(locInfo(wire).wire_data[wire.index].name).str(this)); + + std::array<IdString, 2> ids{id(site.name.get()), IdString(locInfo(wire).wire_data[wire.index].name)}; + return IdStringList(ids); } else { - return id(std::string(chip_info - ->tiles[wire.tile == -1 ? chip_info->nodes[wire.index].tile_wires[0].tile - : wire.tile] - .name.get()) + - "/" + IdString(wireInfo(wire).name).c_str(this)); + int32_t tile = wire.tile == -1 ? chip_info->nodes[wire.index].tile_wires[0].tile + : wire.tile; + IdString tile_name = id(chip_info->tiles[tile].name.get()); + std::array<IdString, 2> ids{tile_name, IdString(wireInfo(wire).name)}; + return IdStringList(ids); } } @@ -1042,9 +1039,10 @@ struct Arch : BaseCtx // ------------------------------------------------- - mutable std::unordered_map<IdString, PipId> pip_by_name_cache; - - PipId getPipByName(IdString name) const; + PipId getPipByName(IdStringList name) const; + IdStringList getPipName(PipId pip) const; + IdString getPipType(PipId pip) const; + std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const; void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) { @@ -1126,11 +1124,6 @@ struct Arch : BaseCtx return loc; } - IdString getPipName(PipId pip) const; - - IdString getPipType(PipId pip) const; - std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const; - uint32_t getPipChecksum(PipId pip) const { return pip.index; } WireId getPipSrcWire(PipId pip) const @@ -1185,8 +1178,8 @@ struct Arch : BaseCtx // ------------------------------------------------- // FIXME: Use groups to get access to sites. - GroupId getGroupByName(IdString name) const { return GroupId(); } - IdString getGroupName(GroupId group) const { return IdString(); } + GroupId getGroupByName(IdStringList name) const { return GroupId(); } + IdStringList getGroupName(GroupId group) const { return IdStringList(); } std::vector<GroupId> getGroups() const { return {}; } std::vector<BelId> getGroupBels(GroupId group) const { return {}; } std::vector<WireId> getGroupWires(GroupId group) const { return {}; } |