diff --git a/xc7/arch.cc b/xc7/arch.cc index 5af81542..ce13edeb 100644 --- a/xc7/arch.cc +++ b/xc7/arch.cc @@ -36,6 +36,7 @@ NEXTPNR_NAMESPACE_BEGIN const DDB *torc = nullptr; const Sites *torc_sites = nullptr; const Tiles *torc_tiles = nullptr; +std::vector bel_index_to_type; // ----------------------------------------------------------------------- @@ -71,6 +72,17 @@ Arch::Arch(ArchArgs args) : args(args) torc_sites = &torc->getSites(); torc_tiles = &torc->getTiles(); + bel_index_to_type.resize(torc_sites->getSiteCount()); + for (SiteIndex i(0); i < torc_sites->getSiteCount(); ++i) { + const auto& s = torc_sites->getSite(i); + auto pd = s.getPrimitiveDefPtr(); + const auto& type = pd->getName(); + if (type == "SLICEL" || type == "SLICEM") + bel_index_to_type[i] = id_QUARTER_SLICE; + else + bel_index_to_type[i] = id(type); + } + bel_to_cell.resize(torc_sites->getSiteCount()); } @@ -115,6 +127,15 @@ BelId Arch::getBelByLocation(Loc loc) const for (SiteIndex i(0); i < torc_sites->getSiteCount(); ++i) { BelId b; b.index = i; + if (bel_index_to_type[i] == id_QUARTER_SLICE) { + 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; } } @@ -130,12 +151,14 @@ BelRange Arch::getBelsByTile(int x, int y) const { BelRange br; - br.b.cursor = std::next(torc_sites->getSites().begin(), Arch::getBelByLocation(Loc(x, y, 0)).index); - br.e.cursor = br.b.cursor; + auto b = getBelByLocation(Loc(x, y, 0)); + br.b.index = b.index; + br.b.pos = b.pos; + br.e = br.b; - if (br.e.cursor != torc_sites->getSites().end()) { - while (br.e.cursor < torc_sites->getSites().end() && torc_sites->getSite((*br.e).index).getTileIndex() == torc_sites->getSite((*br.b).index).getTileIndex()) - br.e.cursor++; + if (br.e.index != SiteIndex(torc_sites->getSiteCount())) { + while (br.e.index < SiteIndex(torc_sites->getSiteCount()) && torc_sites->getSite((*br.e).index).getTileIndex() == torc_sites->getSite((*br.b).index).getTileIndex()) + br.e++; } return br; @@ -674,7 +697,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const { - if (cell->type == id_SLICEL) + if (cell->type == id_QUARTER_SLICE) { if (fromPort.index >= id_A1.index && fromPort.index <= id_A6.index) return toPort == id_A || toPort == id_AQ; @@ -689,7 +712,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort // Get the port class, also setting clockPort to associated clock if applicable TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const { - if (cell->type == id_SLICEL) { + if (cell->type == id_QUARTER_SLICE) { if (port == id_CLK) return TMG_CLOCK_INPUT; if (port == id_CIN) @@ -754,7 +777,7 @@ void Arch::assignArchInfo() void Arch::assignCellInfo(CellInfo *cell) { cell->belType = cell->type; - if (cell->type == id_SLICEL) { + if (cell->type == id_QUARTER_SLICE) { cell->lcInfo.dffEnable = bool_or_default(cell->params, id_DFF_ENABLE); cell->lcInfo.carryEnable = bool_or_default(cell->params, id_CARRY_ENABLE); cell->lcInfo.negClk = bool_or_default(cell->params, id_NEG_CLK); @@ -773,4 +796,14 @@ 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 8ee8c7d6..295a0759 100644 --- a/xc7/arch.h +++ b/xc7/arch.h @@ -236,36 +236,41 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { extern const DDB *torc; extern const Sites *torc_sites; extern const Tiles *torc_tiles; +extern std::vector bel_index_to_type; /************************ End of chipdb section. ************************/ -struct BelIterator +struct BelIterator : public BelId { - Array::iterator cursor; - BelIterator operator++() { - cursor++; + if (bel_index_to_type[index] == id_QUARTER_SLICE) { + if (pos < D) { + ++pos; + return *this; + } + } + + if (bel_index_to_type[++index] == id_QUARTER_SLICE) + pos = A; + else + pos = NOT_APPLICABLE; + return *this; } BelIterator operator++(int) { BelIterator prior(*this); - cursor++; + operator++(); return prior; } - 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; } + bool operator==(const BelIterator &other) const { return BelId::operator==(other); } - BelId operator*() const - { - BelId ret; - ret.index = SiteIndex(std::distance(torc_sites->getSites().begin(), cursor)); - return ret; - } + BelId operator*() const { return *this; } }; struct BelRange @@ -472,8 +477,8 @@ struct Arch : BaseCtx BelRange getBels() const { BelRange range; - range.b.cursor = torc_sites->getSites().begin(); - range.e.cursor = torc_sites->getSites().end(); + range.b.index = SiteIndex(0); + range.e.index = SiteIndex(torc_sites->getSiteCount()); return range; } @@ -496,9 +501,7 @@ struct Arch : BaseCtx IdString getBelType(BelId bel) const { NPNR_ASSERT(bel != BelId()); - const auto& site = torc_sites->getSite(bel.index); - auto prim_def = site.getPrimitiveDefPtr(); - return id(prim_def->getName()); + return bel_index_to_type[bel.index]; } WireId getBelPinWire(BelId bel, IdString pin) const; diff --git a/xc7/archdefs.h b/xc7/archdefs.h index fd5796c3..bfeadea4 100644 --- a/xc7/archdefs.h +++ b/xc7/archdefs.h @@ -67,10 +67,12 @@ enum ConstIds struct BelId { SiteIndex index = SiteIndex(-1); + enum bel : int8_t { NOT_APPLICABLE, A, B, C, D } pos = NOT_APPLICABLE; - bool operator==(const BelId &other) const { return index == other.index; } - bool operator!=(const BelId &other) const { return index != other.index; } + bool operator==(const BelId &other) const { return index == other.index && pos == pos; } + bool operator!=(const BelId &other) const { return index != other.index || pos != pos; } }; +void operator++(BelId::bel &b); struct WireId { diff --git a/xc7/cells.cc b/xc7/cells.cc index 635eaaef..c36d1443 100644 --- a/xc7/cells.cc +++ b/xc7/cells.cc @@ -43,7 +43,7 @@ std::unique_ptr create_ice_cell(Context *ctx, IdString type, std::stri } new_cell->type = type; if (type == ctx->id("XC7_LC")) { - new_cell->type = id_SLICEL; // HACK HACK HACK: Place one LC into each slice + new_cell->type = id_QUARTER_SLICE; // HACK HACK HACK: Place one LC into each slice new_cell->params[ctx->id("LUT_INIT")] = "0"; new_cell->params[ctx->id("NEG_CLK")] = "0"; new_cell->params[ctx->id("CARRY_ENABLE")] = "0"; diff --git a/xc7/constids.inc b/xc7/constids.inc index 27c5c4e7..632524de 100644 --- a/xc7/constids.inc +++ b/xc7/constids.inc @@ -464,7 +464,7 @@ X(FDCE) X(FDPE) X(BUFGCTRL) -X(SLICEL) +X(QUARTER_SLICE) X(IOBUF) X(IOB33S) X(IOB33M) // What is the difference between IOB33S and IOB33M?