Merge pull request #656 from litghost/fix_dedicated_interconnect_bug

Fix bug where DedicateInterconnect incorrectly allows some placements.
This commit is contained in:
gatecat 2021-03-30 22:36:51 +01:00 committed by GitHub
commit edecc06fcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 10 deletions

View File

@ -66,8 +66,8 @@ void DedicatedInterconnect::init(const Context *ctx)
} }
} }
bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, BelId dst_bel, bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, BelId dst_bel, IdString dst_bel_pin,
IdString dst_bel_pin) const bool site_only) const
{ {
std::vector<WireNode> nodes_to_expand; std::vector<WireNode> nodes_to_expand;
@ -78,6 +78,10 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B
WireId dst_wire = ctx->getBelPinWire(dst_bel, dst_bel_pin); WireId dst_wire = ctx->getBelPinWire(dst_bel, dst_bel_pin);
if (src_wire == dst_wire) {
return true;
}
const auto &dst_wire_data = ctx->wire_info(dst_wire); const auto &dst_wire_data = ctx->wire_info(dst_wire);
NPNR_ASSERT(dst_wire_data.site != -1); NPNR_ASSERT(dst_wire_data.site != -1);
@ -102,9 +106,9 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B
continue; continue;
} }
#ifdef DEBUG_EXPANSION if (ctx->debug) {
log_info(" - At wire %s via %s\n", ctx->nameOfWire(wire), ctx->nameOfPip(pip)); log_info(" - At wire %s via %s\n", ctx->nameOfWire(wire), ctx->nameOfPip(pip));
#endif }
WireNode next_node; WireNode next_node;
next_node.wire = wire; next_node.wire = wire;
@ -122,6 +126,11 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B
bool expand_node = true; bool expand_node = true;
if (ctx->is_site_port(pip)) { if (ctx->is_site_port(pip)) {
if (site_only) {
// When routing site only, don't allow site ports.
continue;
}
switch (node_to_expand.state) { switch (node_to_expand.state) {
case IN_SOURCE_SITE: case IN_SOURCE_SITE:
NPNR_ASSERT(wire_data.site == -1); NPNR_ASSERT(wire_data.site == -1);
@ -214,8 +223,12 @@ bool DedicatedInterconnect::is_driver_on_net_valid(BelId driver_bel, const CellI
Loc sink_loc = ctx->getBelLocation(port_ref.cell->bel); Loc sink_loc = ctx->getBelLocation(port_ref.cell->bel);
if (sink_bel.tile == driver_bel.tile && sink_bel_data.site == driver_bel_data.site) { if (sink_bel.tile == driver_bel.tile && sink_bel_data.site == driver_bel_data.site) {
// This is a site local routing, even though this is a sink // This might site local routing. See if it can be routed
// with a dedicated interconnect. for (IdString sink_bel_pin : ctx->getBelPinsForCellPin(port_ref.cell, port_ref.port)) {
if (!check_routing(driver_bel, driver_bel_pin, sink_bel, sink_bel_pin, /*site_only=*/true)) {
return false;
}
}
continue; continue;
} }
@ -243,7 +256,7 @@ bool DedicatedInterconnect::is_driver_on_net_valid(BelId driver_bel, const CellI
// FIXME: This might be too slow, but it handles a case on // FIXME: This might be too slow, but it handles a case on
// SLICEL.COUT -> SLICEL.CIN has delta_y = {1, 2}, but the // SLICEL.COUT -> SLICEL.CIN has delta_y = {1, 2}, but the
// delta_y=2 case is rare. // delta_y=2 case is rare.
if (!check_routing(driver_bel, driver_bel_pin, sink_bel, sink_bel_pin)) { if (!check_routing(driver_bel, driver_bel_pin, sink_bel, sink_bel_pin, /*site_only=*/false)) {
if (ctx->debug) { if (ctx->debug) {
log_info("BEL %s is not valid because pin %s cannot be reach %s/%s (via detailed check)\n", log_info("BEL %s is not valid because pin %s cannot be reach %s/%s (via detailed check)\n",
ctx->nameOfBel(driver_bel), driver_bel_pin.c_str(ctx), ctx->nameOfBel(sink_bel), ctx->nameOfBel(driver_bel), driver_bel_pin.c_str(ctx), ctx->nameOfBel(sink_bel),
@ -323,7 +336,7 @@ bool DedicatedInterconnect::is_sink_on_net_valid(BelId bel, const CellInfo *cell
// FIXME: This might be too slow, but it handles a case on // FIXME: This might be too slow, but it handles a case on
// SLICEL.COUT -> SLICEL.CIN has delta_y = {1, 2}, but the // SLICEL.COUT -> SLICEL.CIN has delta_y = {1, 2}, but the
// delta_y=2 case is rare. // delta_y=2 case is rare.
if (!check_routing(driver_bel, driver_type_bel_pin.type_bel_pin.bel_pin, bel, bel_pin)) { if (!check_routing(driver_bel, driver_type_bel_pin.type_bel_pin.bel_pin, bel, bel_pin, /*site_only=*/false)) {
if (ctx->debug) { if (ctx->debug) {
log_info("BEL %s is not valid because pin %s cannot be driven by %s/%s (via detailed check)\n", log_info("BEL %s is not valid because pin %s cannot be driven by %s/%s (via detailed check)\n",
ctx->nameOfBel(bel), bel_pin.c_str(ctx), ctx->nameOfBel(driver_bel), ctx->nameOfBel(bel), bel_pin.c_str(ctx), ctx->nameOfBel(driver_bel),

View File

@ -137,7 +137,7 @@ struct DedicatedInterconnect
void find_dedicated_interconnect(); void find_dedicated_interconnect();
void print_dedicated_interconnect() const; void print_dedicated_interconnect() const;
bool check_routing(BelId src_bel, IdString src_bel_pin, BelId dst_bel, IdString dst_bel_pin) const; bool check_routing(BelId src_bel, IdString src_bel_pin, BelId dst_bel, IdString dst_bel_pin, bool site_only) const;
void expand_sink_bel(BelId bel, IdString pin, WireId wire); void expand_sink_bel(BelId bel, IdString pin, WireId wire);
void expand_source_bel(BelId bel, IdString pin, WireId wire); void expand_source_bel(BelId bel, IdString pin, WireId wire);