diff --git a/xc7/arch.cc b/xc7/arch.cc index 52d88326..31b02a9e 100644 --- a/xc7/arch.cc +++ b/xc7/arch.cc @@ -32,6 +32,12 @@ NEXTPNR_NAMESPACE_BEGIN + +const DDB *ddb = nullptr; +const Sites *ddbSites = nullptr; +const Tiles *ddbTiles = nullptr; + + // ----------------------------------------------------------------------- void IdString::initialize_arch(const BaseCtx *ctx) @@ -61,6 +67,9 @@ Arch::Arch(ArchArgs args) : args(args) // } // if (package_info == nullptr) // log_error("Unsupported package '%s'.\n", args.package.c_str()); + + ddbSites = &ddb->getSites(); + ddbTiles = &ddb->getTiles(); } // ----------------------------------------------------------------------- @@ -89,14 +98,9 @@ BelId Arch::getBelByName(IdString name) const { BelId ret; - if (bel_by_name.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_name[id(chip_info->bel_data[i].name.get())] = i; - } - - auto it = bel_by_name.find(name); - if (it != bel_by_name.end()) - ret.index = it->second; + auto it = ddbSites->findSiteIndex(name.str(this)); + if (it != SiteIndex(-1)) + ret.index = it; return ret; } @@ -106,32 +110,29 @@ BelId Arch::getBelByLocation(Loc loc) const BelId bel; if (bel_by_loc.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) { + for (SiteIndex i(0); i < ddbSites->getSiteCount(); ++i) { BelId b; b.index = i; - bel_by_loc[getBelLocation(b)] = i; + bel_by_loc[getBelLocation(b)] = b; } } auto it = bel_by_loc.find(loc); if (it != bel_by_loc.end()) - bel.index = it->second; + bel = it->second; return bel; } BelRange Arch::getBelsByTile(int x, int y) const { - // In iCE40 chipdb bels at the same tile are consecutive and dense z ordinates - // are used BelRange br; - br.b.cursor = Arch::getBelByLocation(Loc(x, y, 0)).index; + br.b.cursor = std::next(ddbSites->getSites().begin(), Arch::getBelByLocation(Loc(x, y, 0)).index); br.e.cursor = br.b.cursor; - 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) + if (br.e.cursor != ddbSites->getSites().end()) { + while (br.e.cursor < ddbSites->getSites().end() && ddbSites->getSite((*br.e).index).getTileIndex() == ddbSites->getSite((*br.b).index).getTileIndex()) br.e.cursor++; } @@ -316,23 +317,23 @@ IdString Arch::getPipName(PipId pip) const BelId Arch::getPackagePinBel(const std::string &pin) const { - for (int i = 0; i < package_info->num_pins; i++) { - if (package_info->pins[i].name.get() == pin) { - BelId id; - id.index = package_info->pins[i].bel_index; - return id; - } - } +// for (int i = 0; i < package_info->num_pins; i++) { +// if (package_info->pins[i].name.get() == pin) { +// BelId id; +// id.index = package_info->pins[i].bel_index; +// return id; +// } +// } return BelId(); } std::string Arch::getBelPackagePin(BelId bel) const { - for (int i = 0; i < package_info->num_pins; i++) { - if (package_info->pins[i].bel_index == bel.index) { - return std::string(package_info->pins[i].name.get()); - } - } +// for (int i = 0; i < package_info->num_pins; i++) { +// if (package_info->pins[i].bel_index == bel.index) { +// return std::string(package_info->pins[i].name.get()); +// } +// } return ""; } @@ -617,7 +618,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const if (decal.type == DecalId::TYPE_BEL) { BelId bel; - bel.index = decal.index; + bel.index = SiteIndex(decal.index); auto bel_type = getBelType(bel); diff --git a/xc7/arch.h b/xc7/arch.h index 5f3988a5..810ff4d5 100644 --- a/xc7/arch.h +++ b/xc7/arch.h @@ -24,6 +24,7 @@ #include "torc/Architecture.hpp" #include "torc/Common.hpp" using namespace torc::architecture; +using namespace torc::architecture::xilinx; NEXTPNR_NAMESPACE_BEGIN @@ -231,23 +232,17 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { RelPtr cell_timing; }); -#if defined(_MSC_VER) -extern const char *chipdb_blob_384; -extern const char *chipdb_blob_1k; -extern const char *chipdb_blob_5k; -extern const char *chipdb_blob_8k; -#else -extern const char chipdb_blob_384[]; -extern const char chipdb_blob_1k[]; -extern const char chipdb_blob_5k[]; -extern const char chipdb_blob_8k[]; -#endif + +extern const DDB *ddb; +extern const Sites *ddbSites; +extern const Tiles *ddbTiles; + /************************ End of chipdb section. ************************/ struct BelIterator { - int cursor; + Array::iterator cursor; BelIterator operator++() { @@ -268,7 +263,7 @@ struct BelIterator BelId operator*() const { BelId ret; - ret.index = cursor; + ret.index = SiteIndex(std::distance(ddbSites->getSites().begin(), cursor)); return ret; } }; @@ -284,16 +279,17 @@ struct BelRange struct BelPinIterator { - const BelPortPOD *ptr = nullptr; + const BelId bel; + Array::iterator it; - void operator++() { ptr++; } - bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; } + void operator++() { it++; } + bool operator!=(const BelPinIterator &other) const { return it != other.it && bel != other.bel; } BelPin operator*() const { BelPin ret; - ret.bel.index = ptr->bel_index; - ret.pin = ptr->port; + ret.bel = bel; + ret.pin = IdString(); return ret; } }; @@ -391,13 +387,11 @@ struct Arch : BaseCtx { bool fast_part; const ChipInfoPOD *chip_info; - const DDB *ddb; const PackageInfoPOD *package_info; - mutable std::unordered_map bel_by_name; mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; - mutable std::unordered_map bel_by_loc; + mutable std::unordered_map bel_by_loc; std::vector bel_carry; std::vector bel_to_cell; @@ -428,7 +422,7 @@ struct Arch : BaseCtx IdString getBelName(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return id(chip_info->bel_data[bel.index].name.get()); + return id(ddbSites->getSite(bel.index).getName()); } uint32_t getBelChecksum(BelId bel) const { return bel.index; } @@ -477,17 +471,19 @@ struct Arch : BaseCtx BelRange getBels() const { BelRange range; - range.b.cursor = 0; - range.e.cursor = chip_info->num_bels; + range.b.cursor = ddbSites->getSites().begin(); + range.e.cursor = ddbSites->getSites().end(); return range; } Loc getBelLocation(BelId bel) const { + const auto& site = ddbSites->getSite(bel.index); + const auto& tile_info = ddbTiles->getTileInfo(site.getTileIndex()); Loc loc; - loc.x = chip_info->bel_data[bel.index].x; - loc.y = chip_info->bel_data[bel.index].y; - loc.z = chip_info->bel_data[bel.index].z; + loc.x = tile_info.getCol(); + loc.y = tile_info.getRow(); + loc.z = 0; return loc; } @@ -499,7 +495,9 @@ struct Arch : BaseCtx IdString getBelType(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return IdString(chip_info->bel_data[bel.index].type); + const auto& site = ddbSites->getSite(bel.index); + const auto& tile_info = ddbTiles->getTileInfo(site.getTileIndex()); + return id(ddbTiles->getTileTypeName(tile_info.getTypeIndex())); } WireId getBelPinWire(BelId bel, IdString pin) const; @@ -582,9 +580,9 @@ struct Arch : BaseCtx BelPinRange getWireBelPins(WireId wire) const { BelPinRange range; - NPNR_ASSERT(wire != WireId()); - range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); - range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins; + //NPNR_ASSERT(wire != WireId()); + //range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); + //range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins; return range; } diff --git a/xc7/arch_place.cc b/xc7/arch_place.cc index c69fd34f..ca98fa18 100644 --- a/xc7/arch_place.cc +++ b/xc7/arch_place.cc @@ -93,70 +93,70 @@ bool Arch::isBelLocationValid(BelId bel) const bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { - if (cell->type == id_ICESTORM_LC) { - NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); - - std::array bel_cells; - size_t num_cells = 0; - - Loc bel_loc = getBelLocation(bel); - for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { - CellInfo *ci_other = getBoundBelCell(bel_other); - if (ci_other != nullptr && bel_other != bel) - bel_cells[num_cells++] = ci_other; - } - - bel_cells[num_cells++] = cell; - return logicCellsCompatible(bel_cells.data(), num_cells); - } else if (cell->type == id_SB_IO) { - // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. - - // Find shared PLL by looking for driving bel siblings from D_IN_0 - // that are a PLL clock output. - auto wire = getBelPinWire(bel, id_D_IN_0); - IdString pll_bel_pin; - BelId pll_bel; - for (auto pin : getWireBelPins(wire)) { - if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { - pll_bel = pin.bel; - pll_bel_pin = pin.pin; - break; - } - } - // Is there a PLL that shares this IO buffer? - if (pll_bel.index != -1) { - auto pll_cell = getBoundBelCell(pll_bel); - // Is a PLL placed in this PLL bel? - if (pll_cell != nullptr) { - // Is the shared port driving a net? - auto pi = pll_cell->ports[pll_bel_pin]; - if (pi.net != nullptr) { - // Are we perhaps a PAD INPUT Bel that can be placed here? - if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { - return true; - } - return false; - } - } - } - return getBelPackagePin(bel) != ""; - } else if (cell->type == id_SB_GB) { - NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); - const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; - IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); - int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); - if (net->is_reset && net->is_enable) - return false; - else if (net->is_reset) - return (glb_id % 2) == 0; - else if (net->is_enable) - return (glb_id % 2) == 1; - else - return true; - } else { - // TODO: IO cell clock checks +// if (cell->type == id_ICESTORM_LC) { +// NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); +// +// std::array bel_cells; +// size_t num_cells = 0; +// +// Loc bel_loc = getBelLocation(bel); +// for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { +// CellInfo *ci_other = getBoundBelCell(bel_other); +// if (ci_other != nullptr && bel_other != bel) +// bel_cells[num_cells++] = ci_other; +// } +// +// bel_cells[num_cells++] = cell; +// return logicCellsCompatible(bel_cells.data(), num_cells); +// } else if (cell->type == id_SB_IO) { +// // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. +// +// // Find shared PLL by looking for driving bel siblings from D_IN_0 +// // that are a PLL clock output. +// auto wire = getBelPinWire(bel, id_D_IN_0); +// IdString pll_bel_pin; +// BelId pll_bel; +// for (auto pin : getWireBelPins(wire)) { +// if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { +// pll_bel = pin.bel; +// pll_bel_pin = pin.pin; +// break; +// } +// } +// // Is there a PLL that shares this IO buffer? +// if (pll_bel.index != -1) { +// auto pll_cell = getBoundBelCell(pll_bel); +// // Is a PLL placed in this PLL bel? +// if (pll_cell != nullptr) { +// // Is the shared port driving a net? +// auto pi = pll_cell->ports[pll_bel_pin]; +// if (pi.net != nullptr) { +// // Are we perhaps a PAD INPUT Bel that can be placed here? +// if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { +// return true; +// } +// return false; +// } +// } +// } +// return getBelPackagePin(bel) != ""; +// } else if (cell->type == id_SB_GB) { +// NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); +// const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; +// IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); +// int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); +// if (net->is_reset && net->is_enable) +// return false; +// else if (net->is_reset) +// return (glb_id % 2) == 0; +// else if (net->is_enable) +// return (glb_id % 2) == 1; +// else +// return true; +// } else { +// // TODO: IO cell clock checks return true; - } +// } } NEXTPNR_NAMESPACE_END diff --git a/xc7/archdefs.h b/xc7/archdefs.h index 360617fd..757d0d61 100644 --- a/xc7/archdefs.h +++ b/xc7/archdefs.h @@ -21,6 +21,9 @@ #error Include "archdefs.h" via "nextpnr.h" only. #endif +#include "torc/Architecture.hpp" +using namespace torc::architecture::xilinx; + NEXTPNR_NAMESPACE_BEGIN typedef int delay_t; @@ -62,7 +65,7 @@ enum ConstIds struct BelId { - int32_t index = -1; + SiteIndex index = SiteIndex(-1); bool operator==(const BelId &other) const { return index == other.index; } bool operator!=(const BelId &other) const { return index != other.index; }