From 17918b59920bcee376e5b749ce9f89a01de62b8b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 17 Aug 2018 23:05:12 -0700 Subject: [PATCH] Fix for multiple id_SLICE_LUT6 per actual SLICE --- xc7/arch.cc | 106 +++++++++++++++++++++++++++++-------------------- xc7/arch.h | 71 ++++++++++++++++++--------------- xc7/archdefs.h | 8 ++-- xc7/xdl.cc | 18 ++++++--- 4 files changed, 117 insertions(+), 86 deletions(-) diff --git a/xc7/arch.cc b/xc7/arch.cc index ce7c5c1a..05d0841a 100644 --- a/xc7/arch.cc +++ b/xc7/arch.cc @@ -35,17 +35,36 @@ NEXTPNR_NAMESPACE_BEGIN std::unique_ptr torc_info; TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName) - : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), site_index_to_type(construct_site_index_to_type(ctx, sites)), site_index_to_z_offset(construct_site_index_to_z_offset(sites, site_index_to_type)) + : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), bel_to_site_index(construct_bel_to_site_index(ctx, sites)), num_bels(bel_to_site_index.size()), site_index_to_type(construct_site_index_to_type(ctx, sites)), bel_to_z(construct_bel_to_z(sites, num_bels, site_index_to_type)) { } +std::vector TorcInfo::construct_bel_to_site_index(Arch* ctx, const Sites &sites) +{ + std::vector bel_to_site_index; + bel_to_site_index.reserve(sites.getSiteCount()); + for (SiteIndex i(0); i < sites.getSiteCount(); ++i) { + const auto &s = sites.getSite(i); + const auto &pd = s.getPrimitiveDefPtr(); + const auto &type = pd->getName(); + if (type == "SLICEL" || type == "SLICEM") { + bel_to_site_index.push_back(i); + bel_to_site_index.push_back(i); + bel_to_site_index.push_back(i); + bel_to_site_index.push_back(i); + } + else + bel_to_site_index.push_back(i); + } + return bel_to_site_index; +} std::vector TorcInfo::construct_site_index_to_type(Arch* ctx, const Sites &sites) { std::vector site_index_to_type; site_index_to_type.resize(sites.getSiteCount()); for (SiteIndex i(0); i < sites.getSiteCount(); ++i) { - auto s = sites.getSite(i); - auto pd = s.getPrimitiveDefPtr(); - auto type = pd->getName(); + const auto &s = sites.getSite(i); + const auto &pd = s.getPrimitiveDefPtr(); + const auto &type = pd->getName(); if (type == "SLICEL" || type == "SLICEM") site_index_to_type[i] = id_SLICE_LUT6; else @@ -53,20 +72,33 @@ std::vector TorcInfo::construct_site_index_to_type(Arch* ctx, const Si } return site_index_to_type; } -std::vector TorcInfo::construct_site_index_to_z_offset(const Sites &sites, const std::vector &site_index_to_type) +std::vector TorcInfo::construct_bel_to_z(const Sites &sites, const int num_bels, const std::vector &site_index_to_type) { - std::vector site_index_to_z_offset; - site_index_to_z_offset.resize(site_index_to_type.size()); + std::vector bel_to_z; + bel_to_z.resize(num_bels); + int32_t bel_index = 0; for (SiteIndex i(0); i < site_index_to_type.size(); ++i) { if (site_index_to_type[i] == id_SLICE_LUT6) { auto site = sites.getSite(i); auto site_name = site.getName(); auto site_name_back = site_name.back(); - if (site_name_back == '1' || site_name_back == '3' || site_name_back == '5' || site_name_back == '7' || site_name_back == '9') - site_index_to_z_offset[i] = 4; + if (site_name_back == '0' || site_name_back == '2' || site_name_back == '4' || site_name_back == '6' || site_name_back == '8') { + bel_to_z[bel_index++] = 0; + bel_to_z[bel_index++] = 1; + bel_to_z[bel_index++] = 2; + bel_to_z[bel_index++] = 3; + } + else { + bel_to_z[bel_index++] = 4; + bel_to_z[bel_index++] = 5; + bel_to_z[bel_index++] = 6; + bel_to_z[bel_index++] = 7; + } } + else + ++bel_index; } - return site_index_to_z_offset; + return bel_to_z; } @@ -100,7 +132,7 @@ Arch::Arch(ArchArgs args) : args(args) // if (package_info == nullptr) // log_error("Unsupported package '%s'.\n", args.package.c_str()); - bel_to_cell.resize(torc_info->sites.getSiteCount()); + bel_to_cell.resize(torc_info->num_bels); } // ----------------------------------------------------------------------- @@ -141,18 +173,9 @@ BelId Arch::getBelByLocation(Loc loc) const BelId bel; if (bel_by_loc.empty()) { - for (SiteIndex i(0); i < torc_info->sites.getSiteCount(); ++i) { + for (int i = 0; i < torc_info->num_bels; i++) { BelId b; b.index = i; - if (torc_info->site_index_to_type[i] == id_SLICE_LUT6) { - b.pos = BelId::A; - bel_by_loc[getBelLocation(b)] = b; - b.pos = BelId::B; - bel_by_loc[getBelLocation(b)] = b; - b.pos = BelId::C; - bel_by_loc[getBelLocation(b)] = b; - b.pos = BelId::D; - } bel_by_loc[getBelLocation(b)] = b; } } @@ -168,14 +191,13 @@ BelRange Arch::getBelsByTile(int x, int y) const { BelRange br; - auto b = getBelByLocation(Loc(x, y, 0)); - br.b.index = b.index; - br.b.pos = b.pos; - br.e = br.b; + br.b.cursor = Arch::getBelByLocation(Loc(x, y, 0)).index; + br.e.cursor = br.b.cursor; - if (br.e.index != SiteIndex(torc_info->sites.getSiteCount())) { - while (br.e.index < SiteIndex(torc_info->sites.getSiteCount()) && torc_info->sites.getSite((*br.e).index).getTileIndex() == torc_info->sites.getSite((*br.b).index).getTileIndex()) - br.e++; + if (br.e.cursor != -1) { + while (br.e.cursor < chip_info->num_bels && chip_info->bel_data[br.e.cursor].x == x && + chip_info->bel_data[br.e.cursor].y == y) + br.e.cursor++; } return br; @@ -213,17 +235,25 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const { WireId ret; - auto &site = torc_info->sites.getSite(bel.index); + auto site_index = torc_info->bel_to_site_index[bel.index]; auto pin_name = pin.str(this); - if (torc_info->site_index_to_type[bel.index] == id_SLICE_LUT6) { + if (torc_info->site_index_to_type[site_index] == id_SLICE_LUT6) { // For all LUT based inputs (I1-I6,O,OQ,OMUX) then change the I/O into the LUT - if (pin_name[0] == 'I' || pin_name[0] == 'O') - pin_name[0] = bel.pos; + if (pin_name[0] == 'I' || pin_name[0] == 'O') { + switch (torc_info->bel_to_z[bel.index]) { + case 0: case 4: pin_name[0] = 'A'; break; + case 1: case 5: pin_name[0] = 'B'; break; + case 2: case 6: pin_name[0] = 'C'; break; + case 3: case 7: pin_name[0] = 'D'; break; + default: throw; + } + } } + auto &site = torc_info->sites.getSite(site_index); ret.index = site.getPinTilewire(pin_name); if (ret.index.isUndefined()) - log_error("no wire found for site '%s' pin '%s' \n", torc_info->site_index_to_name(bel.index).c_str(), pin_name.c_str()); + log_error("no wire found for site '%s' pin '%s' \n", torc_info->bel_to_name(bel.index).c_str(), pin_name.c_str()); // NPNR_ASSERT(bel != BelId()); @@ -823,14 +853,4 @@ void Arch::assignCellInfo(CellInfo *cell) } } -void operator++(BelId::bel &b) { - switch (b) { - case BelId::A: b = BelId::B; return; - case BelId::B: b = BelId::C; return; - case BelId::C: b = BelId::D; return; - default: break; - } - throw; -} - NEXTPNR_NAMESPACE_END diff --git a/xc7/arch.h b/xc7/arch.h index 379369c6..60039240 100644 --- a/xc7/arch.h +++ b/xc7/arch.h @@ -240,56 +240,57 @@ struct TorcInfo { const Sites &sites; const Tiles &tiles; - SiteIndex sites_begin() const { return SiteIndex(0); } - SiteIndex sites_end() const { return SiteIndex(sites.getSiteCount()); } - const TileInfo& site_index_to_tile_info(SiteIndex si) const { + const TileInfo& bel_to_tile_info(int32_t index) const { + auto si = bel_to_site_index[index]; auto &site = sites.getSite(si); return tiles.getTileInfo(site.getTileIndex()); } - const std::string& site_index_to_name(SiteIndex si) const { + const std::string& bel_to_name(int32_t index) const { + auto si = bel_to_site_index[index]; return sites.getSite(si).getName(); } + const std::vector bel_to_site_index; + const int num_bels; const std::vector site_index_to_type; - const std::vector site_index_to_z_offset; + const std::vector bel_to_z; private: + static std::vector construct_bel_to_site_index(Arch *ctx, const Sites &sites); static std::vector construct_site_index_to_type(Arch *ctx, const Sites &sites); - static std::vector construct_site_index_to_z_offset(const Sites &sites, const std::vector &site_index_to_type); + static std::vector construct_bel_to_z(const Sites &sites, const int num_bels, const std::vector &site_index_to_type); }; extern std::unique_ptr torc_info; /************************ End of chipdb section. ************************/ -struct BelIterator : public BelId +struct BelIterator { + int cursor; + BelIterator operator++() { - if (pos >= A && pos < D) { - ++pos; - return *this; - } - - if (torc_info->site_index_to_type[++index] == id_SLICE_LUT6) - pos = A; - else - pos = NOT_APPLICABLE; - + cursor++; return *this; } BelIterator operator++(int) { BelIterator prior(*this); - operator++(); + cursor++; return prior; } - bool operator!=(const BelIterator &other) const { return BelId::operator!=(other); } + bool operator!=(const BelIterator &other) const { return cursor != other.cursor; } - bool operator==(const BelIterator &other) const { return BelId::operator==(other); } + bool operator==(const BelIterator &other) const { return cursor == other.cursor; } - BelId operator*() const { return *this; } + BelId operator*() const + { + BelId ret; + ret.index = cursor; + return ret; + } }; struct BelRange @@ -447,12 +448,19 @@ struct Arch : BaseCtx IdString getBelName(BelId bel) const { NPNR_ASSERT(bel != BelId()); - auto name = torc_info->site_index_to_name(bel.index); - if (torc_info->site_index_to_type[bel.index] == id_SLICE_LUT6) { + auto name = torc_info->bel_to_name(bel.index); + auto site_index = torc_info->bel_to_site_index[bel.index]; + if (torc_info->site_index_to_type[site_index] == id_SLICE_LUT6) { // Append LUT name to name name.reserve(name.size() + 2); name += "_"; - name += bel.pos; + switch (torc_info->bel_to_z[bel.index]) { + case 0: case 4: name += 'A'; break; + case 1: case 5: name += 'B'; break; + case 2: case 6: name += 'C'; break; + case 3: case 7: name += 'D'; break; + default: throw; + } } return id(name); } @@ -503,23 +511,19 @@ struct Arch : BaseCtx BelRange getBels() const { BelRange range; - range.b.index = torc_info->sites_begin(); - range.e.index = torc_info->sites_end(); + range.b.cursor = 0; + range.e.cursor = torc_info->num_bels; return range; } Loc getBelLocation(BelId bel) const { - auto &tile_info = torc_info->site_index_to_tile_info(bel.index); + auto &tile_info = torc_info->bel_to_tile_info(bel.index); Loc loc; loc.x = tile_info.getCol(); loc.y = tile_info.getRow(); - if (torc_info->site_index_to_type[bel.index] == id_SLICE_LUT6) { - loc.z = bel.pos - 'A'; - // Apply offset if upper slice - loc.z += torc_info->site_index_to_z_offset[bel.index]; - } + loc.z = torc_info->bel_to_z[bel.index]; return loc; } @@ -531,7 +535,8 @@ struct Arch : BaseCtx IdString getBelType(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return torc_info->site_index_to_type[bel.index]; + auto site_index = torc_info->bel_to_site_index[bel.index]; + return torc_info->site_index_to_type[site_index]; } WireId getBelPinWire(BelId bel, IdString pin) const; diff --git a/xc7/archdefs.h b/xc7/archdefs.h index 9c0efc70..9f0f8382 100644 --- a/xc7/archdefs.h +++ b/xc7/archdefs.h @@ -66,13 +66,11 @@ enum ConstIds struct BelId { - SiteIndex index = SiteIndex(-1); - enum bel : int8_t { NOT_APPLICABLE, A='A', B='B', C='C', D='D' } pos = NOT_APPLICABLE; + int32_t index = -1; - bool operator==(const BelId &other) const { return index == other.index && pos == pos; } - bool operator!=(const BelId &other) const { return index != other.index || pos != pos; } + bool operator==(const BelId &other) const { return index == other.index; } + bool operator!=(const BelId &other) const { return index != other.index; } }; -void operator++(BelId::bel &b); struct WireId { diff --git a/xc7/xdl.cc b/xc7/xdl.cc index 5894d5ae..c627c4db 100644 --- a/xc7/xdl.cc +++ b/xc7/xdl.cc @@ -37,7 +37,7 @@ void write_xdl(const Context *ctx, std::ostream &out) XdlExporter exporter(out); auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), "clg484", "", ""); - std::map site_to_instance; + std::unordered_map site_to_instance; for (const auto& cell : ctx->cells) { const char* type; @@ -46,7 +46,8 @@ void write_xdl(const Context *ctx, std::ostream &out) else if (cell.second->type == id_BUFGCTRL) type = "BUFGCTRL"; else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); - auto ret = site_to_instance.emplace(cell.second->bel.index, nullptr); + auto site_index = torc_info->bel_to_site_index[cell.second->bel.index]; + auto ret = site_to_instance.emplace(site_index, nullptr); InstanceSharedPtr instPtr; if (ret.second) { instPtr = Factory::newInstancePtr(cell.second->name.str(ctx), type, "", ""); @@ -54,15 +55,22 @@ void write_xdl(const Context *ctx, std::ostream &out) assert(b); ret.first->second = instPtr; - const auto& tile_info = torc_info->site_index_to_tile_info(cell.second->bel.index); + const auto& tile_info = torc_info->bel_to_tile_info(cell.second->bel.index); instPtr->setTile(tile_info.getName()); - instPtr->setSite(torc_info->site_index_to_name(cell.second->bel.index)); + instPtr->setSite(torc_info->bel_to_name(cell.second->bel.index)); } else instPtr = ret.first->second; if (cell.second->type == id_SLICE_LUT6) { - std::string config(1, cell.second->bel.pos); + std::string config; + switch (torc_info->bel_to_z[cell.second->bel.index]) { + case 0: case 4: config += 'A'; break; + case 1: case 5: config += 'B'; break; + case 2: case 6: config += 'C'; break; + case 3: case 7: config += 'D'; break; + default: throw; + } config += "6LUT"; instPtr->setConfig(config, cell.second->name.str(ctx), "#LUT:O6="); }