aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/arch.cc
diff options
context:
space:
mode:
authorKeith Rothman <537074+litghost@users.noreply.github.com>2021-03-29 16:19:47 -0700
committerKeith Rothman <537074+litghost@users.noreply.github.com>2021-03-30 10:04:18 -0700
commit7e47af10851274e495223f11e94547fe6aa7124f (patch)
treeefa675a1c8cb640c4aa1c12af19466a3f78cbc62 /fpga_interchange/arch.cc
parent7a9082e698d74823081a7f408502f700536bcf4a (diff)
downloadnextpnr-7e47af10851274e495223f11e94547fe6aa7124f.tar.gz
nextpnr-7e47af10851274e495223f11e94547fe6aa7124f.tar.bz2
nextpnr-7e47af10851274e495223f11e94547fe6aa7124f.zip
[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>
Diffstat (limited to 'fpga_interchange/arch.cc')
-rw-r--r--fpga_interchange/arch.cc29
1 files changed, 22 insertions, 7 deletions
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc
index 09e539e2..2e1c452a 100644
--- a/fpga_interchange/arch.cc
+++ b/fpga_interchange/arch.cc
@@ -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.