From c9ff60e3923a5bdd88fe4e35981fd662500dc177 Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 10 Feb 2026 15:09:10 +0100 Subject: [PATCH] Support use of router2 for gowin Signed-off-by: gatecat --- common/route/router2.cc | 8 ++++++-- himbaechel/uarch/gowin/gowin.cc | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common/route/router2.cc b/common/route/router2.cc index df1a7876..5097a62e 100644 --- a/common/route/router2.cc +++ b/common/route/router2.cc @@ -54,7 +54,7 @@ struct Router2 { WireId sink_wire; BoundingBox bb; - bool routed = false; + bool routed = false, pre_routed = false; }; // As we allow overlap at first; the nextpnr bind functions can't be used @@ -358,6 +358,9 @@ struct Router2 cursor = ctx->getPipSrcWire(pip); } ad.routed = false; + // Once we've ripped up the arc, the routing may no longer be the same as before... + // (this should only happen if it was not strongly bound) + ad.pre_routed = false; } float score_wire_for_arc(NetInfo *net, store_index user, size_t phys_pin, WireId wire, PipId pip, @@ -419,6 +422,7 @@ struct Router2 auto &nd = nets.at(net->udata); auto &ad = nd.arcs.at(usr.idx()).at(phys_pin); ad.routed = true; + ad.pre_routed = true; WireId src = nets.at(net->udata).src_wire; WireId cursor = ad.sink_wire; @@ -1141,7 +1145,7 @@ struct Router2 if (bound_net == nullptr) { to_bind.push_back(p); } - } else { + } else if (!ad.pre_routed || ctx->getBoundPipNet(p) != net) { // allow pre routing to break normal validity checking rules if (ctx->verbose) { log_info("Failed to bind pip %s to net %s\n", ctx->nameOfPip(p), net->name.c_str(ctx)); } diff --git a/himbaechel/uarch/gowin/gowin.cc b/himbaechel/uarch/gowin/gowin.cc index 3ca0739f..c5e0d76b 100644 --- a/himbaechel/uarch/gowin/gowin.cc +++ b/himbaechel/uarch/gowin/gowin.cc @@ -45,6 +45,7 @@ struct GowinImpl : HimbaechelAPI // wires bool checkPipAvail(PipId pip) const override; + bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override; // Cluster bool isClusterStrict(const CellInfo *cell) const override { return true; } @@ -247,6 +248,12 @@ bool GowinImpl::checkPipAvail(PipId pip) const (!(gwu.is_global_pip(pip) || gwu.is_segment_pip(pip))); } +bool GowinImpl::checkPipAvailForNet(PipId pip, const NetInfo *net) const +{ + return (net->constant_value == IdString() && ctx->getWireConstantValue(ctx->getPipSrcWire(pip)) != IdString()) || + (!(gwu.is_global_pip(pip) || gwu.is_segment_pip(pip))); +} + void GowinImpl::pack() { if (ctx->settings.count(ctx->id("cst.filename"))) {