[interchange] Fix site pip check for drivers.

Previous code allowed router to entire sites with no sinks.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2021-03-29 16:19:47 -07:00
parent 7a9082e698
commit 7e47af1085

View File

@ -1655,7 +1655,8 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
// If this pip is a route-though, make sure all of the route-though
// wires are unbound.
const PipInfoPOD &pip_data = pip_info(chip_info, pip);
const TileTypeInfoPOD &tile_type = loc_info(chip_info, pip);
const PipInfoPOD &pip_data = tile_type.pip_data[pip.index];
WireId wire;
wire.tile = pip.tile;
for (int32_t wire_index : pip_data.pseudo_cell_wires) {
@ -1676,23 +1677,37 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
}
if (pip_data.site != -1 && net != nullptr) {
// FIXME: This check isn't perfect. If a driver and sink are in the
// same site, it is possible for the router to route-thru the site
// ports without hitting a sink, which is not legal in the FPGA
// interchange.
NPNR_ASSERT(net->driver.cell != nullptr);
NPNR_ASSERT(net->driver.cell->bel != BelId());
auto &src_wire_data = tile_type.wire_data[pip_data.src_index];
auto &dst_wire_data = tile_type.wire_data[pip_data.dst_index];
bool valid_pip = false;
if (pip.tile == net->driver.cell->bel.tile) {
auto &bel_data = bel_info(chip_info, net->driver.cell->bel);
const BelInfoPOD &bel_data = tile_type.bel_data[net->driver.cell->bel.index];
if (bel_data.site == pip_data.site) {
valid_pip = true;
// Only allow site pips or output site ports.
if (dst_wire_data.site == -1) {
// Allow output site port from this site.
NPNR_ASSERT(src_wire_data.site == pip_data.site);
valid_pip = true;
}
if (dst_wire_data.site == bel_data.site && src_wire_data.site == bel_data.site) {
// This is site pip for the same site as the driver, allow
// this site pip.
valid_pip = true;
}
}
}
if (!valid_pip) {
// See if one users can enter this site.
auto &tile_type = loc_info(chip_info, pip);
auto &src_wire_data = tile_type.wire_data[pip_data.src_index];
auto &dst_wire_data = tile_type.wire_data[pip_data.dst_index];
if (dst_wire_data.site == -1) {
// This is an output site port, but not for the driver net.
// Disallow.