From 746d63f9fa7ffd7fcc5c460c04b65eccfbb3f205 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Jun 2018 15:16:24 +0200 Subject: Refactoring bind/unbind API Signed-off-by: Clifford Wolf --- common/nextpnr.cc | 40 ++++++++++++++++++++++++++++++---------- common/nextpnr.h | 11 ++++++++--- common/place_sa.cc | 36 +++++++++++++++--------------------- common/route.cc | 45 +++++++++++++++++++++++++++++++-------------- 4 files changed, 84 insertions(+), 48 deletions(-) (limited to 'common') diff --git a/common/nextpnr.cc b/common/nextpnr.cc index d29d3fec..188906e2 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -97,20 +97,12 @@ uint32_t Context::checksum() const for (auto &w : ni.wires) { uint32_t wire_x = 123456789; wire_x = xorshift32(wire_x + xorshift32(getWireChecksum(w.first))); - wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second))); + wire_x = xorshift32(wire_x + xorshift32(getPipChecksum(w.second.pip))); + wire_x = xorshift32(wire_x + xorshift32(int(w.second.strength))); wire_x_sum += wire_x; } x = xorshift32(x + xorshift32(wire_x_sum)); - uint32_t pip_x_sum = 0; - for (auto &p : ni.pips) { - uint32_t pip_x = 123456789; - pip_x = xorshift32(pip_x + xorshift32(getPipChecksum(p.first))); - pip_x = xorshift32(pip_x + xorshift32(p.second)); - pip_x_sum += pip_x; - } - x = xorshift32(x + xorshift32(pip_x_sum)); - cksum_nets_sum += x; } cksum = xorshift32(cksum + xorshift32(cksum_nets_sum)); @@ -175,4 +167,32 @@ uint32_t Context::checksum() const return cksum; } +void Context::check() const +{ + for (auto &n : nets) { + auto ni = n.second; + assert(n.first == ni->name); + for (auto &w : ni->wires) { + assert(n.first == getBoundWireNet(w.first)); + if (w.second.pip != PipId()) { + assert(w.first == getPipDstWire(w.second.pip)); + assert(n.first == getBoundPipNet(w.second.pip)); + } + } + } + + for (auto w : getWires()) { + IdString net = getBoundWireNet(w); + if (net != IdString()) { + assert(nets.at(net)->wires.count(w)); + } + } + + for (auto &c : cells) { + assert(c.first == c.second->name); + if (c.second->bel != BelId()) + assert(getBoundBelCell(c.second->bel) == c.first); + } +} + NEXTPNR_NAMESPACE_END diff --git a/common/nextpnr.h b/common/nextpnr.h index 9c6c9d68..8cbead7d 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -211,6 +211,12 @@ struct PortRef delay_t budget = 0; }; +struct PipMap +{ + PipId pip = PipId(); + PlaceStrength strength = STRENGTH_NONE; +}; + struct NetInfo { IdString name; @@ -219,9 +225,7 @@ struct NetInfo std::unordered_map attrs; // wire -> uphill_pip - std::unordered_map wires; - - std::unordered_map pips; + std::unordered_map wires; }; enum PortType @@ -357,6 +361,7 @@ struct Context : Arch } uint32_t checksum() const; + void check() const; }; NEXTPNR_NAMESPACE_END diff --git a/common/place_sa.cc b/common/place_sa.cc index 6743e0ce..f4fb5aff 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -103,9 +103,7 @@ class SAPlacer cell->name.c_str(ctx), cell->type.c_str(ctx)); } - cell->bel = bel; - cell->belStrength = STRENGTH_USER; - ctx->bindBel(bel, cell->name); + ctx->bindBel(bel, cell->name, STRENGTH_USER); locked_bels.insert(bel); placed_cells++; } @@ -231,7 +229,7 @@ class SAPlacer } // Final post-pacement validitiy check for (auto bel : ctx->getBels()) { - IdString cell = ctx->getBelCell(bel, false); + IdString cell = ctx->getBoundBelCell(bel); if (!checker->isBelLocationValid(bel)) { std::string cell_text = "no cell"; if (cell != IdString()) @@ -266,7 +264,6 @@ class SAPlacer BelId ripup_bel = BelId(); if (cell->bel != BelId()) { ctx->unbindBel(cell->bel); - cell->bel = BelId(); } BelType targetType = ctx->belTypeFromId(cell->type); for (auto bel : ctx->getBels()) { @@ -283,7 +280,7 @@ class SAPlacer if (score <= best_ripup_score) { best_ripup_score = score; ripup_target = - ctx->cells.at(ctx->getBelCell(bel, true)); + ctx->cells.at(ctx->getBoundBelCell(bel)); ripup_bel = bel; } } @@ -295,14 +292,11 @@ class SAPlacer cell->name.c_str(ctx), cell->type.c_str(ctx)); --iters; ctx->unbindBel(ripup_target->bel); - ripup_target->bel = BelId(); best_bel = ripup_bel; } else { all_placed = true; } - cell->bel = best_bel; - cell->belStrength = STRENGTH_WEAK; - ctx->bindBel(cell->bel, cell->name); + ctx->bindBel(best_bel, cell->name, STRENGTH_WEAK); // Back annotate location cell->attrs[ctx->id("BEL")] = ctx->getBelName(cell->bel).str(ctx); @@ -375,7 +369,7 @@ class SAPlacer new_lengths.clear(); update.clear(); BelId oldBel = cell->bel; - IdString other = ctx->getBelCell(newBel, true); + IdString other = ctx->getBoundBelCell(newBel); CellInfo *other_cell = nullptr; wirelen_t new_wirelength = 0, delta; ctx->unbindBel(oldBel); @@ -394,10 +388,10 @@ class SAPlacer update.insert(port.second.net); } - ctx->bindBel(newBel, cell->name); + ctx->bindBel(newBel, cell->name, STRENGTH_WEAK); if (other != IdString()) { - ctx->bindBel(oldBel, other_cell->name); + ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK); } if (!checker->isBelLocationValid(newBel) || @@ -408,10 +402,6 @@ class SAPlacer goto swap_fail; } - cell->bel = newBel; - if (other != IdString()) - other_cell->bel = oldBel; - new_wirelength = curr_wirelength; // Recalculate wirelengths for all nets touched by the peturbation @@ -442,11 +432,9 @@ class SAPlacer return true; swap_fail: - ctx->bindBel(oldBel, cell->name); - cell->bel = oldBel; + ctx->bindBel(oldBel, cell->name, STRENGTH_WEAK); if (other != IdString()) { - ctx->bindBel(newBel, other); - other_cell->bel = newBel; + ctx->bindBel(newBel, other, STRENGTH_WEAK); } return false; } @@ -498,8 +486,14 @@ bool place_design_sa(Context *ctx, bool timing_driven) SAPlacer placer(ctx, timing_driven); placer.place(); log_info("Checksum: 0x%08x\n", ctx->checksum()); +#ifndef NDEBUG + ctx->check(); +#endif return true; } catch (log_execution_error_exception) { +#ifndef NDEBUG + ctx->check(); +#endif return false; } } diff --git a/common/route.cc b/common/route.cc index a60f1c41..fe2c05e4 100644 --- a/common/route.cc +++ b/common/route.cc @@ -79,14 +79,26 @@ struct RipupScoreboard void ripup_net(Context *ctx, IdString net_name) { auto net_info = ctx->nets.at(net_name); + std::vector pips; + std::vector wires; + + pips.reserve(net_info->wires.size()); + wires.reserve(net_info->wires.size()); for (auto &it : net_info->wires) { - if (it.second != PipId()) - ctx->unbindPip(it.second); - ctx->unbindWire(it.first); + if (it.second.pip != PipId()) + pips.push_back(it.second.pip); + else + wires.push_back(it.first); } - net_info->wires.clear(); + for (auto pip : pips) + ctx->unbindPip(pip); + + for (auto wire : wires) + ctx->unbindWire(wire); + + assert(net_info->wires.empty()); } struct Router @@ -147,7 +159,7 @@ struct Router if (!ctx->checkWireAvail(next_wire)) { if (!ripup) continue; - IdString ripupWireNet = ctx->getWireNet(next_wire, true); + IdString ripupWireNet = ctx->getConflictingWireNet(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; auto it = scores.wireScores.find( @@ -160,7 +172,7 @@ struct Router if (!ctx->checkPipAvail(pip)) { if (!ripup) continue; - IdString ripupPipNet = ctx->getPipNet(pip, true); + IdString ripupPipNet = ctx->getConflictingPipNet(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; auto it = scores.pipScores.find( @@ -280,8 +292,7 @@ struct Router std::unordered_map src_wires; src_wires[src_wire] = 0; - net_info->wires[src_wire] = PipId(); - ctx->bindWire(src_wire, net_name); + ctx->bindWire(src_wire, net_name, STRENGTH_WEAK); std::vector users_array = net_info->users; ctx->shuffle(users_array); @@ -361,9 +372,9 @@ struct Router if (src_wires.count(cursor)) break; - IdString conflicting_wire_net = ctx->getWireNet(cursor, true); + IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor); IdString conflicting_pip_net = - ctx->getPipNet(visited[cursor].pip, true); + ctx->getConflictingPipNet(visited[cursor].pip); if (conflicting_wire_net != IdString()) { assert(ripup); @@ -388,10 +399,7 @@ struct Router visited[cursor].pip)]++; } - net_info->wires[cursor] = visited[cursor].pip; - ctx->bindWire(cursor, net_name); - ctx->bindPip(visited[cursor].pip, net_name); - + ctx->bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); src_wires[cursor] = visited[cursor].delay; cursor = ctx->getPipSrcWire(visited[cursor].pip); } @@ -495,6 +503,9 @@ bool route_design(Context *ctx) if (iterCnt == 200) { log_warning("giving up after %d iterations.\n", iterCnt); log_info("Checksum: 0x%08x\n", ctx->checksum()); +#ifndef NDEBUG + ctx->check(); +#endif return false; } @@ -655,8 +666,14 @@ bool route_design(Context *ctx) (100.0 * totalOvertimeRevisitCnt) / totalVisitCnt); log_info("Checksum: 0x%08x\n", ctx->checksum()); +#ifndef NDEBUG + ctx->check(); +#endif return true; } catch (log_execution_error_exception) { +#ifndef NDEBUG + ctx->check(); +#endif return false; } } -- cgit v1.2.3