Fix for multiple id_SLICE_LUT6 per actual SLICE

This commit is contained in:
Eddie Hung 2018-08-17 23:05:12 -07:00
parent d05ac75fda
commit 17918b5992
4 changed files with 117 additions and 86 deletions

View File

@ -35,17 +35,36 @@ NEXTPNR_NAMESPACE_BEGIN
std::unique_ptr<const TorcInfo> torc_info; std::unique_ptr<const TorcInfo> torc_info;
TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName) 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<SiteIndex> TorcInfo::construct_bel_to_site_index(Arch* ctx, const Sites &sites)
{
std::vector<SiteIndex> 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<IdString> TorcInfo::construct_site_index_to_type(Arch* ctx, const Sites &sites) std::vector<IdString> TorcInfo::construct_site_index_to_type(Arch* ctx, const Sites &sites)
{ {
std::vector<IdString> site_index_to_type; std::vector<IdString> site_index_to_type;
site_index_to_type.resize(sites.getSiteCount()); site_index_to_type.resize(sites.getSiteCount());
for (SiteIndex i(0); i < sites.getSiteCount(); ++i) { for (SiteIndex i(0); i < sites.getSiteCount(); ++i) {
auto s = sites.getSite(i); const auto &s = sites.getSite(i);
auto pd = s.getPrimitiveDefPtr(); const auto &pd = s.getPrimitiveDefPtr();
auto type = pd->getName(); const auto &type = pd->getName();
if (type == "SLICEL" || type == "SLICEM") if (type == "SLICEL" || type == "SLICEM")
site_index_to_type[i] = id_SLICE_LUT6; site_index_to_type[i] = id_SLICE_LUT6;
else else
@ -53,20 +72,33 @@ std::vector<IdString> TorcInfo::construct_site_index_to_type(Arch* ctx, const Si
} }
return site_index_to_type; return site_index_to_type;
} }
std::vector<int8_t> TorcInfo::construct_site_index_to_z_offset(const Sites &sites, const std::vector<IdString> &site_index_to_type) std::vector<int8_t> TorcInfo::construct_bel_to_z(const Sites &sites, const int num_bels, const std::vector<IdString> &site_index_to_type)
{ {
std::vector<int8_t> site_index_to_z_offset; std::vector<int8_t> bel_to_z;
site_index_to_z_offset.resize(site_index_to_type.size()); bel_to_z.resize(num_bels);
int32_t bel_index = 0;
for (SiteIndex i(0); i < site_index_to_type.size(); ++i) { for (SiteIndex i(0); i < site_index_to_type.size(); ++i) {
if (site_index_to_type[i] == id_SLICE_LUT6) { if (site_index_to_type[i] == id_SLICE_LUT6) {
auto site = sites.getSite(i); auto site = sites.getSite(i);
auto site_name = site.getName(); auto site_name = site.getName();
auto site_name_back = site_name.back(); 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') if (site_name_back == '0' || site_name_back == '2' || site_name_back == '4' || site_name_back == '6' || site_name_back == '8') {
site_index_to_z_offset[i] = 4; 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) // if (package_info == nullptr)
// log_error("Unsupported package '%s'.\n", args.package.c_str()); // 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; BelId bel;
if (bel_by_loc.empty()) { 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; BelId b;
b.index = i; 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; bel_by_loc[getBelLocation(b)] = b;
} }
} }
@ -168,14 +191,13 @@ BelRange Arch::getBelsByTile(int x, int y) const
{ {
BelRange br; BelRange br;
auto b = getBelByLocation(Loc(x, y, 0)); br.b.cursor = Arch::getBelByLocation(Loc(x, y, 0)).index;
br.b.index = b.index; br.e.cursor = br.b.cursor;
br.b.pos = b.pos;
br.e = br.b;
if (br.e.index != SiteIndex(torc_info->sites.getSiteCount())) { if (br.e.cursor != -1) {
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()) while (br.e.cursor < chip_info->num_bels && chip_info->bel_data[br.e.cursor].x == x &&
br.e++; chip_info->bel_data[br.e.cursor].y == y)
br.e.cursor++;
} }
return br; return br;
@ -213,17 +235,25 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{ {
WireId ret; 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); 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 // 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') if (pin_name[0] == 'I' || pin_name[0] == 'O') {
pin_name[0] = bel.pos; 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); ret.index = site.getPinTilewire(pin_name);
if (ret.index.isUndefined()) 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()); // 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 NEXTPNR_NAMESPACE_END

View File

@ -240,56 +240,57 @@ struct TorcInfo {
const Sites &sites; const Sites &sites;
const Tiles &tiles; const Tiles &tiles;
SiteIndex sites_begin() const { return SiteIndex(0); } const TileInfo& bel_to_tile_info(int32_t index) const {
SiteIndex sites_end() const { return SiteIndex(sites.getSiteCount()); } auto si = bel_to_site_index[index];
const TileInfo& site_index_to_tile_info(SiteIndex si) const {
auto &site = sites.getSite(si); auto &site = sites.getSite(si);
return tiles.getTileInfo(site.getTileIndex()); 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(); return sites.getSite(si).getName();
} }
const std::vector<SiteIndex> bel_to_site_index;
const int num_bels;
const std::vector<IdString> site_index_to_type; const std::vector<IdString> site_index_to_type;
const std::vector<int8_t> site_index_to_z_offset; const std::vector<int8_t> bel_to_z;
private: private:
static std::vector<SiteIndex> construct_bel_to_site_index(Arch *ctx, const Sites &sites);
static std::vector<IdString> construct_site_index_to_type(Arch *ctx, const Sites &sites); static std::vector<IdString> construct_site_index_to_type(Arch *ctx, const Sites &sites);
static std::vector<int8_t> construct_site_index_to_z_offset(const Sites &sites, const std::vector<IdString> &site_index_to_type); static std::vector<int8_t> construct_bel_to_z(const Sites &sites, const int num_bels, const std::vector<IdString> &site_index_to_type);
}; };
extern std::unique_ptr<const TorcInfo> torc_info; extern std::unique_ptr<const TorcInfo> torc_info;
/************************ End of chipdb section. ************************/ /************************ End of chipdb section. ************************/
struct BelIterator : public BelId struct BelIterator
{ {
int cursor;
BelIterator operator++() BelIterator operator++()
{ {
if (pos >= A && pos < D) { cursor++;
++pos;
return *this;
}
if (torc_info->site_index_to_type[++index] == id_SLICE_LUT6)
pos = A;
else
pos = NOT_APPLICABLE;
return *this; return *this;
} }
BelIterator operator++(int) BelIterator operator++(int)
{ {
BelIterator prior(*this); BelIterator prior(*this);
operator++(); cursor++;
return prior; 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 struct BelRange
@ -447,12 +448,19 @@ struct Arch : BaseCtx
IdString getBelName(BelId bel) const IdString getBelName(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
auto name = torc_info->site_index_to_name(bel.index); auto name = torc_info->bel_to_name(bel.index);
if (torc_info->site_index_to_type[bel.index] == id_SLICE_LUT6) { 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 // Append LUT name to name
name.reserve(name.size() + 2); name.reserve(name.size() + 2);
name += "_"; 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); return id(name);
} }
@ -503,23 +511,19 @@ struct Arch : BaseCtx
BelRange getBels() const BelRange getBels() const
{ {
BelRange range; BelRange range;
range.b.index = torc_info->sites_begin(); range.b.cursor = 0;
range.e.index = torc_info->sites_end(); range.e.cursor = torc_info->num_bels;
return range; return range;
} }
Loc getBelLocation(BelId bel) const 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 loc;
loc.x = tile_info.getCol(); loc.x = tile_info.getCol();
loc.y = tile_info.getRow(); loc.y = tile_info.getRow();
if (torc_info->site_index_to_type[bel.index] == id_SLICE_LUT6) { loc.z = torc_info->bel_to_z[bel.index];
loc.z = bel.pos - 'A';
// Apply offset if upper slice
loc.z += torc_info->site_index_to_z_offset[bel.index];
}
return loc; return loc;
} }
@ -531,7 +535,8 @@ struct Arch : BaseCtx
IdString getBelType(BelId bel) const IdString getBelType(BelId bel) const
{ {
NPNR_ASSERT(bel != BelId()); 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; WireId getBelPinWire(BelId bel, IdString pin) const;

View File

@ -66,13 +66,11 @@ enum ConstIds
struct BelId struct BelId
{ {
SiteIndex index = SiteIndex(-1); int32_t index = -1;
enum bel : int8_t { NOT_APPLICABLE, A='A', B='B', C='C', D='D' } pos = NOT_APPLICABLE;
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 || pos != pos; } bool operator!=(const BelId &other) const { return index != other.index; }
}; };
void operator++(BelId::bel &b);
struct WireId struct WireId
{ {

View File

@ -37,7 +37,7 @@ void write_xdl(const Context *ctx, std::ostream &out)
XdlExporter exporter(out); XdlExporter exporter(out);
auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), "clg484", "", ""); auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), "clg484", "", "");
std::map<SiteIndex,InstanceSharedPtr> site_to_instance; std::unordered_map<int32_t,InstanceSharedPtr> site_to_instance;
for (const auto& cell : ctx->cells) { for (const auto& cell : ctx->cells) {
const char* type; 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 if (cell.second->type == id_BUFGCTRL) type = "BUFGCTRL";
else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); 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; InstanceSharedPtr instPtr;
if (ret.second) { if (ret.second) {
instPtr = Factory::newInstancePtr(cell.second->name.str(ctx), type, "", ""); instPtr = Factory::newInstancePtr(cell.second->name.str(ctx), type, "", "");
@ -54,15 +55,22 @@ void write_xdl(const Context *ctx, std::ostream &out)
assert(b); assert(b);
ret.first->second = instPtr; 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->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 else
instPtr = ret.first->second; instPtr = ret.first->second;
if (cell.second->type == id_SLICE_LUT6) { 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"; config += "6LUT";
instPtr->setConfig(config, cell.second->name.str(ctx), "#LUT:O6="); instPtr->setConfig(config, cell.second->name.str(ctx), "#LUT:O6=");
} }