Fix BBA import bugs.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2021-01-27 18:00:43 -08:00
parent 1dd24f6461
commit 5a89dc58e1
2 changed files with 201 additions and 69 deletions

View File

@ -145,10 +145,10 @@ BelRange Arch::getBelsByTile(int x, int y) const
br.e.cursor_index = chip_info->tile_types[chip_info->tiles[br.b.cursor_tile].type].num_bels; br.e.cursor_index = chip_info->tile_types[chip_info->tiles[br.b.cursor_tile].type].num_bels;
br.b.chip = chip_info; br.b.chip = chip_info;
br.e.chip = chip_info; br.e.chip = chip_info;
if (br.e.cursor_index == -1)
++br.e.cursor_index; if(br.b != br.e) {
else
++br.e; ++br.e;
}
return br; return br;
} }
@ -156,36 +156,34 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires; int pin_index = getBelPinIndex(bel, pin);
const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get(); if(pin_index < 0) {
for (int i = 0; i < num_bel_wires; i++) { // Port could not be found!
if (ports[i] == pin.index) { return WireId();
} else {
const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get(); const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get();
int32_t wire_index = wires[i]; int32_t wire_index = wires[pin_index];
if(wire_index < 0) {
// This BEL pin is not connected.
return WireId();
} else {
return canonicalWireId(chip_info, bel.tile, wire_index); return canonicalWireId(chip_info, bel.tile, wire_index);
} }
} }
// Port could not be found!
return WireId();
} }
PortType Arch::getBelPinType(BelId bel, IdString pin) const PortType Arch::getBelPinType(BelId bel, IdString pin) const
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires; int pin_index = getBelPinIndex(bel, pin);
const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get(); if(pin_index < 0) {
// Port could not be found!
for (int i = 0; i < num_bel_wires; i++) {
if (ports[i] == pin.index) {
const int32_t *types = locInfo(bel).bel_data[bel.index].types.get();
return PortType(types[i]);
}
}
return PORT_INOUT; return PORT_INOUT;
} else {
const int32_t *types = locInfo(bel).bel_data[bel.index].types.get();
return PortType(types[pin_index]);
}
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -250,41 +248,128 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co
PipId Arch::getPipByName(IdString name) const PipId Arch::getPipByName(IdString name) const
{ {
if (pip_by_name_cache.count(name)) // PIP name structure:
return pip_by_name_cache.at(name); // 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>
PipId ret; PipId ret;
setup_byname(); setup_byname();
const std::string &s = name.str(this); const std::string &s = name.str(this);
auto sp = split_identifier_name(s.substr(8)); auto sp = split_identifier_name(s);
auto iter = site_by_name.find(sp.first); auto iter = site_by_name.find(sp.first);
if (iter != site_by_name.end()) { if (iter != site_by_name.end()) {
// This is either a site pip or site pin.
int tile; int tile;
int site; int site;
std::tie(tile, site) = iter->second; std::tie(tile, site) = iter->second;
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
auto sp3 = split_identifier_name(sp.second);
IdString belname = id(sp3.first); // psuedo site pips are <site>/<src site wire>.<dst site wire>
IdString pinname = id(sp3.second); // 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());
int pin_index = getBelPinIndex(bel, pinname);
NPNR_ASSERT(pin_index >= 0);
for (int i = 0; i < tile_info.num_pips; i++) { for (int i = 0; i < tile_info.num_pips; i++) {
if (tile_info.pip_data[i].site == site && tile_info.pip_data[i].bel == belname.index && if (tile_info.pip_data[i].site == site &&
tile_info.pip_data[i].extra_data == pinname.index) { tile_info.pip_data[i].bel == bel.index &&
tile_info.pip_data[i].extra_data == pin_index) {
ret.tile = tile; ret.tile = tile;
ret.index = i; ret.index = i;
break; break;
} }
} }
} else {
auto split = sp.second.find('.');
if(split == std::string::npos) {
// This is a site pin!
BelId bel = getBelByName(name);
NPNR_ASSERT(bel != BelId());
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) {
ret.tile = tile;
ret.index = i;
break;
}
}
} 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));
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;
if(dst_index != -1) {
break;
}
}
if (tile_info.wire_data[i].site == site && tile_info.wire_data[i].name == dst_site_wire.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].site == site &&
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;
}
}
}
}
} else { } else {
int tile = tile_by_name.at(sp.first); int tile = tile_by_name.at(sp.first);
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type]; auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
auto spn = split_identifier_name_dot(sp.second); auto spn = split_identifier_name_dot(sp.second);
int fromwire = std::stoi(spn.first), towire = std::stoi(spn.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;
}
}
}
NPNR_ASSERT(src_index != -1);
NPNR_ASSERT(dst_index != -1);
for (int i = 0; i < tile_info.num_pips; i++) { for (int i = 0; i < tile_info.num_pips; i++) {
if (tile_info.pip_data[i].src_index == fromwire && if (tile_info.pip_data[i].src_index == src_index &&
tile_info.pip_data[i].dst_index == towire) { tile_info.pip_data[i].dst_index == dst_index) {
ret.tile = tile; ret.tile = tile;
ret.index = i; ret.index = i;
break; break;
@ -292,23 +377,45 @@ PipId Arch::getPipByName(IdString name) const
} }
} }
pip_by_name_cache[name] = ret;
return ret; return ret;
} }
IdString Arch::getPipName(PipId pip) const IdString Arch::getPipName(PipId pip) const
{ {
// PIP name structure:
// Tile PIP: <tile name>/<source wire name>.<destination wire name>
// Psuedo site PIP: <site name>/<input site wire>.<output site wire>
// Site PIP: <site name>/<bel name>/<input bel pin name>
// Site pin: <site name>/<bel name>
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
if (locInfo(pip).pip_data[pip.index].site != -1) { auto &tile = chip_info->tiles[pip.tile];
auto site_index = chip_info->tiles[pip.tile].sites[locInfo(pip).pip_data[pip.index].site]; auto &tile_type = locInfo(pip);
auto &site = chip_info->sites[site_index]; auto &pip_info = tile_type.pip_data[pip.index];
return id(site.name.get() + std::string("/") + IdString(locInfo(pip).pip_data[pip.index].bel).str(this) + "/" + if (pip_info.site != -1) {
IdString(locInfo(pip).wire_data[locInfo(pip).pip_data[pip.index].src_index].name).str(this)); // This is either a site pin or a site pip.
auto &site = chip_info->sites[tile.sites[pip_info.site]];
auto &bel = tile_type.bel_data[pip_info.bel];
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));
} 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));
} else { } else {
return id(std::string(chip_info->tiles[pip.tile].name.get()) + "/" + NPNR_ASSERT(bel.category == BEL_CATEGORY_SITE_PORT);
std::to_string(locInfo(pip).pip_data[pip.index].src_index) + "." + // This is a site pin, just the name of the BEL is a unique identifier.
std::to_string(locInfo(pip).pip_data[pip.index].dst_index)); return id(site.name.get() + std::string("/") + bel_name.str(this));
}
} 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));
} }
} }

View File

@ -77,15 +77,24 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
int32_t num_bel_wires; int32_t num_bel_wires;
RelPtr<int32_t> ports; // port name constid RelPtr<int32_t> ports; // port name constid
RelPtr<int32_t> types; // port name (IN/OUT/BIDIR) RelPtr<int32_t> types; // port type (IN/OUT/BIDIR)
RelPtr<int32_t> wires; // connected wire index in tile, or -1 if NA RelPtr<int32_t> wires; // connected wire index in tile, or -1 if NA
int16_t site; int16_t site;
int16_t site_variant; // some sites have alternative types int16_t site_variant; // some sites have alternative types
int16_t is_routing; int16_t category;
int16_t padding; int16_t padding;
}); });
enum BELCategory {
// BEL is a logic element
BEL_CATEGORY_LOGIC = 0,
// BEL is a site routing mux
BEL_CATEGORY_ROUTING = 1,
// BEL is a site port, e.g. boundry between site and routing graph.
BEL_CATEGORY_SITE_PORT = 2
};
NPNR_PACKED_STRUCT(struct BelPortPOD { NPNR_PACKED_STRUCT(struct BelPortPOD {
int32_t bel_index; int32_t bel_index;
int32_t port; int32_t port;
@ -255,8 +264,16 @@ struct TileWireIterator
WireId baseWire; WireId baseWire;
int cursor = -1; int cursor = -1;
void operator++() { cursor++; } void operator++() {
bool operator!=(const TileWireIterator &other) const { return cursor != other.cursor; } cursor++;
}
bool operator==(const TileWireIterator &other) const {
return cursor == other.cursor;
}
bool operator!=(const TileWireIterator &other) const {
return cursor != other.cursor;
}
// Returns a *denormalised* identifier always pointing to a tile wire rather than a node // Returns a *denormalised* identifier always pointing to a tile wire rather than a node
WireId operator*() const WireId operator*() const
@ -505,13 +522,13 @@ struct BelPinIterator
void operator++() void operator++()
{ {
cursor++; cursor++;
while (true) {
if (!(twi != twi_end)) while (twi != twi_end) {
break;
WireId w = *twi; WireId w = *twi;
auto &tile = tileInfo(chip, w.tile); auto &tile = tileInfo(chip, w.tile);
if (cursor < tile.wire_data[w.index].num_bel_pins) if (cursor < tile.wire_data[w.index].num_bel_pins)
break; break;
++twi; ++twi;
cursor = 0; cursor = 0;
} }
@ -606,7 +623,7 @@ struct Arch : BaseCtx
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
int site_index = locInfo(bel).bel_data[bel.index].site; int site_index = locInfo(bel).bel_data[bel.index].site;
NPNR_ASSERT(site_index != -1); NPNR_ASSERT(site_index >= 0);
const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[bel.tile].sites[site_index]]; const SiteInstInfoPOD &site = chip_info->sites[chip_info->tiles[bel.tile].sites[site_index]];
return id(std::string(site.name.get()) + return id(std::string(site.name.get()) +
"/" + IdString(locInfo(bel).bel_data[bel.index].name).str(this)); "/" + IdString(locInfo(bel).bel_data[bel.index].name).str(this));
@ -683,7 +700,9 @@ struct Arch : BaseCtx
return false; return false;
} }
bool getBelHidden(BelId bel) const { return locInfo(bel).bel_data[bel.index].is_routing; } bool getBelHidden(BelId bel) const {
return locInfo(bel).bel_data[bel.index].category != BEL_CATEGORY_LOGIC;
}
IdString getBelType(BelId bel) const IdString getBelType(BelId bel) const
{ {
@ -693,6 +712,19 @@ struct Arch : BaseCtx
std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const; std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const;
int getBelPinIndex(BelId bel, IdString pin) const {
NPNR_ASSERT(bel != BelId());
int num_bel_wires = locInfo(bel).bel_data[bel.index].num_bel_wires;
const int32_t *ports = locInfo(bel).bel_data[bel.index].ports.get();
for (int i = 0; i < num_bel_wires; i++) {
if (ports[i] == pin.index) {
return i;
}
}
return -1;
}
WireId getBelPinWire(BelId bel, IdString pin) const; WireId getBelPinWire(BelId bel, IdString pin) const;
PortType getBelPinType(BelId bel, IdString pin) const; PortType getBelPinType(BelId bel, IdString pin) const;
std::vector<IdString> getBelPins(BelId bel) const; std::vector<IdString> getBelPins(BelId bel) const;
@ -813,10 +845,11 @@ struct Arch : BaseCtx
range.e.chip = chip_info; range.e.chip = chip_info;
range.e.baseWire = wire; range.e.baseWire = wire;
if (wire.tile == -1) if (wire.tile == -1) {
range.e.cursor = chip_info->nodes[wire.index].num_tile_wires; range.e.cursor = chip_info->nodes[wire.index].num_tile_wires;
else } else {
range.e.cursor = 1; range.e.cursor = 1;
}
return range; return range;
} }
@ -824,12 +857,14 @@ struct Arch : BaseCtx
{ {
BelPinRange range; BelPinRange range;
NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire != WireId());
TileWireRange twr = getTileWireRange(wire); TileWireRange twr = getTileWireRange(wire);
range.b.chip = chip_info; range.b.chip = chip_info;
range.b.twi = twr.b; range.b.twi = twr.b;
range.b.twi_end = twr.e; range.b.twi_end = twr.e;
range.b.cursor = -1; range.b.cursor = -1;
++range.b; ++range.b;
range.e.chip = chip_info; range.e.chip = chip_info;
range.e.twi = twr.e; range.e.twi = twr.e;
range.e.twi_end = twr.e; range.e.twi_end = twr.e;
@ -991,16 +1026,6 @@ struct Arch : BaseCtx
return range; return range;
} }
UphillPipRange getWireAliases(WireId wire) const
{
UphillPipRange range;
range.b.cursor = 0;
range.b.twi.cursor = 0;
range.e.cursor = 0;
range.e.twi.cursor = 0;
return range;
}
// ------------------------------------------------- // -------------------------------------------------
GroupId getGroupByName(IdString name) const { return GroupId(); } GroupId getGroupByName(IdString name) const { return GroupId(); }