aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange
diff options
context:
space:
mode:
authorAlessandro Comodi <acomodi@antmicro.com>2021-05-12 18:25:47 +0200
committerAlessandro Comodi <acomodi@antmicro.com>2021-05-13 11:00:42 +0200
commit8c468acff8900f40e909882cfbf9381a59199b79 (patch)
treebd1b8dba70b86034fae4adb61f1cb2d10140fb49 /fpga_interchange
parentfd93697a2d4eca02fc5091a15a497f7a761f251a (diff)
downloadnextpnr-8c468acff8900f40e909882cfbf9381a59199b79.tar.gz
nextpnr-8c468acff8900f40e909882cfbf9381a59199b79.tar.bz2
nextpnr-8c468acff8900f40e909882cfbf9381a59199b79.zip
interchange: site router: add valid pips list to check during routing
Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
Diffstat (limited to 'fpga_interchange')
-rw-r--r--fpga_interchange/arch.cc26
-rw-r--r--fpga_interchange/site_router.cc43
-rw-r--r--fpga_interchange/site_router.h1
3 files changed, 59 insertions, 11 deletions
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc
index ad4d90e8..a05878f6 100644
--- a/fpga_interchange/arch.cc
+++ b/fpga_interchange/arch.cc
@@ -1776,15 +1776,15 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
}
}
+ auto tile_status_iter = tileStatus.find(pip.tile);
+
if (pip_data.pseudo_cell_wires.size() > 0) {
// FIXME: This pseudo pip check is incomplete, because constraint
// failures will not be detected. However the current FPGA
// interchange schema does not provide a cell type to place.
- auto iter = tileStatus.find(pip.tile);
- if (iter != tileStatus.end()) {
- if (!iter->second.pseudo_pip_model.checkPipAvail(getCtx(), pip)) {
- return false;
- }
+ if (tile_status_iter != tileStatus.end() &&
+ !tile_status_iter->second.pseudo_pip_model.checkPipAvail(getCtx(), pip)) {
+ return false;
}
}
@@ -1797,12 +1797,16 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
bool valid_pip = false;
if (pip.tile == net->driver.cell->bel.tile) {
- const BelInfoPOD &bel_data = tile_type.bel_data[net->driver.cell->bel.index];
- if (bel_data.site == pip_data.site) {
- // 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);
+ if (tile_status_iter == tileStatus.end()) {
+ // there is no tile status and nothing blocks the validity of this PIP
+ valid_pip = true;
+ } else {
+ const BelInfoPOD &bel_data = tile_type.bel_data[net->driver.cell->bel.index];
+ const SiteRouter &site_router = get_site_status(tile_status_iter->second, bel_data);
+
+ const auto& pips = site_router.valid_pips;
+ auto result = std::find(pips.begin(), pips.end(), pip);
+ if (result != pips.end()) {
valid_pip = true;
}
}
diff --git a/fpga_interchange/site_router.cc b/fpga_interchange/site_router.cc
index e9b3f61f..da46a166 100644
--- a/fpga_interchange/site_router.cc
+++ b/fpga_interchange/site_router.cc
@@ -1070,6 +1070,47 @@ static void block_lut_outputs(SiteArch *site_arch,
}
}
+// Recursively visit downhill PIPs until a SITE_PORT_SINK is reached.
+// Marks all PIPs for all valid paths.
+static bool visit_downhill_pips(const SiteArch *site_arch, const SiteWire &site_wire, std::vector<PipId> &valid_pips) {
+ bool valid_path_exists = false;
+ for (SitePip site_pip : site_arch->getPipsDownhill(site_wire)) {
+ const SiteWire &dst_wire = site_arch->getPipDstWire(site_pip);
+ if (dst_wire.type == SiteWire::SITE_PORT_SINK) {
+ valid_pips.push_back(site_pip.pip);
+ return true;
+ }
+
+ bool path_ok = visit_downhill_pips(site_arch, dst_wire, valid_pips);
+ valid_path_exists |= path_ok;
+
+ if (path_ok) {
+ valid_pips.push_back(site_pip.pip);
+ }
+ }
+
+ return valid_path_exists;
+}
+
+// Checks all downhill PIPs starting from driver wires.
+// All valid PIPs are stored and returned in a vector.
+static std::vector<PipId> check_downhill_pips(Context *ctx, const SiteArch *site_arch) {
+ auto &cells_in_site = site_arch->site_info->cells_in_site;
+
+ std::vector<PipId> valid_pips;
+ for (auto &net_pair : site_arch->nets) {
+ NetInfo *net = net_pair.first;
+ const SiteNetInfo *site_net = &net_pair.second;
+
+ if (net->driver.cell && cells_in_site.count(net->driver.cell)) {
+ const SiteWire &site_wire = site_net->driver;
+
+ visit_downhill_pips(site_arch, site_wire, valid_pips);
+ }
+ }
+ return valid_pips;
+}
+
bool SiteRouter::checkSiteRouting(const Context *ctx, const TileStatus &tile_status) const
{
// Overview:
@@ -1211,6 +1252,8 @@ void SiteRouter::bindSiteRouting(Context *ctx)
check_routing(site_arch);
apply_routing(ctx, site_arch);
+
+ valid_pips = check_downhill_pips(ctx, &site_arch);
if (verbose_site_router(ctx)) {
print_current_state(&site_arch);
}
diff --git a/fpga_interchange/site_router.h b/fpga_interchange/site_router.h
index cf17026d..3222669a 100644
--- a/fpga_interchange/site_router.h
+++ b/fpga_interchange/site_router.h
@@ -38,6 +38,7 @@ struct SiteRouter
SiteRouter(int16_t site) : site(site), dirty(false), site_ok(true) {}
std::unordered_set<CellInfo *> cells_in_site;
+ std::vector<PipId> valid_pips;
const int16_t site;
mutable bool dirty;