From 5a89dc58e16a39c42133c28ac6359018ae5ba70d Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:00:43 -0800 Subject: Fix BBA import bugs. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fpga_interchange/arch.cc | 203 ++++++++++++++++++++++++++++++++++++----------- fpga_interchange/arch.h | 67 +++++++++++----- 2 files changed, 201 insertions(+), 69 deletions(-) (limited to 'fpga_interchange') diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index 6e69f137..acbe205f 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -145,10 +145,10 @@ BelRange Arch::getBelsByTile(int x, int y) const br.e.cursor_index = chip_info->tile_types[chip_info->tiles[br.b.cursor_tile].type].num_bels; br.b.chip = chip_info; br.e.chip = chip_info; - if (br.e.cursor_index == -1) - ++br.e.cursor_index; - else + + if(br.b != br.e) { ++br.e; + } return br; } @@ -156,36 +156,34 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires; - const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get(); - for (int i = 0; i < num_bel_wires; i++) { - if (ports[i] == pin.index) { - const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get(); - int32_t wire_index = wires[i]; + int pin_index = getBelPinIndex(bel, pin); + if(pin_index < 0) { + // Port could not be found! + return WireId(); + } else { + const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get(); + int32_t wire_index = wires[pin_index]; + if(wire_index < 0) { + // This BEL pin is not connected. + return WireId(); + } else { return canonicalWireId(chip_info, bel.tile, wire_index); } } - - // Port could not be found! - return WireId(); } PortType Arch::getBelPinType(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires; - const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get(); - - for (int i = 0; i < num_bel_wires; i++) { - if (ports[i] == pin.index) { - const int32_t *types = locInfo(bel).bel_data[bel.index].types.get(); - return PortType(types[i]); - } + int pin_index = getBelPinIndex(bel, pin); + if(pin_index < 0) { + // Port could not be found! + return PORT_INOUT; + } else { + const int32_t *types = locInfo(bel).bel_data[bel.index].types.get(); + return PortType(types[pin_index]); } - - - return PORT_INOUT; } // ----------------------------------------------------------------------- @@ -250,29 +248,95 @@ std::vector> Arch::getWireAttrs(WireId wire) co PipId Arch::getPipByName(IdString name) const { - if (pip_by_name_cache.count(name)) - return pip_by_name_cache.at(name); + // PIP name structure: + // Tile PIP: /. + // Site PIP: // + // Site pin: / PipId ret; setup_byname(); const std::string &s = name.str(this); - auto sp = split_identifier_name(s.substr(8)); + 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. int tile; int site; std::tie(tile, site) = iter->second; auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; - auto sp3 = split_identifier_name(sp.second); - IdString belname = id(sp3.first); - IdString pinname = id(sp3.second); - for (int i = 0; i < tile_info.num_pips; i++) { - if (tile_info.pip_data[i].site == site && tile_info.pip_data[i].bel == belname.index && - tile_info.pip_data[i].extra_data == pinname.index) { - ret.tile = tile; - ret.index = i; - break; + + // psuedo site pips are /. + // site pips are // + // site pins are / + 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()); + + 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; + } + } + } else { + auto split = sp.second.find('.'); + if(split == std::string::npos) { + // This is a site pin! + BelId bel = getBelByName(name); + NPNR_ASSERT(bel != BelId()); + + 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) { + ret.tile = tile; + ret.index = i; + break; + } + } + } 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)); + 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; + if(dst_index != -1) { + break; + } + } + if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == dst_site_wire.index) { + dst_index = i; + if(src_index != -1) { + break; + } + } + } + + 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].site == site && + 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; + } + } } } } else { @@ -280,11 +344,32 @@ PipId Arch::getPipByName(IdString name) const auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; auto spn = split_identifier_name_dot(sp.second); - int fromwire = std::stoi(spn.first), towire = std::stoi(spn.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; + } + } + } + + 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 == fromwire && - tile_info.pip_data[i].dst_index == towire) { + 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; @@ -292,23 +377,45 @@ PipId Arch::getPipByName(IdString name) const } } - pip_by_name_cache[name] = ret; - return ret; } IdString Arch::getPipName(PipId pip) const { + // PIP name structure: + // Tile PIP: /. + // Psuedo site PIP: /. + // Site PIP: // + // Site pin: / NPNR_ASSERT(pip != PipId()); - if (locInfo(pip).pip_data[pip.index].site != -1) { - auto site_index = chip_info->tiles[pip.tile].sites[locInfo(pip).pip_data[pip.index].site]; - auto &site = chip_info->sites[site_index]; - return id(site.name.get() + std::string("/") + IdString(locInfo(pip).pip_data[pip.index].bel).str(this) + "/" + - IdString(locInfo(pip).wire_data[locInfo(pip).pip_data[pip.index].src_index].name).str(this)); + auto &tile = chip_info->tiles[pip.tile]; + auto &tile_type = locInfo(pip); + auto &pip_info = tile_type.pip_data[pip.index]; + if (pip_info.site != -1) { + // This is either a site pin or a site pip. + auto &site = chip_info->sites[tile.sites[pip_info.site]]; + auto &bel = tile_type.bel_data[pip_info.bel]; + 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)); + + } 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)); + } 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)); + } } else { - return id(std::string(chip_info->tiles[pip.tile].name.get()) + "/" + - std::to_string(locInfo(pip).pip_data[pip.index].src_index) + "." + - std::to_string(locInfo(pip).pip_data[pip.index].dst_index)); + // 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)); } } diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 390af594..f00ae04f 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -77,15 +77,24 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD { int32_t num_bel_wires; RelPtr ports; // port name constid - RelPtr types; // port name (IN/OUT/BIDIR) + RelPtr types; // port type (IN/OUT/BIDIR) RelPtr wires; // connected wire index in tile, or -1 if NA int16_t site; int16_t site_variant; // some sites have alternative types - int16_t is_routing; + int16_t category; int16_t padding; }); +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; @@ -255,8 +264,16 @@ struct TileWireIterator WireId baseWire; int cursor = -1; - void operator++() { cursor++; } - bool operator!=(const TileWireIterator &other) const { return cursor != other.cursor; } + 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 @@ -505,13 +522,13 @@ struct BelPinIterator void operator++() { cursor++; - while (true) { - if (!(twi != twi_end)) - break; + + while (twi != twi_end) { WireId w = *twi; auto &tile = tileInfo(chip, w.tile); if (cursor < tile.wire_data[w.index].num_bel_pins) break; + ++twi; cursor = 0; } @@ -606,7 +623,7 @@ struct Arch : BaseCtx { NPNR_ASSERT(bel != BelId()); int site_index = locInfo(bel).bel_data[bel.index].site; - NPNR_ASSERT(site_index != -1); + 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)); @@ -683,7 +700,9 @@ struct Arch : BaseCtx return false; } - bool getBelHidden(BelId bel) const { return locInfo(bel).bel_data[bel.index].is_routing; } + bool getBelHidden(BelId bel) const { + return locInfo(bel).bel_data[bel.index].category != BEL_CATEGORY_LOGIC; + } IdString getBelType(BelId bel) const { @@ -693,6 +712,19 @@ struct Arch : BaseCtx std::vector> getBelAttrs(BelId bel) const; + int getBelPinIndex(BelId bel, IdString pin) const { + NPNR_ASSERT(bel != BelId()); + int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires; + const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get(); + for (int i = 0; i < num_bel_wires; i++) { + if (ports[i] == pin.index) { + return i; + } + } + + return -1; + } + WireId getBelPinWire(BelId bel, IdString pin) const; PortType getBelPinType(BelId bel, IdString pin) const; std::vector getBelPins(BelId bel) const; @@ -813,10 +845,11 @@ struct Arch : BaseCtx range.e.chip = chip_info; range.e.baseWire = wire; - if (wire.tile == -1) + if (wire.tile == -1) { range.e.cursor = chip_info->nodes[wire.index].num_tile_wires; - else + } else { range.e.cursor = 1; + } return range; } @@ -824,12 +857,14 @@ struct Arch : BaseCtx { BelPinRange range; NPNR_ASSERT(wire != WireId()); + TileWireRange twr = getTileWireRange(wire); range.b.chip = chip_info; range.b.twi = twr.b; range.b.twi_end = twr.e; range.b.cursor = -1; ++range.b; + range.e.chip = chip_info; range.e.twi = twr.e; range.e.twi_end = twr.e; @@ -991,16 +1026,6 @@ struct Arch : BaseCtx return range; } - UphillPipRange getWireAliases(WireId wire) const - { - UphillPipRange range; - range.b.cursor = 0; - range.b.twi.cursor = 0; - range.e.cursor = 0; - range.e.twi.cursor = 0; - return range; - } - // ------------------------------------------------- GroupId getGroupByName(IdString name) const { return GroupId(); } -- cgit v1.2.3