Update FPGA interchange to use IdStringList.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
083f6afb1c
commit
78737ab01d
@ -35,13 +35,6 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
static std::pair<std::string, std::string> split_identifier_name(const std::string &name)
|
||||
{
|
||||
size_t first_slash = name.find('/');
|
||||
NPNR_ASSERT(first_slash != std::string::npos);
|
||||
return std::make_pair(name.substr(0, first_slash), name.substr(first_slash + 1));
|
||||
};
|
||||
|
||||
static std::pair<std::string, std::string> split_identifier_name_dot(const std::string &name)
|
||||
{
|
||||
size_t first_dot = name.find('.');
|
||||
@ -103,7 +96,7 @@ void Arch::setup_byname() const
|
||||
{
|
||||
if (tile_by_name.empty()) {
|
||||
for (int i = 0; i < chip_info->num_tiles; i++) {
|
||||
tile_by_name[chip_info->tiles[i].name.get()] = i;
|
||||
tile_by_name[id(chip_info->tiles[i].name.get())] = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,24 +106,25 @@ void Arch::setup_byname() const
|
||||
auto &tile_type = chip_info->tile_types[tile.type];
|
||||
for (int j = 0; j < tile_type.number_sites; j++) {
|
||||
auto &site = chip_info->sites[tile.sites[j]];
|
||||
site_by_name[site.name.get()] = std::make_pair(i, j);
|
||||
site_by_name[id(site.name.get())] = std::make_pair(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BelId Arch::getBelByName(IdString name) const
|
||||
BelId Arch::getBelByName(IdStringList name) const
|
||||
{
|
||||
BelId ret;
|
||||
if(name.ids.size() != 2) {
|
||||
return BelId();
|
||||
}
|
||||
|
||||
setup_byname();
|
||||
|
||||
auto split = split_identifier_name(name.str(this));
|
||||
|
||||
int tile, site;
|
||||
std::tie(tile, site) = site_by_name.at(split.first);
|
||||
std::tie(tile, site) = site_by_name.at(name.ids[0]);
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
IdString belname = id(split.second);
|
||||
IdString belname = name.ids[1];
|
||||
for (int i = 0; i < tile_info.num_bels; i++) {
|
||||
if (tile_info.bel_data[i].site == site && tile_info.bel_data[i].name == belname.index) {
|
||||
ret.tile = tile;
|
||||
@ -191,23 +185,22 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
WireId Arch::getWireByName(IdString name) const
|
||||
WireId Arch::getWireByName(IdStringList name) const
|
||||
{
|
||||
if (wire_by_name_cache.count(name))
|
||||
return wire_by_name_cache.at(name);
|
||||
|
||||
WireId ret;
|
||||
if(name.ids.size() != 2) {
|
||||
return WireId();
|
||||
}
|
||||
|
||||
setup_byname();
|
||||
|
||||
const std::string &s = name.str(this);
|
||||
auto sp = split_identifier_name(s);
|
||||
auto iter = site_by_name.find(sp.first);
|
||||
auto iter = site_by_name.find(name.ids[0]);
|
||||
if (iter != site_by_name.end()) {
|
||||
int tile;
|
||||
int site;
|
||||
std::tie(tile, site) = iter->second;
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
IdString wirename = id(sp.second);
|
||||
IdString wirename = name.ids[1];
|
||||
for (int i = 0; i < tile_info.num_wires; i++) {
|
||||
if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == wirename.index) {
|
||||
ret.tile = tile;
|
||||
@ -216,9 +209,9 @@ WireId Arch::getWireByName(IdString name) const
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int tile = tile_by_name.at(sp.first);
|
||||
int tile = tile_by_name.at(name.ids[0]);
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
IdString wirename = id(sp.second);
|
||||
IdString wirename = name.ids[1];
|
||||
for (int i = 0; i < tile_info.num_wires; i++) {
|
||||
if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == wirename.index) {
|
||||
int32_t node = chip_info->tiles[tile].tile_wire_to_node[i];
|
||||
@ -236,8 +229,6 @@ WireId Arch::getWireByName(IdString name) const
|
||||
}
|
||||
}
|
||||
|
||||
wire_by_name_cache[name] = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -249,51 +240,58 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
PipId Arch::getPipByName(IdString name) const
|
||||
PipId Arch::getPipByName(IdStringList name) const
|
||||
{
|
||||
// PIP name structure:
|
||||
// Tile PIP: <tile name>/<source wire name>.<destination wire name>
|
||||
// Site PIP: <site name>/<bel name>/<input bel pin name>
|
||||
// Site pin: <site name>/<bel name>
|
||||
// Psuedo site PIP: <site name>/<source wire name>.<destination wire name>
|
||||
|
||||
PipId ret;
|
||||
setup_byname();
|
||||
|
||||
const std::string &s = name.str(this);
|
||||
auto sp = split_identifier_name(s);
|
||||
auto iter = site_by_name.find(sp.first);
|
||||
if (iter != site_by_name.end()) {
|
||||
// This is either a site pip or site pin.
|
||||
if(name.ids.size() == 3) {
|
||||
// This is a Site PIP.
|
||||
IdString site_name = name.ids[0];
|
||||
IdString belname = name.ids[1];
|
||||
IdString pinname = name.ids[2];
|
||||
|
||||
int tile;
|
||||
int site;
|
||||
std::tie(tile, site) = iter->second;
|
||||
std::tie(tile, site) = site_by_name.at(site_name);
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
|
||||
// psuedo site pips are <site>/<src site wire>.<dst site wire>
|
||||
// site pips are <site>/<bel>/<pin>
|
||||
// site pins are <site>/<bel>
|
||||
auto split = sp.second.find('/');
|
||||
if(split != std::string::npos) {
|
||||
// This is a site pip!
|
||||
IdString belname = id(sp.second.substr(0, split));
|
||||
IdString pinname = id(sp.second.substr(split+1));
|
||||
BelId bel = getBelByName(id(sp.first + '/' + belname.str(this)));
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
std::array<IdString, 2> ids{name.ids[0], belname};
|
||||
BelId bel = getBelByName(IdStringList(ids));
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
|
||||
int pin_index = getBelPinIndex(bel, pinname);
|
||||
NPNR_ASSERT(pin_index >= 0);
|
||||
int pin_index = getBelPinIndex(bel, pinname);
|
||||
NPNR_ASSERT(pin_index >= 0);
|
||||
|
||||
for (int i = 0; i < tile_info.num_pips; i++) {
|
||||
if (tile_info.pip_data[i].site == site &&
|
||||
tile_info.pip_data[i].bel == bel.index &&
|
||||
tile_info.pip_data[i].extra_data == pin_index) {
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < tile_info.num_pips; i++) {
|
||||
if (tile_info.pip_data[i].site == site &&
|
||||
tile_info.pip_data[i].bel == bel.index &&
|
||||
tile_info.pip_data[i].extra_data == pin_index) {
|
||||
|
||||
PipId ret;
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
auto split = sp.second.find('.');
|
||||
}
|
||||
} else {
|
||||
auto iter = site_by_name.find(name.ids[0]);
|
||||
if (iter != site_by_name.end()) {
|
||||
// This is either a site pin or a psuedo site pip.
|
||||
// psuedo site pips are <site>/<src site wire>.<dst site wire>
|
||||
// site pins are <site>/<bel>
|
||||
int tile;
|
||||
int site;
|
||||
std::tie(tile, site) = iter->second;
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
|
||||
std::string pip_second = name.ids[1].str(this);
|
||||
auto split = pip_second.find('.');
|
||||
if(split == std::string::npos) {
|
||||
// This is a site pin!
|
||||
BelId bel = getBelByName(name);
|
||||
@ -302,17 +300,20 @@ PipId Arch::getPipByName(IdString name) const
|
||||
for (int i = 0; i < tile_info.num_pips; i++) {
|
||||
if (tile_info.pip_data[i].site == site &&
|
||||
tile_info.pip_data[i].bel == bel.index) {
|
||||
|
||||
PipId ret;
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is a psuedo site pip!
|
||||
IdString src_site_wire = id(sp.second.substr(0, split));
|
||||
IdString dst_site_wire = id(sp.second.substr(split+1));
|
||||
IdString src_site_wire = id(pip_second.substr(0, split));
|
||||
IdString dst_site_wire = id(pip_second.substr(split+1));
|
||||
int32_t src_index = -1;
|
||||
int32_t dst_index = -1;
|
||||
|
||||
for (int i = 0; i < tile_info.num_wires; i++) {
|
||||
if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == src_site_wire.index) {
|
||||
src_index = i;
|
||||
@ -335,55 +336,60 @@ PipId Arch::getPipByName(IdString name) const
|
||||
if (tile_info.pip_data[i].site == site &&
|
||||
tile_info.pip_data[i].src_index == src_index &&
|
||||
tile_info.pip_data[i].dst_index == dst_index) {
|
||||
|
||||
PipId ret;
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int tile = tile_by_name.at(name.ids[0]);
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
|
||||
std::string pip_second = name.ids[1].str(this);
|
||||
auto spn = split_identifier_name_dot(pip_second);
|
||||
auto src_wire_name = id(spn.first);
|
||||
auto dst_wire_name = id(spn.second);
|
||||
|
||||
int32_t src_index = -1;
|
||||
int32_t dst_index = -1;
|
||||
for (int i = 0; i < tile_info.num_wires; i++) {
|
||||
if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == src_wire_name.index) {
|
||||
src_index = i;
|
||||
if(dst_index != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == dst_wire_name.index) {
|
||||
dst_index = i;
|
||||
if(src_index != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int tile = tile_by_name.at(sp.first);
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
|
||||
auto spn = split_identifier_name_dot(sp.second);
|
||||
auto src_wire_name = id(spn.first);
|
||||
auto dst_wire_name = id(spn.second);
|
||||
NPNR_ASSERT(src_index != -1);
|
||||
NPNR_ASSERT(dst_index != -1);
|
||||
|
||||
int32_t src_index = -1;
|
||||
int32_t dst_index = -1;
|
||||
for (int i = 0; i < tile_info.num_wires; i++) {
|
||||
if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == src_wire_name.index) {
|
||||
src_index = i;
|
||||
if(dst_index != -1) {
|
||||
break;
|
||||
for (int i = 0; i < tile_info.num_pips; i++) {
|
||||
if (tile_info.pip_data[i].src_index == src_index &&
|
||||
tile_info.pip_data[i].dst_index == dst_index) {
|
||||
|
||||
PipId ret;
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (tile_info.wire_data[i].site == -1 && tile_info.wire_data[i].name == dst_wire_name.index) {
|
||||
dst_index = i;
|
||||
if(src_index != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NPNR_ASSERT(src_index != -1);
|
||||
NPNR_ASSERT(dst_index != -1);
|
||||
|
||||
for (int i = 0; i < tile_info.num_pips; i++) {
|
||||
if (tile_info.pip_data[i].src_index == src_index &&
|
||||
tile_info.pip_data[i].dst_index == dst_index) {
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return PipId();
|
||||
}
|
||||
|
||||
IdString Arch::getPipName(PipId pip) const
|
||||
IdStringList Arch::getPipName(PipId pip) const
|
||||
{
|
||||
// PIP name structure:
|
||||
// Tile PIP: <tile name>/<source wire name>.<destination wire name>
|
||||
@ -401,24 +407,30 @@ IdString Arch::getPipName(PipId pip) const
|
||||
IdString bel_name(bel.name);
|
||||
if(bel.category == BEL_CATEGORY_LOGIC) {
|
||||
// This is a psuedo pip
|
||||
IdString src_wire_name = IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].src_index].name);
|
||||
IdString dst_wire_name = IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].dst_index].name);
|
||||
return id(site.name.get() + std::string("/") + src_wire_name.str(this) + "." + dst_wire_name.str(this));
|
||||
IdString src_wire_name = IdString(tile_type.wire_data[pip_info.src_index].name);
|
||||
IdString dst_wire_name = IdString(tile_type.wire_data[pip_info.dst_index].name);
|
||||
IdString pip = id(src_wire_name.str(this) + "." + dst_wire_name.str(this));
|
||||
std::array<IdString, 2> ids{id(site.name.get()), pip};
|
||||
return IdStringList(ids);
|
||||
|
||||
} else if(bel.category == BEL_CATEGORY_ROUTING) {
|
||||
// This is a site pip.
|
||||
IdString pin_name(bel.ports[pip_info.extra_data]);
|
||||
return id(site.name.get() + std::string("/") + bel_name.str(this) + "/" + pin_name.str(this));
|
||||
std::array<IdString, 3> ids{id(site.name.get()), bel_name, pin_name};
|
||||
return IdStringList(ids);
|
||||
} else {
|
||||
NPNR_ASSERT(bel.category == BEL_CATEGORY_SITE_PORT);
|
||||
// This is a site pin, just the name of the BEL is a unique identifier.
|
||||
return id(site.name.get() + std::string("/") + bel_name.str(this));
|
||||
std::array<IdString, 2> ids{id(site.name.get()), bel_name};
|
||||
return IdStringList(ids);
|
||||
}
|
||||
} else {
|
||||
// This is a tile pip.
|
||||
return id(std::string(tile.name.get()) + "/" +
|
||||
IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].src_index].name).str(this) + "." +
|
||||
IdString(tile_type.wire_data[locInfo(pip).pip_data[pip.index].dst_index].name).str(this));
|
||||
IdString src_wire_name = IdString(tile_type.wire_data[pip_info.src_index].name);
|
||||
IdString dst_wire_name = IdString(tile_type.wire_data[pip_info.dst_index].name);
|
||||
IdString pip = id(src_wire_name.str(this) + "." + dst_wire_name.str(this));
|
||||
std::array<IdString, 2> ids{id(std::string(tile.name.get())), pip};
|
||||
return IdStringList(ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,6 @@
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
#include "fpga_interchange_generated_defs.h"
|
||||
|
||||
/**** Everything in this section must be kept in sync with chipdb.py ****/
|
||||
|
||||
template <typename T> struct RelPtr
|
||||
@ -705,8 +703,8 @@ struct Arch : BaseCtx
|
||||
boost::iostreams::mapped_file_source blob_file;
|
||||
const ChipInfoPOD *chip_info;
|
||||
|
||||
mutable std::unordered_map<std::string, int> tile_by_name;
|
||||
mutable std::unordered_map<std::string, std::pair<int, int>> site_by_name;
|
||||
mutable std::unordered_map<IdString, int> tile_by_name;
|
||||
mutable std::unordered_map<IdString, std::pair<int, int>> site_by_name;
|
||||
|
||||
std::unordered_map<WireId, NetInfo *> wire_to_net;
|
||||
std::unordered_map<PipId, NetInfo *> pip_to_net;
|
||||
@ -715,11 +713,10 @@ struct Arch : BaseCtx
|
||||
|
||||
struct TileStatus
|
||||
{
|
||||
std::bitset<kMaxNumberOfCells> bel_available;
|
||||
std::vector<CellInfo *> boundcells;
|
||||
};
|
||||
|
||||
std::unordered_map<TileStatus> tileStatus;
|
||||
std::vector<TileStatus> tileStatus;
|
||||
|
||||
ArchArgs args;
|
||||
Arch(ArchArgs args);
|
||||
@ -755,21 +752,22 @@ struct Arch : BaseCtx
|
||||
int getTilePipDimZ(int x, int y) const {
|
||||
return chip_info->tile_types[chip_info->tiles[getTileIndex(x, y)].type].number_sites;
|
||||
}
|
||||
char getNameDelimiter() const { return '/'; }
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
void setup_byname() const;
|
||||
|
||||
BelId getBelByName(IdString name) const;
|
||||
BelId getBelByName(IdStringList name) const;
|
||||
|
||||
IdString getBelName(BelId bel) const
|
||||
IdStringList getBelName(BelId bel) const
|
||||
{
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
int site_index = locInfo(bel).bel_data[bel.index].site;
|
||||
NPNR_ASSERT(site_index >= 0);
|
||||
const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[bel.tile].sites[site_index]];
|
||||
return id(std::string(site.name.get()) +
|
||||
"/" + IdString(locInfo(bel).bel_data[bel.index].name).str(this));
|
||||
std::array<IdString, 2> ids{id(site.name.get()), IdString(locInfo(bel).bel_data[bel.index].name)};
|
||||
return IdStringList(ids);
|
||||
}
|
||||
|
||||
uint32_t getBelChecksum(BelId bel) const { return bel.index; }
|
||||
@ -880,7 +878,7 @@ struct Arch : BaseCtx
|
||||
|
||||
IdStringRange str_range;
|
||||
str_range.b.cursor = &ports[0];
|
||||
str_range.b.cursor = &ports[num_bel_wires-1];
|
||||
str_range.e.cursor = &ports[num_bel_wires-1];
|
||||
|
||||
return str_range;
|
||||
}
|
||||
@ -889,9 +887,7 @@ struct Arch : BaseCtx
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
mutable std::unordered_map<IdString, WireId> wire_by_name_cache;
|
||||
|
||||
WireId getWireByName(IdString name) const;
|
||||
WireId getWireByName(IdStringList name) const;
|
||||
|
||||
const TileWireInfoPOD &wireInfo(WireId wire) const
|
||||
{
|
||||
@ -903,20 +899,21 @@ struct Arch : BaseCtx
|
||||
}
|
||||
}
|
||||
|
||||
IdString getWireName(WireId wire) const
|
||||
IdStringList getWireName(WireId wire) const
|
||||
{
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
if (wire.tile != -1 && locInfo(wire).wire_data[wire.index].site != -1) {
|
||||
int site_index = locInfo(wire).wire_data[wire.index].site;
|
||||
const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[wire.tile].sites[site_index]];
|
||||
return id(site.name.get() +
|
||||
std::string("/") + IdString(locInfo(wire).wire_data[wire.index].name).str(this));
|
||||
|
||||
std::array<IdString, 2> ids{id(site.name.get()), IdString(locInfo(wire).wire_data[wire.index].name)};
|
||||
return IdStringList(ids);
|
||||
} else {
|
||||
return id(std::string(chip_info
|
||||
->tiles[wire.tile == -1 ? chip_info->nodes[wire.index].tile_wires[0].tile
|
||||
: wire.tile]
|
||||
.name.get()) +
|
||||
"/" + IdString(wireInfo(wire).name).c_str(this));
|
||||
int32_t tile = wire.tile == -1 ? chip_info->nodes[wire.index].tile_wires[0].tile
|
||||
: wire.tile;
|
||||
IdString tile_name = id(chip_info->tiles[tile].name.get());
|
||||
std::array<IdString, 2> ids{tile_name, IdString(wireInfo(wire).name)};
|
||||
return IdStringList(ids);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1042,9 +1039,10 @@ struct Arch : BaseCtx
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
mutable std::unordered_map<IdString, PipId> pip_by_name_cache;
|
||||
|
||||
PipId getPipByName(IdString name) const;
|
||||
PipId getPipByName(IdStringList name) const;
|
||||
IdStringList getPipName(PipId pip) const;
|
||||
IdString getPipType(PipId pip) const;
|
||||
std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const;
|
||||
|
||||
void bindPip(PipId pip, NetInfo *net, PlaceStrength strength)
|
||||
{
|
||||
@ -1126,11 +1124,6 @@ struct Arch : BaseCtx
|
||||
return loc;
|
||||
}
|
||||
|
||||
IdString getPipName(PipId pip) const;
|
||||
|
||||
IdString getPipType(PipId pip) const;
|
||||
std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const;
|
||||
|
||||
uint32_t getPipChecksum(PipId pip) const { return pip.index; }
|
||||
|
||||
WireId getPipSrcWire(PipId pip) const
|
||||
@ -1185,8 +1178,8 @@ struct Arch : BaseCtx
|
||||
// -------------------------------------------------
|
||||
|
||||
// FIXME: Use groups to get access to sites.
|
||||
GroupId getGroupByName(IdString name) const { return GroupId(); }
|
||||
IdString getGroupName(GroupId group) const { return IdString(); }
|
||||
GroupId getGroupByName(IdStringList name) const { return GroupId(); }
|
||||
IdStringList getGroupName(GroupId group) const { return IdStringList(); }
|
||||
std::vector<GroupId> getGroups() const { return {}; }
|
||||
std::vector<BelId> getGroupBels(GroupId group) const { return {}; }
|
||||
std::vector<WireId> getGroupWires(GroupId group) const { return {}; }
|
||||
|
Loading…
Reference in New Issue
Block a user