From 2400a90e042c52b0b9147fcbaa694f4faf53a911 Mon Sep 17 00:00:00 2001 From: myrtle Date: Tue, 24 Feb 2026 14:28:25 +0100 Subject: [PATCH] router2: Try harder on constants to prevent infinite loop (#1647) Signed-off-by: gatecat --- common/route/router2.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/common/route/router2.cc b/common/route/router2.cc index 5097a62e..304b3b08 100644 --- a/common/route/router2.cc +++ b/common/route/router2.cc @@ -707,6 +707,7 @@ struct Router2 // This records the point where forwards and backwards routing met int midpoint_wire = -1; + float best_midpoint_cost = 0; int explored = 1; for (; mode < 2; mode++) { @@ -776,7 +777,7 @@ struct Router2 // Mode 0 required both queues to be live while (((mode == 0) ? (!t.fwd_queue.empty() && !t.bwd_queue.empty()) : (!t.fwd_queue.empty() || !t.bwd_queue.empty())) && - (!is_bb || iter < toexplore)) { + ((!is_bb && midpoint_wire == -1) || iter < toexplore)) { ++iter; if (!t.fwd_queue.empty() && !const_mode) { // Explore forwards @@ -828,11 +829,26 @@ struct Router2 t.bwd_queue.pop(); ++explored; auto &curr_data = flat_wires.at(curr.wire); - if (was_visited_fwd(curr.wire, std::numeric_limits::max()) || - (const_mode && ctx->getWireConstantValue(curr_data.w) == net->constant_value)) { - // Meet in the middle; done - midpoint_wire = curr.wire; - break; + if (const_mode && ctx->getWireConstantValue(curr_data.w) == net->constant_value) { + if (midpoint_wire == -1) { + midpoint_wire = curr.wire; + best_midpoint_cost = curr.score.cost; + if (curr_cong_weight >= 10) { + // try harder at this point to prevent infinite iterations when constants conflict + toexplore = iter + std::min(200, int(curr.score.cost)); + } else { + break; + } + } else if (curr.score.cost < best_midpoint_cost) { + midpoint_wire = curr.wire; + best_midpoint_cost = curr.score.cost; + } + } else { + if (was_visited_fwd(curr.wire, std::numeric_limits::max())) { + // Meet in the middle; done + midpoint_wire = curr.wire; + break; + } } // Don't allow the same wire to be bound to the same net with a different driving pip PipId bound_pip;