From beff2b912c2dfdd05334f642e1d86bbd197b16ef Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Mon, 10 May 2021 14:03:44 +0200 Subject: [PATCH] interchange: site router: fix illegal site thru paths Signed-off-by: Alessandro Comodi --- fpga_interchange/site_router.cc | 12 ++++++++++++ fpga_interchange/site_routing_storage.h | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/fpga_interchange/site_router.cc b/fpga_interchange/site_router.cc index f8cc2208..561b1790 100644 --- a/fpga_interchange/site_router.cc +++ b/fpga_interchange/site_router.cc @@ -157,6 +157,7 @@ struct SiteExpansionLoop NPNR_ASSERT((*parent)->wire.type == SiteWire::SITE_WIRE); NPNR_ASSERT(node->can_leave_site()); node->mark_left_site(); + node->mark_left_site_after_entering(); } else if (wire.type == SiteWire::SITE_PORT_SOURCE) { // This is a backward walk, so this is considered entering // the site. @@ -171,6 +172,7 @@ struct SiteExpansionLoop // the site. NPNR_ASSERT(node->can_leave_site()); node->mark_left_site(); + node->mark_left_site_after_entering(); } else { NPNR_ASSERT((*parent)->wire.type == SiteWire::SITE_PORT_SOURCE); NPNR_ASSERT(node->can_enter_site()); @@ -274,6 +276,16 @@ struct SiteExpansionLoop } auto node = new_node(wire, pip, &parent_node); + + if (!node->is_valid_node()) { + if (verbose_site_router(ctx)) { + log_info( + "Pip %s is not a valid for this path because it has left the site after entering it.\n", + ctx->nameOfPip(pip)); + } + continue; + } + if (targets.count(wire)) { completed_routes.push_back(node.get_index()); max_depth = std::max(max_depth, node->depth); diff --git a/fpga_interchange/site_routing_storage.h b/fpga_interchange/site_routing_storage.h index a8ea51f5..2fbc246e 100644 --- a/fpga_interchange/site_routing_storage.h +++ b/fpga_interchange/site_routing_storage.h @@ -45,14 +45,25 @@ struct RouteNode LEFT_SITE = 0, // Has this path entered the site? ENTERED_SITE = 1, + // Has this path left the site after entering it? + // This node should be discarded as being part of an illegal path + // which allows entering and exiting a site, situation that needs + // to be handled with a tile PIP. + LEFT_SITE_AFTER_ENTERING = 2, }; bool has_left_site() const { return (flags & (1 << LEFT_SITE)) != 0; } + bool has_left_site_after_entering() const { return (flags & (1 << LEFT_SITE_AFTER_ENTERING)) != 0; } + bool can_leave_site() const { return !has_left_site(); } + bool is_valid_node() const { return !has_left_site_after_entering(); } + void mark_left_site() { flags |= (1 << LEFT_SITE); } + void mark_left_site_after_entering() { flags |= (has_entered_site() << LEFT_SITE_AFTER_ENTERING); } + bool has_entered_site() const { return (flags & (1 << ENTERED_SITE)) != 0; } bool can_enter_site() const { return !has_entered_site(); }