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
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<GraphicElement> 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);

View File

@ -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<CellTimingPOD> 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<const Site>::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<const WireIndex>::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<IdString, int> bel_by_name;
mutable std::unordered_map<IdString, int> wire_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<CellInfo *> 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;
}

View File

@ -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<const CellInfo *, 8> 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<const CellInfo *, 8> 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

View File

@ -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; }