mirror of https://github.com/YosysHQ/nextpnr.git
Gowin. BUGFIX Use a separate net for segment gates (#1470)
* Gowin. BUGFIX Use a separate net for segment gates We use a temporary separate small network (typically 2 - 3 sinks) for routing from the segment network source to the segment gate. This fixes the rare but unpleasant case of self-intersection when a route to a gate is routed using PIPs after the gate, this is no longer allowed when using a separate small network. Signed-off-by: YRabbit <rabbit@yrabbit.cyou> * Gowin. Fix style. Signed-off-by: YRabbit <rabbit@yrabbit.cyou> --------- Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
0c01cb9e41
commit
a5cff55520
|
|
@ -795,23 +795,44 @@ struct GowinGlobalRouter
|
||||||
if (ctx->debug) {
|
if (ctx->debug) {
|
||||||
log_info(" step 3: %s -> \n", ctx->nameOfWire(src_wire));
|
log_info(" step 3: %s -> \n", ctx->nameOfWire(src_wire));
|
||||||
}
|
}
|
||||||
|
// Create a temporary small network where segment gates will be the sinks
|
||||||
|
IdString gate_net_name = ctx->idf("%s$gate_net$", ni->name.c_str(ctx));
|
||||||
|
NetInfo *gate_ni = ctx->createNet(gate_net_name);
|
||||||
|
std::vector<PipId> gate_bound_pips;
|
||||||
|
pool<WireId> gate_bound_wires;
|
||||||
|
|
||||||
for (WireId gatewire : gate_wires) {
|
for (WireId gatewire : gate_wires) {
|
||||||
if (ctx->debug) {
|
if (ctx->debug) {
|
||||||
log_info(" %s\n", ctx->nameOfWire(gatewire));
|
log_info(" %s\n", ctx->nameOfWire(gatewire));
|
||||||
}
|
}
|
||||||
routed = backwards_bfs_route(
|
routed = backwards_bfs_route(
|
||||||
ni, src_wire, gatewire, 1000000, false,
|
gate_ni, src_wire, gatewire, 1000000, false,
|
||||||
[&](PipId pip, WireId src) { return dcs_input_filter(pip); }, &bound_pips);
|
[&](PipId pip, WireId src) { return dcs_input_filter(pip); }, &gate_bound_pips);
|
||||||
if (routed) {
|
if (routed) {
|
||||||
// bind src
|
// bind src
|
||||||
if (ctx->checkWireAvail(src_wire)) {
|
if (ctx->checkWireAvail(src_wire)) {
|
||||||
ctx->bindWire(src_wire, ni, STRENGTH_LOCKED);
|
ctx->bindWire(src_wire, gate_ni, STRENGTH_LOCKED);
|
||||||
bound_wires.insert(src_wire);
|
gate_bound_wires.insert(src_wire);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge with original net
|
||||||
|
if (routed) {
|
||||||
|
for (PipId pip : gate_bound_pips) {
|
||||||
|
ctx->unbindPip(pip);
|
||||||
|
ctx->bindPip(pip, ni, STRENGTH_LOCKED);
|
||||||
|
bound_pips.push_back(pip);
|
||||||
|
}
|
||||||
|
for (WireId wire : gate_bound_wires) {
|
||||||
|
ctx->unbindWire(wire);
|
||||||
|
ctx->bindWire(wire, ni, STRENGTH_LOCKED);
|
||||||
|
bound_wires.insert(wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return routed ? SEG_ROUTED : SEG_NOT_ROUTED;
|
return routed ? SEG_ROUTED : SEG_NOT_ROUTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1172,9 +1193,7 @@ struct GowinGlobalRouter
|
||||||
if (!wires_to_isolate.empty()) {
|
if (!wires_to_isolate.empty()) {
|
||||||
ni->attrs[id_SEG_WIRES_TO_ISOLATE] = wires_to_isolate;
|
ni->attrs[id_SEG_WIRES_TO_ISOLATE] = wires_to_isolate;
|
||||||
}
|
}
|
||||||
if (ctx->verbose) {
|
log_info(" '%s' is routed using segments.\n", ctx->nameOf(ni));
|
||||||
log_info("Net %s is routed using segments.\n", ctx->nameOf(ni));
|
|
||||||
}
|
|
||||||
if (ctx->debug) {
|
if (ctx->debug) {
|
||||||
log_info(" routed\n");
|
log_info(" routed\n");
|
||||||
for (PipId pip : bound_pips) {
|
for (PipId pip : bound_pips) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue