Fix BBA import bugs.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
1dd24f6461
commit
5a89dc58e1
@ -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.b.chip = chip_info;
|
||||
br.e.chip = chip_info;
|
||||
if (br.e.cursor_index == -1)
|
||||
++br.e.cursor_index;
|
||||
else
|
||||
|
||||
if(br.b != br.e) {
|
||||
++br.e;
|
||||
}
|
||||
return br;
|
||||
}
|
||||
|
||||
@ -156,36 +156,34 @@ WireId Arch::getBelPinWire(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) {
|
||||
const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get();
|
||||
int32_t wire_index = wires[i];
|
||||
int pin_index = getBelPinIndex(bel, pin);
|
||||
if(pin_index < 0) {
|
||||
// Port could not be found!
|
||||
return WireId();
|
||||
} else {
|
||||
const int32_t *wires = locInfo(bel).bel_data[bel.index].wires.get();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Port could not be found!
|
||||
return WireId();
|
||||
}
|
||||
|
||||
PortType Arch::getBelPinType(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) {
|
||||
const int32_t *types = locInfo(bel).bel_data[bel.index].types.get();
|
||||
return PortType(types[i]);
|
||||
}
|
||||
int pin_index = getBelPinIndex(bel, pin);
|
||||
if(pin_index < 0) {
|
||||
// Port could not be found!
|
||||
return PORT_INOUT;
|
||||
} else {
|
||||
const int32_t *types = locInfo(bel).bel_data[bel.index].types.get();
|
||||
return PortType(types[pin_index]);
|
||||
}
|
||||
|
||||
|
||||
return PORT_INOUT;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
@ -250,29 +248,95 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co
|
||||
|
||||
PipId Arch::getPipByName(IdString name) const
|
||||
{
|
||||
if (pip_by_name_cache.count(name))
|
||||
return pip_by_name_cache.at(name);
|
||||
// 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>
|
||||
|
||||
PipId ret;
|
||||
setup_byname();
|
||||
|
||||
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);
|
||||
if (iter != site_by_name.end()) {
|
||||
// This is either a site pip or site pin.
|
||||
int tile;
|
||||
int site;
|
||||
std::tie(tile, site) = iter->second;
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
auto sp3 = split_identifier_name(sp.second);
|
||||
IdString belname = id(sp3.first);
|
||||
IdString pinname = id(sp3.second);
|
||||
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 &&
|
||||
tile_info.pip_data[i].extra_data == pinname.index) {
|
||||
ret.tile = tile;
|
||||
ret.index = i;
|
||||
break;
|
||||
|
||||
// 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());
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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 {
|
||||
@ -280,11 +344,32 @@ PipId Arch::getPipByName(IdString name) const
|
||||
auto &tile_info = chip_info->tile_types[chip_info->tiles[tile].type];
|
||||
|
||||
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++) {
|
||||
if (tile_info.pip_data[i].src_index == fromwire &&
|
||||
tile_info.pip_data[i].dst_index == towire) {
|
||||
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;
|
||||
@ -292,23 +377,45 @@ PipId Arch::getPipByName(IdString name) const
|
||||
}
|
||||
}
|
||||
|
||||
pip_by_name_cache[name] = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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());
|
||||
if (locInfo(pip).pip_data[pip.index].site != -1) {
|
||||
auto site_index = chip_info->tiles[pip.tile].sites[locInfo(pip).pip_data[pip.index].site];
|
||||
auto &site = chip_info->sites[site_index];
|
||||
return id(site.name.get() + std::string("/") + IdString(locInfo(pip).pip_data[pip.index].bel).str(this) + "/" +
|
||||
IdString(locInfo(pip).wire_data[locInfo(pip).pip_data[pip.index].src_index].name).str(this));
|
||||
auto &tile = chip_info->tiles[pip.tile];
|
||||
auto &tile_type = locInfo(pip);
|
||||
auto &pip_info = tile_type.pip_data[pip.index];
|
||||
if (pip_info.site != -1) {
|
||||
// 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 {
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
return id(std::string(chip_info->tiles[pip.tile].name.get()) + "/" +
|
||||
std::to_string(locInfo(pip).pip_data[pip.index].src_index) + "." +
|
||||
std::to_string(locInfo(pip).pip_data[pip.index].dst_index));
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,15 +77,24 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD {
|
||||
|
||||
int32_t num_bel_wires;
|
||||
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
|
||||
|
||||
int16_t site;
|
||||
int16_t site_variant; // some sites have alternative types
|
||||
int16_t is_routing;
|
||||
int16_t category;
|
||||
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 {
|
||||
int32_t bel_index;
|
||||
int32_t port;
|
||||
@ -255,8 +264,16 @@ struct TileWireIterator
|
||||
WireId baseWire;
|
||||
int cursor = -1;
|
||||
|
||||
void operator++() { cursor++; }
|
||||
bool operator!=(const TileWireIterator &other) const { return cursor != other.cursor; }
|
||||
void operator++() {
|
||||
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
|
||||
WireId operator*() const
|
||||
@ -505,13 +522,13 @@ struct BelPinIterator
|
||||
void operator++()
|
||||
{
|
||||
cursor++;
|
||||
while (true) {
|
||||
if (!(twi != twi_end))
|
||||
break;
|
||||
|
||||
while (twi != twi_end) {
|
||||
WireId w = *twi;
|
||||
auto &tile = tileInfo(chip, w.tile);
|
||||
if (cursor < tile.wire_data[w.index].num_bel_pins)
|
||||
break;
|
||||
|
||||
++twi;
|
||||
cursor = 0;
|
||||
}
|
||||
@ -606,7 +623,7 @@ struct Arch : BaseCtx
|
||||
{
|
||||
NPNR_ASSERT(bel != BelId());
|
||||
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]];
|
||||
return id(std::string(site.name.get()) +
|
||||
"/" + IdString(locInfo(bel).bel_data[bel.index].name).str(this));
|
||||
@ -683,7 +700,9 @@ struct Arch : BaseCtx
|
||||
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
|
||||
{
|
||||
@ -693,6 +712,19 @@ struct Arch : BaseCtx
|
||||
|
||||
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;
|
||||
PortType getBelPinType(BelId bel, IdString pin) const;
|
||||
std::vector<IdString> getBelPins(BelId bel) const;
|
||||
@ -813,10 +845,11 @@ struct Arch : BaseCtx
|
||||
|
||||
range.e.chip = chip_info;
|
||||
range.e.baseWire = wire;
|
||||
if (wire.tile == -1)
|
||||
if (wire.tile == -1) {
|
||||
range.e.cursor = chip_info->nodes[wire.index].num_tile_wires;
|
||||
else
|
||||
} else {
|
||||
range.e.cursor = 1;
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
@ -824,12 +857,14 @@ struct Arch : BaseCtx
|
||||
{
|
||||
BelPinRange range;
|
||||
NPNR_ASSERT(wire != WireId());
|
||||
|
||||
TileWireRange twr = getTileWireRange(wire);
|
||||
range.b.chip = chip_info;
|
||||
range.b.twi = twr.b;
|
||||
range.b.twi_end = twr.e;
|
||||
range.b.cursor = -1;
|
||||
++range.b;
|
||||
|
||||
range.e.chip = chip_info;
|
||||
range.e.twi = twr.e;
|
||||
range.e.twi_end = twr.e;
|
||||
@ -991,16 +1026,6 @@ struct Arch : BaseCtx
|
||||
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(); }
|
||||
|
Loading…
Reference in New Issue
Block a user