From 8c468acff8900f40e909882cfbf9381a59199b79 Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Wed, 12 May 2021 18:25:47 +0200 Subject: interchange: site router: add valid pips list to check during routing Signed-off-by: Alessandro Comodi --- fpga_interchange/arch.cc | 26 ++++++++++++++----------- fpga_interchange/site_router.cc | 43 +++++++++++++++++++++++++++++++++++++++++ fpga_interchange/site_router.h | 1 + 3 files changed, 59 insertions(+), 11 deletions(-) (limited to 'fpga_interchange') 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 &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 check_downhill_pips(Context *ctx, const SiteArch *site_arch) { + auto &cells_in_site = site_arch->site_info->cells_in_site; + + std::vector 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 cells_in_site; + std::vector valid_pips; const int16_t site; mutable bool dirty; -- cgit v1.2.3