Starts placement onto all Xilinx sites

This commit is contained in:
Eddie Hung 2018-08-11 18:52:48 -07:00
parent 45009ac09d
commit 8cddc49abc
4 changed files with 127 additions and 125 deletions

View File

@ -32,6 +32,12 @@
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
const DDB *ddb = nullptr;
const Sites *ddbSites = nullptr;
const Tiles *ddbTiles = nullptr;
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void IdString::initialize_arch(const BaseCtx *ctx) void IdString::initialize_arch(const BaseCtx *ctx)
@ -61,6 +67,9 @@ Arch::Arch(ArchArgs args) : args(args)
// } // }
// if (package_info == nullptr) // if (package_info == nullptr)
// log_error("Unsupported package '%s'.\n", args.package.c_str()); // 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; BelId ret;
if (bel_by_name.empty()) { auto it = ddbSites->findSiteIndex(name.str(this));
for (int i = 0; i < chip_info->num_bels; i++) if (it != SiteIndex(-1))
bel_by_name[id(chip_info->bel_data[i].name.get())] = i; ret.index = it;
}
auto it = bel_by_name.find(name);
if (it != bel_by_name.end())
ret.index = it->second;
return ret; return ret;
} }
@ -106,32 +110,29 @@ BelId Arch::getBelByLocation(Loc loc) const
BelId bel; BelId bel;
if (bel_by_loc.empty()) { 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; BelId b;
b.index = i; b.index = i;
bel_by_loc[getBelLocation(b)] = i; bel_by_loc[getBelLocation(b)] = b;
} }
} }
auto it = bel_by_loc.find(loc); auto it = bel_by_loc.find(loc);
if (it != bel_by_loc.end()) if (it != bel_by_loc.end())
bel.index = it->second; bel = it->second;
return bel; return bel;
} }
BelRange Arch::getBelsByTile(int x, int y) const 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; 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; br.e.cursor = br.b.cursor;
if (br.e.cursor != -1) { if (br.e.cursor != ddbSites->getSites().end()) {
while (br.e.cursor < chip_info->num_bels && chip_info->bel_data[br.e.cursor].x == x && while (br.e.cursor < ddbSites->getSites().end() && ddbSites->getSite((*br.e).index).getTileIndex() == ddbSites->getSite((*br.b).index).getTileIndex())
chip_info->bel_data[br.e.cursor].y == y)
br.e.cursor++; br.e.cursor++;
} }
@ -316,23 +317,23 @@ IdString Arch::getPipName(PipId pip) const
BelId Arch::getPackagePinBel(const std::string &pin) const BelId Arch::getPackagePinBel(const std::string &pin) const
{ {
for (int i = 0; i < package_info->num_pins; i++) { // for (int i = 0; i < package_info->num_pins; i++) {
if (package_info->pins[i].name.get() == pin) { // if (package_info->pins[i].name.get() == pin) {
BelId id; // BelId id;
id.index = package_info->pins[i].bel_index; // id.index = package_info->pins[i].bel_index;
return id; // return id;
} // }
} // }
return BelId(); return BelId();
} }
std::string Arch::getBelPackagePin(BelId bel) const std::string Arch::getBelPackagePin(BelId bel) const
{ {
for (int i = 0; i < package_info->num_pins; i++) { // for (int i = 0; i < package_info->num_pins; i++) {
if (package_info->pins[i].bel_index == bel.index) { // if (package_info->pins[i].bel_index == bel.index) {
return std::string(package_info->pins[i].name.get()); // return std::string(package_info->pins[i].name.get());
} // }
} // }
return ""; return "";
} }
@ -617,7 +618,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
if (decal.type == DecalId::TYPE_BEL) { if (decal.type == DecalId::TYPE_BEL) {
BelId bel; BelId bel;
bel.index = decal.index; bel.index = SiteIndex(decal.index);
auto bel_type = getBelType(bel); auto bel_type = getBelType(bel);

View File

@ -24,6 +24,7 @@
#include "torc/Architecture.hpp" #include "torc/Architecture.hpp"
#include "torc/Common.hpp" #include "torc/Common.hpp"
using namespace torc::architecture; using namespace torc::architecture;
using namespace torc::architecture::xilinx;
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -231,23 +232,17 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<CellTimingPOD> cell_timing; RelPtr<CellTimingPOD> cell_timing;
}); });
#if defined(_MSC_VER)
extern const char *chipdb_blob_384; extern const DDB *ddb;
extern const char *chipdb_blob_1k; extern const Sites *ddbSites;
extern const char *chipdb_blob_5k; extern const Tiles *ddbTiles;
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
/************************ End of chipdb section. ************************/ /************************ End of chipdb section. ************************/
struct BelIterator struct BelIterator
{ {
int cursor; Array<const Site>::iterator cursor;
BelIterator operator++() BelIterator operator++()
{ {
@ -268,7 +263,7 @@ struct BelIterator
BelId operator*() const BelId operator*() const
{ {
BelId ret; BelId ret;
ret.index = cursor; ret.index = SiteIndex(std::distance(ddbSites->getSites().begin(), cursor));
return ret; return ret;
} }
}; };
@ -284,16 +279,17 @@ struct BelRange
struct BelPinIterator struct BelPinIterator
{ {
const BelPortPOD *ptr = nullptr; const BelId bel;
Array<const WireIndex>::iterator it;
void operator++() { ptr++; } void operator++() { it++; }
bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; } bool operator!=(const BelPinIterator &other) const { return it != other.it && bel != other.bel; }
BelPin operator*() const BelPin operator*() const
{ {
BelPin ret; BelPin ret;
ret.bel.index = ptr->bel_index; ret.bel = bel;
ret.pin = ptr->port; ret.pin = IdString();
return ret; return ret;
} }
}; };
@ -391,13 +387,11 @@ struct Arch : BaseCtx
{ {
bool fast_part; bool fast_part;
const ChipInfoPOD *chip_info; const ChipInfoPOD *chip_info;
const DDB *ddb;
const PackageInfoPOD *package_info; const PackageInfoPOD *package_info;
mutable std::unordered_map<IdString, int> bel_by_name;
mutable std::unordered_map<IdString, int> wire_by_name; mutable std::unordered_map<IdString, int> wire_by_name;
mutable std::unordered_map<IdString, int> pip_by_name; mutable std::unordered_map<IdString, int> pip_by_name;
mutable std::unordered_map<Loc, int> bel_by_loc; mutable std::unordered_map<Loc, BelId> bel_by_loc;
std::vector<bool> bel_carry; std::vector<bool> bel_carry;
std::vector<CellInfo *> bel_to_cell; std::vector<CellInfo *> bel_to_cell;
@ -428,7 +422,7 @@ struct Arch : BaseCtx
IdString getBelName(BelId bel) const IdString getBelName(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); 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; } uint32_t getBelChecksum(BelId bel) const { return bel.index; }
@ -477,17 +471,19 @@ struct Arch : BaseCtx
BelRange getBels() const BelRange getBels() const
{ {
BelRange range; BelRange range;
range.b.cursor = 0; range.b.cursor = ddbSites->getSites().begin();
range.e.cursor = chip_info->num_bels; range.e.cursor = ddbSites->getSites().end();
return range; return range;
} }
Loc getBelLocation(BelId bel) const Loc getBelLocation(BelId bel) const
{ {
const auto& site = ddbSites->getSite(bel.index);
const auto& tile_info = ddbTiles->getTileInfo(site.getTileIndex());
Loc loc; Loc loc;
loc.x = chip_info->bel_data[bel.index].x; loc.x = tile_info.getCol();
loc.y = chip_info->bel_data[bel.index].y; loc.y = tile_info.getRow();
loc.z = chip_info->bel_data[bel.index].z; loc.z = 0;
return loc; return loc;
} }
@ -499,7 +495,9 @@ struct Arch : BaseCtx
IdString getBelType(BelId bel) const IdString getBelType(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); 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; WireId getBelPinWire(BelId bel, IdString pin) const;
@ -582,9 +580,9 @@ struct Arch : BaseCtx
BelPinRange getWireBelPins(WireId wire) const BelPinRange getWireBelPins(WireId wire) const
{ {
BelPinRange range; BelPinRange range;
NPNR_ASSERT(wire != WireId()); //NPNR_ASSERT(wire != WireId());
range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); //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; //range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins;
return range; return range;
} }

View File

@ -93,70 +93,70 @@ bool Arch::isBelLocationValid(BelId bel) const
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{ {
if (cell->type == id_ICESTORM_LC) { // if (cell->type == id_ICESTORM_LC) {
NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); // NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC);
//
std::array<const CellInfo *, 8> bel_cells; // std::array<const CellInfo *, 8> bel_cells;
size_t num_cells = 0; // size_t num_cells = 0;
//
Loc bel_loc = getBelLocation(bel); // Loc bel_loc = getBelLocation(bel);
for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { // for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
CellInfo *ci_other = getBoundBelCell(bel_other); // CellInfo *ci_other = getBoundBelCell(bel_other);
if (ci_other != nullptr && bel_other != bel) // if (ci_other != nullptr && bel_other != bel)
bel_cells[num_cells++] = ci_other; // bel_cells[num_cells++] = ci_other;
} // }
//
bel_cells[num_cells++] = cell; // bel_cells[num_cells++] = cell;
return logicCellsCompatible(bel_cells.data(), num_cells); // return logicCellsCompatible(bel_cells.data(), num_cells);
} else if (cell->type == id_SB_IO) { // } else if (cell->type == id_SB_IO) {
// Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. // // 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 // // Find shared PLL by looking for driving bel siblings from D_IN_0
// that are a PLL clock output. // // that are a PLL clock output.
auto wire = getBelPinWire(bel, id_D_IN_0); // auto wire = getBelPinWire(bel, id_D_IN_0);
IdString pll_bel_pin; // IdString pll_bel_pin;
BelId pll_bel; // BelId pll_bel;
for (auto pin : getWireBelPins(wire)) { // for (auto pin : getWireBelPins(wire)) {
if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { // if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) {
pll_bel = pin.bel; // pll_bel = pin.bel;
pll_bel_pin = pin.pin; // pll_bel_pin = pin.pin;
break; // break;
} // }
} // }
// Is there a PLL that shares this IO buffer? // // Is there a PLL that shares this IO buffer?
if (pll_bel.index != -1) { // if (pll_bel.index != -1) {
auto pll_cell = getBoundBelCell(pll_bel); // auto pll_cell = getBoundBelCell(pll_bel);
// Is a PLL placed in this PLL bel? // // Is a PLL placed in this PLL bel?
if (pll_cell != nullptr) { // if (pll_cell != nullptr) {
// Is the shared port driving a net? // // Is the shared port driving a net?
auto pi = pll_cell->ports[pll_bel_pin]; // auto pi = pll_cell->ports[pll_bel_pin];
if (pi.net != nullptr) { // if (pi.net != nullptr) {
// Are we perhaps a PAD INPUT Bel that can be placed here? // // Are we perhaps a PAD INPUT Bel that can be placed here?
if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { // if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) {
return true; // return true;
} // }
return false; // return false;
} // }
} // }
} // }
return getBelPackagePin(bel) != ""; // return getBelPackagePin(bel) != "";
} else if (cell->type == id_SB_GB) { // } else if (cell->type == id_SB_GB) {
NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); // NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr);
const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; // const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net;
IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); // IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT));
int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); // int glb_id = std::stoi(std::string("") + glb_net.str(this).back());
if (net->is_reset && net->is_enable) // if (net->is_reset && net->is_enable)
return false; // return false;
else if (net->is_reset) // else if (net->is_reset)
return (glb_id % 2) == 0; // return (glb_id % 2) == 0;
else if (net->is_enable) // else if (net->is_enable)
return (glb_id % 2) == 1; // return (glb_id % 2) == 1;
else // else
return true; // return true;
} else { // } else {
// TODO: IO cell clock checks // // TODO: IO cell clock checks
return true; return true;
} // }
} }
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -21,6 +21,9 @@
#error Include "archdefs.h" via "nextpnr.h" only. #error Include "archdefs.h" via "nextpnr.h" only.
#endif #endif
#include "torc/Architecture.hpp"
using namespace torc::architecture::xilinx;
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
typedef int delay_t; typedef int delay_t;
@ -62,7 +65,7 @@ enum ConstIds
struct BelId 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; }
bool operator!=(const BelId &other) const { return index != other.index; } bool operator!=(const BelId &other) const { return index != other.index; }